mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-09-11 14:46:37 +03:00
Fix require/define detection (#2168)
Summary: Release Notes: None It is okay for a define call to happen within a require call so long as the define call has happened by the time the require call has returned (since all define calls should have the same effect and only happen once). Previously if we encountered a module required before it was defined (or defined in a nested partial evaluation scope), we would not record it in ModuleTracer logic. Closes https://github.com/facebook/prepack/pull/2168 Differential Revision: D8688788 Pulled By: cblappert fbshipit-source-id: 6696ea54ed9ae7a3d7e8a944c45e14feccf3139b
This commit is contained in:
parent
9905f613d6
commit
bb49439adf
@ -107,14 +107,11 @@ export class ModuleTracer extends Tracer {
|
||||
// If we don't delay unsupported requires, we simply want to record here
|
||||
// when a module gets initialized, and then we return.
|
||||
_callRequireAndRecord(moduleIdValue: number | string, performCall: () => Value) {
|
||||
if (
|
||||
(this.requireStack.length === 0 || this.requireStack[this.requireStack.length - 1] !== moduleIdValue) &&
|
||||
this.modules.moduleIds.has(moduleIdValue)
|
||||
) {
|
||||
if (this.requireStack.length === 0 || this.requireStack[this.requireStack.length - 1] !== moduleIdValue) {
|
||||
this.requireStack.push(moduleIdValue);
|
||||
try {
|
||||
let value = performCall();
|
||||
this.modules.recordModuleInitialized(moduleIdValue, value);
|
||||
if (this.modules.moduleIds.has(moduleIdValue)) this.modules.recordModuleInitialized(moduleIdValue, value);
|
||||
return value;
|
||||
} finally {
|
||||
invariant(this.requireStack.pop() === moduleIdValue);
|
||||
@ -337,26 +334,45 @@ export class ModuleTracer extends Tracer {
|
||||
// Here, we handle calls of the form
|
||||
// __d(factoryFunction, moduleId, dependencyArray)
|
||||
|
||||
if (this.evaluateForEffectsNesting !== 0)
|
||||
this.modules.logger.logWarning(F, "Defining a module in nested partial evaluation is not supported.");
|
||||
else {
|
||||
let factoryFunction = argumentsList[0];
|
||||
if (factoryFunction instanceof FunctionValue) {
|
||||
let dependencies = this._tryExtractDependencies(argumentsList[2]);
|
||||
if (dependencies !== undefined) this.modules.factoryFunctionDependencies.set(factoryFunction, dependencies);
|
||||
else
|
||||
this.modules.logger.logError(
|
||||
argumentsList[2],
|
||||
"Third argument to define function is present but not a concrete array."
|
||||
);
|
||||
let factoryFunction = argumentsList[0];
|
||||
if (factoryFunction instanceof FunctionValue) {
|
||||
let dependencies = this._tryExtractDependencies(argumentsList[2]);
|
||||
if (dependencies !== undefined) {
|
||||
let previousDependencies = this.modules.factoryFunctionDependencies.get(factoryFunction);
|
||||
if (previousDependencies) {
|
||||
// Verify that they are the same
|
||||
let logError = () => {
|
||||
let moduleId = argumentsList[1];
|
||||
let moduleString =
|
||||
moduleId instanceof StringValue || moduleId instanceof NumberValue ? moduleId.value : "unknown";
|
||||
this.modules.logger.logError(
|
||||
factoryFunction,
|
||||
`Called define on the same module ${moduleString} twice with different dependencies each time.`
|
||||
);
|
||||
};
|
||||
if (previousDependencies.length !== dependencies.length) {
|
||||
logError();
|
||||
} else {
|
||||
let previousDependenciesSet = new Set(previousDependencies);
|
||||
dependencies.forEach(dependency => {
|
||||
if (!previousDependenciesSet.has(dependency)) logError();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.modules.factoryFunctionDependencies.set(factoryFunction, dependencies);
|
||||
}
|
||||
} else
|
||||
this.modules.logger.logError(factoryFunction, "First argument to define function is not a function value.");
|
||||
let moduleId = argumentsList[1];
|
||||
if (moduleId instanceof NumberValue || moduleId instanceof StringValue)
|
||||
this.modules.moduleIds.add(moduleId.value);
|
||||
else
|
||||
this.modules.logger.logError(moduleId, "Second argument to define function is not a number or string value.");
|
||||
}
|
||||
this.modules.logger.logError(
|
||||
argumentsList[2],
|
||||
"Third argument to define function is present but not a concrete array."
|
||||
);
|
||||
} else
|
||||
this.modules.logger.logError(factoryFunction, "First argument to define function is not a function value.");
|
||||
let moduleId = argumentsList[1];
|
||||
if (moduleId instanceof NumberValue || moduleId instanceof StringValue)
|
||||
this.modules.moduleIds.add(moduleId.value);
|
||||
else
|
||||
this.modules.logger.logError(moduleId, "Second argument to define function is not a number or string value.");
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user