closure-compiler
closure-compiler copied to clipboard
IllegalStateException upon assigning a created object to a class prototype
This is very easy to reproduce:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// ==/ClosureCompiler==
class TestClass {};
TestClass.prototype = Object.create({});
Results in a breaking exception upon closure compiler run:
23: java.lang.IllegalStateException
at com.google.common.base.Preconditions.checkState(Preconditions.java:528)
at com.google.javascript.rhino.jstype.PrototypeObjectType.setImplicitPrototype(PrototypeObjectType.java:374)
at com.google.javascript.rhino.jstype.FunctionType.setPrototypeBasedOn(FunctionType.java:487)
at com.google.javascript.rhino.jstype.FunctionType.defineProperty(FunctionType.java:766)
at com.google.javascript.rhino.jstype.ObjectType.defineDeclaredProperty(ObjectType.java:345)
at com.google.javascript.jscomp.TypeInference.ensurePropertyDefined(TypeInference.java:1368)
at com.google.javascript.jscomp.TypeInference.updateScopeForAssignment(TypeInference.java:1305)
at com.google.javascript.jscomp.TypeInference.updateScopeForAssignment(TypeInference.java:1173)
at com.google.javascript.jscomp.TypeInference.traverseAssign(TypeInference.java:1113)
at com.google.javascript.jscomp.TypeInference.traverse(TypeInference.java:549)
at com.google.javascript.jscomp.TypeInference.traverseChildren(TypeInference.java:2395)
at com.google.javascript.jscomp.TypeInference.traverse(TypeInference.java:722)
at com.google.javascript.jscomp.TypeInference.flowThrough(TypeInference.java:386)
at com.google.javascript.jscomp.TypeInference.flowThrough(TypeInference.java:81)
at com.google.javascript.jscomp.DataFlowAnalysis.flow(DataFlowAnalysis.java:285)
at com.google.javascript.jscomp.DataFlowAnalysis.analyze(DataFlowAnalysis.java:224)
at com.google.javascript.jscomp.TypeInferencePass.inferScope(TypeInferencePass.java:157)
at com.google.javascript.jscomp.TypeInferencePass$SecondScopeBuildingCallback.enterScope(TypeInferencePass.java:195)
at com.google.javascript.jscomp.NodeTraversal.pushScope(NodeTraversal.java:1175)
at com.google.javascript.jscomp.NodeTraversal.pushScope(NodeTraversal.java:1163)
at com.google.javascript.jscomp.NodeTraversal.traverseWithScope(NodeTraversal.java:595)
at com.google.javascript.jscomp.NodeTraversal$Builder.traverseWithScope(NodeTraversal.java:484)
at com.google.javascript.jscomp.TypeInferencePass.inferAllScopes(TypeInferencePass.java:114)
at com.google.javascript.jscomp.DefaultPassConfig.lambda$new$33(DefaultPassConfig.java:1868)
at com.google.javascript.jscomp.PhaseOptimizer$NamedPass.process(PhaseOptimizer.java:240)
at com.google.javascript.jscomp.PhaseOptimizer.process(PhaseOptimizer.java:179)
at com.google.javascript.jscomp.Compiler.check(Compiler.java:1339)
at com.google.javascript.jscomp.Compiler.performChecks(Compiler.java:1127)
at com.google.javascript.jscomp.Compiler.lambda$stage1Passes$0(Compiler.java:1036)
at com.google.javascript.jscomp.CompilerExecutor.runInCompilerThread(CompilerExecutor.java:126)
at com.google.javascript.jscomp.Compiler.runInCompilerThread(Compiler.java:1115)
at com.google.javascript.jscomp.Compiler.stage1Passes(Compiler.java:1034)
at com.google.javascript.jscomp.Compiler.compile(Compiler.java:948)
at com.google.javascript.jscomp.webservice.backend.CompilerInvokerImpl.compile(CompilerInvokerImpl.java:43)
at com.google.javascript.jscomp.webservice.backend.ServerController.executeRequest(ServerController.java:179)
at com.google.javascript.jscomp.webservice.backend.CompilationRequestHandler.serviceParsedRequest(CompilationRequestHandler.java:177)
at com.google.javascript.jscomp.webservice.backend.CompilationRequestHandler.service(CompilationRequestHandler.java:159)
at com.google.javascript.jscomp.webservice.frontend.CompilationServlet.doPost(CompilationServlet.java:79)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:526)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:593)
at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1459)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799)
at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:78)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at com.google.corp.cloud.carafe.StaticFileFilter.doFilter(StaticFileFilter.java:67)
at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:201)
at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:571)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at com.google.apphosting.runtime.jetty9.ParseBlobUploadHandler.handle(ParseBlobUploadHandler.java:125)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440)
at com.google.apphosting.runtime.jetty9.AppEngineWebAppContext.doHandle(AppEngineWebAppContext.java:289)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at com.google.appengine.runtime.lite.RequestHandler.handle(RequestHandler.java:228)
at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:772)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
at org.eclipse.jetty.server.Server.handle(Server.java:516)
at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:487)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
at java.base/java.lang.Thread.run(Thread.java:1656)
I reproduced it on Closure compiler service. It only happens on ADVANCED_OPTIMIZATIONS. I tried it with 20240317.0.0 and 20230206.0.0 and neither work.
Thanks for reporting this.
I can reproduce this at head. As far as I can tell, it only happens when assigning to the prototype of a class, which doesn't actually work (the class keyword makes functions whose 'prototype' property descriptor is neither writable nor configurable). Probably the best resolution is to turn it into a real error, rather than a crash.