From 6ab888ea841ea9f17513977e05a5ebbe8a263f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Fri, 31 Mar 2023 17:59:39 +0200 Subject: [PATCH] Improve getAllSubtypeOf (#10487) - Put locally declared classes first in the list, and remove the parent prefix from them instead of using the fully qualified name. --- OMCompiler/Compiler/FrontEnd/AbsynUtil.mo | 22 +++++++++++ OMCompiler/Compiler/Script/CevalScript.mo | 1 - OMCompiler/Compiler/Script/InteractiveUtil.mo | 35 ++++++++++------- .../interactive-API/GetAllSubtypeOf1.mos | 19 +++++++++ .../openmodelica/interactive-API/Makefile | 39 ++++++++++--------- 5 files changed, 83 insertions(+), 33 deletions(-) create mode 100644 testsuite/openmodelica/interactive-API/GetAllSubtypeOf1.mos diff --git a/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo b/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo index 84b30318d48..ef60268a639 100644 --- a/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo +++ b/OMCompiler/Compiler/FrontEnd/AbsynUtil.mo @@ -1713,6 +1713,28 @@ algorithm end match; end removePrefix; +public function removePrefixOpt + "Removes prefixPath from path and returns the rest of the path, or returns + NONE() if prefixPath isn't a prefix of path." + input Absyn.Path prefixPath; + input Absyn.Path path; + output Option outPath; +algorithm + outPath := match (prefixPath, path) + case (_, Absyn.FULLYQUALIFIED()) then removePrefixOpt(prefixPath, path.path); + + case (Absyn.QUALIFIED(), Absyn.QUALIFIED()) + guard prefixPath.name == path.name + then removePrefixOpt(prefixPath.path, path.path); + + case (Absyn.IDENT(), Absyn.QUALIFIED()) + guard prefixPath.name == path.name + then SOME(path.path); + + else NONE(); + end match; +end removePrefixOpt; + public function removePartialPrefix "Tries to remove a given prefix from a path with removePrefix. If it fails it removes the first identifier in the prefix and tries again, until it either diff --git a/OMCompiler/Compiler/Script/CevalScript.mo b/OMCompiler/Compiler/Script/CevalScript.mo index ce4727775c1..c561ae5b890 100644 --- a/OMCompiler/Compiler/Script/CevalScript.mo +++ b/OMCompiler/Compiler/Script/CevalScript.mo @@ -1469,7 +1469,6 @@ algorithm Values.BOOL(sort)}) algorithm paths := InteractiveUtil.getAllSubtypeOf(path, parentClass, SymbolTable.getAbsyn(), qualified, includePartial); - paths := listReverse(paths); paths := if sort then List.sort(paths, AbsynUtil.pathGe) else paths; vals := List.map(paths,ValuesUtil.makeCodeTypeName); then diff --git a/OMCompiler/Compiler/Script/InteractiveUtil.mo b/OMCompiler/Compiler/Script/InteractiveUtil.mo index c033ba7a666..ff1a1e7ee4f 100644 --- a/OMCompiler/Compiler/Script/InteractiveUtil.mo +++ b/OMCompiler/Compiler/Script/InteractiveUtil.mo @@ -3997,16 +3997,14 @@ public function getAllSubtypeOf input Boolean includePartial; output list paths; protected - Absyn.Class cdef; - String s1; list strlst; Absyn.Path pp, fqpath; - Absyn.Program p; list classes; list result_path_lst; - list acc, extendPaths; - Boolean b,c; + list acc, extendPaths, local_paths; + Boolean b; GraphicEnvCache genv; + Option opt_path; algorithm Absyn.PROGRAM(classes=classes) := inProgram; strlst := List.map(List.filterOnTrue(classes, AbsynUtil.isNotPartial), AbsynUtil.getClassName); @@ -4018,20 +4016,31 @@ algorithm genv := createEnvironment(inProgram, NONE(), inParentClass); fqpath := qualifyPath(genv, inClass); else - // print("Bummer PPPath: " + AbsynUtil.pathString(inParentClass) + "\n"); fqpath := inClass; end try; - // print("FQPath: " + AbsynUtil.pathString(fqpath) + "\n"); - // print("PPPath: " + AbsynUtil.pathString(inParentClass) + "\n"); + paths := {}; + local_paths := {}; + for pt in acc loop - // print("Path: " + AbsynUtil.pathString(pt) + ":\n"); extendPaths := getAllInheritedClasses(pt, inProgram); - // print(" " + stringDelimitList(List.map(extendPaths, AbsynUtil.pathStringDefault), ", ")); print("\n"); System.fflush(); - b := List.applyAndFold1(extendPaths, boolOr, AbsynUtil.pathSuffixOfr, fqpath, false); - paths := if b then pt::paths else paths; + + if List.contains(extendPaths, fqpath, AbsynUtil.pathSuffixOfr) then + // Put classes declared locally in the parent class first in the list and + // remove the parent prefix from their name, since they're usually meant + // to be the default option. + opt_path := AbsynUtil.removePrefixOpt(inParentClass, pt); + + if isSome(opt_path) then + SOME(pt) := opt_path; + local_paths := pt :: local_paths; + else + paths := pt :: paths; + end if; + end if; end for; - paths := List.unique(paths); + + paths := List.unique(listAppend(local_paths, paths)); end getAllSubtypeOf; public function updateConnectionAnnotation diff --git a/testsuite/openmodelica/interactive-API/GetAllSubtypeOf1.mos b/testsuite/openmodelica/interactive-API/GetAllSubtypeOf1.mos new file mode 100644 index 00000000000..8e0cfea49b9 --- /dev/null +++ b/testsuite/openmodelica/interactive-API/GetAllSubtypeOf1.mos @@ -0,0 +1,19 @@ +// name: GetAllSubtypeOf1 +// keywords: +// status: correct +// cflags: -d=newInst +// +// Tests the getAllSubtypeOf API function. +// + +loadModel(Modelica, {"3.2.3"}); +getErrorString(); +getAllSubtypeOf(Modelica.Media.Interfaces.PartialMedium,Modelica.Fluid.Examples.PumpingSystem,false,false,false); +getErrorString(); + +// Result: +// true +// "" +// {Medium,Modelica.Media.Examples.TwoPhaseWater,Modelica.Media.Examples.TestOnly.N2AsMix,Modelica.Media.Air.SimpleAir,Modelica.Media.Air.DryAirNasa,Modelica.Media.Air.ReferenceAir.Air_ph,Modelica.Media.Air.ReferenceAir.Air_pT,Modelica.Media.Air.ReferenceAir.Air_dT,Modelica.Media.Air.MoistAir,Modelica.Media.Air.ReferenceMoistAir,Modelica.Media.CompressibleLiquids.LinearColdWater,Modelica.Media.CompressibleLiquids.LinearWater_pT_Ambient,Modelica.Media.IdealGases.SingleGases.Ar,Modelica.Media.IdealGases.SingleGases.CH4,Modelica.Media.IdealGases.SingleGases.CH3OH,Modelica.Media.IdealGases.SingleGases.CO,Modelica.Media.IdealGases.SingleGases.CO2,Modelica.Media.IdealGases.SingleGases.C2H2_vinylidene,Modelica.Media.IdealGases.SingleGases.C2H4,Modelica.Media.IdealGases.SingleGases.C2H5OH,Modelica.Media.IdealGases.SingleGases.C2H6,Modelica.Media.IdealGases.SingleGases.C3H6_propylene,Modelica.Media.IdealGases.SingleGases.C3H8,Modelica.Media.IdealGases.SingleGases.C3H8O_1propanol,Modelica.Media.IdealGases.SingleGases.C4H8_1_butene,Modelica.Media.IdealGases.SingleGases.C4H10_n_butane,Modelica.Media.IdealGases.SingleGases.C5H10_1_pentene,Modelica.Media.IdealGases.SingleGases.C5H12_n_pentane,Modelica.Media.IdealGases.SingleGases.C6H6,Modelica.Media.IdealGases.SingleGases.C6H12_1_hexene,Modelica.Media.IdealGases.SingleGases.C6H14_n_hexane,Modelica.Media.IdealGases.SingleGases.C7H14_1_heptene,Modelica.Media.IdealGases.SingleGases.C7H16_n_heptane,Modelica.Media.IdealGases.SingleGases.C8H10_ethylbenz,Modelica.Media.IdealGases.SingleGases.C8H18_n_octane,Modelica.Media.IdealGases.SingleGases.CL2,Modelica.Media.IdealGases.SingleGases.F2,Modelica.Media.IdealGases.SingleGases.H2,Modelica.Media.IdealGases.SingleGases.H2O,Modelica.Media.IdealGases.SingleGases.He,Modelica.Media.IdealGases.SingleGases.NH3,Modelica.Media.IdealGases.SingleGases.NO,Modelica.Media.IdealGases.SingleGases.NO2,Modelica.Media.IdealGases.SingleGases.N2,Modelica.Media.IdealGases.SingleGases.N2O,Modelica.Media.IdealGases.SingleGases.Ne,Modelica.Media.IdealGases.SingleGases.O2,Modelica.Media.IdealGases.SingleGases.SO2,Modelica.Media.IdealGases.SingleGases.SO3,Modelica.Media.IdealGases.MixtureGases.CombustionAir,Modelica.Media.IdealGases.MixtureGases.AirSteam,Modelica.Media.IdealGases.MixtureGases.simpleMoistAir,Modelica.Media.IdealGases.MixtureGases.FlueGasLambdaOnePlus,Modelica.Media.IdealGases.MixtureGases.FlueGasSixComponents,Modelica.Media.IdealGases.MixtureGases.SimpleNaturalGas,Modelica.Media.IdealGases.MixtureGases.SimpleNaturalGasFixedComposition,Modelica.Media.Incompressible.Examples.Glycol47,Modelica.Media.Incompressible.Examples.Essotherm650,Modelica.Media.Incompressible.TableBased,Modelica.Media.R134a.R134a_ph,Modelica.Media.Water.IdealSteam,Modelica.Media.Water.ConstantPropertyLiquidWater,Modelica.Media.Water.StandardWater,Modelica.Media.Water.StandardWaterOnePhase,Modelica.Media.Water.WaterIF97OnePhase_ph,Modelica.Media.Water.WaterIF97_pT,Modelica.Media.Water.WaterIF97_ph,Modelica.Media.Water.WaterIF97_R4ph,Modelica.Media.Water.WaterIF97_R5ph,Modelica.Media.Water.WaterIF97_R1pT,Modelica.Media.Water.WaterIF97_R2pT,Modelica.Media.Water.WaterIF97_R1ph,Modelica.Media.Water.WaterIF97_R2ph,Modelica.Media.Water.WaterIF97_R3ph} +// "" +// endResult diff --git a/testsuite/openmodelica/interactive-API/Makefile b/testsuite/openmodelica/interactive-API/Makefile index cbd0e5aa707..25ee01a151d 100644 --- a/testsuite/openmodelica/interactive-API/Makefile +++ b/testsuite/openmodelica/interactive-API/Makefile @@ -1,13 +1,11 @@ TEST = ../../rtest -v TESTFILES = \ -VendorAnnotation.mos \ AddClassAnnotation.mos \ ArraySlicing.mos \ -Buildings.PartialFlowMachine.mos \ Bug2871.mos \ -Bug2943.mos \ Bug2882.mos \ +Bug2943.mos \ Bug3269_deleteFile.mos \ Bug3282.mos \ Bug3417.mos \ @@ -17,11 +15,12 @@ Bug3974.mos \ Bug3979.mos \ Bug4209.mos \ Bug4248.mos \ +Buildings.PartialFlowMachine.mos \ checkAllModelsRecursive1.mos \ choicesAllMatching.mos \ -ConvertUnits.mos \ -ConversionVersions.mos \ ConnectionList.mos \ +ConversionVersions.mos \ +ConvertUnits.mos \ CopyClass.mos \ DefaultComponentName.mos \ DeleteConnection.mos \ @@ -35,10 +34,14 @@ ForStatement5fail.mos \ ForStatement6.mos \ ForStatement7.mos \ ForStatement8.mos \ +GetAllSubtypeOf1.mos \ getClassComment.mos \ getClassNames.mos \ getCommandLineOptions.mos \ GetComponents.mos \ +getComponentsTestNF.mos \ +getComponentsTestOF.mos \ +getDefinitions.mos \ getDialogAnnotation.mos \ getIconAnnotation.mos \ IfStatementIllegal.mos \ @@ -53,6 +56,8 @@ interactive_api_loadsave.mos \ interactive_api_param.mos \ interactive_api_simulations.mos \ interactive_test.mos \ +Issue7544.mos \ +Issue7706.mos \ ListAnnotation.mos \ ListExpressions.mos \ ListImport.mos \ @@ -60,11 +65,12 @@ ListMultilineComment.mos \ loadFileInteractiveQualified.mos \ matrices.mos \ Modelica.Media.Examples.getComponents.mos \ -MoveClass.mos \ MoveClass2.mos \ +MoveClass.mos \ Obfuscation1.mos \ Obfuscation2.mos \ ProtectedHandlingBug2917.mos \ +ReadOnlyPkg.mos \ refactorGraphAnn1.mos \ refactorGraphAnn2.mos \ regex.mos \ @@ -78,19 +84,16 @@ setElementModifierValue.mos \ setSourceFileListFile.mos \ showDoc.mos \ showStructuralAnnotations.mos \ +StateMachine.mos \ StoreAST.mos \ -stringSplit.mos \ strings.mos \ -variables.mos \ -getDefinitions.mos \ -StateMachine.mos \ +stringSplit.mos \ +TestChoices.mos \ Ticket4674.mos \ -UsesAnnotation1.mos \ -UsesAnnotation2.mos \ Ticket5506.mos \ Ticket5548.mos \ -Ticket5571.mos \ Ticket5565.mos \ +Ticket5571.mos \ Ticket5662.mos \ Ticket5680.mos \ Ticket5696.mos \ @@ -100,12 +103,10 @@ Ticket6287and6288.mos \ Ticket6300.mos \ Ticket6307.mos \ Ticket6406.mos \ -ReadOnlyPkg.mos \ -getComponentsTestNF.mos \ -getComponentsTestOF.mos \ -Issue7544.mos \ -Issue7706.mos \ -TestChoices.mos \ +UsesAnnotation1.mos \ +UsesAnnotation2.mos \ +variables.mos \ +VendorAnnotation.mos \ # test that currently fail. Move up when fixed.