Skip to content

Commit a702abf

Browse files
Add isSupported helper for Darwin. (#1000)
* Add isSupported helper for Darwin. This supports marking this as "provisional", which unlike "removed" can be overridden by a later "introduced". * Make handling of introduced things inside a provisional thing better. * Also include description in zcl_clusters, to match all_user_clusters.
1 parent 313e73a commit a702abf

File tree

2 files changed

+122
-15
lines changed

2 files changed

+122
-15
lines changed

src-electron/db/db-mapping.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ exports.map = {
7575
label: x.NAME,
7676
name: x.NAME,
7777
caption: x.DESCRIPTION,
78+
description: x.DESCRIPTION,
7879
define: x.DEFINE,
7980
domainName: x.DOMAIN_NAME,
8081
isSingleton: dbApi.fromDbBool(x.IS_SINGLETON),

src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js

Lines changed: 121 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -739,42 +739,147 @@ async function availability(clusterName, options) {
739739
}", ${availabilityStrings.join(', ')})`;
740740
}
741741

742-
function wasIntroducedBeforeRelease(releaseName, clusterName, options) {
743-
const data = fetchAvailabilityData(this.global);
744-
const path = makeAvailabilityPath(clusterName, options);
742+
/**
743+
* Utility for wasIntroducedBeforeRelease and isSupported. Returns undefined if
744+
* the the path we are looking at was not officially introduced, otherwise
745+
* returns -1 if it was introduced before the reference release, 0 if it was
746+
* introduced in the reference release, 1 if it was introduced after the
747+
* reference release.
748+
*
749+
* Throws if referenceRelease is not defined.
750+
*/
751+
function compareIntroductionToReferenceRelease(global, path, options, referenceRelease) {
752+
if (referenceRelease === undefined) {
753+
throw new Error("Can't compare to non-existent release");
754+
}
755+
756+
const data = fetchAvailabilityData(global);
745757

746758
let introducedRelease = findReleaseForPath(
747759
data,
748760
['introduced', ...path],
749761
options
750762
);
751763
if (introducedRelease === undefined) {
752-
return false;
764+
return undefined;
765+
}
766+
767+
let referenceIndex = data.indexOf(referenceRelease);
768+
let introducedIndex = data.indexOf(introducedRelease);
769+
if (introducedIndex < referenceIndex) {
770+
return -1;
771+
}
772+
773+
if (introducedIndex > referenceIndex) {
774+
return 1;
753775
}
754776

777+
return 0;
778+
}
779+
780+
function wasIntroducedBeforeRelease(releaseName, clusterName, options) {
781+
const data = fetchAvailabilityData(this.global);
782+
const path = makeAvailabilityPath(clusterName, options);
783+
755784
let referenceRelease = findReleaseByName(data, releaseName);
756785
if (referenceRelease === undefined) {
757786
throw new Error(`Invalid release name: ${releaseName}`);
758787
}
759788

760-
return data.indexOf(introducedRelease) < data.indexOf(referenceRelease);
789+
let comparisonStatus = compareIntroductionToReferenceRelease(
790+
this.global,
791+
makeAvailabilityPath(clusterName, options),
792+
options, referenceRelease
793+
);
794+
if (comparisonStatus === undefined) {
795+
// Not introduced yet, so not introduced before anything in particular.
796+
return false;
797+
}
798+
799+
return comparisonStatus == -1;
761800
}
762801

763-
function wasRemoved(cluster, options) {
764-
const data = fetchAvailabilityData(this.global);
765-
const path = makeAvailabilityPath(cluster, options);
802+
/**
803+
* Utility for wasRemoved and findProvisionalRelease. Finds a release that
804+
* mentions the given path or some ancestor of it in the given section. Returns
805+
* the release and the path that ended up being found, or undefined if nothing
806+
* was found.
807+
*/
808+
function findReleaseForPathOrAncestorAndSection(global, cluster, options, section) {
809+
const data = fetchAvailabilityData(global);
810+
let path = makeAvailabilityPath(cluster, options);
766811

767-
let removedRelease = undefined;
768-
let removalPath = [...path];
769-
while (removedRelease === undefined && removalPath !== undefined) {
770-
removedRelease = findReleaseForPath(
812+
while (path !== undefined) {
813+
let foundRelease = findReleaseForPath(
771814
data,
772-
['removed', ...removalPath],
815+
[section, ...path],
773816
options
774817
);
775-
removalPath = findPathToContainer(removalPath);
818+
if (foundRelease !== undefined) {
819+
return { release: foundRelease, path: path };
820+
}
821+
path = findPathToContainer(path);
822+
}
823+
return undefined;
824+
}
825+
826+
function wasRemoved(cluster, options) {
827+
return findReleaseForPathOrAncestorAndSection(this.global, cluster, options, 'removed') !== undefined;
828+
}
829+
830+
function pathsEqual(path1, path2) {
831+
if (path1.length != path2.length) {
832+
return false;
833+
}
834+
835+
for (let i = 0; i < path1.length; ++i) {
836+
if (path1[i] != path2[i]) {
837+
return false;
838+
}
839+
}
840+
841+
return true;
842+
}
843+
844+
function isSupported(cluster, options) {
845+
if (wasRemoved.call(this, cluster, options)) {
846+
return false;
847+
}
848+
849+
let provisionalRelease = findReleaseForPathOrAncestorAndSection(this.global, cluster, options, 'provisional');
850+
if (provisionalRelease === undefined) {
851+
// Default to enabled, even if not explicitly introduced.
852+
return true;
853+
}
854+
855+
let path = makeAvailabilityPath(cluster, options);
856+
while (path !== undefined) {
857+
let comparisonStatus = compareIntroductionToReferenceRelease(
858+
this.global,
859+
path,
860+
options,
861+
provisionalRelease.release
862+
);
863+
864+
// If we have an explicit introduction for something that is at the scope of
865+
// the provisional thing or narrower, and that introduction comes no earlier
866+
// than the provisional marking (we allow the same release for cases we
867+
// unfortunately have where we introduced some parts of a provisional
868+
// thing), then this is supported.
869+
if (comparisonStatus === 1 || comparisonStatus === 0) {
870+
return true;
871+
}
872+
873+
// If we have walked all the way up to the path to the provisional thing
874+
// without finding an overriding introduction, we are done.
875+
if (pathsEqual(path, provisionalRelease.path)) {
876+
break;
877+
}
878+
879+
path = findPathToContainer(path);
776880
}
777-
return removedRelease !== undefined;
881+
882+
return false;
778883
}
779884

780885
function hasRenamedFields(cluster, options) {
@@ -921,6 +1026,7 @@ exports.compatCommandNameRemapping = compatCommandNameRemapping;
9211026
exports.availability = availability;
9221027
exports.wasIntroducedBeforeRelease = wasIntroducedBeforeRelease;
9231028
exports.wasRemoved = wasRemoved;
1029+
exports.isSupported = isSupported;
9241030
exports.and = and;
9251031
exports.or = or;
9261032
exports.not = not;

0 commit comments

Comments
 (0)