Package: OnFailAnnotation

OnFailAnnotation

nameinstructionbranchcomplexitylinemethod
OnFailAnnotation()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
checkArgs(INode, TypeCheckInfo)
M: 59 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 13 C: 0
0%
M: 1 C: 0
0%
inAfter(PExp, Value, Context)
M: 8 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
inAfter(PStm, Value, Context)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
inBefore(PExp, Context)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
inBefore(PStm, Context)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isBracketed()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
printArgs(Context)
M: 82 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
tcAfter(AModuleModules, TypeCheckInfo)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
tcAfter(PDefinition, TypeCheckInfo)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
tcAfter(PExp, TypeCheckInfo)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
tcAfter(PStm, TypeCheckInfo)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
tcAfter(SClassDefinition, TypeCheckInfo)
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
tcBefore(AModuleModules, TypeCheckInfo)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
tcBefore(PDefinition, TypeCheckInfo)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
tcBefore(PExp, TypeCheckInfo)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
tcBefore(PStm, TypeCheckInfo)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
tcBefore(SClassDefinition, TypeCheckInfo)
M: 8 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
typecheckArgs()
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: *
3: *        Copyright (c) 2019 Nick Battle.
4: *
5: *        Author: Nick Battle
6: *
7: *        This file is part of Overture
8: *
9: ******************************************************************************/
10:
11: package org.overture.annotations.provided;
12:
13: import java.util.Arrays;
14:
15: import org.overture.ast.analysis.AnalysisException;
16: import org.overture.ast.definitions.PDefinition;
17: import org.overture.ast.definitions.SClassDefinition;
18: import org.overture.ast.expressions.AStringLiteralExp;
19: import org.overture.ast.expressions.PExp;
20: import org.overture.ast.modules.AModuleModules;
21: import org.overture.ast.node.INode;
22: import org.overture.ast.statements.PStm;
23: import org.overture.interpreter.annotations.INAnnotation;
24: import org.overture.interpreter.eval.ExpressionEvaluator;
25: import org.overture.interpreter.runtime.Context;
26: import org.overture.interpreter.values.Value;
27: import org.overture.parser.annotations.ASTAnnotationAdapter;
28: import org.overture.typechecker.TypeCheckInfo;
29: import org.overture.typechecker.TypeChecker;
30: import org.overture.typechecker.annotations.TCAnnotation;
31:
32: public class OnFailAnnotation extends ASTAnnotationAdapter implements TCAnnotation, INAnnotation
33: {
34:         public OnFailAnnotation()
35:         {
36:                 super();
37:         }
38:         
39:         @Override
40:         public boolean typecheckArgs()
41:         {
42:                 return true;        // Check args
43:         }
44:
45:         @Override
46:         public boolean isBracketed()
47:         {
48:                 return true;
49:         }
50:         
51:         /**
52:          * Type checker...
53:          */
54:
55:         @Override
56:         public void tcBefore(PDefinition node, TypeCheckInfo question)
57:         {
58:                 TypeChecker.report(6005, "@OnFail only applies to expressions", ast.getName().getLocation());
59:         }
60:
61:         @Override
62:         public void tcBefore(PExp node, TypeCheckInfo question)
63:         {
64:                 checkArgs(node, question);
65:         }
66:
67:         @Override
68:         public void tcBefore(PStm node, TypeCheckInfo question)
69:         {
70:                 TypeChecker.report(6005, "@OnFail only applies to expressions", ast.getName().getLocation());
71:         }
72:
73:         @Override
74:         public void tcBefore(AModuleModules node, TypeCheckInfo question)
75:         {
76:                 TypeChecker.report(6005, "@OnFail only applies to expressions", ast.getName().getLocation());
77:         }
78:
79:         @Override
80:         public void tcBefore(SClassDefinition node, TypeCheckInfo question)
81:         {
82:                 TypeChecker.report(6005, "@OnFail only applies to expressions", ast.getName().getLocation());
83:         }
84:
85:         public void checkArgs(INode node, TypeCheckInfo question)
86:         {
87:•                if (ast.getArgs().isEmpty())
88:                 {
89:                         TypeChecker.report(6008, "@OnFail must srart with a string argument", ast.getName().getLocation());
90:                 }
91:•                else if (!(ast.getArgs().get(0) instanceof AStringLiteralExp))
92:                 {
93:                         TypeChecker.report(6008, "@OnFail must start with a string argument", ast.getName().getLocation());
94:                 }
95:                 else
96:                 {
97:                         AStringLiteralExp str = (AStringLiteralExp)ast.getArgs().get(0);
98:                         String format = str.getValue().getValue();
99:                         
100:                         try
101:                         {
102:                                 // Try to format with string arguments to check they are all %s (up to 20)
103:                                 Object[] args = new String[20];
104:                                 Arrays.fill(args, "A string");
105:                                 String.format(format, args);
106:                         }
107:                         catch (IllegalArgumentException e)
108:                         {
109:                                 TypeChecker.report(6008, "@OnFail must use %[arg$][width]s conversions", ast.getName().getLocation());
110:                         }
111:                 }
112:         }
113:
114:         @Override
115:         public void tcAfter(PDefinition node, TypeCheckInfo question)
116:         {
117:                 // Nothing
118:         }
119:
120:         @Override
121:         public void tcAfter(PExp node, TypeCheckInfo question)
122:         {
123:                 // Nothing
124:         }
125:
126:         @Override
127:         public void tcAfter(PStm node, TypeCheckInfo question)
128:         {
129:                 // Nothing
130:         }
131:
132:         @Override
133:         public void tcAfter(AModuleModules node, TypeCheckInfo question)
134:         {
135:                 // Nothing
136:         }
137:
138:         @Override
139:         public void tcAfter(SClassDefinition node, TypeCheckInfo question)
140:         {
141:                 // Nothing
142:         }
143:         
144:         /**
145:          * Interpreter...
146:          */
147:
148:         @Override
149:         public void inBefore(PStm node, Context ctxt) throws AnalysisException
150:         {
151:                 // Nothing
152:         }
153:
154:         @Override
155:         public void inAfter(PStm node, Value value, Context ctxt)
156:         {
157:                 // Nothing
158:         }
159:
160:         @Override
161:         public void inBefore(PExp node, Context ctxt) throws AnalysisException
162:         {
163:                 // Nothing
164:         }
165:
166:         @Override
167:         public void inAfter(PExp node, Value value, Context ctxt) throws AnalysisException
168:         {
169:•                if (!value.boolValue(ctxt))                // ONLY if we failed
170:                 {
171:                         printArgs(ctxt);
172:                 }
173:         }
174:
175:         private void printArgs(Context ctxt) throws AnalysisException
176:         {
177:                 Object[] values = new Value[ast.getArgs().size() - 1];
178:                 ExpressionEvaluator eval = new ExpressionEvaluator();
179:                 
180:•                for (int p=1; p < ast.getArgs().size(); p++)
181:                 {
182:                         values[p-1] = ast.getArgs().get(p).apply(eval, ctxt);
183:                 }
184:                 
185:                 AStringLiteralExp fmt = (AStringLiteralExp)ast.getArgs().get(0);
186:                 String fmts = fmt.getValue().getValue();
187:                 String location = "";
188:                 
189:•                if (fmts.endsWith("$"))
190:                 {
191:                          location = ast.getName().getLocation().toString();
192:                          fmts = fmts.substring(0, fmts.length() - 1);
193:                 }
194:                                         
195:                 System.out.printf(fmts + location + "\n", values);
196:         }
197: }