Package: SeqConvTrans

SeqConvTrans

nameinstructionbranchcomplexitylinemethod
SeqConvTrans(TransAssistantIR)
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
caseAApplyExpIR(AApplyExpIR)
M: 0 C: 87
100%
M: 0 C: 16
100%
M: 0 C: 9
100%
M: 0 C: 20
100%
M: 0 C: 1
100%
caseAAssignToExpStmIR(AAssignToExpStmIR)
M: 0 C: 24
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 6
100%
M: 0 C: 1
100%
caseAForAllStmIR(AForAllStmIR)
M: 0 C: 36
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
correctExpToSeq(SExpIR, STypeIR)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
correctExpToString(SExpIR)
M: 0 C: 18
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
correctIfTemplateTypeCase(SExpIR)
M: 0 C: 56
100%
M: 4 C: 10
71%
M: 4 C: 4
50%
M: 0 C: 17
100%
M: 0 C: 1
100%
defaultInSBinaryExpIR(SBinaryExpIR)
M: 0 C: 67
100%
M: 2 C: 16
89%
M: 2 C: 8
80%
M: 0 C: 18
100%
M: 0 C: 1
100%
getMethodType(AApplyExpIR, List)
M: 54 C: 132
71%
M: 6 C: 20
77%
M: 4 C: 10
71%
M: 13 C: 39
75%
M: 0 C: 1
100%
handleExp(SExpIR, STypeIR)
M: 3 C: 20
87%
M: 1 C: 7
88%
M: 1 C: 4
80%
M: 1 C: 4
80%
M: 0 C: 1
100%
handleVarExp(STypeIR, SExpIR)
M: 0 C: 10
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
inAFieldDeclIR(AFieldDeclIR)
M: 0 C: 24
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
inAFieldNumberExpIR(AFieldNumberExpIR)
M: 0 C: 22
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
inAReturnStmIR(AReturnStmIR)
M: 0 C: 49
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 16
100%
M: 0 C: 1
100%
inAVarDeclIR(AVarDeclIR)
M: 1 C: 23
96%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 8
89%
M: 0 C: 1
100%

Coverage

