Skip to content

Commit

Permalink
feat: Enable toggle for collection of borrowed options
Browse files Browse the repository at this point in the history
+ Fix: Collect options of base class too (sap.ui.base.Object)
  • Loading branch information
maxreichmann committed Jan 3, 2025
1 parent a35ae26 commit 9f7cca4
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 37 deletions.
83 changes: 54 additions & 29 deletions scripts/metadataProvider/MetadataProvider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
import {createSemanticModel} from "./model.js";

import {
Expand All @@ -12,8 +13,10 @@ import {
UI5SemanticModel,
} from "@ui5-language-assistant/semantic-model-types";

type SymbolOption = "aggregation" | "association" | "defaultAggregation" | "event" | "property";
type SymbolOptionValues = Record<string, SymbolOption>;
type SymbolOption = "aggregation" | "association" | "defaultAggregation" | "event" | "method" | "property";
type SymbolOptionValue = string; // e.g. "press" | "text" | "items" | "firePress"
type SymbolName = string; // e.g. "sap.m.Button" | "jQuery.sap" | "module:sap/base/Event" | "sap.ui.base.Object"
type SymbolOptionValues = Record<SymbolOptionValue | "extends", SymbolOption | SymbolName>;

export default class MetadataProvider {
#model: UI5SemanticModel | null = null;
Expand Down Expand Up @@ -53,62 +56,84 @@ export default class MetadataProvider {
}

/**
* Collects all option values (aggregation, association, defaultAggregation, event, method, property)
* for a given symbol (incl. borrowed ones).
* Collects all option values for a given symbol.
* Possible option values: "aggregation" | "association" | "defaultAggregation" | "event" | "method" | "property".
* By providing includeBorrowed = true, borrowed option values from parent classes are included.
* If not (default), an "extends" entry with the symbolname is added to the result.
* @param {BaseUI5Node} symbol
* @param {boolean} includeBorrowed
* @returns {SymbolOptionValues}
*/
collectOptionValuesForSymbol(symbol: BaseUI5Node): SymbolOptionValues | undefined {
collectOptionValuesForSymbol(symbol: BaseUI5Node, includeBorrowed = false): SymbolOptionValues | undefined {
const symbolOptionValues: SymbolOptionValues = {};
let symbolMetadata;

// TODO: If includeBorrowed = true, '"Type": "property"' is collected for every Symbol??
switch (symbol.kind) {
case "UI5Class":
symbolMetadata = symbol as UI5Class;
// Collect own and borrowed option values:
while (symbolMetadata.extends) {
symbolMetadata.aggregations.forEach((aggregation) => {
symbolOptionValues[aggregation.name] = "aggregation";
});
symbolMetadata.associations.forEach((association) => {
symbolOptionValues[association.name] = "association";
});
if (symbolMetadata.defaultAggregation) {
symbolOptionValues[symbolMetadata.defaultAggregation.name] = "defaultAggregation";
do {
if (symbolMetadata) {
for (const aggregation of symbolMetadata.aggregations) {
// Check if defaultAggregation is already collected to prevent overwriting
if (!symbolOptionValues[aggregation.name]) {
symbolOptionValues[aggregation.name] = "aggregation";
}
};
symbolMetadata.associations.forEach((association) => {
symbolOptionValues[association.name] = "association";
});
if (symbolMetadata.defaultAggregation) {
symbolOptionValues[symbolMetadata.defaultAggregation.name] = "defaultAggregation";
}
symbolMetadata.events.forEach((event) => {
symbolOptionValues[event.name] = "event";
});
symbolMetadata.properties.forEach((property) => {
symbolOptionValues[property.name] = "property";
});
/* Disabled, as not being required:
symbolMetadata.methods.forEach((method) => {
symbolOptionValues[method.name] = "method";
}); */
if (includeBorrowed) symbolMetadata = symbolMetadata.extends;
else if (symbolMetadata.extends) symbolOptionValues.extends =
`${symbolMetadata.extends.library}.${symbolMetadata.extends.name}`;
}
symbolMetadata.events.forEach((event) => {
symbolOptionValues[event.name] = "event";
});
symbolMetadata.properties.forEach((property) => {
symbolOptionValues[property.name] = "property";
});
symbolMetadata = symbolMetadata.extends;
}
} while (includeBorrowed && symbolMetadata?.extends);
break;
/* case "UI5Enum": // Disabled because UI5Enum does not contain any option values
/* case "UI5Enum": // Disabled, as UI5Enum does not contain any option values (with 1.131.1)
symbolMetadata = symbol as UI5Enum;
break;
case "UI5Function": // Disabled because UI5Function does not contain any option values
case "UI5Function": // Disabled, as UI5Function does not contain any option values (with 1.131.1)
symbolMetadata = symbol as UI5Function;
break; */
case "UI5Namespace":
symbolMetadata = symbol as UI5Namespace;
symbolMetadata.events.forEach((event) => {
symbolOptionValues[event.name] = "event";
});
/* Disabled, as not being required:
symbolMetadata.methods.forEach((method) => {
symbolOptionValues[method.name] = "method";
}); */
break;
case "UI5Typedef":
symbolMetadata = symbol as UI5Typedef;
// NPM package "@ui5-language-assistant/semantic-model-types" was not updated:
// symbolMetadata.properties.forEach((property) => {
// symbolOptionValues[property.name] = "property";
// });
/* NPM package "@ui5-language-assistant/semantic-model-types" was not updated:
symbolMetadata.properties.forEach((property) => {
symbolOptionValues[property.name] = "property";
}); */
break;
case "UI5Interface":
symbolMetadata = symbol as UI5Interface;
symbolMetadata.events.forEach((event) => {
symbolOptionValues[event.name] = "event";
});
/* Disabled, as not being required:
symbolMetadata.methods.forEach((method) => {
symbolOptionValues[method.name] = "method";
}); */
break;
default:
return undefined;
Expand Down
8 changes: 2 additions & 6 deletions scripts/metadataProvider/createMetadataInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,11 @@ export default async function createMetadataInfo(apiJsonsRoot: string, sapui5Ver
};

forEachSymbol(semanticModel, (symbol, symbolName) => {
apiExtract.metadata[symbolName] = {};

// Generate metadata:
if (isAllowedSymbolKind(symbol.kind)) {
const symbolOptionValues = metadataProvider.collectOptionValuesForSymbol(symbol);
const symbolOptionValues = metadataProvider.collectOptionValuesForSymbol(symbol, false);// Toggle true/false
if (symbolOptionValues) {
Object.entries(symbolOptionValues).forEach(([optionName, optionValue]) => {
apiExtract.metadata[symbolName][optionName] = optionValue;
});
apiExtract.metadata[symbolName] = symbolOptionValues;
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/utils/ApiExtract.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */
import {readFile} from "node:fs/promises";

export type AllowedSymbolKind = "UI5Class" | "UI5Enum" | "UI5Interface" | "UI5Namespace" | "UI5Typedef" | "UI5Function";
export type AllowedSymbolOption = "aggregation" | "association" | "defaultAggregation" | "event" | "property";
export type AllowedMetadataOptions = "aggregation" | "association" | "defaultAggregation" | "event" |
"method" | "property" | string;

export interface ApiExtractJson {
framework: {
name: string;
version: string;
};
metadata: Record<string, Record<string, AllowedSymbolOption>>;
metadata: Record<string, Record<string, AllowedMetadataOptions>>;
deprecations: Record<AllowedSymbolKind, Record<string, string>>;
}

Expand Down

0 comments on commit 9f7cca4

Please sign in to comment.