Package: PatternTrans

PatternTrans

nameinstructionbranchcomplexitylinemethod
PatternTrans(IterationVarPrefixes, TransAssistantIR, PatternVarPrefixes, String)
M: 0 C: 21
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
basicCaseHandled(SPatternIR)
M: 0 C: 23
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
caseABlockStmIR(ABlockStmIR)
M: 14 C: 190
93%
M: 2 C: 24
92%
M: 2 C: 12
86%
M: 2 C: 46
96%
M: 0 C: 1
100%
caseACasesStmIR(ACasesStmIR)
M: 0 C: 261
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 51
100%
M: 0 C: 1
100%
caseAFieldDeclIR(AFieldDeclIR)
M: 0 C: 16
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
caseAForAllStmIR(AForAllStmIR)
M: 0 C: 88
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 20
100%
M: 0 C: 1
100%
caseALocalPatternAssignmentStmIR(ALocalPatternAssignmentStmIR)
M: 0 C: 49
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
caseAMethodDeclIR(AMethodDeclIR)
M: 31 C: 61
66%
M: 4 C: 6
60%
M: 3 C: 3
50%
M: 6 C: 15
71%
M: 0 C: 1
100%
checkRecordPattern(SExpIR)
M: 0 C: 10
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
consFieldCheckBlock(PatternBlockData, AIdentifierVarExpIR, List, List, boolean)
M: 0 C: 98
100%
M: 1 C: 9
90%
M: 1 C: 5
83%
M: 0 C: 23
100%
M: 0 C: 1
100%
consFieldValueToMatch(AIdentifierVarExpIR, int, STypeIR, boolean)
M: 2 C: 22
92%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 4
80%
M: 0 C: 1
100%
consIdVarDeclaration(PatternInfo, SPatternIR)
M: 0 C: 28
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
consMismatchCheck(AIdentifierVarExpIR, SStmIR)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
consPatternBlock(PatternBlockData, SPatternIR, STypeIR, SExpIR, boolean)
M: 4 C: 69
95%
M: 1 C: 7
88%
M: 1 C: 4
80%
M: 1 C: 17
94%
M: 0 C: 1
100%
consPatternCheck(SPatternIR, STypeIR, SExpIR, ABlockStmIR)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
consPatternCheck(boolean, SPatternIR, STypeIR, PatternBlockData, SExpIR)
M: 23 C: 265
92%
M: 2 C: 26
93%
M: 2 C: 13
87%
M: 2 C: 53
96%
M: 0 C: 1
100%
consPatternHandlingBlock(List)
M: 0 C: 46
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
consPatternHandlingBlockCases(List, PatternBlockData)
M: 0 C: 94
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 20
100%
M: 0 C: 1
100%
consPatternHandlingBlocksSeparate(List, List)
M: 0 C: 71
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
consPatternHandlingInIterationBlock(AVarDeclIR, DeclarationTag, SExpIR)
M: 22 C: 145
87%
M: 3 C: 7
70%
M: 3 C: 3
50%
M: 2 C: 35
95%
M: 0 C: 1
100%
consRecFieldExp(AIdentifierVarExpIR, STypeIR, String)
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%
consRecFieldExp(AIdentifierVarExpIR, int, STypeIR, boolean)
M: 0 C: 45
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
consRecordPatternCheck(boolean, ARecordPatternIR, ARecordTypeIR, PatternBlockData, SExpIR, boolean)
M: 0 C: 179
100%
M: 0 C: 12
100%
M: 0 C: 7
100%
M: 0 C: 37
100%
M: 0 C: 1
100%
consRecordType(ARecordPatternIR)
M: 49 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
consSimplePatternCheck(boolean, SPatternIR, SExpIR, PatternBlockData, SExpIR)
M: 0 C: 94
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 21
100%
M: 0 C: 1
100%
consSuccessVarCheck(SPatternIR, PatternBlockData)
M: 18 C: 51
74%
M: 3 C: 1
25%
M: 2 C: 1
33%
M: 2 C: 11
85%
M: 0 C: 1
100%
consTupleFieldExp(AIdentifierVarExpIR, int, STypeIR, boolean)
M: 0 C: 42
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
consTuplePatternCheck(boolean, ATuplePatternIR, ATupleTypeIR, PatternBlockData, SExpIR, boolean)
M: 0 C: 123
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 28
100%
M: 0 C: 1
100%
consTupleType(ATuplePatternIR)
M: 0 C: 27
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 6
100%
M: 0 C: 1
100%
consType(SPatternIR)
M: 66 C: 31
32%
M: 11 C: 9
45%
M: 10 C: 1
9%
M: 16 C: 10
38%
M: 0 C: 1
100%
consUnionTypedTuplePatternCheck(boolean, AUnionTypeIR, PatternBlockData, SExpIR, ATuplePatternIR)
M: 0 C: 58
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
declareAndAssignIdVarAssignment(ABlockStmIR, SPatternIR, STypeIR, SExpIR)
M: 0 C: 53
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
extractFromCases(List, SExpIR)
M: 0 C: 28
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
extractFromLocalDefs(List)
M: 0 C: 25
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
extractFromParams(List)
M: 0 C: 32
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
extractPatternInfo(AVarDeclIR)
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
fetchTag(PIR)
M: 13 C: 11
46%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 2 C: 4
67%
M: 0 C: 1
100%
getIdPattern(String)
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
initPattern(boolean, SPatternIR, STypeIR, SExpIR, AIdentifierPatternIR)
M: 0 C: 31
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
initSuccessVar(PatternBlockData, SExpIR, ABlockStmIR)
M: 0 C: 28
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
mismatchHandling(SPatternIR, PatternBlockData)
M: 0 C: 63
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 14
100%
M: 0 C: 1
100%
morePatternsToGenerate(List, int)
M: 0 C: 25
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
skipPattern(SPatternIR)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * #%~
3: * VDM Code Generator
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.codegen.trans.patterns;
23:
24: import java.util.LinkedList;
25: import java.util.List;
26:
27: import org.apache.log4j.Logger;
28: import org.overture.codegen.ir.INode;
29: import org.overture.codegen.ir.PIR;
30: import org.overture.codegen.ir.SExpIR;
31: import org.overture.codegen.ir.SPatternIR;
32: import org.overture.codegen.ir.SStmIR;
33: import org.overture.codegen.ir.STypeIR;
34: import org.overture.codegen.ir.analysis.AnalysisException;
35: import org.overture.codegen.ir.analysis.DepthFirstAnalysisAdaptor;
36: import org.overture.codegen.ir.declarations.AFieldDeclIR;
37: import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR;
38: import org.overture.codegen.ir.declarations.AMethodDeclIR;
39: import org.overture.codegen.ir.declarations.ARecordDeclIR;
40: import org.overture.codegen.ir.declarations.AVarDeclIR;
41: import org.overture.codegen.ir.expressions.ABoolLiteralExpIR;
42: import org.overture.codegen.ir.expressions.ACastUnaryExpIR;
43: import org.overture.codegen.ir.expressions.ACharLiteralExpIR;
44: import org.overture.codegen.ir.expressions.AEqualsBinaryExpIR;
45: import org.overture.codegen.ir.expressions.AFieldExpIR;
46: import org.overture.codegen.ir.expressions.AFieldNumberExpIR;
47: import org.overture.codegen.ir.expressions.AIdentifierVarExpIR;
48: import org.overture.codegen.ir.expressions.AIntLiteralExpIR;
49: import org.overture.codegen.ir.expressions.AIsOfClassExpIR;
50: import org.overture.codegen.ir.expressions.ANotUnaryExpIR;
51: import org.overture.codegen.ir.expressions.APatternMatchRuntimeErrorExpIR;
52: import org.overture.codegen.ir.expressions.AQuoteLiteralExpIR;
53: import org.overture.codegen.ir.expressions.ARealLiteralExpIR;
54: import org.overture.codegen.ir.expressions.ATupleCompatibilityExpIR;
55: import org.overture.codegen.ir.expressions.AUndefinedExpIR;
56: import org.overture.codegen.ir.expressions.SVarExpIR;
57: import org.overture.codegen.ir.name.ATypeNameIR;
58: import org.overture.codegen.ir.patterns.ABoolPatternIR;
59: import org.overture.codegen.ir.patterns.ACharPatternIR;
60: import org.overture.codegen.ir.patterns.AIdentifierPatternIR;
61: import org.overture.codegen.ir.patterns.AIgnorePatternIR;
62: import org.overture.codegen.ir.patterns.AIntPatternIR;
63: import org.overture.codegen.ir.patterns.ANullPatternIR;
64: import org.overture.codegen.ir.patterns.AQuotePatternIR;
65: import org.overture.codegen.ir.patterns.ARealPatternIR;
66: import org.overture.codegen.ir.patterns.ARecordPatternIR;
67: import org.overture.codegen.ir.patterns.AStringPatternIR;
68: import org.overture.codegen.ir.patterns.ATuplePatternIR;
69: import org.overture.codegen.ir.statements.AAssignToExpStmIR;
70: import org.overture.codegen.ir.statements.ABlockStmIR;
71: import org.overture.codegen.ir.statements.ACaseAltStmStmIR;
72: import org.overture.codegen.ir.statements.ACasesStmIR;
73: import org.overture.codegen.ir.statements.AContinueStmIR;
74: import org.overture.codegen.ir.statements.AForAllStmIR;
75: import org.overture.codegen.ir.statements.AIfStmIR;
76: import org.overture.codegen.ir.statements.ALocalPatternAssignmentStmIR;
77: import org.overture.codegen.ir.statements.ARaiseErrorStmIR;
78: import org.overture.codegen.ir.types.ABoolBasicTypeIR;
79: import org.overture.codegen.ir.types.ACharBasicTypeIR;
80: import org.overture.codegen.ir.types.AErrorTypeIR;
81: import org.overture.codegen.ir.types.AIntNumericBasicTypeIR;
82: import org.overture.codegen.ir.types.AQuoteTypeIR;
83: import org.overture.codegen.ir.types.ARealNumericBasicTypeIR;
84: import org.overture.codegen.ir.types.ARecordTypeIR;
85: import org.overture.codegen.ir.types.ASeqSeqTypeIR;
86: import org.overture.codegen.ir.types.AStringTypeIR;
87: import org.overture.codegen.ir.types.ATupleTypeIR;
88: import org.overture.codegen.ir.types.AUnionTypeIR;
89: import org.overture.codegen.ir.types.AUnknownTypeIR;
90: import org.overture.codegen.trans.DeclarationTag;
91: import org.overture.codegen.trans.IterationVarPrefixes;
92: import org.overture.codegen.trans.assistants.TransAssistantIR;
93:
94: public class PatternTrans extends DepthFirstAnalysisAdaptor
95: {
96:         private TransAssistantIR transAssistant;
97:
98:         private PatternVarPrefixes config;
99:
100:         private IterationVarPrefixes iteVarPrefixes;
101:
102:         private String casesExpNamePrefix;
103:
104:         private Logger log = Logger.getLogger(this.getClass().getName());
105:
106:         public PatternTrans(IterationVarPrefixes iteVarPrefixes,
107:                         TransAssistantIR transAssistant, PatternVarPrefixes config,
108:                         String casesExpNamePrefix)
109:         {
110:                 this.transAssistant = transAssistant;
111:                 this.iteVarPrefixes = iteVarPrefixes;
112:
113:                 this.config = config;
114:
115:                 this.casesExpNamePrefix = casesExpNamePrefix;
116:         }
117:         
118:         @Override
119:         public void caseAFieldDeclIR(AFieldDeclIR node) throws AnalysisException {
120:
121:                 //TODO: currently values patterns are replaced by strings
122:•                if(node.getName().equals("-"))
123:                 {
124:                         node.setName(transAssistant.getInfo().getTempVarNameGen().nextVarName(config.getIgnorePatternPrefix()));
125:                 }
126:         }
127:
128:         @Override
129:         public void caseALocalPatternAssignmentStmIR(
130:                         ALocalPatternAssignmentStmIR node) throws AnalysisException
131:         {
132:                 AVarDeclIR nextElementDecl = node.getNextElementDecl();
133:                 SPatternIR pattern = nextElementDecl.getPattern();
134:
135:•                if (pattern instanceof AIdentifierPatternIR)
136:                 {
137:                         return;
138:                 }
139:
140:•                if (pattern instanceof AIgnorePatternIR)
141:                 {
142:                         AIdentifierPatternIR idPattern = getIdPattern(config.getIgnorePatternPrefix());
143:                         transAssistant.replaceNodeWith(node.getTarget(), idPattern);
144:                         transAssistant.replaceNodeWith(pattern, idPattern.clone());
145:                         return;
146:                 }
147:
148:                 DeclarationTag tag = fetchTag(node);
149:
150:                 ABlockStmIR replacementBlock = consPatternHandlingInIterationBlock(nextElementDecl, tag, node.getExp());
151:                 transAssistant.replaceNodeWith(node, replacementBlock);
152:         }
153:
154:         @Override
155:         public void caseACasesStmIR(ACasesStmIR node) throws AnalysisException
156:         {
157:                 List<ACaseAltStmStmIR> nodeCases = node.getCases();
158:                 SPatternIR firstOriginal = nodeCases.get(0).getPattern().clone();
159:
160:                 ABlockStmIR replacementBlock = new ABlockStmIR();
161:                 String expName = transAssistant.getInfo().getTempVarNameGen().nextVarName(casesExpNamePrefix);
162:
163:                 SExpIR exp = node.getExp();
164:
165:•                if (!(node.getExp() instanceof SVarExpIR))
166:                 {
167:                         AVarDeclIR expVarDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(node.getExp().getType().clone(), transAssistant.getInfo().getPatternAssistant().consIdPattern(expName), node.getExp().clone());
168:                         replacementBlock.getLocalDefs().add(expVarDecl);
169:                         exp = transAssistant.getInfo().getExpAssistant().consIdVar(expName, node.getExp().getType().clone());
170:                 }
171:
172:                 List<PatternInfo> patternInfo = extractFromCases(nodeCases, exp);
173:                 PatternBlockData patternData = new PatternBlockData(MismatchHandling.NONE);
174:
175:                 List<ABlockStmIR> blocks = consPatternHandlingBlockCases(patternInfo, patternData);
176:
177:                 replacementBlock.getStatements().add(blocks.get(0));
178:
179:                 ANotUnaryExpIR notSuccess = transAssistant.getInfo().getExpAssistant().negate(patternData.getSuccessVar());
180:
181:                 AIfStmIR ifStm = new AIfStmIR();
182:                 ABlockStmIR enclosingIf = new ABlockStmIR();
183:                 enclosingIf.getStatements().add(ifStm);
184:                 replacementBlock.getStatements().add(enclosingIf);
185:
186:                 ifStm.setIfExp(notSuccess);
187:
188:                 AIfStmIR nextCase = ifStm;
189:
190:•                if (nodeCases.size() > 1)
191:                 {
192:                         ifStm.setElseStm(nodeCases.get(0).getResult().clone());
193:
194:                         nextCase = new AIfStmIR();
195:
196:                         enclosingIf = new ABlockStmIR();
197:                         ifStm.setThenStm(enclosingIf);
198:                         enclosingIf.getStatements().add(nextCase);
199:
200:                         // All cases except for the first and the last
201:•                        for (int i = 1; i < nodeCases.size() - 1; i++)
202:                         {
203:                                 enclosingIf.getStatements().addFirst(blocks.get(i));
204:                                 enclosingIf = new ABlockStmIR();
205:
206:                                 ACaseAltStmStmIR currentCase = nodeCases.get(i);
207:                                 nextCase.setIfExp(notSuccess.clone());
208:                                 nextCase.setElseStm(currentCase.getResult().clone());
209:
210:                                 AIfStmIR tmp = new AIfStmIR();
211:                                 enclosingIf.getStatements().add(tmp);
212:
213:                                 nextCase.setThenStm(enclosingIf);
214:                                 nextCase = tmp;
215:                         }
216:                 } else
217:                 {
218:                         APatternMatchRuntimeErrorExpIR matchFail = new APatternMatchRuntimeErrorExpIR();
219:                         matchFail.setType(new AErrorTypeIR());
220:                         matchFail.setMessage(config.getMatchFailedMessage(firstOriginal));
221:                         ARaiseErrorStmIR noMatchStm = new ARaiseErrorStmIR();
222:                         noMatchStm.setError(matchFail);
223:
224:                         ifStm.setElseStm(noMatchStm);
225:                 }
226:
227:                 enclosingIf.getStatements().addFirst(blocks.get(blocks.size() - 1));
228:                 nextCase.setIfExp(patternData.getSuccessVar().clone());
229:                 nextCase.setThenStm(nodeCases.get(nodeCases.size()
230:                                 - 1).getResult().clone());
231:
232:•                if (node.getOthers() != null)
233:                 {
234:                         nextCase.setElseStm(node.getOthers().clone());
235:                 }
236:
237:                 transAssistant.replaceNodeWith(node, replacementBlock);
238:
239:                 ifStm.apply(this);
240:         }
241:
242:         @Override
243:         public void caseAMethodDeclIR(AMethodDeclIR node) throws AnalysisException
244:         {
245:                 List<PatternInfo> patternInfo = extractFromParams(node.getFormalParams());
246:
247:•                if (!node.getAbstract() && node.getBody() != null)
248:                 {
249:                         ABlockStmIR patternHandlingBlock = consPatternHandlingBlock(patternInfo);
250:
251:                         ABlockStmIR newBody = new ABlockStmIR();
252:                         newBody.getStatements().add(patternHandlingBlock);
253:
254:                         SStmIR oldBody = node.getBody();
255:                         transAssistant.replaceNodeWith(oldBody, newBody);
256:                         newBody.getStatements().add(oldBody);
257:
258:                         newBody.apply(this);
259:                 } else
260:                 {
261:•                        for (AFormalParamLocalParamIR param : node.getFormalParams())
262:                         {
263:                                 SPatternIR paramPattern = param.getPattern();
264:
265:•                                if (!(paramPattern instanceof AIdentifierPatternIR))
266:                                 {
267:                                         String prefix = config.getName(param.getPattern().getClass());
268:
269:•                                        if (prefix != null)
270:                                         {
271:                                                 AIdentifierPatternIR idPattern = getIdPattern(prefix);
272:                                                 transAssistant.replaceNodeWith(param.getPattern(), idPattern);
273:                                         } else
274:                                         {
275:                                                 log.error("Could not find prefix for pattern: "
276:                                                                 + paramPattern);
277:                                         }
278:                                 }
279:                         }
280:                 }
281:         }
282:
283:         @Override
284:         public void caseABlockStmIR(ABlockStmIR node) throws AnalysisException
285:         {
286:                 boolean taggedBlock = false;
287:•                for (int i = 0; i < node.getLocalDefs().size(); i++)
288:                 {
289:                         AVarDeclIR dec = node.getLocalDefs().get(i);
290:
291:•                        if (dec.getTag() != null)
292:                         {
293:                                 taggedBlock = true;
294:
295:                                 DeclarationTag tag = fetchTag(dec);
296:
297:•                                if (tag.isDeclared() || !(dec instanceof AVarDeclIR))
298:                                 {
299:                                         continue;
300:                                 }
301:
302:                                 AVarDeclIR nextElementDecl = (AVarDeclIR) dec;
303:
304:                                 SPatternIR pattern = nextElementDecl.getPattern();
305:
306:•                                if (pattern instanceof AIdentifierPatternIR)
307:                                 {
308:                                         continue;
309:                                 }
310:•                                else if(pattern instanceof AIgnorePatternIR)
311:                                 {
312:                                         AIdentifierPatternIR idPattern = getIdPattern(config.getIgnorePatternPrefix());
313:                                         transAssistant.replaceNodeWith(pattern, idPattern);
314:                                         continue;
315:                                 }
316:
317:                                 // TODO: Make it such that the successer var is passed on (multiple binds)
318:                                 ABlockStmIR patternHandlingBlock = consPatternHandlingInIterationBlock(nextElementDecl, tag, nextElementDecl.getExp());
319:
320:                                 List<SStmIR> stms = new LinkedList<SStmIR>();
321:                                 stms.addAll(patternHandlingBlock.getStatements());
322:                                 stms.addAll(node.getStatements());
323:
324:                                 node.setStatements(stms);
325:
326:                                 dec.apply(this);
327:                         }
328:                 }
329:
330:•                if (!taggedBlock)
331:                 {
332:                         List<PatternInfo> patternInfo = extractFromLocalDefs(node.getLocalDefs());
333:
334:•                        if (!patternInfo.isEmpty())
335:                         {
336:                                 List<DeclBlockPair> declBlockPairs = consPatternHandlingBlocksSeparate(node.getLocalDefs(), patternInfo);
337:
338:•                                for (int i = 0; i < declBlockPairs.size(); i++)
339:                                 {
340:                                         DeclBlockPair currentDeclBlockPair = declBlockPairs.get(i);
341:•                                        if (currentDeclBlockPair.getNextDecl() != null)
342:                                         {
343:                                                 // The pattern handling block must be put before the
344:                                                 // enclosing statement of the next declaration
345:                                                 SStmIR stm = transAssistant.getEnclosingStm(currentDeclBlockPair.getNextDecl(), "block statement pattern handling");
346:                                                 ABlockStmIR block = new ABlockStmIR();
347:
348:                                                 transAssistant.replaceNodeWith(stm, block);
349:                                                 block.getStatements().add(currentDeclBlockPair.getBlock());
350:                                                 block.getStatements().add(stm);
351:                                         } else
352:                                         {
353:                                                 // If there is no next declaration the current declaration
354:                                                 // must be the last declaration of the block statement
355:                                                 INode parent = currentDeclBlockPair.getDecl().parent();
356:
357:•                                                if (parent instanceof ABlockStmIR)
358:                                                 {
359:                                                         ABlockStmIR enc = (ABlockStmIR) parent;
360:                                                         enc.getStatements().addFirst(currentDeclBlockPair.getBlock());
361:
362:                                                 } else
363:                                                 {
364:                                                         log.error("Expected parent of current declaration to be a block statement but got: "
365:                                                                         + parent
366:                                                                         + ". Pattern handling block could not be added.");
367:                                                 }
368:                                         }
369:                                 }
370:                         }
371:                 }
372:
373:•                for(AVarDeclIR dcl : node.getLocalDefs())
374:                 {
375:                         dcl.apply(this);
376:                 }
377:
378:•                for (SStmIR stm : node.getStatements())
379:                 {
380:                         stm.apply(this);
381:                 }
382:         }
383:
384:         @Override
385:         public void caseAForAllStmIR(AForAllStmIR node) throws AnalysisException
386:         {
387:                 SPatternIR pattern = node.getPattern();
388:
389:•                if (pattern instanceof AIdentifierPatternIR)
390:                 {
391:                         node.getExp().apply(this);
392:                         node.getBody().apply(this);
393:                         return;
394:                 }
395:
396:•                if (pattern instanceof AIgnorePatternIR)
397:                 {
398:                         AIdentifierPatternIR idPattern = getIdPattern(config.getIgnorePatternPrefix());
399:                         transAssistant.replaceNodeWith(pattern, idPattern);
400:                 }
401:
402:                 PatternBlockData patternData = new PatternBlockData(MismatchHandling.LOOP_CONTINUE);
403:                 patternData.setPattern(pattern);
404:                 ABlockStmIR declBlock = new ABlockStmIR();
405:                 patternData.setDeclBlock(declBlock);
406:
407:                 ABlockStmIR patternHandlingBlock = consPatternCheck(false, pattern, transAssistant.getInfo().getTypeAssistant().findElementType(node.getExp().getType().clone()), patternData, null);
408:
409:•                if (patternHandlingBlock != null)
410:                 {
411:                         declBlock.getStatements().addFirst(patternHandlingBlock);
412:                 }
413:
414:                 declBlock.getStatements().add(node.getBody().clone());
415:
416:                 transAssistant.replaceNodeWith(node.getBody(), declBlock);
417:
418:                 node.getExp().apply(this);
419:                 node.getBody().apply(this);
420:         }
421:
422:         private ABlockStmIR consPatternHandlingInIterationBlock(
423:                         AVarDeclIR nextElementDecl, DeclarationTag tag, SExpIR assignedExp)
424:         {
425:                 PatternInfo declInfo = extractPatternInfo(nextElementDecl);
426:                 ABlockStmIR declBlockTmp = new ABlockStmIR();
427:                 PatternBlockData data = new PatternBlockData(declInfo.getPattern(), declBlockTmp, MismatchHandling.LOOP_CONTINUE);
428:
429:                 AVarDeclIR successVarDecl = tag.getSuccessVarDecl();
430:•                if (successVarDecl != null)
431:                 {
432:                         SPatternIR successVarDeclPattern = successVarDecl.getPattern();
433:•                        if (successVarDeclPattern instanceof AIdentifierPatternIR)
434:                         {
435:                                 AIdentifierPatternIR idPattern = (AIdentifierPatternIR) successVarDeclPattern;
436:                                 data.setSuccessVarDecl(successVarDecl.clone());
437:                                 AIdentifierVarExpIR successVar = transAssistant.consSuccessVar(idPattern.getName());
438:                                 data.setSuccessVar(successVar);
439:                         } else
440:                         {
441:                                 log.error("Expected success variable declaration to use an identifier pattern. Got: "
442:                                                 + successVarDeclPattern);
443:                         }
444:                 }
445:
446:                 List<PatternInfo> patternInfo = new LinkedList<PatternInfo>();
447:                 patternInfo.add(declInfo);
448:
449:                 ABlockStmIR replacementBlock = new ABlockStmIR();
450:                 replacementBlock.getStatements().add(consPatternCheck(false, declInfo.getPattern(), declInfo.getType(), data, declInfo.getActualValue()));
451:                 replacementBlock.getStatements().addAll(declBlockTmp.getStatements());
452:                 ABlockStmIR enclosingBlock = nextElementDecl.getAncestor(ABlockStmIR.class);
453:                 enclosingBlock.getLocalDefs().addAll(declBlockTmp.getLocalDefs());
454:
455:                 AVarDeclIR nextDeclCopy = nextElementDecl.clone();
456:
457:•                if (tag == null || !tag.isDeclared())
458:                 {
459:                         replacementBlock.getLocalDefs().addFirst(nextDeclCopy);
460:                 } else
461:                 {
462:                         SPatternIR nextDeclPattern = nextDeclCopy.getPattern();
463:•                        if (nextDeclPattern instanceof AIdentifierPatternIR)
464:                         {
465:                                 AIdentifierVarExpIR varExp = new AIdentifierVarExpIR();
466:                                 varExp.setType(nextDeclCopy.getType());
467:                                 varExp.setIsLocal(true);
468:                                 varExp.setIsLambda(false);
469:                                 varExp.setName(((AIdentifierPatternIR) nextDeclPattern).getName());
470:
471:                                 AAssignToExpStmIR assignment = new AAssignToExpStmIR();
472:                                 assignment.setTarget(varExp);
473:                                 assignment.setExp(assignedExp.clone());
474:                                 replacementBlock.getStatements().addFirst(assignment);
475:                         } else
476:                         {
477:                                 log.error("Expected the declaration to have its pattern transformed into an identifier pattern. Got: "
478:                                                 + nextDeclPattern);
479:                         }
480:                 }
481:
482:                 return replacementBlock;
483:         }
484:
485:         private List<ABlockStmIR> consPatternHandlingBlockCases(
486:                         List<PatternInfo> patternInfo, PatternBlockData patternData)
487:         {
488:                 List<ABlockStmIR> patternHandlingBlocks = new LinkedList<ABlockStmIR>();
489:
490:•                for (PatternInfo currentInfo : patternInfo)
491:                 {
492:                         SPatternIR currentPattern = currentInfo.getPattern();
493:
494:                         ABlockStmIR nextPatternBlock = new ABlockStmIR();
495:                         patternData.setDeclBlock(nextPatternBlock);
496:
497:                         // Use same success variable
498:                         patternData.setPattern(currentPattern);
499:
500:•                        if (currentPattern instanceof AIdentifierPatternIR)
501:                         {
502:                                 nextPatternBlock.getStatements().add(consIdVarDeclaration(currentInfo, currentPattern));
503:                                 initSuccessVar(patternData, this.transAssistant.getInfo().getExpAssistant().consBoolLiteral(true), nextPatternBlock);
504:•                        } else if (currentPattern instanceof AIgnorePatternIR)
505:                         {
506:                                 initSuccessVar(patternData, this.transAssistant.getInfo().getExpAssistant().consBoolLiteral(true), nextPatternBlock);
507:
508:                         } else
509:                         {
510:                                 STypeIR currentType = currentInfo.getType();
511:                                 SExpIR currentActualValue = currentInfo.getActualValue();
512:
513:                                 boolean declareVarPattern = true;
514:                                 ABlockStmIR patternCheck = consPatternCheck(declareVarPattern, currentPattern, currentType, patternData, currentActualValue);
515:
516:                                 patternCheck.getLocalDefs().addAll(nextPatternBlock.getLocalDefs());
517:                                 nextPatternBlock = patternCheck;
518:                         }
519:
520:                         patternHandlingBlocks.add(nextPatternBlock);
521:                 }
522:
523:                 return patternHandlingBlocks;
524:         }
525:
526:         private ABlockStmIR consIdVarDeclaration(PatternInfo currentInfo,
527:                         SPatternIR currentPattern)
528:         {
529:                 AIdentifierPatternIR idPattern = (AIdentifierPatternIR) currentPattern;
530:                 AVarDeclIR idPatternDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(currentInfo.getType().clone(), idPattern.clone(), currentInfo.getActualValue().clone());
531:
532:                 ABlockStmIR wrappingStatement = new ABlockStmIR();
533:                 wrappingStatement.getLocalDefs().add(idPatternDecl);
534:
535:                 return wrappingStatement;
536:         }
537:
538:         private ABlockStmIR consPatternHandlingBlock(List<PatternInfo> patternInfo)
539:         {
540:                 ABlockStmIR topBlock = new ABlockStmIR();
541:
542:•                for (PatternInfo info : patternInfo)
543:                 {
544:                         SPatternIR currentPattern = info.getPattern();
545:
546:•                        if (!basicCaseHandled(currentPattern))
547:                         {
548:                                 ABlockStmIR currentDeclBlock = new ABlockStmIR();
549:
550:                                 ABlockStmIR patternHandlingBlock = consPatternCheck(currentPattern, info.getType(), info.getActualValue(), currentDeclBlock);
551:                                 currentDeclBlock.getStatements().addFirst(patternHandlingBlock);
552:                                 topBlock.getStatements().add(currentDeclBlock);
553:                         }
554:                 }
555:
556:                 return topBlock;
557:         }
558:
559:         private List<DeclBlockPair> consPatternHandlingBlocksSeparate(
560:                         List<AVarDeclIR> decls, List<PatternInfo> patternInfo)
561:         {
562:                 List<DeclBlockPair> blocks = new LinkedList<DeclBlockPair>();
563:
564:•                for (int i = 0; i < patternInfo.size(); i++)
565:                 {
566:                         PatternInfo info = patternInfo.get(i);
567:
568:•                        if (!basicCaseHandled(info.getPattern()))
569:                         {
570:                                 ABlockStmIR currentDeclBlock = new ABlockStmIR();
571:
572:                                 ABlockStmIR patternHandlingBlock = consPatternCheck(info.getPattern(), info.getType(), info.getActualValue(), currentDeclBlock);
573:                                 currentDeclBlock.getStatements().addFirst(patternHandlingBlock);
574:
575:•                                AVarDeclIR nextDecl = i < decls.size() - 1 ? decls.get(1 + i)
576:                                                 : null;
577:                                 DeclBlockPair declBlockPair = new DeclBlockPair(decls.get(i), nextDecl, currentDeclBlock);
578:
579:                                 blocks.add(declBlockPair);
580:                         }
581:                 }
582:
583:                 return blocks;
584:         }
585:
586:         private boolean basicCaseHandled(SPatternIR currentPattern)
587:         {
588:•                if (currentPattern instanceof AIdentifierPatternIR)
589:                 {
590:                         return true;
591:•                } else if (currentPattern instanceof AIgnorePatternIR)
592:                 {
593:                         AIdentifierPatternIR idPattern = getIdPattern(config.getIgnorePatternPrefix());
594:                         transAssistant.replaceNodeWith(currentPattern, idPattern);
595:
596:                         return true;
597:                 }
598:
599:                 return false;
600:         }
601:
602:         private ABlockStmIR consPatternCheck(SPatternIR pattern, STypeIR type,
603:                         SExpIR actualValue, ABlockStmIR declBlock)
604:         {
605:                 boolean declareVarPattern = false;
606:                 PatternBlockData patternData = new PatternBlockData(pattern, declBlock, MismatchHandling.RAISE_ERROR);
607:
608:                 return consPatternCheck(declareVarPattern, pattern, type, patternData, actualValue);
609:         }
610:
611:         private ABlockStmIR consPatternCheck(boolean declarePatternVar,
612:                         SPatternIR pattern, STypeIR type, PatternBlockData patternData,
613:                         SExpIR actualValue)
614:         {
615:•                if (pattern instanceof ABoolPatternIR)
616:                 {
617:                         ABoolPatternIR boolPattern = (ABoolPatternIR) pattern;
618:
619:                         Boolean value = boolPattern.getValue();
620:                         ABoolLiteralExpIR consBoolLiteral = transAssistant.getInfo().getExpAssistant().consBoolLiteral(value);
621:
622:                         return consSimplePatternCheck(declarePatternVar, boolPattern, consBoolLiteral, patternData, actualValue);
623:•                } else if (pattern instanceof ACharPatternIR)
624:                 {
625:                         ACharPatternIR charPattern = (ACharPatternIR) pattern;
626:
627:                         Character value = charPattern.getValue();
628:                         ACharLiteralExpIR charLiteral = transAssistant.getInfo().getExpAssistant().consCharLiteral(value);
629:
630:                         return consSimplePatternCheck(declarePatternVar, charPattern, charLiteral, patternData, actualValue);
631:•                } else if (pattern instanceof AIntPatternIR)
632:                 {
633:                         AIntPatternIR intPattern = (AIntPatternIR) pattern;
634:
635:                         Long value = intPattern.getValue();
636:                         AIntLiteralExpIR intLit = transAssistant.getInfo().getExpAssistant().consIntLiteral(value);
637:
638:                         return consSimplePatternCheck(declarePatternVar, intPattern, intLit, patternData, actualValue);
639:•                } else if (pattern instanceof ANullPatternIR)
640:                 {
641:                         return consSimplePatternCheck(declarePatternVar, pattern, transAssistant.getInfo().getExpAssistant().consNullExp(), patternData, actualValue);
642:•                } else if (pattern instanceof AQuotePatternIR)
643:                 {
644:                         AQuotePatternIR quotePattern = (AQuotePatternIR) pattern;
645:
646:                         String value = quotePattern.getValue();
647:                         AQuoteLiteralExpIR quoteLit = transAssistant.getInfo().getExpAssistant().consQuoteLiteral(value);
648:
649:                         return consSimplePatternCheck(declarePatternVar, pattern, quoteLit, patternData, actualValue);
650:•                } else if (pattern instanceof ARealPatternIR)
651:                 {
652:                         ARealPatternIR realPattern = (ARealPatternIR) pattern;
653:
654:                         Double value = realPattern.getValue();
655:                         ARealLiteralExpIR realLit = transAssistant.getInfo().getExpAssistant().consRealLiteral(value);
656:
657:                         return consSimplePatternCheck(declarePatternVar, realPattern, realLit, patternData, actualValue);
658:
659:•                } else if (pattern instanceof AStringPatternIR)
660:                 {
661:                         AStringPatternIR stringPattern = (AStringPatternIR) pattern;
662:                         String value = stringPattern.getValue();
663:
664:                         SExpIR stringValue = null;
665:
666:•                        if (transAssistant.getInfo().getSettings().getCharSeqAsString())
667:                         {
668:                                 stringValue = transAssistant.getInfo().getExpAssistant().consStringLiteral(value, false);
669:                         } else
670:                         {
671:                                 ASeqSeqTypeIR seqType = new ASeqSeqTypeIR();
672:                                 seqType.setEmpty(false);
673:                                 seqType.setSeqOf(new ACharBasicTypeIR());
674:
675:                                 stringValue = transAssistant.getInfo().getExpAssistant().consCharSequence(seqType, value);
676:                         }
677:
678:                         return consSimplePatternCheck(declarePatternVar, stringPattern, stringValue, patternData, actualValue);
679:•                } else if (pattern instanceof ATuplePatternIR)
680:                 {
681:                         ATuplePatternIR tuplePattern = (ATuplePatternIR) pattern;
682:
683:•                        if (type instanceof ATupleTypeIR)
684:                         {
685:                                 ATupleTypeIR tupleType = (ATupleTypeIR) type;
686:
687:                                 return consTuplePatternCheck(declarePatternVar, tuplePattern, tupleType, patternData, actualValue, false);
688:•                        } else if (type instanceof AUnionTypeIR)
689:                         {
690:                                 return consUnionTypedTuplePatternCheck(declarePatternVar, (AUnionTypeIR) type, patternData, actualValue, tuplePattern);
691:                         } else
692:                         {
693:                                 log.error("Expected tuple type or union type. Got: " + type);
694:                         }
695:•                } else if (pattern instanceof ARecordPatternIR)
696:                 {
697:                         ARecordPatternIR recordPattern = (ARecordPatternIR) pattern;
698:                         ARecordTypeIR recordType = (ARecordTypeIR) recordPattern.getType();
699:
700:•                        if (type instanceof ARecordTypeIR)
701:                         {
702:
703:                                 return consRecordPatternCheck(declarePatternVar, recordPattern, recordType, patternData, actualValue, checkRecordPattern(actualValue));
704:
705:•                        } else if (type instanceof AUnionTypeIR)
706:                         {
707:                                 return consRecordPatternCheck(declarePatternVar, recordPattern, recordType, patternData, actualValue, true);
708:                         } else
709:                         {
710:                                 log.error("Expected record type or union type. Got: " + type);
711:                         }
712:                 }
713:
714:                 return null;
715:         }
716:
717:         private ABlockStmIR consUnionTypedTuplePatternCheck(
718:                         boolean declarePatternVar, AUnionTypeIR unionType,
719:                         PatternBlockData patternData, SExpIR actualValue,
720:                         ATuplePatternIR tuplePattern)
721:         {
722:                 ATupleTypeIR resTupleType = transAssistant.getInfo().getPatternAssistant().getTupleType(unionType, tuplePattern);
723:
724:                 ABlockStmIR tuplePatternCheck = consTuplePatternCheck(declarePatternVar, tuplePattern, resTupleType, patternData, actualValue, true);
725:
726:                 AIsOfClassExpIR instanceCheck = new AIsOfClassExpIR();
727:                 instanceCheck.setType(new ABoolBasicTypeIR());
728:                 instanceCheck.setCheckedType(patternData.getRootPatternVar().getType().clone());
729:                 instanceCheck.setExp(patternData.getRootPatternVar().clone());
730:
731:                 AIfStmIR typeCheck = new AIfStmIR();
732:                 typeCheck.setIfExp(instanceCheck);
733:                 typeCheck.setThenStm(tuplePatternCheck);
734:
735:                 ABlockStmIR block = new ABlockStmIR();
736:                 block.getStatements().add(typeCheck);
737:
738:                 return block;
739:         }
740:
741:         private ABlockStmIR consRecordPatternCheck(boolean declarePattern,
742:                         ARecordPatternIR recordPattern, ARecordTypeIR recordType,
743:                         PatternBlockData patternData, SExpIR actualValue,
744:                         boolean checkRecordType)
745:         {
746:                 AIdentifierPatternIR idPattern = getIdPattern(config.getName(recordPattern.getClass()));
747:
748:                 AIdentifierVarExpIR recordPatternVar = new AIdentifierVarExpIR();
749:                 recordPatternVar.setType(recordType.clone());
750:                 recordPatternVar.setName(idPattern.getName());
751:                 recordPatternVar.setIsLambda(false);
752:                 recordPatternVar.setIsLocal(true);
753:                 patternData.setRootPatternVar(recordPatternVar);
754:
755:•                if (!declarePattern)
756:                 {
757:                         actualValue = recordPatternVar;
758:                 }
759:
760:                 ABlockStmIR recordPatternBlock = initPattern(declarePattern, recordPattern, recordType, actualValue, idPattern);
761:
762:                 ARecordDeclIR record = transAssistant.getInfo().getAssistantManager().getDeclAssistant().findRecord(transAssistant.getInfo().getClasses(), recordType);
763:
764:•                if (patternData.getSuccessVarDecl() == null)
765:                 {
766:                         consSuccessVarCheck(recordPattern, patternData);
767:                 }
768:
769:                 mismatchHandling(recordPattern, patternData);
770:                 initSuccessVar(patternData, transAssistant.getInfo().getExpAssistant().consBoolLiteral(true), recordPatternBlock);
771:
772:                 List<STypeIR> types = new LinkedList<STypeIR>();
773:
774:•                for (AFieldDeclIR currentField : record.getFields())
775:                 {
776:                         types.add(currentField.getType());
777:                 }
778:
779:•                ABlockStmIR fieldCheckBlock = consFieldCheckBlock(patternData, recordPatternVar, recordPattern.getPatterns(), types, checkRecordType
780:                                 && !declarePattern);
781:
782:                 recordPatternBlock.getStatements().add(fieldCheckBlock);
783:
784:•                if (checkRecordType)
785:                 {
786:                         AIsOfClassExpIR instanceOfExp = new AIsOfClassExpIR();
787:                         instanceOfExp.setType(new ABoolBasicTypeIR());
788:                         instanceOfExp.setExp(actualValue.clone());
789:                         instanceOfExp.setCheckedType(recordType.clone());
790:
791:                         AIfStmIR ifStm = new AIfStmIR();
792:                         ifStm.setIfExp(instanceOfExp);
793:                         ifStm.setThenStm(recordPatternBlock);
794:
795:                         AAssignToExpStmIR setFalse = new AAssignToExpStmIR();
796:                         setFalse.setTarget(patternData.getSuccessVar().clone());
797:                         setFalse.setExp(transAssistant.getInfo().getExpAssistant().consBoolLiteral(false));
798:                         ifStm.setElseStm(setFalse);
799:
800:                         ABlockStmIR wrappingBlock = new ABlockStmIR();
801:                         wrappingBlock.getStatements().add(ifStm);
802:
803:                         return wrappingBlock;
804:                 }
805:
806:                 return recordPatternBlock;
807:         }
808:
809:         @SuppressWarnings("unchecked")
810:         private ABlockStmIR consTuplePatternCheck(boolean declarePatternVar,
811:                         ATuplePatternIR tuplePattern, ATupleTypeIR tupleType,
812:                         PatternBlockData patternData, SExpIR actualValue, boolean cast)
813:         {
814:                 AIdentifierPatternIR idPattern = getIdPattern(config.getName(tuplePattern.getClass()));
815:
816:                 ABlockStmIR tuplePatternBlock = initPattern(declarePatternVar, tuplePattern, tupleType, actualValue, idPattern);
817:
818:                 AIdentifierVarExpIR tuplePatternVar = new AIdentifierVarExpIR();
819:                 tuplePatternVar.setType(tupleType.clone());
820:                 tuplePatternVar.setName(idPattern.getName());
821:                 tuplePatternVar.setIsLambda(false);
822:                 tuplePatternVar.setIsLocal(true);
823:                 patternData.setRootPatternVar(tuplePatternVar);
824:
825:                 ATupleCompatibilityExpIR tupleCheck = new ATupleCompatibilityExpIR();
826:                 tupleCheck.setType(new ABoolBasicTypeIR());
827:
828:•                if (!cast)
829:                 {
830:                         tupleCheck.setTuple(tuplePatternVar.clone());
831:                 } else
832:                 {
833:                         ACastUnaryExpIR castTuple = new ACastUnaryExpIR();
834:                         castTuple.setType(tupleType.clone());
835:                         castTuple.setExp(tuplePatternVar.clone());
836:                         tupleCheck.setTuple(castTuple);
837:                 }
838:
839:                 tupleCheck.setTypes((List<? extends STypeIR>) tupleType.getTypes().clone());
840:
841:•                if (patternData.getSuccessVarDecl() == null)
842:                 {
843:                         consSuccessVarCheck(tuplePattern, patternData);
844:                 }
845:
846:                 mismatchHandling(tuplePattern, patternData);
847:                 initSuccessVar(patternData, tupleCheck, tuplePatternBlock);
848:
849:                 LinkedList<SPatternIR> patterns = tuplePattern.getPatterns();
850:                 LinkedList<STypeIR> types = tupleType.getTypes();
851:
852:                 AIfStmIR fieldSizeCheck = new AIfStmIR();
853:                 fieldSizeCheck.setIfExp(patternData.getSuccessVar().clone());
854:                 fieldSizeCheck.setThenStm(consFieldCheckBlock(patternData, tuplePatternVar, patterns, types, cast));
855:
856:                 tuplePatternBlock.getStatements().add(fieldSizeCheck);
857:
858:                 return tuplePatternBlock;
859:         }
860:
861:         private void consSuccessVarCheck(SPatternIR pattern,
862:                         PatternBlockData patternData)
863:         {
864:                 String successVarName = this.transAssistant.getInfo().getTempVarNameGen().nextVarName(iteVarPrefixes.success());
865:                 SExpIR init = null;
866:
867:•                if (!patternData.IsRootPattern(pattern))
868:                 {
869:•                        init = transAssistant.getInfo().getExpAssistant().consBoolLiteral(pattern instanceof ATuplePatternIR
870:                                         ? false : true);
871:                         init.setType(new ABoolBasicTypeIR());
872:                 } else
873:                 {
874:                         init = new AUndefinedExpIR();
875:                         init.setType(new AUnknownTypeIR());
876:                 }
877:
878:                 AVarDeclIR successVarDecl = transAssistant.consDecl(successVarName, new ABoolBasicTypeIR(), init);
879:                 patternData.setSuccessVarDecl(successVarDecl);
880:
881:                 AIdentifierVarExpIR successVar = transAssistant.consSuccessVar(successVarName);
882:                 patternData.setSuccessVar(successVar);
883:
884:                 patternData.getDeclBlock().getLocalDefs().add(successVarDecl);
885:         }
886:
887:         private void mismatchHandling(SPatternIR pattern,
888:                         PatternBlockData patternData)
889:         {
890:•                if (!patternData.IsRootPattern(pattern))
891:                 {
892:                         return;
893:                 }
894:
895:•                if (patternData.getMismatchHandling() == MismatchHandling.RAISE_ERROR)
896:                 {
897:                         APatternMatchRuntimeErrorExpIR matchFail = new APatternMatchRuntimeErrorExpIR();
898:                         matchFail.setType(new AErrorTypeIR());
899:                         matchFail.setMessage(config.getMatchFailedMessage(pattern));
900:                         ARaiseErrorStmIR noMatchStm = new ARaiseErrorStmIR();
901:                         noMatchStm.setError(matchFail);
902:
903:                         AIfStmIR consMismatchCheck = consMismatchCheck(patternData.getSuccessVar(), noMatchStm);
904:                         patternData.getDeclBlock().getStatements().add(consMismatchCheck);
905:•                } else if (patternData.getMismatchHandling() == MismatchHandling.LOOP_CONTINUE)
906:                 {
907:                         AIfStmIR consMismatchCheck = consMismatchCheck(patternData.getSuccessVar(), new AContinueStmIR());
908:                         patternData.getDeclBlock().getStatements().add(consMismatchCheck);
909:                 }
910:         }
911:
912:         private AIfStmIR consMismatchCheck(AIdentifierVarExpIR successVar,
913:                         SStmIR noMatchStm)
914:         {
915:                 AIfStmIR ifCheck = new AIfStmIR();
916:                 ifCheck.setIfExp(transAssistant.consBoolCheck(successVar.getName(), true));
917:                 ifCheck.setThenStm(noMatchStm);
918:
919:                 return ifCheck;
920:         }
921:
922:         private void initSuccessVar(PatternBlockData patternData, SExpIR initExp,
923:                         ABlockStmIR patternBlock)
924:         {
925:•                if (patternData.getSuccessVarDecl().getExp() instanceof AUndefinedExpIR)
926:                 {
927:                         patternData.getSuccessVarDecl().setExp(initExp);
928:                 } else
929:                 {
930:                         AAssignToExpStmIR successVarAssignment = new AAssignToExpStmIR();
931:                         successVarAssignment.setTarget(patternData.getSuccessVar().clone());
932:                         successVarAssignment.setExp(initExp);
933:
934:                         patternBlock.getStatements().add(successVarAssignment);
935:                 }
936:         }
937:
938:         private ABlockStmIR initPattern(boolean declare, SPatternIR pattern,
939:                         STypeIR type, SExpIR actualValue, AIdentifierPatternIR idPattern)
940:         {
941:                 ABlockStmIR patternBlock = new ABlockStmIR();
942:
943:•                if (declare)
944:                 {
945:                         AVarDeclIR patternDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(type.clone(), idPattern.clone(), actualValue.clone());
946:                         patternBlock.getLocalDefs().add(patternDecl);
947:                 } else
948:                 {
949:                         transAssistant.replaceNodeWith(pattern, idPattern);
950:                 }
951:
952:                 return patternBlock;
953:         }
954:
955:         private ABlockStmIR consFieldCheckBlock(PatternBlockData patternData,
956:                         AIdentifierVarExpIR patternVar, List<SPatternIR> patterns,
957:                         List<STypeIR> types, boolean cast)
958:         {
959:                 ABlockStmIR thenPart = new ABlockStmIR();
960:                 ABlockStmIR topBlock = thenPart;
961:
962:•                for (int i = 0; i < patterns.size(); i++)
963:                 {
964:                         SPatternIR currentPattern = patterns.get(i);
965:                         STypeIR currentType = types.get(i);
966:
967:•                        if (skipPattern(currentPattern))
968:                         {
969:                                 continue;
970:                         } else
971:                         {
972:                                 SExpIR actualValue = consFieldValueToMatch(patternVar, i, currentType, cast);
973:
974:•                                if (currentPattern instanceof AIdentifierPatternIR)
975:                                 {
976:                                         AAssignToExpStmIR localAssignment = declareAndAssignIdVarAssignment(patternData.getDeclBlock(), currentPattern, currentType, actualValue);
977:                                         thenPart.getStatements().add(localAssignment);
978:                                 } else
979:                                 {
980:                                         ABlockStmIR patternBlock = consPatternBlock(patternData, currentPattern, currentType, actualValue, cast);
981:
982:•                                        if (patternBlock != null)
983:                                         {
984:                                                 thenPart.getStatements().add(patternBlock);
985:
986:                                                 // The tuple/record pattern have more field patterns to be generated.
987:                                                 // Check the success variable and add a new nesting level
988:•                                                if (morePatternsToGenerate(patterns, i))
989:                                                 {
990:                                                         AIfStmIR successVarCheck = new AIfStmIR();
991:                                                         successVarCheck.setIfExp(patternData.getSuccessVar().clone());
992:
993:                                                         thenPart.getStatements().add(successVarCheck);
994:
995:                                                         ABlockStmIR newThenPart = new ABlockStmIR();
996:                                                         successVarCheck.setThenStm(newThenPart);
997:
998:                                                         thenPart = newThenPart;
999:                                                 }
1000:                                         }
1001:                                 }
1002:                         }
1003:                 }
1004:
1005:                 return topBlock;
1006:         }
1007:
1008:         private boolean skipPattern(SPatternIR pattern)
1009:         {
1010:                 return pattern instanceof AIgnorePatternIR;
1011:         }
1012:
1013:         private boolean morePatternsToGenerate(List<SPatternIR> patterns,
1014:                         int currentPatternIndex)
1015:         {
1016:                 int nextPatternIndex = currentPatternIndex + 1;
1017:
1018:•                for (int i = nextPatternIndex; i < patterns.size(); i++)
1019:                 {
1020:                         SPatternIR nextPattern = patterns.get(i);
1021:
1022:•                        if (!skipPattern(nextPattern))
1023:                         {
1024:                                 return true;
1025:                         }
1026:                 }
1027:
1028:                 return false;
1029:         }
1030:
1031:         private ABlockStmIR consPatternBlock(PatternBlockData patternData,
1032:                         SPatternIR currentPattern, STypeIR currentType, SExpIR actualValue,
1033:                         boolean cast)
1034:         {
1035:                 ABlockStmIR patternBlock = null;
1036:
1037:•                if (currentPattern instanceof ATuplePatternIR)
1038:                 {
1039:                         ATuplePatternIR nextTuplePattern = (ATuplePatternIR) currentPattern;
1040:
1041:                         ATupleTypeIR nextTupleType;
1042:
1043:•                        if(currentType instanceof ATupleTypeIR)
1044:                         {
1045:                                 nextTupleType = (ATupleTypeIR) currentType;
1046:                         }
1047:                         else
1048:                         {
1049:                                 nextTupleType = consTupleType(nextTuplePattern);
1050:                         }
1051:
1052:                         patternBlock = consTuplePatternCheck(true, nextTuplePattern, nextTupleType, patternData, actualValue, cast);
1053:
1054:•                } else if (currentPattern instanceof ARecordPatternIR)
1055:                 {
1056:                         ARecordPatternIR nextRecordPattern = (ARecordPatternIR) currentPattern;
1057:
1058:                         STypeIR t = nextRecordPattern.getType();
1059:
1060:                         ARecordTypeIR nextRecordType;
1061:
1062:•                        if(t instanceof ARecordTypeIR)
1063:                         {
1064:                                 nextRecordType = (ARecordTypeIR) t;
1065:                         }
1066:                         else
1067:                         {
1068:                                 nextRecordType = consRecordType(nextRecordPattern);
1069:                         }
1070:
1071:                         boolean checkRecordPattern = checkRecordPattern(actualValue);
1072:
1073:                         patternBlock = consRecordPatternCheck(true, nextRecordPattern, nextRecordType, patternData, actualValue, checkRecordPattern);
1074:                 } else
1075:                 {
1076:                         patternBlock = consPatternCheck(true, currentPattern, currentType, patternData, actualValue);
1077:                 }
1078:
1079:                 return patternBlock;
1080:         }
1081:
1082:         private ARecordTypeIR consRecordType(ARecordPatternIR pat)
1083:         {
1084:•                if(pat != null) {
1085:                         STypeIR patType = pat.getType();
1086:
1087:•                        if (patType instanceof ARecordTypeIR) {
1088:                                 ARecordTypeIR recType = (ARecordTypeIR) patType;
1089:                                 return recType.clone();
1090:                         } else {
1091:                                 ARecordTypeIR type = new ARecordTypeIR();
1092:
1093:                                 ATypeNameIR typeName = new ATypeNameIR();
1094:                                 typeName.setName(pat.getTypename());
1095:                                 typeName.setDefiningClass("?");
1096:
1097:                                 type.setName(typeName);
1098:
1099:                                 log.warn("Could not determine defining class for record pattern " + pat);
1100:
1101:                                 return type;
1102:                         }
1103:                 }
1104:                 else
1105:                 {
1106:                         return new ARecordTypeIR();
1107:                 }
1108:         }
1109:
1110:         private ATupleTypeIR consTupleType(ATuplePatternIR pat)
1111:         {
1112:                 ATupleTypeIR type = new ATupleTypeIR();
1113:
1114:•                if(pat != null)
1115:                 {
1116:•                        for(SPatternIR p : pat.getPatterns())
1117:                         {
1118:                                 type.getTypes().add(consType(p));
1119:                         }
1120:                 }
1121:
1122:                 return type;
1123:         }
1124:
1125:         private STypeIR consType(SPatternIR pat)
1126:         {
1127:•                if (pat instanceof ABoolPatternIR)
1128:                 {
1129:                         return new ABoolBasicTypeIR();
1130:•                } else if (pat instanceof ACharPatternIR)
1131:                 {
1132:                         return new ACharBasicTypeIR();
1133:•                } else if (pat instanceof AIntPatternIR)
1134:                 {
1135:                         return new AIntNumericBasicTypeIR();
1136:•                } else if (pat instanceof ANullPatternIR)
1137:                 {
1138:                         return new AUnknownTypeIR();
1139:•                } else if (pat instanceof AQuotePatternIR)
1140:                 {
1141:                         AQuoteTypeIR qt = new AQuoteTypeIR();
1142:                         qt.setValue(((AQuotePatternIR) pat).getValue());
1143:                         return qt;
1144:•                } else if (pat instanceof ARealPatternIR)
1145:                 {
1146:                         return new ARealNumericBasicTypeIR();
1147:
1148:•                } else if (pat instanceof AStringPatternIR)
1149:                 {
1150:•                        if (transAssistant.getInfo().getSettings().getCharSeqAsString())
1151:                         {
1152:                                 return new AStringTypeIR();
1153:                         } else
1154:                         {
1155:                                 ASeqSeqTypeIR seqType = new ASeqSeqTypeIR();
1156:                                 seqType.setEmpty(false);
1157:                                 seqType.setSeqOf(new ACharBasicTypeIR());
1158:
1159:                                 return seqType;
1160:                         }
1161:
1162:•                } else if (pat instanceof ATuplePatternIR)
1163:                 {
1164:                         return consTupleType((ATuplePatternIR) pat);
1165:
1166:•                } else if (pat instanceof ARecordPatternIR)
1167:                 {
1168:                         return consRecordType((ARecordPatternIR) pat);
1169:                 }
1170:
1171:                 return new AUnknownTypeIR();
1172:         }
1173:         private SExpIR consFieldValueToMatch(AIdentifierVarExpIR patternVar,
1174:                         int fieldNumber, STypeIR currentType, boolean cast)
1175:         {
1176:•                if (patternVar.getType() instanceof ATupleTypeIR)
1177:                 {
1178:                         return consTupleFieldExp(patternVar, fieldNumber, currentType, cast);
1179:•                } else if (patternVar.getType() instanceof ARecordTypeIR)
1180:                 {
1181:                         return consRecFieldExp(patternVar, fieldNumber, currentType, cast);
1182:                 }
1183:
1184:                 return null;
1185:         }
1186:
1187:         private AAssignToExpStmIR declareAndAssignIdVarAssignment(
1188:                         ABlockStmIR declBlock, SPatternIR currentPattern,
1189:                         STypeIR currentType, SExpIR valueToMatch)
1190:         {
1191:                 AIdentifierPatternIR currentId = (AIdentifierPatternIR) currentPattern;
1192:
1193:                 AVarDeclIR idVarDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(currentType.clone(), currentPattern.clone(), new AUndefinedExpIR());
1194:
1195:                 declBlock.getLocalDefs().add(idVarDecl);
1196:
1197:                 AIdentifierVarExpIR var = new AIdentifierVarExpIR();
1198:                 var.setType(currentType.clone());
1199:                 var.setName(currentId.getName());
1200:                 var.setIsLocal(true);
1201:                 var.setIsLambda(false);
1202:
1203:                 AAssignToExpStmIR localAssignment = new AAssignToExpStmIR();
1204:                 localAssignment.setTarget(var);
1205:                 localAssignment.setExp(valueToMatch);
1206:
1207:                 return localAssignment;
1208:         }
1209:
1210:         private <T> ABlockStmIR consSimplePatternCheck(boolean declarePatternVar,
1211:                         SPatternIR pattern, SExpIR valueToMatch,
1212:                         PatternBlockData patternData, SExpIR actualValue)
1213:         {
1214:                 // Example:
1215:                 // Number intPattern_2 = 1L;
1216:                 // Boolean success_2 = intPattern_2.longValue() == 1L;
1217:
1218:                 AIdentifierPatternIR idPattern = getIdPattern(config.getName(pattern.getClass()));
1219:                 transAssistant.replaceNodeWith(pattern, idPattern);
1220:
1221:                 ABlockStmIR block = new ABlockStmIR();
1222:
1223:•                if (declarePatternVar)
1224:                 {
1225:                         AVarDeclIR patternDecl = transAssistant.getInfo().getDeclAssistant().consLocalVarDecl(actualValue.getType().clone(), idPattern.clone(), actualValue.clone());
1226:                         block.getLocalDefs().add(patternDecl);
1227:                 }
1228:
1229:                 AIdentifierVarExpIR var = new AIdentifierVarExpIR();
1230:                 var.setType(valueToMatch.getType().clone());
1231:                 var.setName(idPattern.getName());
1232:                 var.setIsLambda(false);
1233:                 var.setIsLocal(true);
1234:                 patternData.setRootPatternVar(var);
1235:
1236:                 AEqualsBinaryExpIR check = new AEqualsBinaryExpIR();
1237:                 check.setType(new ABoolBasicTypeIR());
1238:                 check.setLeft(var);
1239:                 check.setRight(valueToMatch);
1240:
1241:•                if (patternData.getSuccessVarDecl() == null)
1242:                 {
1243:                         consSuccessVarCheck(pattern, patternData);
1244:                 }
1245:
1246:                 mismatchHandling(pattern, patternData);
1247:                 initSuccessVar(patternData, check, block);
1248:
1249:                 return block;
1250:         }
1251:
1252:         public List<PatternInfo> extractFromLocalDefs(List<AVarDeclIR> localDefs)
1253:         {
1254:                 List<PatternInfo> patternInfo = new LinkedList<PatternInfo>();
1255:
1256:•                for (AVarDeclIR decl : localDefs)
1257:                 {
1258:                         PatternInfo currentInfo = extractPatternInfo(decl);
1259:                         patternInfo.add(currentInfo);
1260:                 }
1261:
1262:                 return patternInfo;
1263:         }
1264:
1265:         private PatternInfo extractPatternInfo(AVarDeclIR decl)
1266:         {
1267:                 STypeIR type = decl.getType();
1268:                 SPatternIR pattern = decl.getPattern();
1269:                 SExpIR actualValue = decl.getExp();
1270:
1271:                 return new PatternInfo(type, pattern, actualValue);
1272:         }
1273:
1274:         public List<PatternInfo> extractFromParams(
1275:                         List<AFormalParamLocalParamIR> params)
1276:         {
1277:                 List<PatternInfo> patternInfo = new LinkedList<PatternInfo>();
1278:
1279:•                for (AFormalParamLocalParamIR param : params)
1280:                 {
1281:                         STypeIR type = param.getType();
1282:                         SPatternIR pattern = param.getPattern();
1283:
1284:                         patternInfo.add(new PatternInfo(type, pattern, null));
1285:                 }
1286:
1287:                 return patternInfo;
1288:         }
1289:
1290:         public List<PatternInfo> extractFromCases(List<ACaseAltStmStmIR> cases,
1291:                         SExpIR exp)
1292:         {
1293:                 List<PatternInfo> patternInfo = new LinkedList<PatternInfo>();
1294:
1295:•                for (ACaseAltStmStmIR alt : cases)
1296:                 {
1297:                         patternInfo.add(new PatternInfo(alt.getPatternType(), alt.getPattern(), exp));
1298:                 }
1299:
1300:                 return patternInfo;
1301:         }
1302:
1303:         private AIdentifierPatternIR getIdPattern(String namePrefix)
1304:         {
1305:                 String name = transAssistant.getInfo().getTempVarNameGen().nextVarName(namePrefix);
1306:
1307:                 AIdentifierPatternIR idPattern = new AIdentifierPatternIR();
1308:                 idPattern.setName(name);
1309:
1310:                 return idPattern;
1311:         }
1312:
1313:         private AFieldNumberExpIR consTupleFieldExp(
1314:                         AIdentifierVarExpIR tuplePatternVar, int i, STypeIR currentType,
1315:                         boolean cast)
1316:         {
1317:                 AFieldNumberExpIR fieldNumberExp = new AFieldNumberExpIR();
1318:                 fieldNumberExp.setType(currentType.clone());
1319:
1320:•                if (!cast)
1321:                 {
1322:                         fieldNumberExp.setTuple(tuplePatternVar.clone());
1323:                 } else
1324:                 {
1325:                         ACastUnaryExpIR castedExp = new ACastUnaryExpIR();
1326:                         castedExp.setType(tuplePatternVar.getType().clone());
1327:                         castedExp.setExp(tuplePatternVar.clone());
1328:                         fieldNumberExp.setTuple(castedExp);
1329:                 }
1330:
1331:                 fieldNumberExp.setField(new Long(1 + i));
1332:
1333:                 return fieldNumberExp;
1334:         }
1335:
1336:         private SExpIR consRecFieldExp(AIdentifierVarExpIR patternVar, int i,
1337:                         STypeIR currentType, boolean cast)
1338:         {
1339:                 ARecordTypeIR recordType = (ARecordTypeIR) patternVar.getType();
1340:
1341:                 AFieldDeclIR recordField = transAssistant.getInfo().getAssistantManager().getDeclAssistant().getFieldDecl(transAssistant.getInfo().getClasses(), recordType, i);
1342:                 String fieldName = recordField.getName();
1343:
1344:                 AFieldExpIR fieldExp = consRecFieldExp(patternVar, currentType, fieldName);
1345:
1346:•                if (cast)
1347:                 {
1348:                         ACastUnaryExpIR casted = new ACastUnaryExpIR();
1349:                         casted.setType(recordType.clone());
1350:                         casted.setExp(fieldExp.getObject());
1351:
1352:                         fieldExp.setObject(casted);
1353:                 }
1354:
1355:                 return fieldExp;
1356:         }
1357:
1358:         private AFieldExpIR consRecFieldExp(AIdentifierVarExpIR patternVar,
1359:                         STypeIR currentType, String fieldName)
1360:         {
1361:                 AFieldExpIR fieldExp = new AFieldExpIR();
1362:                 fieldExp.setType(currentType.clone());
1363:                 fieldExp.setObject(patternVar.clone());
1364:                 fieldExp.setMemberName(fieldName);
1365:
1366:                 return fieldExp;
1367:         }
1368:
1369:         private DeclarationTag fetchTag(PIR node)
1370:         {
1371:•                if (node != null)
1372:                 {
1373:                         Object tag = node.getTag();
1374:•                        if (tag instanceof DeclarationTag)
1375:                         {
1376:                                 return (DeclarationTag) tag;
1377:                         }
1378:                 }
1379:
1380:                 log.error("Could not fetch declaration tag from pattern assignment: "
1381:                                 + node);
1382:
1383:                 return null;
1384:         }
1385:
1386:         private boolean checkRecordPattern(SExpIR actualValue)
1387:         {
1388:•                return actualValue != null
1389:•                                && actualValue.getType() instanceof AUnionTypeIR;
1390:         }
1391: }