source: branches/dev-mj-5835/Compiler/ModelicaFrontEnd/src/jastadd/errorcheck/ComplianceCheck.jadd @ 13714

Last change on this file since 13714 was 13714, checked in by Jesper Mattsson, 2 months ago

Updated error message for variability of format argument of String, and added additional tests. (#5835)

File size: 18.5 KB
Line 
1/*
2    Copyright (C) 2010 Modelon AB
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, version 3 of the License.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program.  If not, see <http://www.gnu.org/licenses/>.
15*/
16
17import org.jmodelica.util.ErrorCheckType;
18import org.jmodelica.util.problemHandling.SimpleProblemProducer;
19import org.jmodelica.util.problemHandling.SimpleWarningProducer;
20import org.jmodelica.util.problemHandling.SimpleErrorProducer;
21import org.jmodelica.util.problemHandling.ComplianceFMUOnlyProducer;
22
23aspect ComplianceCheck {
24
25    /**
26     * Check for code that is not allowed in its current context.
27     *
28     * Examples would be checking that classes follow the requirements of
29     * their restriction.
30     */
31    public void ASTNode.complianceCheck(ErrorCheckType checkType) {}
32
33    public abstract class ErrorChecker {
34        public static class ComplianceChecker extends ErrorChecker {
35            public ComplianceChecker() {
36                super("ComplianceCheck");
37            }
38
39            @Override
40            public void check(ASTNode node, ErrorCheckType checkType) {
41                node.complianceCheck(checkType);
42            }
43        }
44    }
45
46    private static ErrorChecker ASTNode.COMPLIANCE_CHECKER = addErrorChecker(new ErrorChecker.ComplianceChecker());
47
48    public static final SimpleProblemProducer ASTNode.ONLY_FMU_IF_STATEMENTS =
49            new ComplianceFMUOnlyProducer("ONLY_FMU_IF_STATEMENTS", "Using if statements is");
50
51    public void FIfWhenClause.complianceCheck(ErrorCheckType checkType) {
52        super.complianceCheck(checkType);
53        if (!getTest().variability().parameterOrLess())
54            ONLY_FMU_IF_STATEMENTS.invoke(this);
55    }
56
57    public static final SimpleProblemProducer ASTNode.ONLY_FMU_WHILE_STATEMENTS =
58            new ComplianceFMUOnlyProducer("ONLY_FMU_WHILE_STATEMENTS", "Using while statements is");
59
60    public void FWhileStmt.complianceCheck(ErrorCheckType checkType) {
61        super.complianceCheck(checkType);
62        if (!getTest().variability().parameterOrLess())
63            ONLY_FMU_WHILE_STATEMENTS.invoke(this);
64    }
65
66    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_EVENT_GENERATING_EXPRESSION_IN_WHILE_STATEMENT =
67            new SimpleErrorProducer("UNSUPPORTED_EVENT_GENERATING_EXPRESSION_IN_WHILE_STATEMENT", ProblemKind.COMPLIANCE, "Event generating expressions are not supported in while statements");
68
69    public void FRelExp.complianceCheck(ErrorCheckType checkType) {
70        super.complianceCheck(checkType);
71        if (!inFunction() && generatesEvent() && inWhile())
72            UNSUPPORTED_EVENT_GENERATING_EXPRESSION_IN_WHILE_STATEMENT.invoke(this);
73    }
74
75    public static final SimpleProblemProducer ASTNode.ONLY_FMU_FUNCTION_LIKE_OPERATOR =
76            new ComplianceFMUOnlyProducer("ONLY_FMU_FUNCTION_LIKE_OPERATOR", "The %s() function-like operator is");
77
78    public void FEventGenExp.complianceCheck(ErrorCheckType checkType) {
79        super.complianceCheck(checkType);
80        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, name());
81        if (!inFunction() && generatesEvent() && inWhile())
82            UNSUPPORTED_EVENT_GENERATING_EXPRESSION_IN_WHILE_STATEMENT.invoke(this);
83    }
84
85    inh boolean FRelExp.inWhile();
86    inh boolean FEventGenExp.inWhile();
87    eq FWhileStmt.getChild().inWhile() = true;
88    eq Root.getChild().inWhile() = false;
89    eq FAlgorithm.getChild().inWhile() = false;
90       
91    public static final SimpleProblemProducer ASTNode.ONLY_FMU_NON_FIXED_RECORD_ARRAY_INDEX =
92            new ComplianceFMUOnlyProducer("ONLY_FMU_NON_FIXED_RECORD_ARRAY_INDEX", "Using arrays of records with indices of higher than parameter variability is");
93    public static final SimpleProblemProducer ASTNode.EXTERNAL_OBJECT_CONSTANT_IN_COMPOSITE =
94            new SimpleErrorProducer("EXTERNAL_OBJECT_CONSTANT_IN_COMPOSITE", ProblemKind.COMPLIANCE, "Access to external object constants in arrays or records is not supported");
95   
96
97    public void InstAccess.complianceCheck(ErrorCheckType checkType) {
98        super.complianceCheck(checkType);
99        InstComponentDecl decl = myInstComponentDecl();
100        if (decl.isRecord() && hasFArraySubscripts() && inFunction() && 
101                !getFArraySubscripts().variability().parameterOrLess()) {
102            ONLY_FMU_NON_FIXED_RECORD_ARRAY_INDEX.invoke(this);
103        }
104        if (decl.isExternalObject() && decl.isConstant() && (decl.inRecord() || decl.isArray())) {
105            EXTERNAL_OBJECT_CONSTANT_IN_COMPOSITE.invoke(this);
106        }
107    }
108
109    public static final SimpleProblemProducer ASTNode.ONLY_FMU_WHEN_EQUATIONS =
110            new ComplianceFMUOnlyProducer("ONLY_FMU_WHEN_EQUATIONS", "When equations are");
111
112    public void FWhenEquation.complianceCheck(ErrorCheckType checkType) {
113        ONLY_FMU_WHEN_EQUATIONS.invoke(this);
114    }
115
116    @Deprecated
117    public void ASTNode.complianceOnlyFMU(String message) {
118        if (!myOptions().getBooleanOption("generate_ode"))
119            compliance(message + " currently only supported when compiling FMUs");
120    }
121
122    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_EQUATION_TYPE =
123            new SimpleErrorProducer("UNSUPPORTED_EQUATION_TYPE", ProblemKind.COMPLIANCE, "Unsupported equation type");
124
125    public void FUnsupportedEquation.collectErrors(ErrorCheckType checkType) {
126        UNSUPPORTED_EQUATION_TYPE.invoke(this);
127    }
128
129    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_EXPRESSION_TYPE =
130            new SimpleErrorProducer("UNSUPPORTED_EXPRESSION_TYPE", ProblemKind.COMPLIANCE, "Unsupported expression type");
131
132    public void FUnsupportedExp.collectErrors(ErrorCheckType checkType) {
133        UNSUPPORTED_EXPRESSION_TYPE.invoke(this);
134    }
135
136    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTION_LIKE_OPERATOR =
137            new SimpleErrorProducer("UNSUPPORTED_FUNCTION_LIKE_OPERATOR", ProblemKind.COMPLIANCE, "The %s() function-like operator is not supported");
138
139    public void FUnsupportedBuiltIn.complianceCheck(ErrorCheckType checkType) {
140        UNSUPPORTED_FUNCTION_LIKE_OPERATOR.invoke(this, getName());
141    }
142
143    public void FSampleExp.complianceCheck(ErrorCheckType checkType) {
144        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "sample");
145    }
146
147    public void InstPreExp.complianceCheck(ErrorCheckType checkType) {
148        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "pre");
149    }
150
151    public void FEdgeExp.complianceCheck(ErrorCheckType checkType) {
152        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "edge");
153    }
154
155    public void FChangeExp.complianceCheck(ErrorCheckType checkType) {
156        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "change");
157    }
158
159    public void FInitialExp.complianceCheck(ErrorCheckType checkType) {
160        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "initial");
161    }
162
163    public void FSignExp.complianceCheck(ErrorCheckType checkType) {
164        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "sign");
165    }
166
167    public void FSemiLinearExp.complianceCheck(ErrorCheckType checkType) {
168        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "semiLinear");
169    }
170
171    public static final SimpleProblemProducer ASTNode.DEPRECATED_DECOUPLE =
172            new SimpleWarningProducer("DEPRECATED_DECOUPLE", ProblemKind.SEMANTIC, "The Subtask.decouple() function-like operator is removed as of Modelica version 3.2r2");
173
174    public void FDecouple.complianceCheck(ErrorCheckType checkType) {
175        DEPRECATED_DECOUPLE.invoke(this);
176    }
177
178    public static final SimpleProblemProducer ASTNode.DEPRECATED_CARDINALITY =
179            new SimpleWarningProducer("DEPRECATED_CARDINALITY", ProblemKind.SEMANTIC, "The cardinality() function-like operator is deprecated, and will be removed in a future version of Modelica");
180
181    public static final SimpleProblemProducer ASTNode.INCORRECT_USE_OF_CARDINALITY =
182            new SimpleErrorProducer("INCORRECT_USE_OF_CARDINALITY", ProblemKind.COMPLIANCE, "The cardinality() function-like operator is only supported in asserts and in the tests of if clauses that do not contain connect()");
183
184    public void FCardinality.complianceCheck(ErrorCheckType checkType) {
185        DEPRECATED_CARDINALITY.invoke(this);
186        if (!inAssert() && !inIfTestWithoutConnect()) 
187            INCORRECT_USE_OF_CARDINALITY.invoke(this);
188    }
189
190    public void FDelayExp.complianceCheck(ErrorCheckType checkType) {
191        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "delay");
192    }
193   
194    public static final SimpleProblemProducer ASTNode.INCORRECT_USE_OF_SPATIAL_DISTRIBUTION =
195            new SimpleErrorProducer("INCORRECT_USE_OF_SPATIAL_DISTRIBUTION", ProblemKind.COMPLIANCE, "The spatialDistribution() function-like operator is not supported vectorized in function call equations");
196   
197    public void FSpatialDistExp.complianceCheck(ErrorCheckType checkType) {
198        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "spatialDistribution");
199        FAbstractEquation equation = myFEquation();
200        if (isArray() && equation != null && equation instanceof FFunctionCallEquation) {
201            INCORRECT_USE_OF_SPATIAL_DISTRIBUTION.invoke(this);
202        }
203    }
204
205        inh boolean FCardinality.inAssert();
206        eq FAssert.getChild().inAssert()  = true;
207        eq Root.getChild().inAssert()     = false;
208        eq InstNode.getChild().inAssert() = false;
209       
210        inh boolean FCardinality.inIfTestWithoutConnect();
211        eq FIfEquation.getTest().inIfTestWithoutConnect() = !containsConnect();
212        eq Root.getChild().inIfTestWithoutConnect()       = false;
213        eq InstNode.getChild().inIfTestWithoutConnect()   = false;
214       
215        syn boolean FAbstractEquation.containsConnect() = false;
216        eq FConnectClause.containsConnect()             = true;
217        eq FForClauseE.containsConnect()                = containsConnect(getFAbstractEquations());
218        eq FIfWhenElseEquation.containsConnect()        = containsConnect(getFAbstractEquations());
219        eq FIfWhenEquation.containsConnect()            = 
220                super.containsConnect() || (hasElse() && getElse().containsConnect());
221       
222        public static boolean FAbstractEquation.containsConnect(List<FAbstractEquation> eqns) {
223                for (FAbstractEquation eqn : eqns)
224                        if (eqn.containsConnect())
225                                return true;
226                return false;
227        }
228
229    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_IN_FUNCTION_UNKNOWN_SIZE_OPERATOR =
230            new SimpleErrorProducer("UNSUPPORTED_IN_FUNCTION_UNKNOWN_SIZE_OPERATOR", ProblemKind.COMPLIANCE, "Unknown sizes in operator %s is not supported in functions");
231
232    public void FUnaryBuiltIn.complianceCheck(ErrorCheckType checkType) {
233        super.complianceCheck(checkType);
234        if (!unknownSizeSupported() && inFunction() && getFExp().size().isUnknown()) {
235            UNSUPPORTED_IN_FUNCTION_UNKNOWN_SIZE_OPERATOR.invoke(this, name() + "()");
236        }
237    }
238
239        syn boolean FUnaryBuiltIn.unknownSizeSupported() = true;
240        eq FSymmetric.unknownSizeSupported()             = false;
241
242    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_NON_FIXED_FOR_INDEX =
243            new SimpleErrorProducer("UNSUPPORTED_NON_FIXED_FOR_INDEX", ProblemKind.COMPLIANCE, "For index with higher than parameter variability is not supported in equations and algorithms");
244
245    public void InstForIndexWithExp.complianceCheck(ErrorCheckType checkType) {
246        super.complianceCheck(checkType);
247        if (!getFExp().variability().parameterOrLess() && !inFunction()) {
248            UNSUPPORTED_NON_FIXED_FOR_INDEX.invoke(this);
249        }
250    }
251
252    public void InstForIndex.contentCheck(ErrorCheckType checkType) {
253    }
254
255    public void FPowExp.complianceCheck(ErrorCheckType checkType) {
256        super.complianceCheck(checkType);
257        if (inFunction() && getLeft().size().isUnknown()) {
258            UNSUPPORTED_IN_FUNCTION_UNKNOWN_SIZE_OPERATOR.invoke(this, "^");
259        }
260    }
261
262    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTION_LIKE_OPERATOR_IGNORED =
263            new SimpleWarningProducer("UNSUPPORTED_FUNCTION_LIKE_OPERATOR_IGNORED", ProblemKind.COMPLIANCE, "The %s() function-like operator is not supported, and is currently ignored");
264
265    public void FIgnoredBuiltIn.complianceCheck(ErrorCheckType checkType) {
266        UNSUPPORTED_FUNCTION_LIKE_OPERATOR_IGNORED.invoke(this, name());
267    }
268
269    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTION_LIKE_OPERATOR_EVAL_FALSE =
270            new SimpleWarningProducer("UNSUPPORTED_FUNCTION_LIKE_OPERATOR_EVAL_FALSE", ProblemKind.COMPLIANCE, "The %s() function-like operator is not supported, and is currently evaluated to false");
271
272    public void FTerminalExp.complianceCheck(ErrorCheckType checkType) {
273        UNSUPPORTED_FUNCTION_LIKE_OPERATOR_EVAL_FALSE.invoke(this, name());
274    }
275
276    public void FTerminate.complianceCheck(ErrorCheckType checkType) {
277        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "terminate");
278    }
279
280    public void FReinit.complianceCheck(ErrorCheckType checkType) {
281        ONLY_FMU_FUNCTION_LIKE_OPERATOR.invoke(this, "reinit");
282    }
283
284    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_NON_FIXED_STRING_ARGUMENT =
285            new SimpleErrorProducer("UNSUPPORTED_NON_FIXED_STRING_ARGUMENT", ProblemKind.COMPLIANCE, 
286                    "Argument %s of String operator is only supported as a fixed parameter expression.");
287
288    public void FStringExp.complianceCheck(ErrorCheckType checkType) {
289        super.complianceCheck(checkType);
290        if (hasFormat()) {
291            getFormat().markAsStructuralParameter(checkType);
292            if (!getFormat().variability().parameterOrLess())
293                UNSUPPORTED_NON_FIXED_STRING_ARGUMENT.invoke(getFormat(), "format");
294        }
295    }
296
297    public static final SimpleProblemProducer ASTNode.ONLY_FMU_INTEGER_VARIABLES =
298            new ComplianceFMUOnlyProducer("ONLY_FMU_INTEGER_VARIABLES", "Integer variables of discrete variability is");
299    public static final SimpleProblemProducer ASTNode.ONLY_FMU_BOOLEAN_VARIABLES =
300            new ComplianceFMUOnlyProducer("ONLY_FMU_BOOLEAN_VARIABLES", "Boolean variables of discrete variability is");
301
302    public void InstPrimitive.complianceCheck(ErrorCheckType checkType) {
303        super.complianceCheck(checkType);
304        if (!myOptions().getBooleanOption("generate_ode")) {
305            if (isInteger() && !variability().parameterOrLess() && !inFunction())
306                ONLY_FMU_INTEGER_VARIABLES.invoke(this);
307            if (isBoolean() && !variability().parameterOrLess())
308                ONLY_FMU_BOOLEAN_VARIABLES.invoke(this);
309        }
310    }
311
312    public static final SimpleProblemProducer ASTNode.ONLY_FMU_ENUMERATION_VARIABLES =
313            new ComplianceFMUOnlyProducer("ONLY_FMU_ENUMERATION_VARIABLES", "Enumeration variables of discrete variability is");
314
315    public void InstEnum.complianceCheck(ErrorCheckType checkType) {
316        super.complianceCheck(checkType);
317        if (!variability().parameterOrLess())
318            ONLY_FMU_ENUMERATION_VARIABLES.invoke(this);
319    }
320
321    public static final SimpleProblemProducer ASTNode.ONLY_FMU_FUNCTIONAL_INPUT =
322            new ComplianceFMUOnlyProducer("ONLY_FMU_FUNCTIONAL_INPUT", "Using functional input arguments is");
323    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTIONAL_INPUT_FROM_FUNCTION_DEFAULT =
324            new SimpleErrorProducer("UNSUPPORTED_FUNCTIONAL_INPUT_FROM_FUNCTION_DEFAULT", ProblemKind.COMPLIANCE, "Creating functional input arguments from functions with default input arguments is currently not supported");
325    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTIONAL_INPUT_COMPOSITE =
326            new SimpleErrorProducer("UNSUPPORTED_FUNCTIONAL_INPUT_COMPOSITE", ProblemKind.COMPLIANCE, "Functional input arguments with record/array inputs/outputs is currently not supported");
327    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTIONAL_INPUT_DEFAULT =
328            new SimpleErrorProducer("UNSUPPORTED_FUNCTIONAL_INPUT_DEFAULT", ProblemKind.COMPLIANCE, "Default values of functional input arguments is currently not supported");
329    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_FUNCTIONAL_ARRAY_INPUT =
330            new SimpleErrorProducer("UNSUPPORTED_FUNCTIONAL_ARRAY_INPUT", ProblemKind.COMPLIANCE, "Arrays of functional input arguments is currently not supported");
331
332    public void InstPartialFunction.complianceCheck(ErrorCheckType checkType) {
333        ONLY_FMU_FUNCTIONAL_INPUT.invoke(this);
334        for (InstComponentDecl icd : myInputs()) {
335            if (icd.hasBindingExp()) {
336                UNSUPPORTED_FUNCTIONAL_INPUT_FROM_FUNCTION_DEFAULT.invoke(this);
337                break;
338            }
339        }
340        for (InstComponentDecl icd : myInputs()) {
341            if (icd.isComposite()) {
342                UNSUPPORTED_FUNCTIONAL_INPUT_COMPOSITE.invoke(this);
343                break;
344            }
345        }
346        for (InstComponentDecl icd : myOutputs()) {
347            if (icd.isComposite()) {
348                UNSUPPORTED_FUNCTIONAL_INPUT_COMPOSITE.invoke(this);
349                break;
350            }
351        }
352        if (hasBindingExp()) {
353            UNSUPPORTED_FUNCTIONAL_INPUT_DEFAULT.invoke(this);
354        }
355        if (isArray())
356            UNSUPPORTED_FUNCTIONAL_ARRAY_INPUT.invoke(this);
357    }
358
359    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_EXTERNAL_OBJECT_CONSTRUCTORS =
360            new SimpleErrorProducer("UNSUPPORTED_EXTERNAL_OBJECT_CONSTRUCTORS", ProblemKind.COMPLIANCE, "Constructors for external objects is not supported in functions");
361
362    public void InstFunctionCall.complianceCheck(ErrorCheckType checkType) {
363        if (isConstructorCall() && isBound() && inFunction()) {
364            UNSUPPORTED_EXTERNAL_OBJECT_CONSTRUCTORS.invoke(this);
365        }
366    }
367   
368    public static final SimpleProblemProducer ASTNode.UNSUPPORTED_EXTERNAL_FUNCTION_RECORD_RETURN_VALUE =
369            new SimpleErrorProducer("UNSUPPORTED_EXTERNAL_FUNCTION_RECORD_RETURN_VALUE", ProblemKind.COMPLIANCE, "Using records as return value from external functions is not supported");
370
371    public void FExternalStmt.complianceCheck(ErrorCheckType checkType) {
372        getFExternalLanguage().complianceCheck(checkType, this);
373    }
374   
375    public void FExternalLanguage.complianceCheck(ErrorCheckType checkType, FExternalStmt stmt) {}
376    public void FCExternalLanguage.complianceCheck(ErrorCheckType checkType, FExternalStmt stmt) {
377        if (stmt.hasReturnVar() && stmt.getReturnVar().type().isRecord()) {
378            UNSUPPORTED_EXTERNAL_FUNCTION_RECORD_RETURN_VALUE.invoke(stmt);
379        }
380    }
381   
382
383   
384}
Note: See TracBrowser for help on using the repository browser.