Skip to content

Commit

Permalink
Refactor: Cover cases from MVN plugin + cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
d3xter666 committed Aug 12, 2022
1 parent 9527336 commit 986f985
Showing 1 changed file with 62 additions and 64 deletions.
126 changes: 62 additions & 64 deletions lib/processors/jsdoc/lib/ui5/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -524,42 +524,6 @@ function isPotentialEnum(node) {
}

// ---- ES6+ Destructuring ---------------------------------------------------------
/**
* Checks against currentModule.localNames to verify an enum imported from an external module
*
* @param {Array} varsDestructuringStack
* @returns {Object}
*/
function checkEnumsFromExternalModules(varsDestructuringStack) {
const localName = varsDestructuringStack[0];
const potentialEnumKey =
varsDestructuringStack[varsDestructuringStack.length - 1];

const curModuleNames = currentModule.localNames[localName] || {};
const localModule = curModuleNames.module || curModuleNames.class;

// Find if there are enums defined for that module
return Object.keys(enumValues)
.filter((curEnumKey) => {
const [enums, resource] = curEnumKey.split("||");

// Check the resource
if (resource.indexOf(localModule) === -1) {
return false;
}

// Check if the key is in the enums
return enums.split("|").includes(potentialEnumKey);
})
.map((curEnumKey) => {
return {
raw: potentialEnumKey,
value: potentialEnumKey,
// value: enumValues[curEnumKey][potentialEnumKey], // If needed, the Runtime value could be accessed like this
};
})[0];
}

/**
* Tries to resolve an ENUM, regardless where it is defined and being destructured.
*
Expand All @@ -568,19 +532,16 @@ function checkEnumsFromExternalModules(varsDestructuringStack) {
* @returns {Object}
*/
function resolvePotemtialEnum(node, type) {
const varsDestructuringStack = resolveFullyQunatifiedName(node);
const varsDestructuringStack = resolveFullyQunatifiedName(node, type);

if (
!varsDestructuringStack ||
!varsDestructuringStack.originalChain ||
!varsDestructuringStack.originalChain.length
) {
if (!varsDestructuringStack || !varsDestructuringStack.length) {
return null;
}

// When the fully qunatified name gets resolved, we could try the "old" approach by checking
// the type + key
let value = varsDestructuringStack.originalChain.join(".");
let value = varsDestructuringStack.join(".");

if ( value.indexOf(type + ".") === 0 ) {
// starts with fully qualified enum name -> cut off name
value = value.slice(type.length + 1);
Expand All @@ -589,23 +550,20 @@ function resolvePotemtialEnum(node, type) {
raw: value
};
}

// Otherwise look into the imported modules to check for potential enum definitions there
return checkEnumsFromExternalModules(varsDestructuringStack.originalChain);
}

/**
* Builds the fully qunatified name when there's a destrcturing of a variable
*
* @param {Node} node
* @param {String} type
* @returns {Object}
*/
function resolveFullyQunatifiedName(node) {
function resolveFullyQunatifiedName(node, type) {
// The missing part is on the left side. The right side is clear.
// We would eiter ways would resolve to the same leftmost token.
let leftMostName = getLeftmostName(node);
let name = getObjectName(node) || "";
let originalName = name;
let originalName = getObjectName(node) || "";
const currentScope = getEnclosingVariableScope(node);

if (!currentScope) {
Expand All @@ -618,7 +576,7 @@ function resolveFullyQunatifiedName(node) {
// variable.defs[0].node.id.properties[0].key.name === variable.name; // Original
// variable.defs[0].node.id.properties[0].value.name === variable.name; // Renamed

return variable.defs
let potentialRename = variable.defs
.filter(
(def) =>
def.node &&
Expand All @@ -641,6 +599,22 @@ function resolveFullyQunatifiedName(node) {
.map((prop) => {
return { original: prop.key.name, renamed: prop.value.name };
})[0];

if (potentialRename) {
return potentialRename;
}

// var AriaHasPopup = sap.ui.core.aria.HasPopup; -> AriaHasPopup.None
potentialRename =
variable.defs.filter(
(def) =>
def.node && def.node.id && def.node.id.type === Syntax.Identifier
)
.map((def) => {
return { original: getResolvedObjectName(def.name), replaced: def.name.name };
})[0];

return potentialRename;
};

// TODO: Check for hierarchical destructuring
Expand All @@ -652,38 +626,62 @@ function resolveFullyQunatifiedName(node) {
const potentialRenaming = checkVarRenaming(curVar);
const filteredValues = curVar.references
.filter((ref) => ref.writeExpr)
.map((ref) => getObjectName(ref.writeExpr));
.map((ref) => {
const curNode = ref.writeExpr;
if ( curNode.type === Syntax.MemberExpression && !curNode.computed && curNode.object.type === Syntax.Identifier ) {
return curNode.object.name;
} else if (curNode.type === Syntax.MemberExpression && curNode.object.type === Syntax.MemberExpression) { // Standalone variable without leading dot notation namespace
return getResolvedObjectName(curNode);
}

return (curNode && curNode.name) || "";
});

acc.push({
ref: filteredValues[0],
original: potentialRenaming
? potentialRenaming.original
: curVar.name,
renamed: potentialRenaming
? potentialRenaming.renamed
: null,
renamed: potentialRenaming ? potentialRenaming.renamed : null,
replaced: potentialRenaming ? potentialRenaming.replaced : null,
});
return acc;
}, [])[0];

leftMostName = potentialChunk && potentialChunk.ref;
name = leftMostName ? leftMostName + "." + name : name;
originalName = leftMostName
? leftMostName + "." + originalName
: originalName;

if (potentialChunk && potentialChunk.replaced) {
originalName = originalName.replace(potentialChunk.replaced, potentialChunk.original);
} else {
originalName = leftMostName
? leftMostName + "." + originalName
: originalName;
}

if (potentialChunk && potentialChunk.renamed) {
originalName = originalName.replace(
"." + potentialChunk.renamed + ".",
"." + potentialChunk.original + "."
potentialChunk.renamed + ".",
potentialChunk.original + "."
);
}
}

return {
renamedChain: name.split("."),
originalChain: originalName.split("."),
};
// When an enum is defined in an external module, we cannot rely that this module is loaded and we could
// read from enumValues variable. Therefore we need to resolve the enum name from the type.
// The imported dependency name would be replaced by the type i.e. IF type: "sap.ui.core" THEN coreLibrary -> sap.ui.core
// The leftMostChunk is the (eventual) dependency name i.e. coreLibrary
let originalNameChunks = originalName.split(".");
let typeChunks = type.split(".")
const firstMatchedChunkIndex = originalNameChunks.findIndex((chunk) => typeChunks.indexOf(chunk) !== -1);

if (firstMatchedChunkIndex !== -1) {
originalNameChunks = originalNameChunks.slice(firstMatchedChunkIndex);
const typeIndex = typeChunks.indexOf(originalNameChunks[0]);
typeChunks = typeChunks.slice(0, typeIndex);
originalNameChunks = typeChunks.concat(originalNameChunks);
}

return originalNameChunks;
}

/**
Expand Down

0 comments on commit 986f985

Please sign in to comment.