Skip to content

Commit

Permalink
Preserve global context flags in Typing.typeCref2 (#12202)
Browse files Browse the repository at this point in the history
- Preserve the global context flags such as INSTANCE_API when typing
  components in Typing.typeCref2 instead of starting from an empty
  context.

Fixes #12188
  • Loading branch information
perost committed Apr 5, 2024
1 parent 1cb1c69 commit 05e800f
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 3 deletions.
12 changes: 12 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFInstContext.mo
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,14 @@ encapsulated package NFInstContext

// Flag values:
constant Type NO_CONTEXT = 0;
// Global flags:
constant Type RELAXED = intBitLShift(1, 0); // Relaxed instantiation, used by e.g. checkModel.
constant Type INSTANCE_API = intBitLShift(1, 1); // Instantiation for the model instance API.
constant Type FAST_LOOKUP = intBitLShift(1, 2); // Only expand packages when doing lookup.

constant Type GLOBAL_FLAGS = intBitOr(RELAXED, intBitOr(INSTANCE_API, FAST_LOOKUP));

// Scope flags:
constant Type CLASS = intBitLShift(1, 3); // In class.
constant Type FUNCTION = intBitLShift(1, 4); // In function.
constant Type REDECLARED = intBitLShift(1, 5); // In an element that will be replaced with a redeclare.
Expand Down Expand Up @@ -105,6 +110,13 @@ encapsulated package NFInstContext
annotation(__OpenModelica_EarlyInline=true);
end isNotSet;

function clearScopeFlags
input Type context;
output Type outContext;
algorithm
outContext := intBitAnd(context, GLOBAL_FLAGS);
end clearScopeFlags;

function inRelaxed
input Type context;
output Boolean res = intBitAnd(context, RELAXED) > 0;
Expand Down
10 changes: 7 additions & 3 deletions OMCompiler/Compiler/NFFrontEnd/NFTyping.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1978,7 +1978,7 @@ algorithm
// The context used when typing a component node depends on where the
// component was declared, not where it's used. This can be different to
// the given context, e.g. for package constants used in a function.
node_ty := typeComponent(cref.node, crefContext(cref.node), typeChildren = firstPart or not InstContext.inDimension(context));
node_ty := typeComponent(cref.node, crefContext(cref.node, context), typeChildren = firstPart or not InstContext.inDimension(context));

(subs, subs_var) := typeSubscripts(cref.subscripts, node_ty, Expression.CREF(node_ty, cref), context, info);
(rest_cr, rest_var) := typeCref2(cref.restCref, context, info, false);
Expand Down Expand Up @@ -2007,23 +2007,27 @@ end typeCref2;

function crefContext
input InstNode crefNode;
input InstContext.Type currentContext;
output InstContext.Type context;
protected
InstNode parent;
Restriction parent_res;
algorithm
parent := InstNode.explicitParent(crefNode);

context := InstContext.clearScopeFlags(currentContext);

// Records might actually be record constructors that should count as
// functions here, such record constructors are always root classes.
if not InstNode.isRootClass(parent) then
context := NFInstContext.CLASS;
context := InstContext.set(context, NFInstContext.CLASS);
return;
end if;

parent_res := InstNode.restriction(parent);
context := if Restriction.isFunction(parent_res) or Restriction.isRecord(parent_res) then
NFInstContext.FUNCTION else NFInstContext.CLASS;
InstContext.set(context, NFInstContext.FUNCTION) else
InstContext.set(context, NFInstContext.CLASS);
end crefContext;

function typeSubscripts
Expand Down
160 changes: 160 additions & 0 deletions testsuite/openmodelica/instance-API/GetModelInstanceInnerOuter5.mos
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// name: GetModelInstanceInnerOuter5
// keywords:
// status: correct
// cflags: -d=newInst
//
//

loadString("
model World
Position p;
parameter Boolean enableAnimation = true;
end World;

model Arrow
outer World world;
Real x if world.enableAnimation;
end Arrow;

model WorldForce
Arrow arrow;
end WorldForce;

type Length = Real;
type Position = Length;

model M
WorldForce force_a;
inner World world;
end M;
");

getModelInstance(M, prettyPrint=true);

// Result:
// true
// "{
// \"name\": \"M\",
// \"restriction\": \"model\",
// \"elements\": [
// {
// \"$kind\": \"component\",
// \"name\": \"force_a\",
// \"type\": {
// \"name\": \"WorldForce\",
// \"restriction\": \"model\",
// \"elements\": [
// {
// \"$kind\": \"component\",
// \"name\": \"arrow\",
// \"type\": {
// \"name\": \"Arrow\",
// \"restriction\": \"model\",
// \"elements\": [
// {
// \"$kind\": \"component\",
// \"name\": \"x\",
// \"type\": \"Real\",
// \"condition\": {
// \"binding\": true
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 7,
// \"columnStart\": 3,
// \"lineEnd\": 10,
// \"columnEnd\": 12
// }
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 12,
// \"columnStart\": 3,
// \"lineEnd\": 14,
// \"columnEnd\": 17
// }
// }
// },
// {
// \"$kind\": \"component\",
// \"name\": \"world\",
// \"type\": {
// \"name\": \"World\",
// \"restriction\": \"model\",
// \"elements\": [
// {
// \"$kind\": \"component\",
// \"name\": \"p\",
// \"type\": {
// \"name\": \"Position\",
// \"restriction\": \"type\",
// \"elements\": [
// {
// \"$kind\": \"extends\",
// \"baseClass\": {
// \"name\": \"Length\",
// \"restriction\": \"type\",
// \"elements\": [
// {
// \"$kind\": \"extends\",
// \"baseClass\": \"Real\"
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 16,
// \"columnStart\": 3,
// \"lineEnd\": 16,
// \"columnEnd\": 21
// }
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 17,
// \"columnStart\": 3,
// \"lineEnd\": 17,
// \"columnEnd\": 25
// }
// }
// },
// {
// \"$kind\": \"component\",
// \"name\": \"enableAnimation\",
// \"type\": \"Boolean\",
// \"modifiers\": \"true\",
// \"value\": {
// \"binding\": true
// },
// \"prefixes\": {
// \"variability\": \"parameter\"
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 2,
// \"columnStart\": 3,
// \"lineEnd\": 5,
// \"columnEnd\": 12
// }
// },
// \"prefixes\": {
// \"inner\": true
// }
// }
// ],
// \"source\": {
// \"filename\": \"<interactive>\",
// \"lineStart\": 19,
// \"columnStart\": 3,
// \"lineEnd\": 22,
// \"columnEnd\": 8
// }
// }"
// endResult
1 change: 1 addition & 0 deletions testsuite/openmodelica/instance-API/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ GetModelInstanceInnerOuter1.mos \
GetModelInstanceInnerOuter2.mos \
GetModelInstanceInnerOuter3.mos \
GetModelInstanceInnerOuter4.mos \
GetModelInstanceInnerOuter5.mos \
GetModelInstanceMissingClass1.mos \
GetModelInstanceMissingClass2.mos \
GetModelInstanceMissingClass3.mos \
Expand Down

0 comments on commit 05e800f

Please sign in to comment.