Last active
February 5, 2024 06:43
-
-
Save BinToss/41441008e71142ed2bae79b8c0d8ee53 to your computer and use it in GitHub Desktop.
redhat.vscode-xml - assignAttributeGroupIDs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://github.com/redhat-developer/vscode-xml/issues/965 | |
import micromatch from 'micromatch'; | |
// example of a PatternGroup[] parsed from the VSCode workspace's configuration (./.vscode/settings.json) | |
const workspaceConfigurationPatternGroups: PatternGroup[] = [ | |
[ | |
// same matches as "(mc|d):*", but implemented as two calls to micromatch.match and a call to array.push() to combine the matches | |
"mc:*", | |
"d:*" | |
], | |
["xmlns:*"] | |
]; | |
class XmlElement { | |
attributes: IXmlAttributeFormatting[] = []; | |
value: object | null | undefined; | |
/** | |
* @param {PatternGroup[]} patternGroups - two-dimensional array of micromatch pattern. Each sub-array is an array of patterns whose matches should be grouped together. | |
*/ | |
assignAttributeGroupIDs(patternGroups: PatternGroup[]): void { | |
if (this.attributes.length === 0) { | |
return; | |
} | |
// iterate through attributes, assigning IDs for the group they should belong to. This ID will only be used for formatting and will not be written to the XML document. | |
for (let attrI = 0; attrI < this.attributes.length; attrI++) { | |
this.attributes[attrI]._tentativeUniqueIDs = []; // init temporary property | |
// iterate pattern groups | |
for (let groupID: GroupID = 0; groupID < patternGroups.length; groupID++) { | |
const patternGroup = patternGroups[groupID]; | |
//iterate patterns | |
for (let patternID: PatternID = 0; patternID < patternGroup.length; patternID++) { | |
// if the attribute matches the pattern, add the Group-Pattern ID | |
if (micromatch.isMatch(this.attributes[attrI].key, patternGroup[patternID])) { | |
this.attributes[attrI]._tentativeUniqueIDs.push({ groupID, patternID } as UniqueID); | |
} | |
} | |
} | |
} | |
// reiterate: assign final groupID. Iterate the groupID if the current attribute and prior attribute have no tentative IDs in common. | |
for (let attrI = 0; attrI < this.attributes.length; attrI++) { | |
//this.attributes[attrI]; | |
if (attrI === 0) { | |
// first group will always be 0 | |
this.attributes[attrI]._groupID = 0; | |
} | |
else { | |
/** | |
* Check if the prior {@link IXmlAttributeFormatting} and this | |
* {@link IXmlAttributeFormatting} have any of the same | |
* {@link IXmlAttributeFormatting._tentativeUniqueIDs} | |
* If they have at least one {@link UniqueID} in common, assign | |
* the prior's {@link IXmlAttributeFormatting._groupID} as this | |
* attribute's {@link IXmlAttributeFormatting._groupID}. | |
*/ | |
const sharesAtLeastOneUniqueIDWithPriorAttribute = | |
this.attributes[attrI]._tentativeUniqueIDs.some((uniqueID) => | |
this.attributes[attrI]._tentativeUniqueIDs.includes(uniqueID)); | |
if (sharesAtLeastOneUniqueIDWithPriorAttribute) { | |
this.attributes[attrI]._groupID = this.attributes[attrI - 1]._groupID; | |
} | |
} | |
} | |
/** Remove {@link IXmlAttributeFormatting._tentativeUniqueIDs}. We don't need them anymore. */ | |
this.attributes.forEach(attr => attr._tentativeUniqueIDs = []); | |
} | |
} | |
//#region typedefs | |
type Pattern = string; | |
type PatternID = number; | |
type GroupID = number; | |
interface UniqueID { groupID: GroupID, patternID: PatternID }; | |
/** | |
* @remark When this is added to an array, its index in that array becomes this group's ID for use in UniquePatternID. | |
*/ | |
interface PatternGroup extends Array<Pattern> { | |
label?: string; | |
readonly [patternID: PatternID]: Pattern; | |
} | |
interface IXmlAttribute { | |
// remember to delete other properties before writing the document! | |
key: string, | |
value: string | |
} | |
/** | |
* {@link IXmlAttribute} extended with formatting metadata. | |
* | |
* @interface IXmlAttributeFormatting | |
* @type {IXmlAttributeFormatting} | |
* @extends {IXmlAttribute} | |
*/ | |
interface IXmlAttributeFormatting extends IXmlAttribute { | |
/** | |
* Each {@link UniqueID} in this array represents an individual {@link Pattern} matched against this attribute. | |
* @type {UniqueID[]} | |
*/ | |
_tentativeUniqueIDs: UniqueID[], | |
/** | |
* The finalized ID of the attribute formatting group. | |
* @type {number} | |
* @see {@link XmlElement.assignAttributeGroupIDs} | |
*/ | |
_groupID: number | |
} | |
//#endregion typedefs |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment