Skip to content

Commit

Permalink
Check if class exists before linearization. (#8417)
Browse files Browse the repository at this point in the history
* Check if class exists before linearization.

  - Fixes #8415.

  - To be consistent with the simulate() API, add an explicit check for
    existence of class.

  - Also fix a probable wrong parameter to the class lookup which asks
    for the enclosing class when a the actual class is not found inside it.

* Move the check for instantiating invlaid class types

  - The check for attempted instantiation of disallowed class
    types (packages. functions) is now moved to Inst.instantiateClass_dispatch

   - This probably does not cover every path. I am almost sure it does not.
     However, OF is already deprecated. All we care about is the interactive
     environment working properly before passing on things to NF.

* Allow instantiation of TOP level packages/functions
  • Loading branch information
mahge committed Jan 19, 2022
1 parent 52c8c2c commit ebaac9b
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 24 deletions.
30 changes: 28 additions & 2 deletions OMCompiler/Compiler/FrontEnd/Inst.mo
Expand Up @@ -171,6 +171,7 @@ protected function instantiateClass_dispatch
input SCode.Program inProgram;
input SCode.Path inPath;
input Boolean doSCodeDep "Do SCode dependency (if the debug flag is also enabled)";
input Boolean relaxedFrontEnd=true "Do not check for illegal simulation models, so we allow instantation of packages, etc";
output FCore.Cache outCache;
output FCore.Graph outEnv;
output InnerOuter.InstHierarchy outIH;
Expand Down Expand Up @@ -210,7 +211,7 @@ algorithm
end if;
ExecStat.execStat("FrontEnd - mkProgramGraph");

(cache,env,ih,dae2) = instClassInProgram(cache, env, ih, cdecls, path, source);
(cache,env,ih,dae2) = instClassInProgram(cache, env, ih, cdecls, path, source, relaxedFrontEnd);
// check the models for balancing
//Debug.fcall2(Flags.CHECK_MODEL_BALANCE, checkModelBalancing, SOME(path), dae1);
//Debug.fcall2(Flags.CHECK_MODEL_BALANCE, checkModelBalancing, SOME(path), dae2);
Expand Down Expand Up @@ -246,6 +247,9 @@ algorithm
//print("\nLookupClass");
(cache,(cdef as SCode.CLASS(name = n)),env) = Lookup.lookupClass(cache, env, path, SOME(AbsynUtil.dummyInfo));

// Check if we are trying to instantiate a function or pacakage when we should not.
checkInstanceRestriction(cdef, path, relaxedFrontEnd);

//System.stopTimer();
//print("\nLookupClass: " + realString(System.getTimerIntervalTime()));

Expand Down Expand Up @@ -303,6 +307,7 @@ public function instantiateClass
input SCode.Program inProgram;
input SCode.Path inPath;
input Boolean doSCodeDep=true "Do SCode dependency (if the debug flag is also enabled)";
input Boolean relaxedFrontEnd=true "Do not check for illegal simulation models, so we allow instantation of packages, etc";
output FCore.Cache outCache;
output FCore.Graph outEnv;
output InnerOuter.InstHierarchy outIH;
Expand All @@ -326,7 +331,7 @@ algorithm
// instantiate a class
case (cache,ih,cdecls as _::_,path)
algorithm
(outCache,outEnv,outIH,outDAElist) := instantiateClass_dispatch(cache,ih,cdecls,path,doSCodeDep);
(outCache,outEnv,outIH,outDAElist) := instantiateClass_dispatch(cache,ih,cdecls,path,doSCodeDep,relaxedFrontEnd);
outDAElist := UnitCheck.checkUnits(outDAElist,FCore.getFunctionTree(outCache));
then
(outCache,outEnv,outIH,outDAElist);
Expand Down Expand Up @@ -447,6 +452,7 @@ protected function instClassInProgram
input SCode.Program inProgram;
input SCode.Path inPath;
input DAE.ElementSource inSource;
input Boolean relaxedFrontEnd = true "Do not check for illegal simulation models, so we allow instantation of packages, etc";
output FCore.Cache outCache;
output FCore.Graph outEnv;
output InnerOuter.InstHierarchy outIH;
Expand Down Expand Up @@ -474,6 +480,10 @@ algorithm
equation
cls = InstUtil.lookupTopLevelClass(name, inProgram, true);

// Disable this check since we have some test cases that instantiate
// TOP level functions and pacakges.
// checkInstanceRestriction(cls, inPath, relaxedFrontEnd);

(cache, env, ih, _, dae, _, _, _, _, _) = instClass(inCache, inEnv,
inIH, UnitAbsynBuilder.emptyInstStore(), DAE.NOMOD(), makeTopComponentPrefix(inEnv, name),
cls, {}, false, InstTypes.TOP_CALL(), ConnectionGraph.EMPTY, Connect.emptySet);
Expand Down Expand Up @@ -5614,5 +5624,21 @@ algorithm
InstTypes.TOP_CALL(), ConnectionGraph.EMPTY, Connect.emptySet);
end instClassType;


