Skip to content

Commit

Permalink
[FIX] generateResourcesJson: Make resources.json generation determini…
Browse files Browse the repository at this point in the history
…stic

Stop analyzing debug-resources if they correspond to a non-debug
resource.

However, try to analyze the "source" version of a resource's content if
possible. In some cases the dependency analysis has problems with
minified code.

Finally, copy any dependency information of a non-debug resource to
the corresponding debug-resource.

This ensures that we generate the same resources.json, independently
from the order of debug and non-debug resources supplied to the
resourceListCreator processor.

Resolves SAP/ui5-tooling#274
  • Loading branch information
RandomByte committed Nov 24, 2020
1 parent 773c534 commit 44665bb
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 44 deletions.
52 changes: 40 additions & 12 deletions lib/lbt/resources/ResourceCollector.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,14 @@ class ResourceCollector {
}
}

async enrichWithDependencyInfo(resourceInfo) {
return this._pool.getModuleInfo(resourceInfo.name).then((moduleInfo) => {
async enrichWithDependencyInfo({resourceInfo, debugBundleFilter}) {
return this._pool.getModuleInfo(resourceInfo.name, {
// While analyzing non-debug resources, try to analyze the content of the corresponding
// debug resource instead
preferDebugResources: true,
// Provide the debugBundleFilter to prevent that debug bundles are "preferred"
debugBundleFilter
}).then((moduleInfo) => {
if ( moduleInfo.name ) {
resourceInfo.module = moduleInfo.name;
}
Expand Down Expand Up @@ -149,16 +155,25 @@ class ResourceCollector {
});
}

async determineResourceDetails({pool, debugResources, mergedResources, designtimeResources, supportResources}) {
async determineResourceDetails({
debugResources, mergedResources, designtimeResources, supportResources, debugBundles
}) {
const baseNames = new Set();
const debugFilter = new ResourceFilterList(debugResources);
const mergeFilter = new ResourceFilterList(mergedResources);
const designtimeFilter = new ResourceFilterList(designtimeResources);
const supportFilter = new ResourceFilterList(supportResources);
const debugBundleFilter = new ResourceFilterList(debugBundles);

const promises = [];
const nonBundledDebugResources = [];

for (const [name, info] of this._resources.entries()) {
if ( debugFilter.matches(name) ) {
info.isDebug = true;
log.verbose(` found potential debug resource '${name}'`);
}

// log.verbose(` checking ${name}`);
let m;
if ( m = LOCALE.exec(name) ) {
Expand All @@ -179,9 +194,17 @@ class ResourceCollector {
}

if ( /(?:\.js|\.view\.xml|\.control\.xml|\.fragment\.xml)$/.test(name) ) {
promises.push(
this.enrichWithDependencyInfo(info)
);
if ( (!info.isDebug || debugBundleFilter.matches(name)) ) {
// Only analyze non-debug files which are not special debug bundles (like sap-ui-core-dbg.js)
promises.push(
this.enrichWithDependencyInfo({
resourceInfo: info,
debugBundleFilter
})
);
} else {
nonBundledDebugResources.push(info);
}
}

// set the module name for .properties and .json
Expand All @@ -196,11 +219,6 @@ class ResourceCollector {
}));
}

if ( debugFilter.matches(name) ) {
info.isDebug = true;
log.verbose(` found potential debug resource '${name}'`);
}

if ( mergeFilter.matches(name) ) {
info.merged = true;
log.verbose(` found potential merged resource '${name}'`);
Expand All @@ -225,7 +243,17 @@ class ResourceCollector {
}
}

return Promise.all(promises);
await Promise.all(promises);

for (let i = nonBundledDebugResources.length - 1; i >= 0; i--) {
const dbgInfo = nonBundledDebugResources[i];
const nonDebugName = ResourceInfoList.getNonDebugName(dbgInfo.name);
const nonDbgInfo = this._resources.get(nonDebugName);
const newDbgInfo = new ResourceInfo(dbgInfo.name);
newDbgInfo.copyFrom(null, nonDbgInfo);
newDbgInfo.copyFrom(null, dbgInfo);
this._resources.set(dbgInfo.name, newDbgInfo);
}
}

createOrphanFilters() {
Expand Down
26 changes: 1 addition & 25 deletions lib/lbt/resources/ResourceInfoList.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,11 @@ class ResourceInfoList {
* @param {ResourceInfo} info
* @param {boolean} shareDebugInformation
*/
add(info, shareDebugInformation=true) {
add(info) {
const relativeName = ResourceInfoList.makePathRelativeTo(this.name, info.name);

// search for a resource with the same name
let myInfo = this.resourcesByName.get(relativeName);

if ( myInfo == null && shareDebugInformation) {
// when not found, check if the given resource is a debug resource and
// share the information with the non-dbg version
const nonDbgName = ResourceInfoList.getNonDebugName(relativeName);
const dbgName = ResourceInfoList.getDebugName(relativeName);
if ( nonDbgName != null && this.resourcesByName.has(nonDbgName) ) {
// copy from source
myInfo = new ResourceInfo(relativeName);
const source = this.resourcesByName.get(nonDbgName);
myInfo.copyFrom(this.name, source);
this.resources.push(myInfo);
this.resourcesByName.set(relativeName, myInfo);
} else if (dbgName != null && this.resourcesByName.has(dbgName)) {
// copy from debug
myInfo = new ResourceInfo(relativeName);
const source = this.resourcesByName.get(dbgName);
myInfo.copyFrom(this.name, source);
myInfo.module = ResourceInfoList.getNonDebugName(source.module);
this.resources.push(myInfo);
this.resourcesByName.set(relativeName, myInfo);
}
}

// this is the assumption, that the debug one is the same as the non-dbg one
if ( myInfo == null ) {
myInfo = new ResourceInfo(relativeName);
Expand Down
30 changes: 25 additions & 5 deletions lib/lbt/resources/ResourcePool.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const XMLTemplateAnalyzer = require("../analyzer/XMLTemplateAnalyzer");
const LibraryFileAnalyzer = require("./LibraryFileAnalyzer");
const ModuleInfo = require("./ModuleInfo");
const ResourceFilterList = require("./ResourceFilterList");
const ResourceInfoList = require("./ResourceInfoList");
/*
const Resource = require("./Resource");
*/
Expand Down Expand Up @@ -57,12 +58,15 @@ function scanFileOrDir(fileOrDir, name, pool) {
}
*/

async function determineDependencyInfo(resource, rawInfo, pool) {
async function determineDependencyInfo(resource, dbgResource, rawInfo, pool) {
const info = new ModuleInfo(resource.name);
info.size = resource.fileSize;
if ( /\.js$/.test(resource.name) ) {
// console.log("analyzing %s", resource.file);
const code = await resource.buffer();
// console.log("analyzing %s", resource.name);

// Retrieve the content from the "debug resource".
// Note that in many cases "resource" and "dbgResource" are the same object
const code = await dbgResource.buffer();
info.size = code.length;
const promises = [];
let ast;
Expand Down Expand Up @@ -177,14 +181,30 @@ class ResourcePool {
* Retrieves the module info
*
* @param {string} name module name
* @param {object} options
* @param {boolean} options.preferDebugResources
* @param {ResourceFilterList} options.debugBundleFilter
* @returns {Promise<ModuleInfo>}
*/
async getModuleInfo(name) {
async getModuleInfo(name, options) {
let info = this._dependencyInfos.get(name);
if ( info == null ) {
// console.log("analyzing ", name);
let dbgResource;
if (options && options.preferDebugResources) {
// If requested, try to retrieve the corresponding debug-resource (xyz-dbg.js) and pass it to
// determineDependencyInfo as well. Its dependency analysis will perform better with the
// not-minified content of a resource.
const dbgName = ResourceInfoList.getDebugName(name);
if (dbgName && (!options.debugBundleFilter || !options.debugBundleFilter.matches(dbgName))) {
dbgResource = this._resourcesByName.get(dbgName);
}
}
const resource = await this.findResource(name);
info = await determineDependencyInfo( resource, this._rawModuleInfos.get(name), this );
if (!dbgResource) {
dbgResource = resource;
}
info = await determineDependencyInfo(resource, dbgResource, this._rawModuleInfos.get(name), this);
// console.log("finished analyzing ", name);
this._dependencyInfos.set(name, info);
}
Expand Down
6 changes: 4 additions & 2 deletions lib/processors/resourceListCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ const DEFAULT_SUPPORT_RESOURCES_FILTER = [
* @type {string[]}
*/
const DEBUG_BUNDLES = [
"sap-ui-core-dbg.js"
"sap-ui-core-dbg.js",
"sap-ui-core-nojQuery-dbg.js"
];

/**
Expand Down Expand Up @@ -159,7 +160,8 @@ module.exports = async function({resources, options}) {
debugResources: options.debugResources,
mergedResources: options.mergedResources,
designtimeResources: options.designtimeResources,
supportResources: options.supportResources
supportResources: options.supportResources,
debugBundles: options.debugBundles
});

// group resources by components and create ResourceInfoLists
Expand Down

0 comments on commit 44665bb

Please sign in to comment.