From 91847ea6ba1d48859ee22fa62e59564bc8836da7 Mon Sep 17 00:00:00 2001 From: Chris Blappert Date: Tue, 10 Jul 2018 12:03:04 -0700 Subject: [PATCH] =?UTF-8?q?Make=20optimized=20functions=20produce=20compil?= =?UTF-8?q?er=20diagnostic=20on=20mutating=20non-=E2=80=A6=20(#2175)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: …local state The logic was already there for the React Compiler's invocations of evaluatePure, this PR just generalizes it a little to be used for optmized functions as well. Additionally, adds the ability to check for compiler info/warning logs in test-runner + updates test-error-handler. See #1589 Pull Request resolved: https://github.com/facebook/prepack/pull/2175 Differential Revision: D8786744 Pulled By: cblappert fbshipit-source-id: 110a4732dd6bd129b4d91047c3c9a24f5249a5e9 --- scripts/test-runner.js | 95 +++++++++++++++++- src/errors.js | 2 +- src/prepack-standalone.js | 6 +- src/react/reconcilation.js | 44 +++----- src/realm.js | 2 +- src/serializer/functions.js | 13 ++- src/serializer/utils.js | 35 ++++++- .../.write-write-conflict.js.swp | Bin 0 -> 12288 bytes .../ModifiedObjectPropertyLimitation.js | 2 +- test/error-handler/bad-functions.js | 2 +- test/error-handler/write-forin-conflict.js | 2 +- test/error-handler/write-in-conflict.js | 2 +- test/error-handler/write-reflect-conflict.js | 2 +- test/error-handler/write-write-conflict.js | 2 +- test/error-handler/write-write-conflict2.js | 2 +- test/error-handler/write-write-conflict3.js | 2 +- test/error-handler/write-write-conflict4.js | 2 +- .../write-write-unknown-prop-conflict.js | 2 +- .../AdditionalFunCapturedScope.js | 1 + .../additional-functions/ArrayConcat.js | 1 - .../additional-functions/DeadOuterObject.js | 2 + .../EmitPropertyRegressionTest.js | 1 + .../additional-functions/Example1.js | 1 + .../additional-functions/GlobalLetBinding.js | 3 +- .../Issue1821RegressionTest.js | 1 + .../ModifiedBindingWithoutInitialValue.js | 1 + .../ModifiedBindingsCapturedScopesCalls.js | 1 + .../ModifiedObjectProperty.js | 1 + .../ModifiedObjectPropertyWithAbstractKey.js | 1 + .../ObjectCreationGeneratorRegressionTest.js | 3 +- .../additional-functions/ObjectLifetime2.js | 1 + .../OuterScopeCacheRegressionTest.js | 1 + .../additional-functions/ReadThenDelete.js | 1 + .../RegressionTestForIssue1881.js | 1 + ...utatedByOptimizedFunctionRegressionTest.js | 3 +- .../abstract-property-modification.js | 1 + .../additional-functions/conditions2.js | 1 + .../write-write-noconflict.js | 1 + .../optimized-functions/double-call.js | 19 ++++ .../optimized-functions/simple-nesting.js | 17 ++++ 40 files changed, 224 insertions(+), 56 deletions(-) create mode 100644 test/error-handler/.write-write-conflict.js.swp create mode 100644 test/serializer/optimized-functions/double-call.js create mode 100644 test/serializer/optimized-functions/simple-nesting.js diff --git a/scripts/test-runner.js b/scripts/test-runner.js index 543f39aea..719813a0d 100644 --- a/scripts/test-runner.js +++ b/scripts/test-runner.js @@ -13,6 +13,7 @@ import invariant from "../lib/invariant.js"; let FatalError = require("../lib/errors.js").FatalError; let prepackSources = require("../lib/prepack-node.js").prepackSources; import type { PrepackOptions } from "../lib/prepack-options"; +import type { ErrorHandler, Severity, CompilerDiagnostic } from "../lib/errors.js"; function serialRun(promises: Array<() => Promise>, i: number) { if (promises[i] instanceof Function) { @@ -308,6 +309,46 @@ function unescapleUniqueSuffix(code: string, uniqueSuffix?: string) { return uniqueSuffix != null ? code.replace(new RegExp(uniqueSuffix, "g"), "") : code; } +function getErrorHandlerWithWarningCapture( + diagnosticOutput: Map>, + verbose: boolean +): ErrorHandler { + return (diagnostic: CompilerDiagnostic, suppressDiagnostics: boolean) => { + let msg = ""; + if (!suppressDiagnostics) { + msg = `${diagnostic.errorCode}: ${diagnostic.message}`; + if (verbose && diagnostic.location) { + let loc_start = diagnostic.location.start; + let loc_end = diagnostic.location.end; + msg += ` at ${loc_start.line}:${loc_start.column} to ${loc_end.line}:${loc_end.column}`; + } + let errorCodeSet = diagnosticOutput.get(diagnostic.severity); + if (!errorCodeSet) diagnosticOutput.set(diagnostic.severity, (errorCodeSet = new Set())); + errorCodeSet.add(diagnostic.errorCode); + } + try { + switch (diagnostic.severity) { + case "Information": + if (verbose && !suppressDiagnostics) console.log(`Info: ${msg}`); + return "Recover"; + case "Warning": + if (verbose && !suppressDiagnostics) console.warn(`Warn: ${msg}`); + return "Recover"; + case "RecoverableError": + if (verbose && !suppressDiagnostics) console.error(`Error: ${msg}`); + return "Recover"; + case "FatalError": + if (verbose && !suppressDiagnostics) console.error(`Fatal Error: ${msg}`); + return "Fail"; + default: + invariant(false, "Unexpected error type"); + } + } finally { + if (verbose && !suppressDiagnostics) console.log(diagnostic.callStack); + } + }; +} + function runTest(name, code, options: PrepackOptions, args) { console.log(chalk.inverse(name) + " " + JSON.stringify(options)); let compatibility = code.includes("// jsc") ? "jsc-600-1-4-17" : undefined; @@ -457,12 +498,64 @@ function runTest(name, code, options: PrepackOptions, args) { new Array(singleIterationOnly ? 1 : max).fill(0).map(function() { let newUniqueSuffix = `_unique${unique++}`; if (!singleIterationOnly) options.uniqueSuffix = newUniqueSuffix; + + let expectedDiagnostics = new Map(); + // Expected diagnostics comment: "// expected [FatalError | RecoverableError | Warning | Information]: PP0001, PP0002, ..." + let diagnosticOutput = new Map(); + for (let severity of ["FatalError", "RecoverableError", "Warning", "Information"]) { + let diagnosticExpectedComment = `// expected ${severity}:`; + if (code.includes(diagnosticExpectedComment)) { + let idx = code.indexOf(diagnosticExpectedComment); + let errorCodeString = code.substring(idx + diagnosticExpectedComment.length, code.indexOf("\n", idx)); + let errorCodeSet = new Set(); + expectedDiagnostics.set(severity, errorCodeSet); + errorCodeString.split(",").forEach(errorCode => errorCodeSet.add(errorCode.trim())); + options.residual = false; + options.errorHandler = getErrorHandlerWithWarningCapture(diagnosticOutput, args.verbose); + } + } + let serialized = prepackSources([{ filePath: name, fileContents: code, sourceMapContents: "" }], options); if (serialized.statistics && serialized.statistics.delayedValues > 0) anyDelayedValues = true; if (!serialized) { console.error(chalk.red("Error during serialization!")); return () => Promise.reject(); } + + function setEquals(set1, set2) { + if (!set1 || !set2 || set1.size !== set2.size) return false; + for (let x of set1) if (!set2.has(x)) return false; + return true; + } + let diagnosticIssue = false; + if (diagnosticOutput.size > 0 || expectedDiagnostics.size > 0) { + if (diagnosticOutput.size !== expectedDiagnostics.size) { + diagnosticIssue = true; + let diagnosticOutputKeys = [...diagnosticOutput.keys()]; + let expectedOutputKeys = [...expectedDiagnostics.keys()]; + console.error( + chalk.red( + `Expected [${expectedOutputKeys.toString()}] but found [${diagnosticOutputKeys.toString()}]` + ) + ); + } + for (let [severity, diagnostics] of diagnosticOutput) { + let expectedErrorCodes = expectedDiagnostics.get(severity); + if (!setEquals(expectedErrorCodes, diagnostics)) { + diagnosticIssue = true; + console.error( + chalk.red( + `Output Diagnostics Severity:${severity} ${[ + ...diagnostics, + ].toString()} don't match expected diagnostics ${ + expectedErrorCodes ? [...expectedErrorCodes].toString() : "None" + }` + ) + ); + } + } + } + let newCode = serialized.code; if (compileJSXWithBabel) { newCode = transformWithBabel(newCode, ["transform-react-jsx"]); @@ -493,7 +586,7 @@ function runTest(name, code, options: PrepackOptions, args) { console.error(newCode); } } - if (markersIssue || matchesIssue) return () => Promise.reject({ type: "MARKER" }); + if (markersIssue || matchesIssue || diagnosticIssue) return () => Promise.reject({ type: "MARKER" }); let codeToRun = addedCode + newCode; if (!execSpec && options.lazyObjectsRuntime !== undefined) { codeToRun = augmentCodeWithLazyObjectSupport(codeToRun, args.lazyObjectsRuntime); diff --git a/src/errors.js b/src/errors.js index 5e543e1fd..8d77da004 100644 --- a/src/errors.js +++ b/src/errors.js @@ -60,4 +60,4 @@ export class InvariantError extends Error { } } -export type ErrorHandler = (error: CompilerDiagnostic) => ErrorHandlerResult; +export type ErrorHandler = (error: CompilerDiagnostic, suppressDiagnostics: boolean) => ErrorHandlerResult; diff --git a/src/prepack-standalone.js b/src/prepack-standalone.js index 5c0a6c795..149f0b6f9 100644 --- a/src/prepack-standalone.js +++ b/src/prepack-standalone.js @@ -106,10 +106,10 @@ function checkResidualFunctions(modules: Modules, startFunc: number, totalToAnal let env = realm.$GlobalEnv; realm.$GlobalObject.makeSimple(); let errorHandler = realm.errorHandler; - if (!errorHandler) errorHandler = diag => realm.handleError(diag); - realm.errorHandler = diag => { + if (!errorHandler) errorHandler = (diag, suppressDiagnostics) => realm.handleError(diag); + realm.errorHandler = (diag, suppressDiagnostics) => { invariant(errorHandler); - if (diag.severity === "FatalError") return errorHandler(diag); + if (diag.severity === "FatalError") return errorHandler(diag, realm.suppressDiagnostics); else return "Recover"; }; modules.resolveInitializedModules(); diff --git a/src/react/reconcilation.js b/src/react/reconcilation.js index d29e6defe..18c741b57 100644 --- a/src/react/reconcilation.js +++ b/src/react/reconcilation.js @@ -9,7 +9,7 @@ /* @flow */ -import { Realm, type Effects, type SideEffectType } from "../realm.js"; +import { Realm, type Effects } from "../realm.js"; import { AbstractObjectValue, AbstractValue, @@ -77,8 +77,8 @@ import { UnsupportedSideEffect, } from "./errors.js"; import { Logger } from "../utils/logger.js"; -import type { ClassComponentMetadata, PropertyBinding, ReactComponentTreeConfig, ReactHint } from "../types.js"; -import type { Binding } from "../environment.js"; +import type { ClassComponentMetadata, ReactComponentTreeConfig, ReactHint } from "../types.js"; +import { handleReportedSideEffect } from "../serializer/utils.js"; type ComponentResolutionStrategy = | "NORMAL" @@ -187,6 +187,9 @@ export class Reconciler { try { this.realm.react.activeReconciler = this; + let throwUnsupportedSideEffectError = (msg: string) => { + throw new UnsupportedSideEffect(msg); + }; let effects = this.realm.wrapInGlobalEnv(() => this.realm.evaluatePure( () => @@ -195,7 +198,8 @@ export class Reconciler { /*state*/ null, `react component: ${getComponentName(this.realm, componentType)}` ), - this._handleReportedSideEffect + (sideEffectType, binding, expressionLocation) => + handleReportedSideEffect(throwUnsupportedSideEffectError, sideEffectType, binding, expressionLocation) ) ); this._handleNestedOptimizedClosuresFromEffects(effects, evaluatedRootNode); @@ -284,13 +288,17 @@ export class Reconciler { try { this.realm.react.activeReconciler = this; + let throwUnsupportedSideEffectError = (msg: string) => { + throw new UnsupportedSideEffect(msg); + }; let effects = this.realm.wrapInGlobalEnv(() => this.realm.evaluatePure( () => evaluateWithNestedParentEffects(this.realm, nestedEffects, () => this.realm.evaluateForEffects(resolveOptimizedClosure, /*state*/ null, `react nested optimized closure`) ), - this._handleReportedSideEffect + (sideEffectType, binding, expressionLocation) => + handleReportedSideEffect(throwUnsupportedSideEffectError, sideEffectType, binding, expressionLocation) ) ); this._handleNestedOptimizedClosuresFromEffects(effects, evaluatedNode); @@ -1501,30 +1509,4 @@ export class Reconciler { } } } - - _handleReportedSideEffect( - sideEffectType: SideEffectType, - binding: void | Binding | PropertyBinding, - expressionLocation: any - ): void { - let location = getLocationFromValue(expressionLocation); - - if (sideEffectType === "MODIFIED_BINDING") { - let name = binding ? `"${((binding: any): Binding).name}"` : "unknown"; - throw new UnsupportedSideEffect(`side-effects from mutating the binding ${name}${location}`); - } else if (sideEffectType === "MODIFIED_PROPERTY" || sideEffectType === "MODIFIED_GLOBAL") { - let name = ""; - let key = ((binding: any): PropertyBinding).key; - if (typeof key === "string") { - name = `"${key}"`; - } - if (sideEffectType === "MODIFIED_PROPERTY") { - throw new UnsupportedSideEffect(`side-effects from mutating a property ${name}${location}`); - } else { - throw new UnsupportedSideEffect(`side-effects from mutating the global object property ${name}${location}`); - } - } else if (sideEffectType === "EXCEPTION_THROWN") { - throw new UnsupportedSideEffect(`side-effects from throwing exception${location}`); - } - } } diff --git a/src/realm.js b/src/realm.js index 3fe26a6ef..b4e562628 100644 --- a/src/realm.js +++ b/src/realm.js @@ -1815,7 +1815,7 @@ export class Realm { console.log(diagnostic.callStack); } } - return errorHandler(diagnostic); + return errorHandler(diagnostic, this.suppressDiagnostics); } saveNameString(nameString: string): void { diff --git a/src/serializer/functions.js b/src/serializer/functions.js index 3668a9ba3..a2ca58db1 100644 --- a/src/serializer/functions.js +++ b/src/serializer/functions.js @@ -33,6 +33,7 @@ import { ReactStatistics } from "./types"; import type { AdditionalFunctionEffects, WriteEffects } from "./types"; import { convertConfigObjectToReactComponentTreeConfig, valueIsKnownReactAbstraction } from "../react/utils.js"; import { applyOptimizedReactComponents, optimizeReactComponentTreeRoot } from "../react/optimizing.js"; +import { handleReportedSideEffect } from "./utils.js"; import * as t from "babel-types"; type AdditionalFunctionEntry = { @@ -215,11 +216,17 @@ export class Functions { let currentOptimizedFunctionId = optimizedFunctionId++; additionalFunctionStack.push(functionValue); invariant(functionValue instanceof ECMAScriptSourceFunctionValue); + let logCompilerDiagnostic = (msg: string) => { + let error = new CompilerDiagnostic(msg, undefined, "PP1007", "Warning"); + realm.handleError(error); + }; for (let t1 of this.realm.tracers) t1.beginOptimizingFunction(currentOptimizedFunctionId, functionValue); let call = this._callOfFunction(functionValue); - let effects: Effects = this.realm.evaluatePure( - () => this.realm.evaluateForEffectsInGlobalEnv(call, undefined, "additional function"), - /*reportSideEffectFunc*/ null + let realm = this.realm; + let effects: Effects = realm.evaluatePure( + () => realm.evaluateForEffectsInGlobalEnv(call, undefined, "additional function"), + (sideEffectType, binding, expressionLocation) => + handleReportedSideEffect(logCompilerDiagnostic, sideEffectType, binding, expressionLocation) ); invariant(effects); let additionalFunctionEffects = createAdditionalEffects( diff --git a/src/serializer/utils.js b/src/serializer/utils.js index da0c15cd8..d58e1df77 100644 --- a/src/serializer/utils.js +++ b/src/serializer/utils.js @@ -18,15 +18,17 @@ import { ObjectValue, SymbolValue, } from "../values/index.js"; -import type { Effects, Realm } from "../realm.js"; +import type { Effects, Realm, SideEffectType } from "../realm.js"; import { FatalError } from "../errors.js"; -import type { Descriptor } from "../types.js"; +import type { PropertyBinding, Descriptor } from "../types.js"; import invariant from "../invariant.js"; import { IsArray, IsArrayIndex } from "../methods/index.js"; import { Logger } from "../utils/logger.js"; import { Generator } from "../utils/generator.js"; import type { AdditionalFunctionEffects } from "./types"; +import type { Binding } from "../environment.js"; +import { getLocationFromValue } from "../react/utils"; /** * Get index property list length by searching array properties list for the max index key value plus 1. @@ -199,3 +201,32 @@ export function createAdditionalEffects( }; return retValue; } + +export function handleReportedSideEffect( + exceptionHandler: string => void, + sideEffectType: SideEffectType, + binding: void | Binding | PropertyBinding, + expressionLocation: any +): void { + // This causes an infinite recursion because creating a callstack causes internal-only side effects + if (binding && binding.object && binding.object.intrinsicName === "__checkedBindings") return; + let location = getLocationFromValue(expressionLocation); + + if (sideEffectType === "MODIFIED_BINDING") { + let name = binding ? `"${((binding: any): Binding).name}"` : "unknown"; + exceptionHandler(`side-effects from mutating the binding ${name}${location}`); + } else if (sideEffectType === "MODIFIED_PROPERTY" || sideEffectType === "MODIFIED_GLOBAL") { + let name = ""; + let key = ((binding: any): PropertyBinding).key; + if (typeof key === "string") { + name = `"${key}"`; + } + if (sideEffectType === "MODIFIED_PROPERTY") { + exceptionHandler(`side-effects from mutating a property ${name}${location}`); + } else { + exceptionHandler(`side-effects from mutating the global object property ${name}${location}`); + } + } else if (sideEffectType === "EXCEPTION_THROWN") { + exceptionHandler(`side-effects from throwing exception${location}`); + } +} diff --git a/test/error-handler/.write-write-conflict.js.swp b/test/error-handler/.write-write-conflict.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..8df264ad074185b9b085b009fdd2c97ebc7742f5 GIT binary patch literal 12288 zcmeI2&ubGw6vrnXiU*6Lg4c1qB+z8DiO|qeFaE$HLP69+En%`dsoPFwmf2a`8lr!K ze}>hYH$C_-_%C?&=1KA9chbbhl7<{aP~O0IH+k>voA*AM970~F{%HL^Z`JAy>jGo% z7OrpJIQw;B>sE<%l*lq^op;SzQkW;C2hE8QzxrO*VyQ;N@G{s$*1Hb6A>T+a}X$8x7u1{%|>Y5g-Dm5g0Jet#pOed|R20 zP&Kg%lSq=(rA7-Cl`Fp+8s3oVJd?5GYrI?N*hiKtyw8|V*KV84rM>jIEFY(746{si zMLu7bmq+^_$Nb7Tt_<4+9bto2Hr{ojP}DW9U^2dI%=CCP=Hn-05y--j%YEOQO!#nk zI$zu{*Oy_$jJA5k7MJU*)q6cTx9H1qgoZ@Z4 zo14PMzT5d{%hBH?ygR}PHN-NFUvo%fM!n0k%AIunrE0hQd9gA!I33llHNEQ5nPEQx DC{|fo literal 0 HcmV?d00001 diff --git a/test/error-handler/ModifiedObjectPropertyLimitation.js b/test/error-handler/ModifiedObjectPropertyLimitation.js index 683c1e4fa..c02252af2 100644 --- a/test/error-handler/ModifiedObjectPropertyLimitation.js +++ b/test/error-handler/ModifiedObjectPropertyLimitation.js @@ -1,4 +1,4 @@ -// expected errors: [{"location":{"start":{"line":5,"column":16},"end":{"line":5,"column":18},"source":"test/error-handler/ModifiedObjectPropertyLimitation.js"},"severity":"Warning","errorCode":"PP0023","callStack":"Error\n "},{"location":{"start":{"line":5,"column":16},"end":{"line":5,"column":18},"source":"test/error-handler/ModifiedObjectPropertyLimitation.js"},"severity":"FatalError","errorCode":"PP1006","callStack":"Error\n "}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":5,"column":16},"end":{"line":5,"column":18},"source":"test/error-handler/ModifiedObjectPropertyLimitation.js"},"severity":"Warning","errorCode":"PP0023","callStack":"Error\n "},{"location":{"start":{"line":5,"column":16},"end":{"line":5,"column":18},"source":"test/error-handler/ModifiedObjectPropertyLimitation.js"},"severity":"FatalError","errorCode":"PP1006","callStack":"Error\n "}] (function () { let p = {}; function f(c) { diff --git a/test/error-handler/bad-functions.js b/test/error-handler/bad-functions.js index 6bfa775c1..7709769b9 100644 --- a/test/error-handler/bad-functions.js +++ b/test/error-handler/bad-functions.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{location: {"start":{"line":7,"column":26},"end":{"line":7,"column":35},"identifierName":"Exception","source":"test/error-handler/bad-functions.js"}},{"location":{"start":{"line":12,"column":13},"end":{"line":12,"column":18},"source":"test/error-handler/bad-functions.js"},"severity":"FatalError","errorCode":"PP1003"}, {location: {"start":{"line":8,"column":13},"end":{"line":8,"column":18},"source":"test/error-handler/bad-functions.js"}}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":7,"column":26},"end":{"line":7,"column":35},"identifierName":"Exception","source":"test/error-handler/bad-functions.js"},"severity":"Warning","errorCode":"PP0023","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":12,"column":13},"end":{"line":12,"column":18},"source":"test/error-handler/bad-functions.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":8,"column":13},"end":{"line":8,"column":18},"source":"test/error-handler/bad-functions.js"},"severity":"FatalError","errorCode":"PP1003"}] var wildcard = global.__abstract ? global.__abstract("number", "123") : 123; global.a = ""; diff --git a/test/error-handler/write-forin-conflict.js b/test/error-handler/write-forin-conflict.js index f8e4db1bc..a4782b1f2 100644 --- a/test/error-handler/write-forin-conflict.js +++ b/test/error-handler/write-forin-conflict.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":9,"column":16},"end":{"line":9,"column":22},"identifierName":"global","source":"test/error-handler/write-forin-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":9,"column":16},"end":{"line":9,"column":22},"identifierName":"global","source":"test/error-handler/write-forin-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] function additional1() { global.a = { f: "foo" }; diff --git a/test/error-handler/write-in-conflict.js b/test/error-handler/write-in-conflict.js index e1918d785..0b098e053 100644 --- a/test/error-handler/write-in-conflict.js +++ b/test/error-handler/write-in-conflict.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":9,"column":20},"end":{"line":9,"column":26},"identifierName":"global","source":"test/error-handler/write-in-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":9,"column":20},"end":{"line":9,"column":26},"identifierName":"global","source":"test/error-handler/write-in-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] function additional1() { global.a = "foo"; diff --git a/test/error-handler/write-reflect-conflict.js b/test/error-handler/write-reflect-conflict.js index 7720df90c..62f4c36e6 100644 --- a/test/error-handler/write-reflect-conflict.js +++ b/test/error-handler/write-reflect-conflict.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":11,"column":29},"end":{"line":11,"column":30},"identifierName":"a","source":"test/error-handler/write-reflect-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":11,"column":29},"end":{"line":11,"column":30},"identifierName":"a","source":"test/error-handler/write-reflect-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] a = {}; diff --git a/test/error-handler/write-write-conflict.js b/test/error-handler/write-write-conflict.js index 2946664b7..0a9e0dd7f 100644 --- a/test/error-handler/write-write-conflict.js +++ b/test/error-handler/write-write-conflict.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] global.a = ""; diff --git a/test/error-handler/write-write-conflict2.js b/test/error-handler/write-write-conflict2.js index 0252dbd28..663cc1781 100644 --- a/test/error-handler/write-write-conflict2.js +++ b/test/error-handler/write-write-conflict2.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict2.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":9},"end":{"line":7,"column":15},"identifierName":"global","source":"test/error-handler/write-write-conflict2.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict2.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":9},"end":{"line":7,"column":15},"identifierName":"global","source":"test/error-handler/write-write-conflict2.js"},"severity":"FatalError","errorCode":"PP1003"}] global.a = ""; diff --git a/test/error-handler/write-write-conflict3.js b/test/error-handler/write-write-conflict3.js index e39adfb27..d3e16d638 100644 --- a/test/error-handler/write-write-conflict3.js +++ b/test/error-handler/write-write-conflict3.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":11,"column":9},"end":{"line":11,"column":15},"identifierName":"global","source":"test/error-handler/write-write-conflict3.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict3.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":11,"column":9},"end":{"line":11,"column":15},"identifierName":"global","source":"test/error-handler/write-write-conflict3.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict3.js"},"severity":"FatalError","errorCode":"PP1003"}] global.a = ""; diff --git a/test/error-handler/write-write-conflict4.js b/test/error-handler/write-write-conflict4.js index 669e10041..8ec3bfab7 100644 --- a/test/error-handler/write-write-conflict4.js +++ b/test/error-handler/write-write-conflict4.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict4.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict4.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":11,"column":13},"end":{"line":11,"column":18},"source":"test/error-handler/write-write-conflict4.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":7,"column":13},"end":{"line":7,"column":18},"source":"test/error-handler/write-write-conflict4.js"},"severity":"FatalError","errorCode":"PP1003"}] global.a = ""; diff --git a/test/error-handler/write-write-unknown-prop-conflict.js b/test/error-handler/write-write-unknown-prop-conflict.js index 95aa5ccca..0d42c15c1 100644 --- a/test/error-handler/write-write-unknown-prop-conflict.js +++ b/test/error-handler/write-write-unknown-prop-conflict.js @@ -1,5 +1,5 @@ // recover-from-errors -// expected errors: [{"location":{"start":{"line":12,"column":16},"end":{"line":12,"column":21},"source":"test/error-handler/write-write-unknown-prop-conflict.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":8,"column":16},"end":{"line":8,"column":21},"source":"test/error-handler/write-write-unknown-prop-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] +// expected errors: [{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"severity":"Warning","errorCode":"PP1007","callStack":"Error\n "},{"location":{"start":{"line":12,"column":16},"end":{"line":12,"column":21},"source":"test/error-handler/write-write-unknown-prop-conflict.js"},"severity":"FatalError","errorCode":"PP1003"},{"location":{"start":{"line":8,"column":16},"end":{"line":8,"column":21},"source":"test/error-handler/write-write-unknown-prop-conflict.js"},"severity":"FatalError","errorCode":"PP1003"}] let i = global.__abstract ? __abstract("string", "x") : "x"; global.a = { x: "" } diff --git a/test/serializer/additional-functions/AdditionalFunCapturedScope.js b/test/serializer/additional-functions/AdditionalFunCapturedScope.js index 2a1e65260..d4bb1e212 100644 --- a/test/serializer/additional-functions/AdditionalFunCapturedScope.js +++ b/test/serializer/additional-functions/AdditionalFunCapturedScope.js @@ -1,4 +1,5 @@ // serialized function clone count: 0 +// expected Warning: PP1007 var addit_funs = []; var f = function(x) { diff --git a/test/serializer/additional-functions/ArrayConcat.js b/test/serializer/additional-functions/ArrayConcat.js index 858efe6e9..ab155a7e1 100644 --- a/test/serializer/additional-functions/ArrayConcat.js +++ b/test/serializer/additional-functions/ArrayConcat.js @@ -1,4 +1,3 @@ - function fn(arg) { var x = Array.from(arg).map(x => x); return ["start"].concat(x).concat(["end"]); diff --git a/test/serializer/additional-functions/DeadOuterObject.js b/test/serializer/additional-functions/DeadOuterObject.js index 9acd223df..012bdf158 100644 --- a/test/serializer/additional-functions/DeadOuterObject.js +++ b/test/serializer/additional-functions/DeadOuterObject.js @@ -1,3 +1,5 @@ +// expected Warning: PP1007 + (function () { let outer = {}; function f(x) { diff --git a/test/serializer/additional-functions/EmitPropertyRegressionTest.js b/test/serializer/additional-functions/EmitPropertyRegressionTest.js index 432f9271e..fdb07798b 100644 --- a/test/serializer/additional-functions/EmitPropertyRegressionTest.js +++ b/test/serializer/additional-functions/EmitPropertyRegressionTest.js @@ -1,3 +1,4 @@ +// expected Warning: PP0023 (function() { function URI(other) { if (other.foo) { diff --git a/test/serializer/additional-functions/Example1.js b/test/serializer/additional-functions/Example1.js index 5ed0295a5..5b32b3f7d 100644 --- a/test/serializer/additional-functions/Example1.js +++ b/test/serializer/additional-functions/Example1.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 var AGlobalObject = {}; var AGlobalValue = 5; diff --git a/test/serializer/additional-functions/GlobalLetBinding.js b/test/serializer/additional-functions/GlobalLetBinding.js index 99db11775..1e5b5927b 100644 --- a/test/serializer/additional-functions/GlobalLetBinding.js +++ b/test/serializer/additional-functions/GlobalLetBinding.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 let x = undefined; let y = undefined; global.f = function() { @@ -9,4 +10,4 @@ global.f1 = function() { }; if (global.__optimize) __optimize(f); -global.inspect = function() { global.f(); global.f1(); return x !== y; } \ No newline at end of file +global.inspect = function() { global.f(); global.f1(); return x !== y; } diff --git a/test/serializer/additional-functions/Issue1821RegressionTest.js b/test/serializer/additional-functions/Issue1821RegressionTest.js index b6ca60143..93d5af154 100644 --- a/test/serializer/additional-functions/Issue1821RegressionTest.js +++ b/test/serializer/additional-functions/Issue1821RegressionTest.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007, PP0023 (function() { function URI(other) { if (other) { diff --git a/test/serializer/additional-functions/ModifiedBindingWithoutInitialValue.js b/test/serializer/additional-functions/ModifiedBindingWithoutInitialValue.js index e68c429f6..32feb8d2e 100644 --- a/test/serializer/additional-functions/ModifiedBindingWithoutInitialValue.js +++ b/test/serializer/additional-functions/ModifiedBindingWithoutInitialValue.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 // does not contain:dead (function () { let b = { p: "dead" }; diff --git a/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js b/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js index 3db22f0d8..aa7c91853 100644 --- a/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js +++ b/test/serializer/additional-functions/ModifiedBindingsCapturedScopesCalls.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 // add at runtime:var a = 17; // Copies of \|\|:2 (function () { diff --git a/test/serializer/additional-functions/ModifiedObjectProperty.js b/test/serializer/additional-functions/ModifiedObjectProperty.js index 0297c0482..3f31345d7 100644 --- a/test/serializer/additional-functions/ModifiedObjectProperty.js +++ b/test/serializer/additional-functions/ModifiedObjectProperty.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007, PP0023 (function () { let p = {}; function f(c) { diff --git a/test/serializer/additional-functions/ModifiedObjectPropertyWithAbstractKey.js b/test/serializer/additional-functions/ModifiedObjectPropertyWithAbstractKey.js index 57c542013..38c8b9ae8 100644 --- a/test/serializer/additional-functions/ModifiedObjectPropertyWithAbstractKey.js +++ b/test/serializer/additional-functions/ModifiedObjectPropertyWithAbstractKey.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 (function() { var cache = {}; function fn(args) { diff --git a/test/serializer/additional-functions/ObjectCreationGeneratorRegressionTest.js b/test/serializer/additional-functions/ObjectCreationGeneratorRegressionTest.js index abf468d7c..79676ef7b 100644 --- a/test/serializer/additional-functions/ObjectCreationGeneratorRegressionTest.js +++ b/test/serializer/additional-functions/ObjectCreationGeneratorRegressionTest.js @@ -1,3 +1,4 @@ +// expected Warning: PP0023 function nullthrows(x) { if (x != null) { return x; @@ -14,4 +15,4 @@ function App(props) { if (global.__optimize) __optimize(App); -inspect = function() { return 42; } // just make sure no invariants in Prepack blow up \ No newline at end of file +inspect = function() { return 42; } // just make sure no invariants in Prepack blow up diff --git a/test/serializer/additional-functions/ObjectLifetime2.js b/test/serializer/additional-functions/ObjectLifetime2.js index 19719240a..21001063d 100644 --- a/test/serializer/additional-functions/ObjectLifetime2.js +++ b/test/serializer/additional-functions/ObjectLifetime2.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 (function () { let a = [1,2,3]; let f = function() { diff --git a/test/serializer/additional-functions/OuterScopeCacheRegressionTest.js b/test/serializer/additional-functions/OuterScopeCacheRegressionTest.js index 304539a7d..03d9baacb 100644 --- a/test/serializer/additional-functions/OuterScopeCacheRegressionTest.js +++ b/test/serializer/additional-functions/OuterScopeCacheRegressionTest.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 var cache = {}; function additional1(x, y) { diff --git a/test/serializer/additional-functions/ReadThenDelete.js b/test/serializer/additional-functions/ReadThenDelete.js index f621b2826..d67e9cb60 100644 --- a/test/serializer/additional-functions/ReadThenDelete.js +++ b/test/serializer/additional-functions/ReadThenDelete.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 var AGlobalObject = {}; var AGlobalValue = 5; diff --git a/test/serializer/additional-functions/RegressionTestForIssue1881.js b/test/serializer/additional-functions/RegressionTestForIssue1881.js index 3ea72d202..4aec10b45 100644 --- a/test/serializer/additional-functions/RegressionTestForIssue1881.js +++ b/test/serializer/additional-functions/RegressionTestForIssue1881.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007, PP0023 (function () { function f(c) { let o = {}; diff --git a/test/serializer/additional-functions/ResidualFunctionBindingsMutatedByOptimizedFunctionRegressionTest.js b/test/serializer/additional-functions/ResidualFunctionBindingsMutatedByOptimizedFunctionRegressionTest.js index 43bf10a9f..f6e0b3ed9 100644 --- a/test/serializer/additional-functions/ResidualFunctionBindingsMutatedByOptimizedFunctionRegressionTest.js +++ b/test/serializer/additional-functions/ResidualFunctionBindingsMutatedByOptimizedFunctionRegressionTest.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 (function() { let x = 23; function g() { return x; } @@ -8,4 +9,4 @@ if (global.__optimize) __optimize(f); global.f = f; inspect = function() { return x + "+19=" + f()(); } -})(); \ No newline at end of file +})(); diff --git a/test/serializer/additional-functions/abstract-property-modification.js b/test/serializer/additional-functions/abstract-property-modification.js index e5d7aba45..5046b04a0 100644 --- a/test/serializer/additional-functions/abstract-property-modification.js +++ b/test/serializer/additional-functions/abstract-property-modification.js @@ -1,3 +1,4 @@ +// expected Warning: PP1007 // does not contain:x = 5; // does not contain:y = 10; // add at runtime: global.a = {}; global.b = {}; diff --git a/test/serializer/additional-functions/conditions2.js b/test/serializer/additional-functions/conditions2.js index 301811253..ba04fa9be 100644 --- a/test/serializer/additional-functions/conditions2.js +++ b/test/serializer/additional-functions/conditions2.js @@ -1,3 +1,4 @@ +// expected Warning: PP0023 if (!this.__evaluatePureFunction) { this.__evaluatePureFunction = function(f) { return f(); diff --git a/test/serializer/additional-functions/write-write-noconflict.js b/test/serializer/additional-functions/write-write-noconflict.js index 3acd3e789..e024e4fe1 100644 --- a/test/serializer/additional-functions/write-write-noconflict.js +++ b/test/serializer/additional-functions/write-write-noconflict.js @@ -1,5 +1,6 @@ // does not contain:x = 5; // does not contain:y = 10; +// expected Warning: PP1007 global.a = ""; global.b = ""; diff --git a/test/serializer/optimized-functions/double-call.js b/test/serializer/optimized-functions/double-call.js new file mode 100644 index 000000000..6f5138177 --- /dev/null +++ b/test/serializer/optimized-functions/double-call.js @@ -0,0 +1,19 @@ +function fn2(x, y) { + return { + val : x !== null ? y : undefined, + } +} + +function fn(x, y) { + var x = fn2(x, y) + var y = fn2(x, y) + + return [x, y]; +} + +global.__optimize && __optimize(fn); + +inspect = function() { + var x = JSON.stringify([fn(null, 1), fn(true, 2)]); + return x; +} diff --git a/test/serializer/optimized-functions/simple-nesting.js b/test/serializer/optimized-functions/simple-nesting.js new file mode 100644 index 000000000..eb5b8ab68 --- /dev/null +++ b/test/serializer/optimized-functions/simple-nesting.js @@ -0,0 +1,17 @@ +// does not contain:1 + 2 +(function() { + function render1() { + function render2() { + return 1 + 2; // This should get prepacked! + } + if (global.__optimize) __optimize(render2); + return render2; + } + + if (global.__optimize) __optimize(render1); + + global.render1 = render1; + global.inspect = function () { + return render1()(); + } +})();