protected function checkInstanceRestriction
input SCode.Element cdef;
input Absyn.Path path;
input Boolean relaxedFrontEnd;
algorithm
// Do not allow instantiation of functions and packages.
if not relaxedFrontEnd and (SCodeUtil.isFunction(cdef) or
SCodeUtil.isPackage(cdef)) then
Error.addSourceMessage(Error.INST_INVALID_RESTRICTION,
{AbsynUtil.pathString(path), SCodeDump.restrString(SCodeUtil.getClassRestriction(cdef))},
SCodeUtil.elementInfo(cdef));
fail();
end if;
end checkInstanceRestriction;

annotation(__OpenModelica_Interface="frontend");
end Inst;
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/Main/Main.mo
Expand Up @@ -535,7 +535,7 @@ algorithm
// program. Otherwise, instantiate the given class name.
cname := if stringEmpty(cls) then AbsynUtil.lastClassname(SymbolTable.getAbsyn()) else AbsynUtil.stringPath(cls);
(cache, env, SOME(dae), flatString) := CevalScriptBackend.runFrontEnd(FCore.emptyCache(),
FGraph.empty(), cname, relaxedFrontEnd = true,
FGraph.empty(), cname, relaxedFrontEnd = false,
dumpFlat = Config.flatModelica() and not Config.silent());
end instantiate;

Expand Down
29 changes: 12 additions & 17 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -1630,6 +1630,16 @@ algorithm

case (_, _, "copyClass", _, _) then (inCache, Values.BOOL(false));

// see if the model exists before linearization!
case (cache,_,"linearize",vals as Values.CODE(Absyn.C_TYPENAME(className))::_,_)
equation
crefCName = AbsynUtil.pathToCref(className);
false = Interactive.existClass(crefCName, SymbolTable.getAbsyn());
errMsg = "Linearization Failed. Model: " + AbsynUtil.pathString(className) + " does not exist! Please load it first before linearization.";
simValue = createSimulationResultFailure(errMsg, simOptionsAsString(vals));
then
(cache,simValue);

case (cache,env,"linearize",(vals as Values.CODE(Absyn.C_TYPENAME(className))::_),_)
equation