1: package org.overture.codegen.trans;
2:
3: import org.apache.log4j.Logger;
4: import org.overture.ast.definitions.ARenamedDefinition;
5: import org.overture.ast.definitions.PDefinition;
6: import org.overture.ast.expressions.AVariableExp;
7: import org.overture.ast.node.INode;
8: import org.overture.codegen.assistant.AssistantBase;
9: import org.overture.codegen.ir.SExpIR;
10: import org.overture.codegen.ir.STypeIR;
11: import org.overture.codegen.ir.analysis.AnalysisException;
12: import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor;
13: import org.overture.codegen.ir.declarations.AFieldDeclIR;
14: import org.overture.codegen.ir.declarations.AMethodDeclIR;
15: import org.overture.codegen.ir.declarations.AVarDeclIR;
16: import org.overture.codegen.ir.declarations.SClassDeclIR;
17: import org.overture.codegen.ir.expressions.*;
18: import org.overture.codegen.ir.statements.AAssignToExpStmIR;
19: import org.overture.codegen.ir.statements.AForAllStmIR;
20: import org.overture.codegen.ir.statements.AReturnStmIR;
21: import org.overture.codegen.ir.types.*;
22: import org.overture.codegen.trans.assistants.TransAssistantIR;
23:
24: import java.util.LinkedList;
25: import java.util.List;
26:
27: public class SeqConvTrans extends DepthFirstAnalysisAdaptor
28: {
29:         protected Logger log = Logger.getLogger(this.getClass().getName());
30:
31:         private TransAssistantIR transformationAssistant;
32:
33:         public SeqConvTrans(TransAssistantIR transformationAssistant)
34:         {
35:                 this.transformationAssistant = transformationAssistant;
36:         }
37:
38:         @Override
39:         public void caseAForAllStmIR(AForAllStmIR node) throws AnalysisException
40:         {
41:•                if (node.getExp().getType() instanceof AStringTypeIR)
42:                 {
43:                         ASeqSeqTypeIR seqType = new ASeqSeqTypeIR();
44:                         seqType.setEmpty(false);
45:                         seqType.setSeq1(false);
46:                         seqType.setOptional(false);
47:                         seqType.setSeqOf(new ACharBasicTypeIR());
48:
49:                         correctExpToSeq(node.getExp(), seqType);
50:                 }
51:
52:                 node.getBody().apply(this);
53:         }
54:
55:         @Override
56:         public void inAFieldDeclIR(AFieldDeclIR node) throws AnalysisException
57:         {
58:                 STypeIR nodeType = node.getType();
59:                 SExpIR initial = node.getInitial();
60:
61:•                if(nodeType instanceof AStringTypeIR)
62:                 {
63:                         correctIfTemplateTypeCase(initial);
64:                 }
65:                 
66:                 handleVarExp(nodeType, initial);
67:
68:•                if (initial == null)
69:                 {
70:                         return;
71:                 }
72:
73:                 handleExp(initial, nodeType);
74:         }
75:
76:         @Override
77:         public void inAFieldNumberExpIR(AFieldNumberExpIR node)
78:                         throws AnalysisException
79:         {
80:                 node.getTuple().apply(this);
81:
82:•                if (node.getType() instanceof AStringTypeIR)
83:                 {
84:                         correctExpToString(node);
85:•                } else if (node.getType() instanceof SSeqTypeIR)
86:                 {
87:                         correctExpToSeq(node, node.getType());
88:                 }
89:         }
90:
91:         @Override
92:         public void inAVarDeclIR(AVarDeclIR node) throws AnalysisException
93:         {
94:                 STypeIR nodeType = node.getType();
95:                 SExpIR exp = node.getExp();
96:                 
97:•                if(nodeType instanceof AStringTypeIR)
98:                 {
99:                         correctIfTemplateTypeCase(exp);
100:                 }
101:
102:                 handleVarExp(nodeType, exp);
103:
104:•                if (exp == null)
105:                 {
106:                         return;
107:                 }
108:
109:                 handleExp(exp, nodeType);
110:         }
111:
112:         @Override
113:         public void caseAAssignToExpStmIR(AAssignToExpStmIR node)
114:                         throws AnalysisException
115:         {
116:•                if(node.getTarget().getType() instanceof AStringTypeIR)
117:                 {
118:                         correctIfTemplateTypeCase(node.getExp());
119:                 }
120:                 
121:•                if (node.getExp() != null)
122:                 {
123:                         node.getExp().apply(this);
124:                         handleExp(node.getExp(), node.getTarget().getType());
125:                 }
126:         }
127:
128:         private void handleExp(SExpIR exp, STypeIR nodeType)
129:         {
130:•                if (exp.getType() instanceof AStringTypeIR
131:                                 && nodeType instanceof SSeqTypeIR)
132:                 {
133:                         correctExpToSeq(exp, nodeType);
134:•                } else if (exp.getType() instanceof SSeqTypeIR
135:                                 && nodeType instanceof AStringTypeIR)
136:                 {
137:                         correctExpToString(exp);
138:                 }
139:         }
140:
141:         private void handleVarExp(STypeIR nodeType, SExpIR exp)
142:                         throws AnalysisException
143:         {
144:•                if (!(nodeType instanceof SSeqTypeIR))
145:                 {
146:                         return;
147:                 }
148:
149:•                if (exp != null)
150:                 {
151:                         exp.apply(this);
152:                 }
153:         }
154:
155:         public AMethodTypeIR getMethodType(AApplyExpIR node, List<SExpIR> args) throws AnalysisException {
156:                 SExpIR root = node.getRoot();
157:                 STypeIR type = root.getType();
158:
159:                 String moduleName;
160:                 String fieldName;
161:
162:•                if(root instanceof AMethodInstantiationExpIR)
163:                 {
164:                         root = ((AMethodInstantiationExpIR) root).getFunc();
165:                 }
166:
167:•                if(root instanceof AExplicitVarExpIR)
168:                 {
169:                         AExplicitVarExpIR expVar = (AExplicitVarExpIR) root;
170:                         STypeIR classType = expVar.getClassType();
171:
172:•                        if(classType instanceof AClassTypeIR)
173:                         {
174:                                 moduleName = ((AClassTypeIR) classType).getName();
175:                         }
176:                         else
177:                         {
178:                                 return null;
179:                         }
180:                         fieldName = expVar.getName();
181:                 }
182:•                else if(root instanceof AIdentifierVarExpIR)
183:                 {
184:                         fieldName = ((AIdentifierVarExpIR) root).getName();
185:
186:                         INode var = AssistantBase.getVdmNode(node);
187:
188:•                        if(var instanceof AVariableExp) {
189:                                 PDefinition def = ((AVariableExp) var).getVardef();
190:
191:•                                if (def instanceof ARenamedDefinition) {
192:                                         ARenamedDefinition renamedDef = (ARenamedDefinition) def;
193:
194:                                         moduleName = renamedDef.getDef().getName().getModule();
195:                                 }
196:                                 else
197:                                 {
198:                                         SClassDeclIR encClass = node.getAncestor(SClassDeclIR.class);
199:•                                        if(encClass != null)
200:                                         {
201:                                                 moduleName = encClass.getName();
202:                                         }
203:                                         else
204:                                         {
205:                                                 log.warn("Could not find enclosing class for " + node);
206:                                                 return null;
207:                                         }
208:
209:                                 }
210:                         }
211:                         else
212:                         {
213:                                 SClassDeclIR encClass = node.getAncestor(SClassDeclIR.class);
214:•                                if(encClass != null)
215:                                 {
216:                                         moduleName = encClass.getName();
217:                                 }
218:                                 else
219:                                 {
220:                                         log.warn("Could not find enclosing class for " + node);
221:                                         return null;
222:                                 }
223:                         }
224:                 }
225:•                else if(root instanceof AFieldExpIR)
226:                 {
227:                         AFieldExpIR fieldExp = (AFieldExpIR) root;
228:                         fieldName = fieldExp.getMemberName();
229:
230:                         STypeIR classType = ((AFieldExpIR) root).getObject().getType();
231:
232:•                        if(classType instanceof AClassTypeIR)
233:                         {
234:                                 moduleName = ((AClassTypeIR) classType).getName();
235:                         }
236:                         else
237:                         {
238:                                 return null;
239:                         }
240:                 }
241:                 else
242:                 {
243:                         return null;
244:                 }
245:
246:•                if(!(type instanceof AMethodTypeIR))
247:                 {
248:                         return null;
249:                 }
250:
251:                 AMethodTypeIR rootType = (AMethodTypeIR) type;
252:
253:                 // All arguments -- except type arguments (polymorphic types)
254:
255:•                if(args == null)
256:                 {
257:                         args = new LinkedList<>();
258:                 }
259:
260:•                for (int i = 0; i < rootType.getParams().size(); i++) {
261:                         args.add(node.getArgs().get(i));
262:                 }
263:
264:                 AMethodTypeIR methodType = transformationAssistant.getInfo().getTypeAssistant().
265:                                 getMethodType(transformationAssistant.getInfo(), moduleName, fieldName, args);
266:
267:                 return methodType;
268:         }
269:         
270:         private void correctIfTemplateTypeCase(SExpIR arg) throws AnalysisException {
271:                 
272:•                if (arg instanceof AApplyExpIR) {
273:
274:                         AApplyExpIR node = (AApplyExpIR) arg;
275:                         
276:                         AMethodTypeIR methodType = getMethodType(node, new LinkedList<>());
277:
278:•                        if (methodType == null) {
279:                                 return;
280:                         }
281:
282:                         SExpIR root = node.getRoot();
283:
284:•                        if (root instanceof AMethodInstantiationExpIR) {
285:                                 AMethodInstantiationExpIR inst = (AMethodInstantiationExpIR) root;
286:
287:•                                if (inst.getActualTypes().size() == 1) {
288:                                         STypeIR actualType = inst.getActualTypes().get(0);
289:
290:•                                        if (actualType instanceof ACharBasicTypeIR) {
291:                                                 STypeIR resultType = methodType.getResult();
292:•                                                if (resultType instanceof SSeqTypeIR) {
293:                                                         SSeqTypeIR seqType = (SSeqTypeIR) resultType;
294:•                                                        if (seqType.getSeqOf() instanceof ATemplateTypeIR) {
295:                                                                 correctExpToString(node);
296:                                                         }
297:                                                 }
298:                                         }
299:                                 }
300:                         }
301:                 }
302:         }
303:
304:         @Override
305:         public void caseAApplyExpIR(AApplyExpIR node) throws AnalysisException {
306:                 super.caseAApplyExpIR(node);
307:
308:                 List<SExpIR> args = new LinkedList<>();
309:
310:                 AMethodTypeIR methodType = getMethodType(node, args);
311:
312:•                if(methodType == null)
313:                 {
314:                         return;
315:                 }
316:
317:•                for(int i = 0; i < methodType.getParams().size(); i ++)
318:                 {
319:                         STypeIR paramType = methodType.getParams().get(i);
320:
321:                         SExpIR arg = node.getArgs().get(i);
322:
323:                         STypeIR argType;
324:
325:•                        if(arg instanceof AApplyExpIR)
326:                         {
327:                                 // Consider the case where the argument type is string (originating from seq of char).
328:                                 // In this case we cannnot be sure that the return type of the function definition
329:                                 // associated with the apply expression is 'seq of char'.
330:                                 // This is the case if 'arg' is fun[char](..) and the return type of 'fun' is 'seq of @T'.
331:
332:                                 AMethodTypeIR argMethodType = getMethodType((AApplyExpIR) arg, null);
333:
334:•                                if(argMethodType != null)
335:                                 {
336:                                         argType = argMethodType.getResult();
337:                                 }
338:                                 else
339:                                 {
340:                                         // Fall back on the argument type
341:                                         argType = arg.getType();
342:                                 }
343:                         }
344:                         else
345:                         {
346:                                 argType = arg.getType();
347:                         }
348:
349:
350:•                        if (paramType instanceof AStringTypeIR
351:                                         && argType instanceof SSeqTypeIR)
352:                         {
353:                                 correctExpToString(node.getArgs().get(i));
354:
355:•                        } else if (paramType instanceof SSeqTypeIR
356:                                         && argType instanceof AStringTypeIR)
357:                         {
358:                                 correctExpToSeq(node.getArgs().get(i), paramType);
359:                         }
360:                 }
361:         }
362:
363:         @Override
364:         public void defaultInSBinaryExpIR(SBinaryExpIR node)
365:                         throws AnalysisException
366:         {
367:                 SExpIR left = node.getLeft();
368:                 SExpIR right = node.getRight();
369:
370:                 left.apply(this);
371:                 right.apply(this);
372:
373:•                if (left.getType() instanceof AStringTypeIR
374:•                                && right.getType() instanceof AStringTypeIR)
375:                 {
376:                         node.setType(new AStringTypeIR());
377:                         return;
378:                 }
379:
380:•                if (node.getType() instanceof SSeqTypeIR
381:                                 || node instanceof AEqualsBinaryExpIR
382:                                 || node instanceof ANotEqualsBinaryExpIR)
383:                 {
384:•                        if (left.getType() instanceof AStringTypeIR
385:•                                        && right.getType() instanceof SSeqTypeIR)
386:                         {
387:                                 correctExpToString(right);
388:•                        } else if (right.getType() instanceof AStringTypeIR
389:•                                        && left.getType() instanceof SSeqTypeIR)
390:                         {
391:                                 correctExpToString(left);
392:                         } else
393:                         {
394:                                 return;
395:                         }
396:
397:                         node.setType(new AStringTypeIR());
398:                 }
399:         }
400:
401:         @Override
402:         public void inAReturnStmIR(AReturnStmIR node) throws AnalysisException
403:         {
404:                 SExpIR exp = node.getExp();
405:
406:•                if (exp != null)
407:                 {
408:                         exp.apply(this);
409:                 } else
410:                 {
411:                         return;
412:                 }
413:
414:                 AMethodDeclIR method = node.getAncestor(AMethodDeclIR.class);
415:                 AMethodTypeIR methodType = method.getMethodType();
416:
417:•                if (methodType.getResult() instanceof AStringTypeIR)
418:                 {
419:                         correctIfTemplateTypeCase(exp);
420:                         
421:•                        if (!(exp.getType() instanceof SSeqTypeIR))
422:                         {
423:                                 return;
424:                         }
425:
426:                         correctExpToString(exp);
427:                         
428:•                } else if (methodType.getResult() instanceof SSeqTypeIR)
429:                 {
430:•                        if (!(exp.getType() instanceof AStringTypeIR))
431:                         {
432:                                 return;
433:                         }
434:
435:                         correctExpToSeq(exp, exp.getType());
436:                 }
437:         }
438:
439:         private void correctExpToSeq(SExpIR toCorrect, STypeIR type)
440:         {
441:                 AStringToSeqUnaryExpIR conversion = new AStringToSeqUnaryExpIR();
442:
443:                 transformationAssistant.replaceNodeWith(toCorrect, conversion);
444:
445:                 conversion.setType(type.clone());
446:                 conversion.setExp(toCorrect);
447:         }
448:
449:         private void correctExpToString(SExpIR toCorrect)
450:         {
451:                 ASeqToStringUnaryExpIR conversion = new ASeqToStringUnaryExpIR();
452:
453:                 transformationAssistant.replaceNodeWith(toCorrect, conversion);
454:
455:                 conversion.setType(new AStringTypeIR());
456:                 conversion.setExp(toCorrect);
457:         }
458: }