Package: PrintfAnnotation

PrintfAnnotation

nameinstructionbranchcomplexitylinemethod
PrintfAnnotation()
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: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 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: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
inBefore(PStm, Context)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
printArgs(Context)
M: 51 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 7 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: 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(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 PrintfAnnotation extends ASTAnnotationAdapter implements TCAnnotation, INAnnotation
33: {
34:         public PrintfAnnotation()
35:         {
36:                 super();
37:         }
38:         
39:         @Override
40:         public boolean typecheckArgs()
41:         {
42:                 return true;        // Check args
43:         }
44:         
45:         /**
46:          * Type checker...
47:          */
48:
49:         @Override
50:         public void tcBefore(PDefinition node, TypeCheckInfo question)
51:         {
52:                 TypeChecker.report(6005, "@Printf only applies to expressions and statements", ast.getName().getLocation());
53:         }
54:
55:         @Override
56:         public void tcBefore(PExp node, TypeCheckInfo question)
57:         {
58:                 checkArgs(node, question);
59:         }
60:
61:         @Override
62:         public void tcBefore(PStm node, TypeCheckInfo question)
63:         {
64:                 checkArgs(node, question);
65:         }
66:
67:         @Override
68:         public void tcBefore(AModuleModules node, TypeCheckInfo question)
69:         {
70:                 TypeChecker.report(6005, "@Printf only applies to expressions and statements", ast.getName().getLocation());
71:         }
72:
73:         @Override
74:         public void tcBefore(SClassDefinition node, TypeCheckInfo question)
75:         {
76:                 TypeChecker.report(6005, "@Printf only applies to expressions and statements", ast.getName().getLocation());
77:         }
78:
79:         public void checkArgs(INode node, TypeCheckInfo question)
80:         {
81:•                if (ast.getArgs().isEmpty())
82:                 {
83:                         TypeChecker.report(6008, "@Printf must srart with a string argument", ast.getName().getLocation());
84:                 }
85:•                else if (!(ast.getArgs().get(0) instanceof AStringLiteralExp))
86:                 {
87:                         TypeChecker.report(6008, "@Printf must start with a string argument", ast.getName().getLocation());
88:                 }
89:                 else
90:                 {
91:                         AStringLiteralExp str = (AStringLiteralExp)ast.getArgs().get(0);
92:                         String format = str.getValue().getValue();
93:                         
94:                         try
95:                         {
96:                                 // Try to format with string arguments to check they are all %s (up to 20)
97:                                 Object[] args = new String[20];
98:                                 Arrays.fill(args, "A string");
99:                                 String.format(format, args);
100:                         }
101:                         catch (IllegalArgumentException e)
102:                         {
103:                                 TypeChecker.report(6008, "@Printf must use %[arg$][width]s conversions", ast.getName().getLocation());
104:                         }
105:                 }
106:         }
107:
108:         @Override
109:         public void tcAfter(PDefinition node, TypeCheckInfo question)
110:         {
111:                 // Nothing
112:         }
113:
114:         @Override
115:         public void tcAfter(PExp node, TypeCheckInfo question)
116:         {
117:                 // Nothing
118:         }
119:
120:         @Override
121:         public void tcAfter(PStm node, TypeCheckInfo question)
122:         {
123:                 // Nothing
124:         }
125:
126:         @Override
127:         public void tcAfter(AModuleModules node, TypeCheckInfo question)
128:         {
129:                 // Nothing
130:         }
131:
132:         @Override
133:         public void tcAfter(SClassDefinition node, TypeCheckInfo question)
134:         {
135:                 // Nothing
136:         }
137:         
138:         /**
139:          * Interpreter...
140:          */
141:
142:         @Override
143:         public void inBefore(PStm node, Context ctxt) throws AnalysisException
144:         {
145:                 printArgs(ctxt);
146:         }
147:
148:         @Override
149:         public void inAfter(PStm node, Value value, Context ctxt)
150:         {
151:                 // Nothing
152:         }
153:
154:         @Override
155:         public void inBefore(PExp node, Context ctxt) throws AnalysisException
156:         {
157:                 printArgs(ctxt);
158:         }
159:
160:         @Override
161:         public void inAfter(PExp node, Value value, Context ctxt)
162:         {
163:                 // Nothing
164:         }
165:
166:         private void printArgs(Context ctxt) throws AnalysisException
167:         {
168:                 Object[] values = new Value[ast.getArgs().size() - 1];
169:                 ExpressionEvaluator eval = new ExpressionEvaluator();
170:                 
171:•                for (int p=1; p < ast.getArgs().size(); p++)
172:                 {
173:                         values[p-1] = ast.getArgs().get(p).apply(eval, ctxt);
174:                 }
175:                 
176:                 AStringLiteralExp fmt = (AStringLiteralExp)ast.getArgs().get(0);
177:                 System.out.printf(fmt.getValue().getValue(), values);
178:         }
179: }