Expand Down Expand Up @@ -3383,21 +3393,6 @@ protected
Absyn.Restriction restriction;
Absyn.Program p = SymbolTable.getAbsyn();
algorithm
try
Absyn.CLASS(restriction = restriction) := InteractiveUtil.getPathedClassInProgram(className, p, true);
else
Error.addMessage(Error.LOOKUP_ERROR, {AbsynUtil.pathString(className),"<TOP>"});
fail();
end try;
if not relaxedFrontEnd and (AbsynUtil.isFunctionRestriction(restriction) or
AbsynUtil.isPackageRestriction(restriction)) then
Error.addSourceMessage(Error.INST_INVALID_RESTRICTION,
{AbsynUtil.pathString(className), AbsynUtil.restrString(restriction)},
AbsynUtil.dummyInfo);
fail();
end if;
(cache,env,dae) := matchcontinue (inCache,inEnv,className)
local
Absyn.Class absynClass;
Expand Down Expand Up @@ -3448,7 +3443,7 @@ algorithm
//System.startTimer();
//print("\nInst.instantiateClass");
(cache,env,_,dae) = Inst.instantiateClass(cache,InnerOuter.emptyInstHierarchy,scodeP,className);
(cache,env,_,dae) = Inst.instantiateClass(cache,InnerOuter.emptyInstHierarchy,scodeP,className,true,relaxedFrontEnd);
dae = DAEUtil.mergeAlgorithmSections(dae);
Expand Down Expand Up @@ -8540,7 +8535,7 @@ algorithm
case ()
algorithm
ExecStat.execStatReset();
(cache, _, odae, str) := runFrontEnd(cache, env, path, relaxedFrontEnd = true,
(cache, _, odae, str) := runFrontEnd(cache, env, path, relaxedFrontEnd = false,
dumpFlat = Config.flatModelica() and not Config.silent());
ExecStat.execStat("runFrontEnd");

Expand Down
3 changes: 2 additions & 1 deletion testsuite/flattening/libraries/biochem/BiochemModels.mos
Expand Up @@ -2023,7 +2023,8 @@ checkModel(BioChem.Examples.MultiCompartments.Utilities.SmallCompartment); getEr
// "Check of BioChem.Examples.centralMetabolism.cytosol completed successfully.
// Class BioChem.Examples.centralMetabolism.cytosol has 320 equation(s) and 320 variable(s).
// 229 of these are trivial equation(s)."
// "Error: Cannot instantiate BioChem.Examples.centralMetabolism due to class specialization PACKAGE.
// "[BioChem 1.0.1+msl.3.2.1/Examples/package.mo:426:3-1027:24:writable] Error: Cannot instantiate BioChem.Examples.centralMetabolism due to class specialization package.
// Error: Error occurred while flattening model BioChem.Examples.centralMetabolism
// "
// "Check of BioChem.Examples.CircadianOscillator.Container completed successfully.
// Class BioChem.Examples.CircadianOscillator.Container has 252 equation(s) and 252 variable(s).
Expand Down
11 changes: 8 additions & 3 deletions testsuite/flattening/modelica/mosfiles/ErrorSimPackage.mos
@@ -1,13 +1,18 @@
// name: ErrorSimPackage
// status: correct
// cflags: -d=-newInst
//
// This is now allowed temporarily by the OF. For consistency.
// We have test cases assuming we can do this on the .mo files, i.e,
// when it is instantiated as the LAST CLASS in a file it is expected
// to work. But not when it is asked for explicilty.
// So we are going to allow this for now in the OF.

loadString("package P end P;");
translateModel(P);getErrorString();

// Result:
// true
// false
// "Error: Cannot instantiate P due to class specialization PACKAGE.
// "
// true
// ""
// endResult
1 change: 1 addition & 0 deletions testsuite/openmodelica/interactive-API/Makefile
Expand Up @@ -41,6 +41,7 @@ getIconAnnotation.mos \
IfStatementIllegal.mos \
IfStatement.mos\
IllegalGraphics.mos\
instantiateFunction.mos \
interactive_api_annotations.mos \
interactive_api_attributes.mos \
interactive_api_calls.mos \
Expand Down
9 changes: 9 additions & 0 deletions testsuite/openmodelica/interactive-API/instantiateFunction.mo
@@ -0,0 +1,9 @@
model Base
function Foo
parameter Integer foo = 0;
end Foo;
end Base;

model Derived
extends Base;
end Derived;
19 changes: 19 additions & 0 deletions testsuite/openmodelica/interactive-API/instantiateFunction.mos
@@ -0,0 +1,19 @@
// name: instantiateFunction.mos
// keywords: instantiate API function
// status: correct
// cflags: -d=-newInst
//
// Checks that functions can not be instantiated.
//

loadFile("instantiateFunction.mo"); getErrorString();
instantiateModel(Derived.Foo); getErrorString();

// Result:
// true
// ""
// ""
// "[openmodelica/interactive-API/instantiateFunction.mo:2:3-4:10:writable] Error: Cannot instantiate Derived.Foo due to class specialization pure function.
// Error: Error occurred while flattening model Derived.Foo
// "
// endResult

0 comments on commit ebaac9b

Please sign in to comment.