Closed kaljak closed 2 years ago
I think this is a closure compiler bug. I'll have to dig in to replicate using the command line and raise it there.
Hmmm java -jar ~/.m2/repository/com/google/javascript/closure-compiler/v20180402/closure-compiler-v20180402.jar --js test.js --language_in ECMASCRIPT_2017 --language_out ECMASCRIPT_2017 --formatting PRETTY_PRINT
seems to work OK. Will have to debug to see what's the difference in print and/or parser options.
Comparing closure-compile config internals which work (1st line) with JSCover parser's which doesn't (2nd).
CompilerOptions{aggressiveFusion=false, aliasableStrings=[], aliasAllStrings=false, aliasHandler=com.google.javascript.jscomp.CompilerOptions$NullAliasTransformationHandler@2ea227af, aliasStringsBlacklist=, allowHotswapReplaceScript=false, ambiguateProperties=false, angularPass=false, anonymousFunctionNaming=OFF, appNameStr=, assumeClosuresOnlyCaptureReferences=false, assumeStrictThis=false, brokenClosureRequiresLevel=ERROR, checkDeterminism=false, checkGlobalNamesLevel=OFF, checkGlobalThisLevel=OFF, checkMissingGetCssNameLevel=OFF, checksOnly=false, checkSuspiciousCode=true, checkSymbols=false, checkTypes=false, closurePass=true, coalesceVariableNames=true, codingConvention=com.google.javascript.jscomp.ClosureCodingConvention@7e7be63f, collapseAnonymousFunctions=false, collapseObjectLiterals=true, collapseProperties=NONE, collapseVariableDeclarations=true, colorizeErrorOutput=false, computeFunctionSideEffects=false, conformanceConfigs=[], continueAfterErrors=false, convertToDottedProperties=true, crossModuleCodeMotion=false, crossModuleCodeMotionNoStubMethods=false, crossModuleMethodMotion=false, dartPass=false, deadAssignmentElimination=true, declaredGlobalExternsOnWindow=true, defineReplacements={}, dependencyOptions=DependencyOptions{sortDependencies=true, pruneDependencies=false, dropMoochers=false, entryPoints=[]}, devirtualizePrototypeMethods=false, devMode=OFF, disambiguatePrivateProperties=false, disambiguateProperties=false, enforceAccessControlCodingConventions=false, environment=BROWSER, errorFormat=SINGLELINE, exportLocalPropertyDefinitions=false, exportTestFunctions=false, externExports=false, extraAnnotationNames=[], extractPrototypeMemberDeclarations=OFF, extraSmartNameRemoval=false, filesToPrintAfterEachPassRegexList=[], flowSensitiveInlineVariables=false, foldConstants=true, forceLibraryInjection=[], gatherCssNames=false, generateExportsAfterTypeChecking=true, generateExports=false, generatePseudoNames=false, generateTypedExterns=false, idGenerators={}, incrementalCheckMode=OFF, inferConsts=true, inferTypes=false, inlineConstantVars=false, inlineFunctionsLevel=LOCAL_ONLY, inlineGetters=false, inlineLocalVariables=true, inlineProperties=false, inlineVariables=false, inputDelimiter=// Input %num%, inputSourceMaps={}, instrumentationTemplateFile=, instrumentForCoverage=false, instrumentForCoverageOnly=false, instrumentBranchCoverage=false, j2clPassMode=AUTO, labelRenaming=true, languageIn=ECMASCRIPT_2017, languageOut=ECMASCRIPT_2017, legacyCodeCompile=false, lineBreak=false, lineLengthThreshold=500, markAsCompiled=false, markNoSideEffectCalls=false, maxFunctionSizeAfterInlining=-1, moduleRoots=[], modulesToPrintAfterEachPassRegexList=[], moveFunctionDeclarations=false, nameGenerator=com.google.javascript.jscomp.DefaultNameGenerator@31304f14, optimizeArgumentsArray=true, optimizeCalls=false, outputCharset=US-ASCII, outputJs=NORMAL, outputJsStringUsage=false, parentModuleCanSeeSymbolsDeclaredInChildren=false, parseJsDocDocumentation=TYPES_ONLY, preferLineBreakAtEndOfFile=false, preferSingleQuotes=false, preferStableNames=false, preserveDetailedSourceInfo=false, preserveGoogProvidesAndRequires=false, preserveTypeAnnotations=false, prettyPrint=true, preventLibraryInjection=false, printConfig=false, printInputDelimiter=false, printSourceAfterEachPass=false, processCommonJSModules=false, transpileEs6ModulesToCjsModules=false, processObjectPropertyString=false, propertyInvalidationErrors={}, propertyRenaming=OFF, protectHiddenSideEffects=true, quoteKeywordProperties=false, recordFunctionInformation=false, removeAbstractMethods=false, removeSuperMethods=false, removeClosureAsserts=false, removeJ2clAsserts=true, removeDeadCode=true, removeUnusedClassProperties=false, removeUnusedConstructorProperties=false, removeUnusedLocalVars=true, removeUnusedPrototypePropertiesInExterns=false, removeUnusedPrototypeProperties=false, removeUnusedVars=false, renamePrefixNamespaceAssumeCrossModuleNames=false, replaceIdGenerators=false, replaceMessagesWithChromeI18n=false, replaceStringsFunctionDescriptions=[], replaceStringsPlaceholderToken=, replaceStringsReservedStrings=[], reserveRawExports=false, rewriteFunctionExpressions=false, rewritePolyfills=true, runtimeTypeCheck=false, shadowVariables=true, skipNonTranspilationPasses=false, smartNameRemoval=false, sourceMapDetailLevel=ALL, sourceMapFormat=DEFAULT, sourceMapLocationMappings=[], stripNamePrefixes=[], stripNameSuffixes=[], stripTypePrefixes=[], stripTypes=[], summaryDetailLevel=1, tracer=OFF, transformAMDToCJSModules=false, trustedStrings=true, tweakProcessing=OFF, tweakReplacements={}, emitUseStrict=Optional.absent(), useTypesForLocalOptimization=false, variableRenaming=LOCAL, warningsGuard=DiagnosticGroup<checkVars>(OFF), DiagnosticGroup<es5Strict>(ERROR), com.google.javascript.jscomp.DiagnosticGroup@6f15d60e(OFF), DiagnosticGroup<nonStandardJsDocs>(OFF), wrapGoogModulesForWhitespaceOnly=true}
CompilerOptions{aggressiveFusion=false, aliasableStrings=[], aliasAllStrings=false, aliasHandler=com.google.javascript.jscomp.CompilerOptions$NullAliasTransformationHandler@7e0a8eeb, aliasStringsBlacklist=, allowHotswapReplaceScript=false, ambiguateProperties=false, angularPass=false, anonymousFunctionNaming=OFF, appNameStr=, assumeClosuresOnlyCaptureReferences=false, assumeStrictThis=false, brokenClosureRequiresLevel=ERROR, checkDeterminism=false, checkGlobalNamesLevel=OFF, checkGlobalThisLevel=OFF, checkMissingGetCssNameLevel=OFF, checksOnly=false, checkSuspiciousCode=false, checkSymbols=false, checkTypes=false, closurePass=true, coalesceVariableNames=true, codingConvention=com.google.javascript.jscomp.ClosureCodingConvention@70f69ac5, collapseAnonymousFunctions=false, collapseObjectLiterals=true, collapseProperties=NONE, collapseVariableDeclarations=true, colorizeErrorOutput=false, computeFunctionSideEffects=false, conformanceConfigs=[], continueAfterErrors=false, convertToDottedProperties=true, crossModuleCodeMotion=false, crossModuleCodeMotionNoStubMethods=false, crossModuleMethodMotion=false, dartPass=false, deadAssignmentElimination=true, declaredGlobalExternsOnWindow=true, defineReplacements={}, dependencyOptions=DependencyOptions{sortDependencies=true, pruneDependencies=false, dropMoochers=false, entryPoints=[]}, devirtualizePrototypeMethods=false, devMode=OFF, disambiguatePrivateProperties=false, disambiguateProperties=false, enforceAccessControlCodingConventions=false, environment=BROWSER, errorFormat=SINGLELINE, exportLocalPropertyDefinitions=false, exportTestFunctions=false, externExports=false, extractPrototypeMemberDeclarations=OFF, extraSmartNameRemoval=false, filesToPrintAfterEachPassRegexList=[], flowSensitiveInlineVariables=false, foldConstants=true, forceLibraryInjection=[], gatherCssNames=false, generateExportsAfterTypeChecking=true, generateExports=false, generatePseudoNames=false, generateTypedExterns=false, idGenerators={}, incrementalCheckMode=OFF, inferConsts=true, inferTypes=false, inlineConstantVars=false, inlineFunctionsLevel=LOCAL_ONLY, inlineGetters=false, inlineLocalVariables=true, inlineProperties=false, inlineVariables=false, inputDelimiter=// Input %num%, inputSourceMaps={}, instrumentationTemplateFile=, instrumentForCoverage=false, instrumentForCoverageOnly=false, instrumentBranchCoverage=false, j2clPassMode=AUTO, labelRenaming=true, languageIn=ECMASCRIPT_2017, languageOut=ECMASCRIPT_2017, legacyCodeCompile=false, lineBreak=false, lineLengthThreshold=500, markAsCompiled=false, markNoSideEffectCalls=false, maxFunctionSizeAfterInlining=-1, moduleRoots=[./], modulesToPrintAfterEachPassRegexList=[], moveFunctionDeclarations=false, nameGenerator=com.google.javascript.jscomp.DefaultNameGenerator@10096f5d, optimizeArgumentsArray=true, optimizeCalls=false, outputJs=NORMAL, outputJsStringUsage=false, parentModuleCanSeeSymbolsDeclaredInChildren=false, parseJsDocDocumentation=TYPES_ONLY, preferLineBreakAtEndOfFile=false, preferSingleQuotes=true, preferStableNames=false, preserveDetailedSourceInfo=false, preserveGoogProvidesAndRequires=false, preserveTypeAnnotations=false, prettyPrint=true, preventLibraryInjection=false, printConfig=false, printInputDelimiter=false, printSourceAfterEachPass=false, processCommonJSModules=false, transpileEs6ModulesToCjsModules=false, processObjectPropertyString=false, propertyInvalidationErrors={}, propertyRenaming=OFF, protectHiddenSideEffects=true, quoteKeywordProperties=false, recordFunctionInformation=false, removeAbstractMethods=false, removeSuperMethods=false, removeClosureAsserts=false, removeJ2clAsserts=true, removeDeadCode=true, removeUnusedClassProperties=false, removeUnusedConstructorProperties=false, removeUnusedLocalVars=true, removeUnusedPrototypePropertiesInExterns=false, removeUnusedPrototypeProperties=false, removeUnusedVars=false, renamePrefixNamespaceAssumeCrossModuleNames=false, replaceIdGenerators=false, replaceMessagesWithChromeI18n=false, replaceStringsFunctionDescriptions=[], replaceStringsPlaceholderToken=, replaceStringsReservedStrings=[], reserveRawExports=false, rewriteFunctionExpressions=false, rewritePolyfills=false, runtimeTypeCheck=false, shadowVariables=true, skipNonTranspilationPasses=false, smartNameRemoval=false, sourceMapDetailLevel=ALL, sourceMapFormat=DEFAULT, sourceMapLocationMappings=[], stripNamePrefixes=[], stripNameSuffixes=[], stripTypePrefixes=[], stripTypes=[], summaryDetailLevel=1, tracer=OFF, transformAMDToCJSModules=false, trustedStrings=true, tweakProcessing=OFF, tweakReplacements={}, emitUseStrict=Optional.absent(), useTypesForLocalOptimization=false, variableRenaming=LOCAL, warningsGuard=, wrapGoogModulesForWhitespaceOnly=true}
Config{languageMode=ECMASCRIPT8, strictMode=STRICT, jsDocParsingMode=TYPES_ONLY, runMode=STOP_AFTER_ERROR, annotations={ngInject=NG_INJECT, abstract=ABSTRACT, argument=PARAM, author=AUTHOR, consistentIdGenerator=CONSISTENTIDGENERATOR, const=CONSTANT, constant=CONSTANT, constructor=CONSTRUCTOR, customElement=CUSTOM_ELEMENT, copyright=LICENSE, define=DEFINE, deprecated=DEPRECATED, desc=DESC, dict=DICT, disposes=DISPOSES, enum=ENUM, export=EXPORT, expose=EXPOSE, extends=EXTENDS, externs=EXTERNS, fileoverview=FILE_OVERVIEW, final=FINAL, hidden=HIDDEN, idGenerator=IDGENERATOR, implements=IMPLEMENTS, implicitCast=IMPLICIT_CAST, inheritDoc=INHERIT_DOC, interface=INTERFACE, record=RECORD, lends=LENDS, license=LICENSE, meaning=MEANING, mixinClass=MIXIN_CLASS, mixinFunction=MIXIN_FUNCTION, modifies=MODIFIES, nocollapse=NO_COLLAPSE, nocompile=NO_COMPILE, noinline=NO_INLINE, nosideeffects=NO_SIDE_EFFECTS, override=OVERRIDE, owner=AUTHOR, package=PACKAGE, param=PARAM, polymer=POLYMER, polymerBehavior=POLYMER_BEHAVIOR, preserve=PRESERVE, private=PRIVATE, protected=PROTECTED, public=PUBLIC, return=RETURN, returns=RETURN, see=SEE, stableIdGenerator=STABLEIDGENERATOR, struct=STRUCT, suppress=SUPPRESS, template=TEMPLATE, this=THIS, throws=THROWS, type=TYPE, typedef=TYPEDEF, typeSummary=TYPE_SUMMARY, unrestricted=UNRESTRICTED, version=VERSION, wizaction=WIZACTION, exception=NOT_IMPLEMENTED, hassoydelcall=NOT_IMPLEMENTED, parent=NOT_IMPLEMENTED, usage=NOT_IMPLEMENTED, channel=NOT_IMPLEMENTED, methodOf=NOT_IMPLEMENTED, readonly=NOT_IMPLEMENTED, borrows=NOT_IMPLEMENTED, property=NOT_IMPLEMENTED, docsNotRequired=NOT_IMPLEMENTED, model=NOT_IMPLEMENTED, id=NOT_IMPLEMENTED, multiElement=NOT_IMPLEMENTED, element=NOT_IMPLEMENTED, method=NOT_IMPLEMENTED, module=NOT_IMPLEMENTED, eventType=NOT_IMPLEMENTED, priority=NOT_IMPLEMENTED, codepen=NOT_IMPLEMENTED, fires=NOT_IMPLEMENTED, field=NOT_IMPLEMENTED, preserveTry=NOT_IMPLEMENTED, mixes=NOT_IMPLEMENTED, requires=NOT_IMPLEMENTED, propertyOf=NOT_IMPLEMENTED, global=NOT_IMPLEMENTED, hassoydeltemplate=NOT_IMPLEMENTED, restrict=NOT_IMPLEMENTED, example=NOT_IMPLEMENTED, delegate=NOT_IMPLEMENTED, default=NOT_IMPLEMENTED, file=NOT_IMPLEMENTED, member=NOT_IMPLEMENTED, memberOf=NOT_IMPLEMENTED, event=NOT_IMPLEMENTED, url=NOT_IMPLEMENTED, todo=NOT_IMPLEMENTED, bug=NOT_IMPLEMENTED, docs-private=NOT_IMPLEMENTED, classdesc=NOT_IMPLEMENTED, wizmodule=NOT_IMPLEMENTED, config=NOT_IMPLEMENTED, augments=NOT_IMPLEMENTED, supported=NOT_IMPLEMENTED, wizSupportsSymbolicLookup=NOT_IMPLEMENTED, pintomodule=NOT_IMPLEMENTED, exportInterface=NOT_IMPLEMENTED, mods=NOT_IMPLEMENTED, instance=NOT_IMPLEMENTED, enhanceable=NOT_IMPLEMENTED, requirecss=NOT_IMPLEMENTED, function=NOT_IMPLEMENTED, static=NOT_IMPLEMENTED, visibility=NOT_IMPLEMENTED, kind=NOT_IMPLEMENTED, inner=NOT_IMPLEMENTED, mixin=NOT_IMPLEMENTED, name=NOT_IMPLEMENTED, modName=NOT_IMPLEMENTED, memberof=NOT_IMPLEMENTED, exec=NOT_IMPLEMENTED, since=NOT_IMPLEMENTED, virtual=NOT_IMPLEMENTED, addon=NOT_IMPLEMENTED, exportDoc=NOT_IMPLEMENTED, link=NOT_IMPLEMENTED, description=NOT_IMPLEMENTED, constructs=NOT_IMPLEMENTED, demo=NOT_IMPLEMENTED, noalias=NOT_IMPLEMENTED, animations=NOT_IMPLEMENTED, scope=NOT_IMPLEMENTED, alias=NOT_IMPLEMENTED, ignore=NOT_IMPLEMENTED, tutorial=NOT_IMPLEMENTED, class=NOT_IMPLEMENTED, enhance=NOT_IMPLEMENTED, summary=NOT_IMPLEMENTED, ngdoc=NOT_IMPLEMENTED, eventOf=NOT_IMPLEMENTED, namespace=NOT_IMPLEMENTED, provideGoog=NOT_IMPLEMENTED, base=NOT_IMPLEMENTED}, suppressionNames=[accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkEventfulObjectDisposal, checkRegExp, checkTypes, checkVars, closureDepMethodUsageChecks, const, constantProperty, deprecated, duplicate, es5Strict, externsValidation, extraProvide, extraRequire, fileoverviewTags, globalThis, invalidCasts, legacyGoogScopeRequire, lateProvide, lintChecks, messageConventions, misplacedTypeAnnotation, missingOverride, missingPolyfill, missingProperties, missingProvide, missingRequire, missingReturn, moduleLoad, newCheckTypes, newCheckTypesAllChecks, nonStandardJsDocs, reportUnknownTypes, strictCheckTypes, strictMissingProperties, strictModuleDepCheck, strictPrimitiveOperators, suspiciousCode, transitionalSuspiciousCodeWarnings, undefinedNames, undefinedVars, underscore, unknownDefines, unusedLocalVariables, unusedPrivateMembers, uselessCode, visibility, with], parseInlineSourceMaps=true}
Config{languageMode=ECMASCRIPT8, strictMode=SLOPPY, jsDocParsingMode=INCLUDE_DESCRIPTIONS_WITH_WHITESPACE, runMode=KEEP_GOING, annotations={ngInject=NG_INJECT, abstract=ABSTRACT, argument=PARAM, author=AUTHOR, consistentIdGenerator=CONSISTENTIDGENERATOR, const=CONSTANT, constant=CONSTANT, constructor=CONSTRUCTOR, customElement=CUSTOM_ELEMENT, copyright=LICENSE, define=DEFINE, deprecated=DEPRECATED, desc=DESC, dict=DICT, disposes=DISPOSES, enum=ENUM, export=EXPORT, expose=EXPOSE, extends=EXTENDS, externs=EXTERNS, fileoverview=FILE_OVERVIEW, final=FINAL, hidden=HIDDEN, idGenerator=IDGENERATOR, implements=IMPLEMENTS, implicitCast=IMPLICIT_CAST, inheritDoc=INHERIT_DOC, interface=INTERFACE, record=RECORD, lends=LENDS, license=LICENSE, meaning=MEANING, mixinClass=MIXIN_CLASS, mixinFunction=MIXIN_FUNCTION, modifies=MODIFIES, nocollapse=NO_COLLAPSE, nocompile=NO_COMPILE, noinline=NO_INLINE, nosideeffects=NO_SIDE_EFFECTS, override=OVERRIDE, owner=AUTHOR, package=PACKAGE, param=PARAM, polymer=POLYMER, polymerBehavior=POLYMER_BEHAVIOR, preserve=PRESERVE, private=PRIVATE, protected=PROTECTED, public=PUBLIC, return=RETURN, returns=RETURN, see=SEE, stableIdGenerator=STABLEIDGENERATOR, struct=STRUCT, suppress=SUPPRESS, template=TEMPLATE, this=THIS, throws=THROWS, type=TYPE, typedef=TYPEDEF, typeSummary=TYPE_SUMMARY, unrestricted=UNRESTRICTED, version=VERSION, wizaction=WIZACTION, addon=NOT_IMPLEMENTED, alias=NOT_IMPLEMENTED, animations=NOT_IMPLEMENTED, augments=NOT_IMPLEMENTED, base=NOT_IMPLEMENTED, borrows=NOT_IMPLEMENTED, bug=NOT_IMPLEMENTED, channel=NOT_IMPLEMENTED, class=NOT_IMPLEMENTED, classdesc=NOT_IMPLEMENTED, codepen=NOT_IMPLEMENTED, config=NOT_IMPLEMENTED, constructs=NOT_IMPLEMENTED, default=NOT_IMPLEMENTED, delegate=NOT_IMPLEMENTED, demo=NOT_IMPLEMENTED, description=NOT_IMPLEMENTED, docsNotRequired=NOT_IMPLEMENTED, docs-private=NOT_IMPLEMENTED, element=NOT_IMPLEMENTED, enhance=NOT_IMPLEMENTED, enhanceable=NOT_IMPLEMENTED, event=NOT_IMPLEMENTED, eventOf=NOT_IMPLEMENTED, eventType=NOT_IMPLEMENTED, example=NOT_IMPLEMENTED, exception=NOT_IMPLEMENTED, exec=NOT_IMPLEMENTED, exportDoc=NOT_IMPLEMENTED, exportInterface=NOT_IMPLEMENTED, field=NOT_IMPLEMENTED, file=NOT_IMPLEMENTED, fires=NOT_IMPLEMENTED, function=NOT_IMPLEMENTED, global=NOT_IMPLEMENTED, hassoydelcall=NOT_IMPLEMENTED, hassoydeltemplate=NOT_IMPLEMENTED, id=NOT_IMPLEMENTED, ignore=NOT_IMPLEMENTED, inner=NOT_IMPLEMENTED, instance=NOT_IMPLEMENTED, kind=NOT_IMPLEMENTED, link=NOT_IMPLEMENTED, member=NOT_IMPLEMENTED, memberOf=NOT_IMPLEMENTED, memberof=NOT_IMPLEMENTED, method=NOT_IMPLEMENTED, methodOf=NOT_IMPLEMENTED, mixes=NOT_IMPLEMENTED, mixin=NOT_IMPLEMENTED, modName=NOT_IMPLEMENTED, model=NOT_IMPLEMENTED, mods=NOT_IMPLEMENTED, module=NOT_IMPLEMENTED, multiElement=NOT_IMPLEMENTED, name=NOT_IMPLEMENTED, namespace=NOT_IMPLEMENTED, ngdoc=NOT_IMPLEMENTED, noalias=NOT_IMPLEMENTED, parent=NOT_IMPLEMENTED, pintomodule=NOT_IMPLEMENTED, preserveTry=NOT_IMPLEMENTED, priority=NOT_IMPLEMENTED, property=NOT_IMPLEMENTED, propertyOf=NOT_IMPLEMENTED, provideGoog=NOT_IMPLEMENTED, readonly=NOT_IMPLEMENTED, requirecss=NOT_IMPLEMENTED, requires=NOT_IMPLEMENTED, restrict=NOT_IMPLEMENTED, scope=NOT_IMPLEMENTED, since=NOT_IMPLEMENTED, static=NOT_IMPLEMENTED, summary=NOT_IMPLEMENTED, supported=NOT_IMPLEMENTED, todo=NOT_IMPLEMENTED, tutorial=NOT_IMPLEMENTED, url=NOT_IMPLEMENTED, usage=NOT_IMPLEMENTED, virtual=NOT_IMPLEMENTED, visibility=NOT_IMPLEMENTED, wizSupportsSymbolicLookup=NOT_IMPLEMENTED, wizmodule=NOT_IMPLEMENTED}, suppressionNames=[accessControls, ambiguousFunctionDecl, checkDebuggerStatement, checkEventfulObjectDisposal, checkRegExp, checkTypes, checkVars, closureDepMethodUsageChecks, const, constantProperty, deprecated, duplicate, es5Strict, externsValidation, extraProvide, extraRequire, fileoverviewTags, globalThis, invalidCasts, legacyGoogScopeRequire, lateProvide, lintChecks, messageConventions, misplacedTypeAnnotation, missingOverride, missingPolyfill, missingProperties, missingProvide, missingRequire, missingReturn, moduleLoad, newCheckTypes, newCheckTypesAllChecks, nonStandardJsDocs, reportUnknownTypes, strictCheckTypes, strictMissingProperties, strictModuleDepCheck, strictPrimitiveOperators, suspiciousCode, transitionalSuspiciousCodeWarnings, undefinedNames, undefinedVars, underscore, unknownDefines, unusedLocalVariables, unusedPrivateMembers, uselessCode, visibility, with], parseInlineSourceMaps=false}
Hmmm. Still investigating. Here's what's in the patch and what I've tried with debugging:
Node.toStringTree()
)CodeGenerator
options are the same before printingWhat I've noticed that is different is that several external modules are loaded in the colsure-compiler CLI parser.
Hello ! I'm facing the same issue using the last JSCover version (2.0.12). Can you give a status about this issue ? What is the last working version of JSCover ?
I just tested with closure-compiler v20211006, and still have the issue. I'll have to have another look into this. Version 2.0.12 is currently the latest version of JSCover.
The code @kaljak gave should be sufficient to reproduce. (0,eval)
is not equivalent to eval
especially for evaluating this
(cf. https://stackoverflow.com/questions/9107240/1-evalthis-vs-evalthis-in-javascript) so final result is an error.
As soon as I use a JS code generator, these eval('this')
appear really often in the instrumented code. I'm trying to find a closure-compiler CompilerOptions flag for this, but documentation is such a mess...
Edit : I confirm that using closure-compiler comand line eval
is not substituted with (0,eval)
Working AST
jsRoot.toStringTree():
SCRIPT 1:0 [length: 106] [source_file: test.js] [feature_set: []]
VAR 1:0 [length: 106] [source_file: test.js]
NAME functions 1:4 [length: 102] [source_file: test.js]
OBJECTLIT 1:16 [length: 90] [source_file: test.js]
STRING_KEY func 2:2 [length: 4] [source_file: test.js]
CALL 2:8 [length: 78] [source_file: test.js]
GETPROP bind 4:4 [length: 4] [source_file: test.js]
FUNCTION 2:8 [length: 47] [source_file: test.js]
NAME 2:8 [length: 47] [source_file: test.js]
PARAM_LIST 2:16 [length: 2] [source_file: test.js]
BLOCK 2:19 [length: 36] [source_file: test.js]
EXPR_RESULT 3:4 [length: 26] [source_file: test.js]
CALL 3:4 [length: 25] [source_file: test.js]
NAME eval 3:4 [length: 4] [source_file: test.js]
STRINGLIT this.style.height 3:9 [length: 19] [source_file: test.js]
GETPROP documentElement 4:18 [length: 15] [source_file: test.js]
NAME document 4:9 [length: 8] [source_file: test.js]
Broken AST
SCRIPT 1:0 [length: 106] [source_file: test.js] [input_id: InputId: test.js] [feature_set: []]
VAR 1:0 [length: 106] [source_file: test.js]
NAME functions 1:4 [length: 102] [source_file: test.js] [constant_var_flags: 2]
OBJECTLIT 1:16 [length: 90] [source_file: test.js]
STRING_KEY func 2:2 [length: 4] [source_file: test.js]
CALL 2:8 [length: 78] [source_file: test.js]
GETPROP bind 4:4 [length: 4] [source_file: test.js]
FUNCTION 2:8 [length: 47] [source_file: test.js]
NAME 2:8 [length: 47] [source_file: test.js]
PARAM_LIST 2:16 [length: 2] [source_file: test.js]
BLOCK 2:19 [length: 36] [source_file: test.js]
EXPR_RESULT 3:4 [length: 26] [source_file: test.js]
CALL 3:4 [length: 25] [free_call: 1] [source_file: test.js]
NAME eval 3:4 [length: 4] [direct_eval: 1] [source_file: test.js]
STRINGLIT this.style.height 3:9 [length: 19] [source_file: test.js]
GETPROP documentElement 4:18 [length: 15] [source_file: test.js]
NAME document 4:9 [length: 8] [is_constant_name: 1] [source_file: test.js]
Can sort of fix by changing
protected String instrumentSource(String sourceURI, String source) {
SourceFile sourceFile = SourceFile.fromCode(sourceURI, source);
ParserRunner.ParseResult parsed = parse(source, sourceFile);
Node jsRoot = parsed.ast;
commentsHandler.processComments(parsed.comments);
...to...
protected String instrumentSource(String sourceURI, String source) {
SourceFile sourceFile = SourceFile.fromCode(sourceURI, source);
ErrorManager errorManager = new BlackHoleErrorManager();
com.google.javascript.jscomp.Compiler compiler = new com.google.javascript.jscomp.Compiler(errorManager);
Node jsRoot = compiler.parse(sourceFile);
// commentsHandler.processComments(parsed.comments);
...but then I can't process the comments. I'm not sure how the compiler/parser is altered by this yet.
What I've seen debugging and searching in closure-compiler is that PrepareAst
is never used by JSCover whereas it is by using Compiler
.
PrepareAst
is responsible for detecting if a call to eval is indirect or not in order to be changed to (0,eval)
or not in CodeGenerator
. As in you can see in your AST, it is responsible of the direct_eval: 1
causing eval
not being replaced.
That's why your change make it work.
Yep - I noticed that too. Have you seen a way to turn that off using the ParserRunner?
I haven't searched more since I have to focus on another topic. I'll put some effort on that until next week and give you a status.
Maybe the solution is to use Compiler
and get comments differently ? What is the reason comments are treated differently in JSCover ?
@tntim96 I've successfully solved the problem using Compiler
. The harder part was to find the good options to keep the same behavior as before and get the comments. All test suite passes !
Please, review this pull request : #306
Looks good except for a few things:
I've fixed most of the above, but would like to merge your fix so you get the credit for your changes. I'll see if I can merge your commits to a branch, tidy up, then merge to the main branch.
Done - thanks @stephdz !
e.g. I have this code snippet:
If I instrument it with the latest JSCover version, I get this:
Unfortunately this.style.height triggers the script error "Cannot read property 'height' of undefined"