diff --git a/Compiler/FrontEnd/Absyn.mo b/Compiler/FrontEnd/Absyn.mo index 0221df272cd..c8e3d73c00d 100644 --- a/Compiler/FrontEnd/Absyn.mo +++ b/Compiler/FrontEnd/Absyn.mo @@ -4459,7 +4459,7 @@ algorithm Exp x, y; Integer i; Real r; - // real vs. integer + // real vs. integer case (INTEGER(i), REAL(r)) equation true = realEq(intReal(i), r); diff --git a/Compiler/FrontEnd/FDependency.mo b/Compiler/FrontEnd/FDependency.mo index 31dcd7380d2..5ff19813aff 100644 --- a/Compiler/FrontEnd/FDependency.mo +++ b/Compiler/FrontEnd/FDependency.mo @@ -740,7 +740,7 @@ protected function analyseElement input SCode.Restriction inClassRestriction; output list outExtends; algorithm - outExtends := match(inElement, inEnv, inExtends, inClassRestriction) + outExtends := matchcontinue(inElement, inEnv, inExtends, inClassRestriction) local Absyn.Path bc, bc2; SCode.Mod mods; @@ -755,6 +755,7 @@ algorithm SCode.Restriction res; String errorMessage; list exts; + Absyn.InnerOuter io; // Fail on 'extends ExternalObject' so we can handle it as a special case in // analyseClassDef. @@ -853,6 +854,14 @@ algorithm then inExtends; + // inner/innerouter classes may not be explicitly used but might be needed anyway + case (SCode.CLASS(name = name, prefixes = SCode.PREFIXES(innerOuter = io), info = info), _, _, _) + equation + true = boolOr(Absyn.isInner(io), Absyn.isInnerOuter(io)); + analyseClass(Absyn.IDENT(name), inEnv, info); + then + inExtends; + case (SCode.CLASS(name = name, info = info, classDef=SCode.CLASS_EXTENDS(baseClassName = _)), _, _, _) equation analyseClass(Absyn.IDENT(name), inEnv, info); @@ -860,7 +869,8 @@ algorithm inExtends; else inExtends; - end match; + + end matchcontinue; end analyseElement; protected function markAsUsedOnRestriction diff --git a/Compiler/FrontEnd/InnerOuter.mo b/Compiler/FrontEnd/InnerOuter.mo index 5ac82526458..13dcaeefb00 100644 --- a/Compiler/FrontEnd/InnerOuter.mo +++ b/Compiler/FrontEnd/InnerOuter.mo @@ -91,11 +91,9 @@ uniontype InstInner String fullName "full inner component name"; Absyn.Path typePath "the type of the inner"; String scope "the scope of the inner"; - // add these if needed! - // SCode.Mod scodeMod; - // DAE.Mod mod; Option instResult; list outers "which outers are referencing this inner"; + Option innerElement "class or component"; end INST_INNER; end InstInner; @@ -1592,7 +1590,7 @@ public function emptyInstInner output InstInner outInstInner; annotation(__OpenModelica_EarlyInline = true); algorithm - outInstInner := INST_INNER(innerPrefix, name, Absyn.NOT_INNER_OUTER(), "", Absyn.IDENT(""), "", NONE(), {}); + outInstInner := INST_INNER(innerPrefix, name, Absyn.NOT_INNER_OUTER(), "", Absyn.IDENT(""), "", NONE(), {}, NONE()); end emptyInstInner; public function lookupInnerVar @@ -1706,6 +1704,43 @@ algorithm end match; end updateInstHierarchy; +public function addClass + input SCode.Element inClass; + input Prefix.Prefix inPrefix; + input String inScope; + input InstHierarchy inIH; + output InstHierarchy outIH; +algorithm + outIH := matchcontinue(inClass, inPrefix, inScope, inIH) + local + String name; + Absyn.InnerOuter io; + + // add inner or innerouter + case (SCode.CLASS(name = name, prefixes = SCode.PREFIXES(innerOuter = io)), _, _, _) + equation + true = boolOr(Absyn.isInner(io), Absyn.isInnerOuter(io)); + // add to instance hierarchy + outIH = updateInstHierarchy(inIH, inPrefix, io, + INST_INNER( + inPrefix, // prefix + name, // class name + io, + name, + Absyn.IDENT(name), + inScope, + NONE(), + {}, + SOME(inClass))); + then + outIH; + + // do nothing if not inner + else then inIH; + + end matchcontinue; +end addClass; + public function addOuterPrefixToIH "@author: adrpo This function remembers the outer prefix with the correct prefix of the inner" @@ -1888,7 +1923,7 @@ algorithm list outers "which outers are referencing this inner"; String str, strOuters; - case(INST_INNER(innerPrefix, name, io, fullName, typePath, scope, instResult, outers)) + case(INST_INNER(innerPrefix, name, io, fullName, typePath, scope, instResult, outers, _)) equation outers = List.uniqueOnTrue(outers, ComponentReference.crefEqualNoStringCompare); strOuters = Util.if_(listLength(outers) == 0, diff --git a/Compiler/FrontEnd/Inst.mo b/Compiler/FrontEnd/Inst.mo index 588921cf9c0..4228ef051c6 100644 --- a/Compiler/FrontEnd/Inst.mo +++ b/Compiler/FrontEnd/Inst.mo @@ -1542,6 +1542,118 @@ public function instClassIn " output Option optDerAttr; output DAE.EqualityConstraint outEqualityConstraint; output ConnectionGraph.ConnectionGraph outGraph; +algorithm + (outCache,outEnv,outIH,outStore,outDae,outSets,outState,outTypesVarLst,outTypesTypeOption,optDerAttr,outEqualityConstraint,outGraph):= + matchcontinue (inCache,inEnv,inIH,inStore,inMod,inPrefix,inState,inClass,inVisibility,inInstDims,implicitInstantiation,inCallingScope,inGraph,inSets,instSingleCref) + local + Option bc; + list env; + DAE.Mod mods; + Prefix.Prefix pre; + ClassInf.State ci_state; + SCode.Element c; + InstDims inst_dims; + Boolean impl; + SCode.Visibility vis; + String n; + DAE.DAElist dae; + Connect.Sets csets; + list tys; + SCode.Restriction r,rCached; + SCode.ClassDef d; + Env.Cache cache; + Option oDA; + DAE.EqualityConstraint equalityConstraint; + CallingScope callscope; + ConnectionGraph.ConnectionGraph graph; + InstanceHierarchy ih; + Absyn.Path fullEnvPathPlusClass; + Option envPathOpt; + String className, s1, s2; + UnitAbsyn.InstStore store; + Absyn.InnerOuter io; + Absyn.Info info; + + // if the class is no inner and no outer! + case (_,_,_,_,_,_,_,c as SCode.CLASS(prefixes = SCode.PREFIXES(innerOuter = io)),_,_,_,_,_,_,_) + equation + true = Absyn.isNotInnerOuter(io); + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph) = + instClassIn2(inCache,inEnv,inIH,inStore,inMod,inPrefix,inState,inClass,inVisibility,inInstDims,implicitInstantiation,inCallingScope,inGraph,inSets,instSingleCref); + then + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph); + + // if the class is outer we need to instantiate the inner! + case (_,_,_,_,_,_,_,c as SCode.CLASS(name = n, prefixes = SCode.PREFIXES(innerOuter = io)),_,_,_,_,_,_,_) + equation + true = Absyn.isOnlyOuter(io); + + // lookup in IH + InnerOuter.INST_INNER( + innerElement = SOME(c)) = + InnerOuter.lookupInnerVar(inCache, inEnv, inIH, inPrefix, n, io); + + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph) = + instClassIn2(inCache,inEnv,inIH,inStore,inMod,inPrefix,inState,c,inVisibility,inInstDims,implicitInstantiation,inCallingScope,inGraph,inSets,instSingleCref); + then + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph); + + // if the class is outer we need to instantiate the inner! + case (_,_,_,_,_,_,_,c as SCode.CLASS(name = n, prefixes = SCode.PREFIXES(innerOuter = io), info = info),_,_,_,_,_,_,_) + equation + true = Absyn.isOnlyOuter(io); + + // failure(_ = InnerOuter.lookupInnerVar(inCache, inEnv, inIH, inPrefix, n, io)); + + s1 = n; + s2 = Dump.unparseInnerouterStr(io); + Error.addSourceMessage(Error.MISSING_INNER_CLASS,{s1, s2}, info); + + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph) = + instClassIn2(inCache,inEnv,inIH,inStore,inMod,inPrefix,inState,c,inVisibility,inInstDims,implicitInstantiation,inCallingScope,inGraph,inSets,instSingleCref); + then + (cache,env,ih,store,dae,csets,ci_state,tys,bc,oDA,equalityConstraint,graph); + + end matchcontinue; +end instClassIn; + +public function instClassIn2 +"This rule instantiates the contents of a class definition, with a new + environment already setup. + The *implicitInstantiation* boolean indicates if the class should be + instantiated implicit, i.e. without generating DAE. + The last option is a even stronger indication of implicit instantiation, + used when looking up variables in packages. This must be used because + generation of functions in implicit instanitation (according to + *implicitInstantiation* boolean) can cause circular dependencies + (e.g. if a function uses a constant in its body)" + input Env.Cache inCache; + input Env.Env inEnv; + input InstanceHierarchy inIH; + input UnitAbsyn.InstStore inStore; + input DAE.Mod inMod; + input Prefix.Prefix inPrefix; + input ClassInf.State inState; + input SCode.Element inClass; + input SCode.Visibility inVisibility; + input InstDims inInstDims; + input Boolean implicitInstantiation; + input CallingScope inCallingScope; + input ConnectionGraph.ConnectionGraph inGraph; + input Connect.Sets inSets; + input Option instSingleCref; + output Env.Cache outCache; + output Env.Env outEnv; + output InstanceHierarchy outIH; + output UnitAbsyn.InstStore outStore; + output DAE.DAElist outDae; + output Connect.Sets outSets; + output ClassInf.State outState; + output list outTypesVarLst; + output Option outTypesTypeOption; + output Option optDerAttr; + output DAE.EqualityConstraint outEqualityConstraint; + output ConnectionGraph.ConnectionGraph outGraph; algorithm (outCache,outEnv,outIH,outStore,outDae,outSets,outState,outTypesVarLst,outTypesTypeOption,optDerAttr,outEqualityConstraint,outGraph):= matchcontinue (inCache,inEnv,inIH,inStore,inMod,inPrefix,inState,inClass,inVisibility,inInstDims,implicitInstantiation,inCallingScope,inGraph,inSets,instSingleCref) @@ -1668,12 +1780,12 @@ algorithm equation //print("instClassIn(");print(n);print(") failed\n"); true = Flags.isSet(Flags.FAILTRACE); - Debug.fprintln(Flags.FAILTRACE, "- Inst.instClassIn failed on class:" +& + Debug.fprintln(Flags.FAILTRACE, "- Inst.instClassInInnerOuter failed on class:" +& n +& " in environment: " +& Env.printEnvPathStr(env)); then fail(); end matchcontinue; -end instClassIn; +end instClassIn2; protected function checkClassEqual input SCode.Element c1; @@ -6203,6 +6315,7 @@ algorithm enumclass = instEnumeration(s, enumLst, cmt, info); env_1 = Env.extendFrameC(env, enumclass); (env_1,ih,cl2) = addClassdefsToEnv3(env_1, ih, pre, redeclareMod, sel1); + ih = InnerOuter.addClass(cl2, pre, Env.getEnvNameStr(env_1), ih); (env_2,ih) = addClassdefsToEnv2(env_1, ih, pre, xs, impl, redeclareMod); then (env_2,ih); @@ -6214,6 +6327,7 @@ algorithm env_1 = Env.extendFrameC(env, sel1); // call to redeclareType which calls updateComponents in env wich updates the class frame (env_1,ih,cl2) = addClassdefsToEnv3(env_1, ih, pre, redeclareMod, sel1); + ih = InnerOuter.addClass(cl2, pre, Env.getEnvNameStr(env_1), ih); (env_2,ih) = addClassdefsToEnv2(env_1, ih, pre, xs, impl, redeclareMod); then (env_2,ih); @@ -6231,19 +6345,21 @@ algorithm (env,ih); // adrpo: see if is an enumeration! then extend frame with in class. - case (env,ih,pre,( (sel1 as SCode.CLASS(name = s, classDef=SCode.ENUMERATION(enumLst,cmt),info=info)) :: xs),impl,_) + case (env,ih,pre,(sel1 as SCode.CLASS(name = s, classDef=SCode.ENUMERATION(enumLst,cmt),info=info)) :: xs,impl,_) equation enumclass = instEnumeration(s, enumLst, cmt, info); env_1 = Env.extendFrameC(env, enumclass); + ih = InnerOuter.addClass(enumclass, pre, Env.getEnvNameStr(env_1), ih); (env_2,ih) = addClassdefsToEnv2(env_1, ih, pre, xs, impl, redeclareMod); then (env_2,ih); // otherwise, extend frame with in class. - case (env,ih,pre,( (sel1 as SCode.CLASS(classDef = _)) :: xs),impl,_) + case (env,ih,pre,(sel1 as SCode.CLASS(classDef = _)) :: xs,impl,_) equation // Debug.traceln("Extend frame " +& Env.printEnvPathStr(env) +& " with " +& SCode.className(cl)); env_1 = Env.extendFrameC(env, sel1); + ih = InnerOuter.addClass(sel1, pre, Env.getEnvNameStr(env_1), ih); (env_2, ih) = addClassdefsToEnv2(env_1, ih, pre, xs, impl, redeclareMod); then (env_2,ih); @@ -6945,7 +7061,7 @@ algorithm // The types in the environment does not have correct Binding. // We must update those variables that is found in m into a new environment. - own_cref = Absyn.CREF_IDENT(name, {}) ; + own_cref = Absyn.CREF_IDENT(name, {}); crefs1 = getCrefFromMod(m); crefs2 = getCrefFromDim(ad); crefs3 = getCrefFromCond(cond); @@ -7986,7 +8102,8 @@ algorithm typePath, // fully qual type path innerScope, // the scope, SOME(InnerOuter.INST_RESULT(cache,outerCompEnv,store,outerDAE,csets,ty,graph)), // instantiation result - {} // outers connected to this inner + {}, // outers connected to this inner + NONE() )); then (cache,innerCompEnv,ih,store,dae,csets,ty,graph); @@ -8005,7 +8122,7 @@ algorithm s2 = Mod.prettyPrintMod(mod, 0); s = s1 +& " " +& s2; // add a warning! - Error.addMessage(Error.OUTER_MODIFICATION, {s}); + Error.addSourceMessage(Error.OUTER_MODIFICATION, {s}, info); // call myself without any modification! (cache,compenv,ih,store,dae,csets,ty,graph) = @@ -8033,7 +8150,8 @@ algorithm fullName, typePath, innerScope, - instResult as SOME(InnerOuter.INST_RESULT(cache,compenv,store,outerDAE,_,ty,graph)),outers) = + instResult as SOME(InnerOuter.INST_RESULT(cache,compenv,store,outerDAE,_,ty,graph)), + outers,_) = InnerOuter.lookupInnerVar(cache, env, ih, pre, n, io); // add outer prefix + component name and its corresponding inner prefix to the IH @@ -8051,7 +8169,8 @@ algorithm typePath, // fully qual type path innerScope, // the scope, instResult, - outers // outers connected to this inner + outers, // outers connected to this inner + NONE() )); // outer dae has no meaning! @@ -8078,7 +8197,8 @@ algorithm fullName, typePath, innerScope, - instResult as NONE(),outers) = + instResult as NONE(), + outers,_) = InnerOuter.lookupInnerVar(cache, env, ih, pre, n, io); // Debug.fprintln(Flags.INNER_OUTER, "- Inst.instVar failed to lookup inner: " +& PrefixUtil.printPrefixStr(pre) +& "/" +& n +& " in env: " +& Env.printEnvPathStr(env)); @@ -8094,7 +8214,7 @@ algorithm // adrpo: do NOT! display an error message if impl = true and prefix is Prefix.NOPRE() // print(Util.if_(impl, "impl crap\n", "no impl\n")); Debug.bcall(impl and listMember(pre, {Prefix.NOPRE()}), ErrorExt.setCheckpoint, "innerouter-instVar-implicit"); - Error.addMessage(Error.MISSING_INNER_PREFIX,{s1, s2, s3}); + Error.addSourceMessage(Error.MISSING_INNER_PREFIX,{s1, s2, s3}, info); Debug.bcall(impl and listMember(pre, {Prefix.NOPRE()}), ErrorExt.rollBack, "innerouter-instVar-implicit"); // call it normaly @@ -8129,7 +8249,7 @@ algorithm // print(Util.if_(impl, "impl crap\n", "no impl\n")); // adrpo: do NOT! display an error message if impl = true and prefix is Prefix.NOPRE() Debug.bcall(impl and listMember(pre, {Prefix.NOPRE()}), ErrorExt.setCheckpoint, "innerouter-instVar-implicit"); - Error.addMessage(Error.MISSING_INNER_PREFIX,{s1, s2, s3}); + Error.addSourceMessage(Error.MISSING_INNER_PREFIX,{s1, s2, s3}, info); Debug.bcall(impl and listMember(pre, {Prefix.NOPRE()}), ErrorExt.rollBack, "innerouter-instVar-implicit"); // call it normally @@ -8173,7 +8293,9 @@ algorithm fullName, typePath, innerScope, - SOME(InnerOuter.INST_RESULT(cache,outerCompEnv,store,innerDAE,csetsInner,ty,graph)), {})); + SOME(InnerOuter.INST_RESULT(cache,outerCompEnv,store,innerDAE,csetsInner,ty,graph)), + {}, + NONE())); // now instantiate it as an outer with no modifications pf = SCode.prefixesSetInnerOuter(pf, Absyn.OUTER()); @@ -13026,7 +13148,7 @@ algorithm case (cache,env,DAE.CREF(componentRef = cref,ty = crty),DAE.PROP(type_ = ty,constFlag = cnst)) equation - failure((_,_,_,_,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env, cref)); + failure((_,_,_,_,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env,cref)); crefstr = ComponentReference.printComponentRefStr(cref); scope = Env.printEnvPathStr(env); Error.addMessage(Error.LOOKUP_VARIABLE_ERROR, {crefstr,scope}); diff --git a/Compiler/FrontEnd/Mod.mo b/Compiler/FrontEnd/Mod.mo index c34f4668282..2e989569c12 100644 --- a/Compiler/FrontEnd/Mod.mo +++ b/Compiler/FrontEnd/Mod.mo @@ -1324,14 +1324,18 @@ algorithm case(_,_,_) equation true = modEqual(mod1, mod2); - then mod2; + then + mod2; + // print error message case(_,_,_) equation s1 = printModStr(mod1); s2 = printModStr(mod2); s = s1 +& " and " +& s2; Error.addMessage(Error.DUPLICATE_MODIFICATIONS,{s,n}); - then fail(); + then + fail(); + end matchcontinue; end checkDuplicateModifications; @@ -1415,6 +1419,7 @@ algorithm mod = merge(mod1, mod2, {}, Prefix.NOPRE()); then mod; + case ((x as DAE.IDXMOD(mod=mod1))::rest) equation // make sure x is not present in the rest @@ -1740,19 +1745,21 @@ algorithm case(_,_,_,_) equation true = merge2(inModInner); - then doMerge(inModOuter,inModInner,inEnv,inPrefix); + then + doMerge(inModOuter,inModInner,inEnv,inPrefix); case(_,_,_,_) equation true = modSubsetOrEqualOrNonOverlap(inModOuter,inModInner); m = doMerge(inModOuter,inModInner,inEnv,inPrefix); - then m; + then + m; // two exactly the same mod, return just one! (used when it is REDECL or a submod is REDECL) case(DAE.REDECL(fp1, ep1, elsmods1),DAE.REDECL(fp2, ep2, elsmods2),_,_) equation + //true = SCode.finalEqual(fp1, fp2); true = SCode.eachEqual(ep1, ep2); - true = SCode.finalEqual(fp1, fp2); els1 = List.map(elsmods1, Util.tuple21); els2 = List.map(elsmods2, Util.tuple21); true = List.fold(List.threadMap(els1, els2, SCode.elementEqual), boolAnd, true); @@ -1769,7 +1776,9 @@ algorithm s3 = printModStr(inModOuter); s4 = printModStr(inModInner); Error.addMessage(Error.FINAL_OVERRIDE, {s1,s2,s3,s4}); - then fail(); + then + fail(); + end matchcontinue; end merge; @@ -2110,34 +2119,49 @@ algorithm list submods1,submods2; Option eqmod1,eqmod2; Boolean b; + list> elsmods1, elsmods2; + SCode.Program els1, els2; // adrpo: handle non-overlap: final parameter Real eAxis_ia[3](each final unit="1") = {1,2,3}; // mod1 = final each unit="1" mod2 = final = {1,2,3} // otherwise we get an error as: Error: Variable eAxis_ia: trying to override final variable ... case(DAE.MOD(f1,each1,submods1,NONE()),DAE.MOD(f2,SCode.NOT_EACH(),{},eqmod2 as SOME(_))) equation - b = valueEq(f1,f2); - then b; + b = true; // b = SCode.finalEqual(f1, f2); + then + b; case(DAE.MOD(f1,each1,submods1,eqmod1),DAE.MOD(f2,SCode.NOT_EACH(),{},eqmod2)) equation - b = valueEq(eqmod1,eqmod2); - then b; + b = eqModSubsetOrEqual(eqmod1,eqmod2); + then + b; // handle subset equal case(DAE.MOD(f1,each1,submods1,eqmod1),DAE.MOD(f2,each2,submods2,eqmod2)) equation - true = valueEq(f1,f2); + // true = SCode.finalEqual(f1, f2); true = SCode.eachEqual(each1,each2); true = subModsEqual(submods1,submods2); true = eqModSubsetOrEqual(eqmod1,eqmod2); then true; - case(DAE.REDECL(_,_,_),DAE.REDECL(_,_,_)) - then valueEq(mod1,mod2); + + // two exactly the same mod, return just one! (used when it is REDECL or a submod is REDECL) + case(DAE.REDECL(f1, each1, elsmods1),DAE.REDECL(f2, each2, elsmods2)) + equation + // true = SCode.finalEqual(f1, f2); + true = SCode.eachEqual(each1, each2); + els1 = List.map(elsmods1, Util.tuple21); + els2 = List.map(elsmods2, Util.tuple21); + true = List.fold(List.threadMap(els1, els2, SCode.elementEqual), boolAnd, true); + then + true; + case(DAE.NOMOD(),DAE.NOMOD()) then true; - case (_,_) then false; - case(_, _) + case (_, _) then false; + + case (_, _) equation //true = Flags.isSet(Flags.FAILTRACE); //Debug.traceln("- Mod.modSubsetOrEqualOrNonOverlap failed on: " +& @@ -2145,6 +2169,7 @@ algorithm // " mod2: " +& printModStr(mod2)); then fail(); + end matchcontinue; end modSubsetOrEqualOrNonOverlap; @@ -2168,39 +2193,44 @@ algorithm // typed mods case(SOME(DAE.TYPED(modifierAsExp = exp1)),SOME(DAE.TYPED(modifierAsExp = exp2))) equation - equal = Expression.expEqual(exp1,exp2); - then equal; + true = eqModEqual(eqMod1,eqMod2); + then + true; // typed vs. untyped mods case(SOME(DAE.TYPED(modifierAsAbsynExp=SOME(aexp1))),SOME(DAE.UNTYPED(exp=aexp2))) equation - //aexp1 = Expression.unelabExp(exp1); - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; case(SOME(DAE.TYPED(exp1,_,_,NONE(),_)),SOME(DAE.UNTYPED(exp=aexp2))) equation aexp1 = Expression.unelabExp(exp1); - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // untyped vs. typed case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.TYPED(modifierAsAbsynExp=SOME(aexp2)))) equation - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.TYPED(exp2,_,_,NONE(),_))) equation aexp2 = Expression.unelabExp(exp2); - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // untyped mods case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.UNTYPED(exp=aexp2))) equation - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // anything else gives false case(_,_) then false; @@ -2262,21 +2292,34 @@ algorithm SCode.Each each1,each2; list submods1,submods2; Option eqmod1,eqmod2; + list> elsmods1, elsmods2; + SCode.Program els1, els2; case(DAE.MOD(f1,each1,submods1,eqmod1),DAE.MOD(f2,each2,submods2,eqmod2)) equation - true = valueEq(f1,f2); + // true = SCode.finalEqual(f1, f2); true = SCode.eachEqual(each1,each2); true = subModsEqual(submods1,submods2); true = eqModEqual(eqmod1,eqmod2); then true; - case(DAE.REDECL(_,_,_),DAE.REDECL(_,_,_)) then valueEq(mod1,mod2); + // two exactly the same mod, return just one! (used when it is REDECL or a submod is REDECL) + case(DAE.REDECL(f1, each1, elsmods1),DAE.REDECL(f2, each2, elsmods2)) + equation + // true = SCode.finalEqual(f1, f2); + true = SCode.eachEqual(each1, each2); + els1 = List.map(elsmods1, Util.tuple21); + els2 = List.map(elsmods2, Util.tuple21); + true = List.fold(List.threadMap(els1, els2, SCode.elementEqual), boolAnd, true); + then + true; + case(DAE.NOMOD(),DAE.NOMOD()) then true; // adrpo: do not fail, return false! - case (_, _) then false; + case (_, _) + then false; end matchcontinue; end modEqual; @@ -2313,6 +2356,7 @@ algorithm // otherwise false case(_,_) then false; + end matchcontinue; end subModsEqual; @@ -2348,6 +2392,24 @@ algorithm end matchcontinue; end subModEqual; +protected function valEqual + input Values.Value v1; + input Values.Value v2; + input Boolean equal; + output Boolean bEq; +algorithm + bEq := matchcontinue(v1, v2, equal) + case (_, _, true) then true; + case (_, _, false) + equation + bEq = Expression.expEqual( + ValuesUtil.valueExp(v1), + ValuesUtil.valueExp(v2)); + then + bEq; + end matchcontinue; +end valEqual; + protected function eqModEqual "Returns true if two EqMods are equal" input Option eqMod1; input Option eqMod2; @@ -2357,48 +2419,59 @@ algorithm local Absyn.Exp aexp1,aexp2; DAE.Exp exp1,exp2; + Values.Value v1, v2; // no equ mods case(NONE(),NONE()) then true; // typed equmods - case(SOME(DAE.TYPED(modifierAsExp=exp1)),SOME(DAE.TYPED(modifierAsExp=exp2))) + case(SOME(DAE.TYPED(modifierAsExp = exp1, modifierAsValue = SOME(v1))), + SOME(DAE.TYPED(modifierAsExp = exp2, modifierAsValue = SOME(v2)))) equation equal = Expression.expEqual(exp1,exp2); - then equal; + // check the values as crefs might have been replaced! + true = valEqual(v1, v2, equal); + then + true; // typed vs. untyped equmods case(SOME(DAE.TYPED(modifierAsAbsynExp=SOME(aexp1))),SOME(DAE.UNTYPED(exp=aexp2))) equation - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; case(SOME(DAE.TYPED(exp1,_,_,NONE(),_)),SOME(DAE.UNTYPED(exp=aexp2))) equation aexp1 = Expression.unelabExp(exp1); - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // untyped vs. typed equmods case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.TYPED(modifierAsAbsynExp=SOME(aexp2)))) equation - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.TYPED(exp2,_,_,NONE(),_))) equation aexp2 = Expression.unelabExp(exp2); - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // untyped equmods case(SOME(DAE.UNTYPED(exp=aexp1)),SOME(DAE.UNTYPED(exp=aexp2))) equation - equal = Absyn.expEqual(aexp1,aexp2); - then equal; + true = Absyn.expEqual(aexp1,aexp2); + then + true; // anything else will give false case(_,_) then false; + end matchcontinue; end eqModEqual; diff --git a/Compiler/FrontEnd/NFSCodeDependency.mo b/Compiler/FrontEnd/NFSCodeDependency.mo index dd96b6b9755..2d5b4efb3d2 100644 --- a/Compiler/FrontEnd/NFSCodeDependency.mo +++ b/Compiler/FrontEnd/NFSCodeDependency.mo @@ -734,7 +734,7 @@ protected function analyseElement input SCode.Restriction inClassRestriction; output list outExtends; algorithm - outExtends := match(inElement, inEnv, inExtends, inClassRestriction) + outExtends := matchcontinue(inElement, inEnv, inExtends, inClassRestriction) local Absyn.Path bc, bc2; SCode.Mod mods; @@ -749,6 +749,7 @@ algorithm SCode.Restriction res; String errorMessage; list exts; + Absyn.InnerOuter io; // Fail on 'extends ExternalObject' so we can handle it as a special case in // analyseClassDef. @@ -847,6 +848,14 @@ algorithm then inExtends; + // inner/innerouter classes may not be explicitly used but might be needed anyway + case (SCode.CLASS(name = name, prefixes = SCode.PREFIXES(innerOuter = io), info = info), _, _, _) + equation + true = boolOr(Absyn.isInner(io), Absyn.isInnerOuter(io)); + analyseClass(Absyn.IDENT(name), inEnv, info); + then + inExtends; + case (SCode.CLASS(name = name, info = info, classDef=SCode.CLASS_EXTENDS(baseClassName = _)), _, _, _) equation analyseClass(Absyn.IDENT(name), inEnv, info); @@ -854,7 +863,7 @@ algorithm inExtends; else inExtends; - end match; + end matchcontinue; end analyseElement; protected function markAsUsedOnRestriction diff --git a/Compiler/Util/Error.mo b/Compiler/Util/Error.mo index 9150553a659..d46a1e1f853 100644 --- a/Compiler/Util/Error.mo +++ b/Compiler/Util/Error.mo @@ -632,7 +632,9 @@ public constant Message PACKAGE_ORDER_FILE_NOT_COMPLETE = MESSAGE(529, GRAMMAR() Util.gettext("The package.order file does not list all .mo files and directories (containing package.mo) present in its directory.\nMissing names are:\n\t%s")); public constant Message REINIT_IN_WHEN_INITIAL = MESSAGE(530, TRANSLATION(), ERROR(), Util.gettext("Using reinit in when with condition initial() is not allowed. Use assignment or equality equation instead.")); - +public constant Message MISSING_INNER_CLASS = MESSAGE(531, TRANSLATION(), WARNING(), + Util.gettext("No corresponding 'inner' declaration found for class %s declared as '%s'.\n Continuing flattening by only considering the 'outer' class declaration.")); + public constant Message MATCH_SHADOWING = MESSAGE(5001, TRANSLATION(), ERROR(), Util.gettext("Local variable '%s' shadows another variable.")); public constant Message META_POLYMORPHIC = MESSAGE(5002, TRANSLATION(), ERROR(),