@matter/model 0.11.9-alpha.0-20241203-06077d82e → 0.11.9-alpha.0-20241206-22f233334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/elements/MatterElement.d.ts +5 -1
- package/dist/cjs/elements/MatterElement.d.ts.map +1 -1
- package/dist/cjs/elements/MatterElement.js +1 -1
- package/dist/cjs/elements/MatterElement.js.map +1 -1
- package/dist/cjs/logic/DefaultValue.d.ts +3 -1
- package/dist/cjs/logic/DefaultValue.d.ts.map +1 -1
- package/dist/cjs/logic/DefaultValue.js +11 -11
- package/dist/cjs/logic/DefaultValue.js.map +1 -1
- package/dist/cjs/logic/ModelTraversal.d.ts +6 -35
- package/dist/cjs/logic/ModelTraversal.d.ts.map +1 -1
- package/dist/cjs/logic/ModelTraversal.js +15 -109
- package/dist/cjs/logic/ModelTraversal.js.map +1 -1
- package/dist/cjs/logic/ModelVariantTraversal.d.ts.map +1 -1
- package/dist/cjs/logic/ModelVariantTraversal.js.map +1 -1
- package/dist/cjs/logic/Scope.d.ts +102 -0
- package/dist/cjs/logic/Scope.d.ts.map +1 -0
- package/dist/cjs/logic/Scope.js +220 -0
- package/dist/cjs/logic/Scope.js.map +6 -0
- package/dist/cjs/logic/definition-validation/ModelValidator.d.ts.map +1 -1
- package/dist/cjs/logic/index.d.ts +1 -0
- package/dist/cjs/logic/index.d.ts.map +1 -1
- package/dist/cjs/logic/index.js +1 -0
- package/dist/cjs/logic/index.js.map +1 -1
- package/dist/cjs/models/AttributeModel.d.ts +20 -0
- package/dist/cjs/models/AttributeModel.d.ts.map +1 -1
- package/dist/cjs/models/AttributeModel.js +3 -0
- package/dist/cjs/models/AttributeModel.js.map +1 -1
- package/dist/cjs/models/Children.d.ts +4 -0
- package/dist/cjs/models/Children.d.ts.map +1 -1
- package/dist/cjs/models/Children.js +13 -0
- package/dist/cjs/models/Children.js.map +1 -1
- package/dist/cjs/models/ClusterModel.d.ts +6 -7
- package/dist/cjs/models/ClusterModel.d.ts.map +1 -1
- package/dist/cjs/models/ClusterModel.js +5 -38
- package/dist/cjs/models/ClusterModel.js.map +1 -1
- package/dist/cjs/models/CommandModel.d.ts +22 -0
- package/dist/cjs/models/CommandModel.d.ts.map +1 -1
- package/dist/cjs/models/CommandModel.js +3 -0
- package/dist/cjs/models/CommandModel.js.map +1 -1
- package/dist/cjs/models/DatatypeModel.js +0 -2
- package/dist/cjs/models/DatatypeModel.js.map +1 -1
- package/dist/cjs/models/EventModel.d.ts +21 -0
- package/dist/cjs/models/EventModel.d.ts.map +1 -1
- package/dist/cjs/models/EventModel.js +3 -0
- package/dist/cjs/models/EventModel.js.map +1 -1
- package/dist/cjs/models/MatterModel.d.ts +3 -3
- package/dist/cjs/models/MatterModel.d.ts.map +1 -1
- package/dist/cjs/models/MatterModel.js +6 -5
- package/dist/cjs/models/MatterModel.js.map +1 -1
- package/dist/cjs/models/Model.d.ts +10 -6
- package/dist/cjs/models/Model.d.ts.map +1 -1
- package/dist/cjs/models/Model.js +28 -9
- package/dist/cjs/models/Model.js.map +1 -1
- package/dist/cjs/models/ScopeModel.d.ts +22 -0
- package/dist/cjs/models/ScopeModel.d.ts.map +1 -0
- package/dist/cjs/models/ScopeModel.js +63 -0
- package/dist/cjs/models/ScopeModel.js.map +6 -0
- package/dist/cjs/models/ValueModel.d.ts +7 -21
- package/dist/cjs/models/ValueModel.d.ts.map +1 -1
- package/dist/cjs/models/ValueModel.js +15 -34
- package/dist/cjs/models/ValueModel.js.map +1 -1
- package/dist/cjs/models/index.d.ts +1 -0
- package/dist/cjs/models/index.d.ts.map +1 -1
- package/dist/cjs/models/index.js +1 -0
- package/dist/cjs/models/index.js.map +1 -1
- package/dist/cjs/standard/elements/ColorControl.js +3 -4
- package/dist/cjs/standard/elements/ColorControl.js.map +1 -1
- package/dist/cjs/standard/elements/ModeBase.js +1 -1
- package/dist/cjs/standard/elements/ModeBase.js.map +1 -1
- package/dist/cjs/standard/elements/PumpConfigurationAndControl.d.ts.map +1 -1
- package/dist/cjs/standard/elements/PumpConfigurationAndControl.js +3 -20
- package/dist/cjs/standard/elements/PumpConfigurationAndControl.js.map +1 -1
- package/dist/cjs/standard/elements/UserLabel.d.ts.map +1 -1
- package/dist/cjs/standard/elements/UserLabel.js +13 -16
- package/dist/cjs/standard/elements/UserLabel.js.map +1 -1
- package/dist/cjs/standard/elements/WildcardPathFlagsBitmap.d.ts.map +1 -1
- package/dist/cjs/standard/elements/WildcardPathFlagsBitmap.js +1 -5
- package/dist/cjs/standard/elements/WildcardPathFlagsBitmap.js.map +1 -1
- package/dist/cjs/standard/elements/WindowCovering.js +2 -2
- package/dist/esm/elements/MatterElement.d.ts +5 -1
- package/dist/esm/elements/MatterElement.d.ts.map +1 -1
- package/dist/esm/elements/MatterElement.js +1 -1
- package/dist/esm/elements/MatterElement.js.map +1 -1
- package/dist/esm/logic/DefaultValue.d.ts +3 -1
- package/dist/esm/logic/DefaultValue.d.ts.map +1 -1
- package/dist/esm/logic/DefaultValue.js +11 -11
- package/dist/esm/logic/DefaultValue.js.map +1 -1
- package/dist/esm/logic/ModelTraversal.d.ts +6 -35
- package/dist/esm/logic/ModelTraversal.d.ts.map +1 -1
- package/dist/esm/logic/ModelTraversal.js +16 -110
- package/dist/esm/logic/ModelTraversal.js.map +1 -1
- package/dist/esm/logic/ModelVariantTraversal.d.ts.map +1 -1
- package/dist/esm/logic/ModelVariantTraversal.js.map +1 -1
- package/dist/esm/logic/Scope.d.ts +102 -0
- package/dist/esm/logic/Scope.d.ts.map +1 -0
- package/dist/esm/logic/Scope.js +200 -0
- package/dist/esm/logic/Scope.js.map +6 -0
- package/dist/esm/logic/definition-validation/ModelValidator.d.ts.map +1 -1
- package/dist/esm/logic/index.d.ts +1 -0
- package/dist/esm/logic/index.d.ts.map +1 -1
- package/dist/esm/logic/index.js +1 -0
- package/dist/esm/logic/index.js.map +1 -1
- package/dist/esm/models/AttributeModel.d.ts +20 -0
- package/dist/esm/models/AttributeModel.d.ts.map +1 -1
- package/dist/esm/models/AttributeModel.js +3 -0
- package/dist/esm/models/AttributeModel.js.map +1 -1
- package/dist/esm/models/Children.d.ts +4 -0
- package/dist/esm/models/Children.d.ts.map +1 -1
- package/dist/esm/models/Children.js +13 -0
- package/dist/esm/models/Children.js.map +1 -1
- package/dist/esm/models/ClusterModel.d.ts +6 -7
- package/dist/esm/models/ClusterModel.d.ts.map +1 -1
- package/dist/esm/models/ClusterModel.js +5 -38
- package/dist/esm/models/ClusterModel.js.map +1 -1
- package/dist/esm/models/CommandModel.d.ts +22 -0
- package/dist/esm/models/CommandModel.d.ts.map +1 -1
- package/dist/esm/models/CommandModel.js +3 -0
- package/dist/esm/models/CommandModel.js.map +1 -1
- package/dist/esm/models/DatatypeModel.js +0 -2
- package/dist/esm/models/DatatypeModel.js.map +1 -1
- package/dist/esm/models/EventModel.d.ts +21 -0
- package/dist/esm/models/EventModel.d.ts.map +1 -1
- package/dist/esm/models/EventModel.js +3 -0
- package/dist/esm/models/EventModel.js.map +1 -1
- package/dist/esm/models/MatterModel.d.ts +3 -3
- package/dist/esm/models/MatterModel.d.ts.map +1 -1
- package/dist/esm/models/MatterModel.js +6 -5
- package/dist/esm/models/MatterModel.js.map +1 -1
- package/dist/esm/models/Model.d.ts +10 -6
- package/dist/esm/models/Model.d.ts.map +1 -1
- package/dist/esm/models/Model.js +28 -9
- package/dist/esm/models/Model.js.map +1 -1
- package/dist/esm/models/ScopeModel.d.ts +22 -0
- package/dist/esm/models/ScopeModel.d.ts.map +1 -0
- package/dist/esm/models/ScopeModel.js +43 -0
- package/dist/esm/models/ScopeModel.js.map +6 -0
- package/dist/esm/models/ValueModel.d.ts +7 -21
- package/dist/esm/models/ValueModel.d.ts.map +1 -1
- package/dist/esm/models/ValueModel.js +15 -34
- package/dist/esm/models/ValueModel.js.map +1 -1
- package/dist/esm/models/index.d.ts +1 -0
- package/dist/esm/models/index.d.ts.map +1 -1
- package/dist/esm/models/index.js +1 -0
- package/dist/esm/models/index.js.map +1 -1
- package/dist/esm/standard/elements/ColorControl.js +3 -4
- package/dist/esm/standard/elements/ColorControl.js.map +1 -1
- package/dist/esm/standard/elements/ModeBase.js +1 -1
- package/dist/esm/standard/elements/ModeBase.js.map +1 -1
- package/dist/esm/standard/elements/PumpConfigurationAndControl.d.ts.map +1 -1
- package/dist/esm/standard/elements/PumpConfigurationAndControl.js +3 -20
- package/dist/esm/standard/elements/PumpConfigurationAndControl.js.map +1 -1
- package/dist/esm/standard/elements/UserLabel.d.ts.map +1 -1
- package/dist/esm/standard/elements/UserLabel.js +13 -16
- package/dist/esm/standard/elements/UserLabel.js.map +1 -1
- package/dist/esm/standard/elements/WildcardPathFlagsBitmap.d.ts.map +1 -1
- package/dist/esm/standard/elements/WildcardPathFlagsBitmap.js +1 -5
- package/dist/esm/standard/elements/WildcardPathFlagsBitmap.js.map +1 -1
- package/dist/esm/standard/elements/WindowCovering.js +2 -2
- package/package.json +4 -4
- package/src/elements/MatterElement.ts +7 -2
- package/src/logic/DefaultValue.ts +13 -11
- package/src/logic/ModelTraversal.ts +28 -147
- package/src/logic/ModelVariantTraversal.ts +0 -1
- package/src/logic/Scope.ts +400 -0
- package/src/logic/index.ts +1 -0
- package/src/models/AttributeModel.ts +4 -0
- package/src/models/Children.ts +24 -1
- package/src/models/ClusterModel.ts +12 -51
- package/src/models/CommandModel.ts +4 -0
- package/src/models/DatatypeModel.ts +0 -2
- package/src/models/EventModel.ts +4 -0
- package/src/models/MatterModel.ts +6 -5
- package/src/models/Model.ts +38 -12
- package/src/models/ScopeModel.ts +55 -0
- package/src/models/ValueModel.ts +17 -39
- package/src/models/index.ts +1 -0
- package/src/standard/elements/ColorControl.ts +4 -4
- package/src/standard/elements/ModeBase.ts +1 -1
- package/src/standard/elements/PumpConfigurationAndControl.ts +2 -18
- package/src/standard/elements/UserLabel.ts +8 -12
- package/src/standard/elements/WildcardPathFlagsBitmap.ts +1 -4
- package/src/standard/elements/WindowCovering.ts +2 -2
|
@@ -9,6 +9,7 @@ import { ElementTag, FieldValue, Metatype } from "../common/index.js";
|
|
|
9
9
|
import { Model } from "../models/Model.js";
|
|
10
10
|
import type { ValueModel } from "../models/ValueModel.js";
|
|
11
11
|
import { FeatureMap } from "../standard/elements/FeatureMap.js";
|
|
12
|
+
import { Scope } from "./Scope.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Obtain a native JS default value for a ValueModel.
|
|
@@ -17,13 +18,14 @@ import { FeatureMap } from "../standard/elements/FeatureMap.js";
|
|
|
17
18
|
* structural issues but generally returns undefined if the model's default value cannot be converted to the correct
|
|
18
19
|
* type.
|
|
19
20
|
*
|
|
21
|
+
* @param scope the scope in which the model is referenced
|
|
20
22
|
* @param model the model from which the default value is extracted
|
|
21
23
|
* @param ifValid some structs only have partial defaults defined so would be invalid; do not return these
|
|
22
24
|
*/
|
|
23
|
-
export function DefaultValue(model: ValueModel, ifValid = false): any {
|
|
25
|
+
export function DefaultValue(scope: Scope, model: ValueModel, ifValid = false): any {
|
|
24
26
|
const value = castValue(model, model.default);
|
|
25
27
|
if (value === undefined) {
|
|
26
|
-
return buildValue(model, ifValid);
|
|
28
|
+
return buildValue(scope, model, ifValid);
|
|
27
29
|
}
|
|
28
30
|
return value;
|
|
29
31
|
}
|
|
@@ -117,7 +119,7 @@ function castValue(model: ValueModel, modelDefault?: FieldValue): unknown {
|
|
|
117
119
|
/**
|
|
118
120
|
* When an explicit default value is not present, for some types we generate a default from the structure.
|
|
119
121
|
*/
|
|
120
|
-
function buildValue(model: ValueModel, ifValid: boolean) {
|
|
122
|
+
function buildValue(scope: Scope, model: ValueModel, ifValid: boolean) {
|
|
121
123
|
switch (model.effectiveMetatype) {
|
|
122
124
|
case Metatype.array:
|
|
123
125
|
// We don't really build default array values except in the case of non-nullable arrays where zero items is
|
|
@@ -133,23 +135,23 @@ function buildValue(model: ValueModel, ifValid: boolean) {
|
|
|
133
135
|
return;
|
|
134
136
|
|
|
135
137
|
case Metatype.object:
|
|
136
|
-
return buildObject(model, ifValid);
|
|
138
|
+
return buildObject(scope, model, ifValid);
|
|
137
139
|
|
|
138
140
|
case Metatype.bitmap:
|
|
139
|
-
return buildBitmap(model);
|
|
141
|
+
return buildBitmap(scope, model);
|
|
140
142
|
}
|
|
141
143
|
}
|
|
142
144
|
|
|
143
|
-
function buildObject(model: ValueModel, ifValid: boolean) {
|
|
145
|
+
function buildObject(scope: Scope, model: ValueModel, ifValid: boolean) {
|
|
144
146
|
let result: { [key: string]: any } | undefined;
|
|
145
147
|
|
|
146
|
-
for (const child of model
|
|
148
|
+
for (const child of scope.membersOf(model, { conformance: "conformant" })) {
|
|
147
149
|
const name = camelize(child.name);
|
|
148
150
|
if (result && result[name] !== undefined) {
|
|
149
151
|
continue;
|
|
150
152
|
}
|
|
151
153
|
|
|
152
|
-
const value = child
|
|
154
|
+
const value = DefaultValue(scope, child);
|
|
153
155
|
if (value !== undefined) {
|
|
154
156
|
if (!result) {
|
|
155
157
|
result = {};
|
|
@@ -168,11 +170,11 @@ function buildObject(model: ValueModel, ifValid: boolean) {
|
|
|
168
170
|
return result;
|
|
169
171
|
}
|
|
170
172
|
|
|
171
|
-
function buildBitmap(model: ValueModel) {
|
|
173
|
+
function buildBitmap(scope: Scope, model: ValueModel) {
|
|
172
174
|
let result;
|
|
173
175
|
let fieldsDefined = 0;
|
|
174
176
|
|
|
175
|
-
for (const m of model
|
|
177
|
+
for (const m of scope.membersOf(model, { conformance: "conformant" })) {
|
|
176
178
|
const defaultValue = FieldValue.numericValue(m.default);
|
|
177
179
|
if (defaultValue === undefined) {
|
|
178
180
|
continue;
|
|
@@ -228,7 +230,7 @@ function decodeBitmap(model: ValueModel, value: number | bigint) {
|
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
const definition = model.bitDefinition(bit);
|
|
231
|
-
if (!definition
|
|
233
|
+
if (!definition) {
|
|
232
234
|
continue;
|
|
233
235
|
}
|
|
234
236
|
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import { InternalError } from "@matter/general";
|
|
8
8
|
import { Access, Aspect, Constraint } from "../aspects/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import { ElementTag, FeatureSet, FieldValue, Metatype } from "../common/index.js";
|
|
9
|
+
import { ElementTag, FieldValue, Metatype } from "../common/index.js";
|
|
11
10
|
import { AnyElement } from "../elements/index.js";
|
|
12
11
|
import { Children } from "../models/Children.js";
|
|
13
|
-
import { PropertyModel, type ClusterModel, type CommandModel, type Model, type ValueModel } from "../models/index.js";
|
|
14
12
|
import {
|
|
15
13
|
enum16,
|
|
16
14
|
enum8,
|
|
@@ -24,14 +22,13 @@ import {
|
|
|
24
22
|
uint8,
|
|
25
23
|
} from "../standard/elements/definitions.js";
|
|
26
24
|
|
|
25
|
+
// These must be types to avoid circular references
|
|
26
|
+
import type { CommandModel, Model, ScopeModel, ValueModel } from "../models/index.js";
|
|
27
|
+
|
|
27
28
|
const OPERATION_DEPTH_LIMIT = 20;
|
|
28
29
|
|
|
29
30
|
let memos: Memos | undefined;
|
|
30
31
|
|
|
31
|
-
// Member caches. Only populated for frozen models
|
|
32
|
-
const activeMemberCache = new WeakMap<Model, ValueModel[]>();
|
|
33
|
-
const conformantMemberCache = new WeakMap<Model, ValueModel[]>();
|
|
34
|
-
|
|
35
32
|
/**
|
|
36
33
|
* This class performs lookups of models in the scope of a specific model. We use a class so the lookup can maintain
|
|
37
34
|
* state and guard against circular references.
|
|
@@ -173,11 +170,8 @@ export class ModelTraversal {
|
|
|
173
170
|
}
|
|
174
171
|
|
|
175
172
|
const findBaseOp = () => {
|
|
176
|
-
// If I override another element (same identity and tag in parent's inheritance hierarchy)
|
|
177
|
-
// inherit from the shadow.
|
|
178
|
-
//
|
|
179
|
-
// Semantics would be wonky if the model designates a different type than the shadow, but we support this by
|
|
180
|
-
// ignoring the shadow in this case.
|
|
173
|
+
// If I override another element (same identity and tag in parent's inheritance hierarchy) and don't specify
|
|
174
|
+
// a type then I implicitly inherit from the shadow.
|
|
181
175
|
const shadow = this.findShadow(model);
|
|
182
176
|
if (
|
|
183
177
|
shadow !== undefined &&
|
|
@@ -466,126 +460,6 @@ export class ModelTraversal {
|
|
|
466
460
|
});
|
|
467
461
|
}
|
|
468
462
|
|
|
469
|
-
/**
|
|
470
|
-
* Retrieve all children of a specific type, including those inherited from the base or a shadow. Does not include
|
|
471
|
-
* members overridden by a deeper member.
|
|
472
|
-
*/
|
|
473
|
-
findChildren(scope: Model, tags: ElementTag[]) {
|
|
474
|
-
const members = Array<Model>();
|
|
475
|
-
|
|
476
|
-
// This is a map of identity (based on tag + id/name + discriminator) to a priority based on inheritance depth
|
|
477
|
-
const defined = {} as Record<string, number | undefined>;
|
|
478
|
-
|
|
479
|
-
let level = 0;
|
|
480
|
-
const childSearchVisitor = (model: Model) => {
|
|
481
|
-
level++;
|
|
482
|
-
for (const child of model.children) {
|
|
483
|
-
if (!tags.includes(child.tag)) {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Identify and skip shadows based on ID
|
|
488
|
-
let numericIdentity;
|
|
489
|
-
if (child.id !== undefined) {
|
|
490
|
-
numericIdentity = `i␜${child.tag}␜${child.id}␜${child.discriminator ?? ""}`;
|
|
491
|
-
const numericLevel = defined[numericIdentity];
|
|
492
|
-
if (numericLevel !== undefined && numericLevel < level) {
|
|
493
|
-
continue;
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// Identify and skip shadows based on name
|
|
498
|
-
const nameIdentity = `s␜${child.tag}␜${child.name}␜${child.discriminator ?? ""}`;
|
|
499
|
-
const nameLevel = defined[nameIdentity];
|
|
500
|
-
if (nameLevel !== undefined && nameLevel < level) {
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
// Mark the level in which we saw these members
|
|
505
|
-
if (numericIdentity) {
|
|
506
|
-
defined[numericIdentity] = level;
|
|
507
|
-
}
|
|
508
|
-
defined[nameIdentity] = level;
|
|
509
|
-
|
|
510
|
-
// Found a member
|
|
511
|
-
members.push(child);
|
|
512
|
-
}
|
|
513
|
-
};
|
|
514
|
-
this.visitInheritance(scope, childSearchVisitor);
|
|
515
|
-
|
|
516
|
-
return members;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Filter a model's members as follows:
|
|
521
|
-
*
|
|
522
|
-
* - If the member is deprecated, ignore it
|
|
523
|
-
*
|
|
524
|
-
* - If there is only a single member of a given name, select that member
|
|
525
|
-
*
|
|
526
|
-
* - If there are multiple members with the same name but there is no cluster throw an error
|
|
527
|
-
*
|
|
528
|
-
* - If there are multiple members with the same name, use conformance to select the member that is applicable
|
|
529
|
-
* based on active features in the provided cluster
|
|
530
|
-
*
|
|
531
|
-
* - If there are multiple applicable members based on conformance the definitions conflict and throw an error
|
|
532
|
-
*
|
|
533
|
-
* If the model is frozen we cache the return value.
|
|
534
|
-
*
|
|
535
|
-
* Note that "active" in this case does not imply the member is conformant, only that conflicts are resolved.
|
|
536
|
-
*
|
|
537
|
-
* Note 2 - members may not be differentiated with conformance rules that rely on field values in this way. That
|
|
538
|
-
* will probably never be necessary and would require an entirely different (more complicated) structure.
|
|
539
|
-
*/
|
|
540
|
-
findActiveMembers(scope: Model & { members: PropertyModel[] }, conformantOnly: boolean, cluster?: ClusterModel) {
|
|
541
|
-
const cache = Object.isFrozen(scope) ? (conformantOnly ? conformantMemberCache : activeMemberCache) : undefined;
|
|
542
|
-
|
|
543
|
-
const cached = cache?.get(scope);
|
|
544
|
-
if (cached) {
|
|
545
|
-
return cached;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
const features = cluster?.featureNames ?? new FeatureSet();
|
|
549
|
-
const supportedFeatures = cluster?.supportedFeatures ?? new FeatureSet();
|
|
550
|
-
|
|
551
|
-
const selectedMembers = {} as Record<string, ValueModel>;
|
|
552
|
-
for (const member of scope.members) {
|
|
553
|
-
if (member.isDeprecated) {
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
if (conformantOnly && !member.conformance.isApplicable(features, supportedFeatures)) {
|
|
558
|
-
continue;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
const other = selectedMembers[member.name];
|
|
562
|
-
if (other !== undefined) {
|
|
563
|
-
if (!conformantOnly && !member.conformance.isApplicable(features, supportedFeatures)) {
|
|
564
|
-
continue;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
if (other.conformance.isApplicable(features, supportedFeatures)) {
|
|
568
|
-
throw new SchemaImplementationError(
|
|
569
|
-
scope,
|
|
570
|
-
`There are multiple definitions of "${member.name}" that cannot be differentiated by conformance`,
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
// This member takes precedence and will overwrite below
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
selectedMembers[member.name] = member;
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
const result = Object.values(selectedMembers);
|
|
581
|
-
|
|
582
|
-
if (cache) {
|
|
583
|
-
cache.set(scope, result);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return result;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
463
|
/**
|
|
590
464
|
* Search inherited scope for a bit definition.
|
|
591
465
|
*/
|
|
@@ -615,21 +489,21 @@ export class ModelTraversal {
|
|
|
615
489
|
/**
|
|
616
490
|
* Search inherited and structural type scope for a named type.
|
|
617
491
|
*/
|
|
618
|
-
findType(
|
|
619
|
-
if (!
|
|
492
|
+
findType(owner: Model | undefined, name: string, tag: ElementTag): Model | undefined {
|
|
493
|
+
if (!owner) {
|
|
620
494
|
return;
|
|
621
495
|
}
|
|
622
496
|
|
|
623
497
|
const memoKey = `${name} ${tag}`;
|
|
624
|
-
const memosForScope = memos?.types.get(
|
|
498
|
+
const memosForScope = memos?.types.get(owner);
|
|
625
499
|
if (memosForScope && memoKey in memosForScope) {
|
|
626
500
|
return memosForScope[memoKey];
|
|
627
501
|
}
|
|
628
502
|
|
|
629
503
|
const findTypeOp = () => {
|
|
630
|
-
const queue = Array<Model>(
|
|
631
|
-
for (scope = queue.shift(); scope; scope = queue.shift()) {
|
|
632
|
-
if (scope.
|
|
504
|
+
const queue = Array<Model>(owner);
|
|
505
|
+
for (let scope = queue.shift(); scope; scope = queue.shift()) {
|
|
506
|
+
if ((scope as ScopeModel).isScope) {
|
|
633
507
|
const result = scope.children.select(name, tag, this.#dismissed);
|
|
634
508
|
if (result) {
|
|
635
509
|
return result;
|
|
@@ -648,15 +522,22 @@ export class ModelTraversal {
|
|
|
648
522
|
queue.push(parent);
|
|
649
523
|
}
|
|
650
524
|
}
|
|
525
|
+
|
|
526
|
+
// If the model is not part of a MatterModel hierarchy, findBase and findParent will use the fallback model for
|
|
527
|
+
// resolution. However, if the model is part of an incomplete MatterModel hierarchy, that logic is not
|
|
528
|
+
// triggered. So handle the case where a global type is missing here
|
|
529
|
+
if (ModelTraversal.fallbackScope && owner !== ModelTraversal.fallbackScope) {
|
|
530
|
+
return this.findType(ModelTraversal.fallbackScope, name, tag);
|
|
531
|
+
}
|
|
651
532
|
};
|
|
652
533
|
const type = this.operation(findTypeOp);
|
|
653
534
|
|
|
654
535
|
if (memos) {
|
|
655
|
-
const memosForScope = memos.types.get(
|
|
536
|
+
const memosForScope = memos.types.get(owner);
|
|
656
537
|
if (memosForScope) {
|
|
657
538
|
memosForScope[memoKey] = type;
|
|
658
539
|
} else {
|
|
659
|
-
memos.types.set(
|
|
540
|
+
memos.types.set(owner, { [memoKey]: type });
|
|
660
541
|
}
|
|
661
542
|
}
|
|
662
543
|
|
|
@@ -666,8 +547,8 @@ export class ModelTraversal {
|
|
|
666
547
|
/**
|
|
667
548
|
* Similar to findType but operates with a qualified type name.
|
|
668
549
|
*
|
|
669
|
-
* Unlike findType, a qualified type may reference an element parented by any other, not just those
|
|
670
|
-
*
|
|
550
|
+
* Unlike findType, a qualified type may reference an element parented by any other, not just those within
|
|
551
|
+
* ScopeModels.
|
|
671
552
|
*
|
|
672
553
|
* This is quite complicated and would be painfully slow except in practice we don't use many qualified types and
|
|
673
554
|
* those we do use resolve with few failing branches in the search once the root qualifier of the name matches.
|
|
@@ -835,7 +716,7 @@ export class ModelTraversal {
|
|
|
835
716
|
return false;
|
|
836
717
|
}
|
|
837
718
|
const base = this.findBase(model);
|
|
838
|
-
this.visitInheritance(base, visitor);
|
|
719
|
+
return this.visitInheritance(base, visitor);
|
|
839
720
|
});
|
|
840
721
|
}
|
|
841
722
|
|
|
@@ -863,15 +744,15 @@ export class ModelTraversal {
|
|
|
863
744
|
/**
|
|
864
745
|
* Find an owner that defines type scope for a model.
|
|
865
746
|
*/
|
|
866
|
-
findScope(model?: Model):
|
|
747
|
+
findScope(model?: Model): ScopeModel | undefined {
|
|
867
748
|
if (model === undefined) {
|
|
868
749
|
return;
|
|
869
750
|
}
|
|
870
751
|
|
|
871
752
|
// First, examine parents
|
|
872
753
|
if (model.parent) {
|
|
873
|
-
if (model.parent.
|
|
874
|
-
return model.parent;
|
|
754
|
+
if ((model.parent as ScopeModel).isScope) {
|
|
755
|
+
return model.parent as ScopeModel;
|
|
875
756
|
}
|
|
876
757
|
|
|
877
758
|
return this.operationWithDismissal(model, () => this.findScope(model.parent));
|
|
@@ -890,7 +771,7 @@ export class ModelTraversal {
|
|
|
890
771
|
* If a model is not owned by a MatterModel, global resolution won't work. This model acts as a fallback to work
|
|
891
772
|
* around this.
|
|
892
773
|
*/
|
|
893
|
-
static fallbackScope:
|
|
774
|
+
static fallbackScope: ScopeModel | undefined;
|
|
894
775
|
|
|
895
776
|
/**
|
|
896
777
|
* This is a cheap hack to optimize analysis of large static models. It temporarily memoizes key operations.
|
|
@@ -321,7 +321,6 @@ export abstract class ModelVariantTraversal<S = void> {
|
|
|
321
321
|
// For each applicable child of this variant, associated it with a slot
|
|
322
322
|
for (let i = 0; i < variant.children.length; i++) {
|
|
323
323
|
const child = variant.children[i];
|
|
324
|
-
|
|
325
324
|
if (!child.appliesTo(this.revision)) {
|
|
326
325
|
continue;
|
|
327
326
|
}
|