From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- devtools/client/debugger/.remarkignore | 2 + devtools/client/debugger/.remarkrc | 17 + devtools/client/debugger/babel.config.js | 90 + devtools/client/debugger/bin/bundle.js | 125 + devtools/client/debugger/bin/module-manifest.json | 2565 + devtools/client/debugger/bin/watch.js | 31 + .../debugger/configs/mozilla-central-mappings.js | 19 + devtools/client/debugger/dist/moz.build | 11 + devtools/client/debugger/dist/parser-worker.js | 73552 ++++++++++++++++ .../client/debugger/dist/pretty-print-worker.js | 10534 +++ devtools/client/debugger/dist/search-worker.js | 397 + devtools/client/debugger/dist/vendors.css | 20 + devtools/client/debugger/dist/vendors.js | 2496 + devtools/client/debugger/images/arrow-down.svg | 6 + devtools/client/debugger/images/arrow-up.svg | 6 + devtools/client/debugger/images/arrow.svg | 6 + devtools/client/debugger/images/blackBox.svg | 9 + .../client/debugger/images/breadcrumbs-divider.svg | 18 + devtools/client/debugger/images/breakpoint.svg | 6 + devtools/client/debugger/images/case-match.svg | 6 + devtools/client/debugger/images/column-marker.svg | 6 + .../client/debugger/images/command-chevron.svg | 6 + .../client/debugger/images/disable-pausing.svg | 15 + devtools/client/debugger/images/enable-pausing.svg | 15 + devtools/client/debugger/images/file-small.svg | 6 + devtools/client/debugger/images/folder.svg | 6 + devtools/client/debugger/images/globe-small.svg | 7 + devtools/client/debugger/images/globe.svg | 9 + devtools/client/debugger/images/help.svg | 7 + devtools/client/debugger/images/home.svg | 6 + devtools/client/debugger/images/loader.svg | 7 + .../client/debugger/images/markup-breakpoint.svg | 7 + devtools/client/debugger/images/next-circle.svg | 9 + devtools/client/debugger/images/next.svg | 8 + devtools/client/debugger/images/pane-collapse.svg | 7 + devtools/client/debugger/images/pane-expand.svg | 7 + devtools/client/debugger/images/pause.svg | 8 + devtools/client/debugger/images/plus.svg | 6 + devtools/client/debugger/images/prettyPrint.svg | 6 + devtools/client/debugger/images/regex-match.svg | 9 + devtools/client/debugger/images/reload.svg | 7 + devtools/client/debugger/images/search.svg | 6 + devtools/client/debugger/images/sources/aframe.svg | 6 + .../client/debugger/images/sources/angular.svg | 8 + devtools/client/debugger/images/sources/babel.svg | 6 + .../client/debugger/images/sources/backbone.svg | 6 + devtools/client/debugger/images/sources/choo.svg | 14 + .../debugger/images/sources/coffeescript.svg | 6 + devtools/client/debugger/images/sources/dojo.svg | 4 + devtools/client/debugger/images/sources/ember.svg | 4 + .../client/debugger/images/sources/express.svg | 7 + .../client/debugger/images/sources/extension.svg | 6 + .../client/debugger/images/sources/immutable.svg | 6 + .../client/debugger/images/sources/javascript.svg | 6 + devtools/client/debugger/images/sources/jquery.svg | 6 + devtools/client/debugger/images/sources/lodash.svg | 7 + devtools/client/debugger/images/sources/marko.svg | 64 + devtools/client/debugger/images/sources/mobx.svg | 7 + devtools/client/debugger/images/sources/nextjs.svg | 17 + devtools/client/debugger/images/sources/node.svg | 6 + devtools/client/debugger/images/sources/nuxtjs.svg | 4 + devtools/client/debugger/images/sources/preact.svg | 11 + devtools/client/debugger/images/sources/pug.svg | 118 + devtools/client/debugger/images/sources/react.svg | 6 + devtools/client/debugger/images/sources/redux.svg | 6 + devtools/client/debugger/images/sources/rxjs.svg | 33 + .../debugger/images/sources/sencha-extjs.svg | 13 + .../client/debugger/images/sources/typescript.svg | 6 + .../client/debugger/images/sources/underscore.svg | 8 + devtools/client/debugger/images/sources/vuejs.svg | 7 + .../client/debugger/images/sources/webpack.svg | 8 + devtools/client/debugger/images/stepIn.svg | 8 + devtools/client/debugger/images/stepOut.svg | 8 + devtools/client/debugger/images/tab.svg | 6 + devtools/client/debugger/images/trace.svg | 6 + .../client/debugger/images/webconsole-logpoint.svg | 6 + .../client/debugger/images/whole-word-match.svg | 13 + devtools/client/debugger/images/window.svg | 6 + devtools/client/debugger/images/worker.svg | 7 + devtools/client/debugger/index.html | 73 + devtools/client/debugger/jest-test.config.js | 50 + devtools/client/debugger/jest.config.js | 15 + devtools/client/debugger/moz.build | 24 + devtools/client/debugger/package.json | 101 + devtools/client/debugger/panel.js | 348 + devtools/client/debugger/src/.eslintignore | 5 + devtools/client/debugger/src/.eslintrc.js | 372 + devtools/client/debugger/src/actions/README.md | 26 + devtools/client/debugger/src/actions/ast/index.js | 5 + devtools/client/debugger/src/actions/ast/moz.build | 11 + .../debugger/src/actions/ast/setInScopeLines.js | 94 + .../__snapshots__/setInScopeLines.spec.js.snap | 16 + .../src/actions/ast/tests/setInScopeLines.spec.js | 79 + .../src/actions/breakpoints/breakpointPositions.js | 273 + .../debugger/src/actions/breakpoints/index.js | 426 + .../debugger/src/actions/breakpoints/modify.js | 382 + .../debugger/src/actions/breakpoints/moz.build | 13 + .../src/actions/breakpoints/syncBreakpoint.js | 138 + .../tests/__snapshots__/breakpoints.spec.js.snap | 173 + .../actions/breakpoints/tests/breakpoints.spec.js | 521 + .../client/debugger/src/actions/event-listeners.js | 77 + devtools/client/debugger/src/actions/exceptions.js | 30 + .../client/debugger/src/actions/expressions.js | 195 + .../client/debugger/src/actions/file-search.js | 48 + devtools/client/debugger/src/actions/index.js | 48 + devtools/client/debugger/src/actions/moz.build | 31 + devtools/client/debugger/src/actions/navigation.js | 61 + .../debugger/src/actions/pause/breakOnNext.js | 18 + .../client/debugger/src/actions/pause/commands.js | 157 + .../debugger/src/actions/pause/continueToHere.js | 62 + .../debugger/src/actions/pause/expandScopes.js | 17 + .../debugger/src/actions/pause/fetchFrames.js | 23 + .../debugger/src/actions/pause/fetchScopes.js | 30 + .../debugger/src/actions/pause/highlightCalls.js | 89 + .../client/debugger/src/actions/pause/index.js | 33 + .../debugger/src/actions/pause/inlinePreview.js | 244 + .../debugger/src/actions/pause/mapDisplayNames.js | 49 + .../client/debugger/src/actions/pause/mapFrames.js | 157 + .../client/debugger/src/actions/pause/mapScopes.js | 194 + .../client/debugger/src/actions/pause/moz.build | 27 + .../src/actions/pause/pauseOnExceptions.js | 34 + .../client/debugger/src/actions/pause/paused.js | 73 + .../src/actions/pause/resetBreakpointsPaneState.js | 18 + .../client/debugger/src/actions/pause/resumed.js | 28 + .../debugger/src/actions/pause/selectFrame.js | 39 + .../debugger/src/actions/pause/skipPausing.js | 33 + .../__snapshots__/pauseOnExceptions.spec.js.snap | 10 + .../debugger/src/actions/pause/tests/pause.spec.js | 413 + .../actions/pause/tests/pauseOnExceptions.spec.js | 24 + .../src/actions/pause/tests/skipPausing.spec.js | 18 + devtools/client/debugger/src/actions/preview.js | 211 + .../debugger/src/actions/project-text-search.js | 171 + devtools/client/debugger/src/actions/quick-open.js | 21 + .../client/debugger/src/actions/source-actors.js | 12 + .../client/debugger/src/actions/sources-tree.js | 11 + .../debugger/src/actions/sources/blackbox.js | 223 + .../debugger/src/actions/sources/breakableLines.js | 73 + .../client/debugger/src/actions/sources/index.js | 42 + .../debugger/src/actions/sources/loadSourceText.js | 256 + .../client/debugger/src/actions/sources/moz.build | 17 + .../debugger/src/actions/sources/newSources.js | 367 + .../debugger/src/actions/sources/prettyPrint.js | 339 + .../client/debugger/src/actions/sources/select.js | 264 + .../client/debugger/src/actions/sources/symbols.js | 44 + .../src/actions/sources/tests/blackbox.spec.js | 249 + .../src/actions/sources/tests/loadSource.spec.js | 363 + .../src/actions/sources/tests/newSources.spec.js | 172 + .../src/actions/sources/tests/select.spec.js | 288 + devtools/client/debugger/src/actions/tabs.js | 76 + .../tests/__snapshots__/expressions.spec.js.snap | 11 + .../__snapshots__/pending-breakpoints.spec.js.snap | 44 + .../tests/__snapshots__/preview.spec.js.snap | 3 + .../debugger/src/actions/tests/expressions.spec.js | 184 + .../src/actions/tests/fixtures/immutable.js | 2 + .../src/actions/tests/fixtures/reactComponent.js | 7 + .../actions/tests/fixtures/reactFuncComponent.js | 5 + .../debugger/src/actions/tests/fixtures/scopes.js | 11 + .../src/actions/tests/helpers/breakpoints.js | 77 + .../src/actions/tests/helpers/mockCommandClient.js | 49 + .../src/actions/tests/helpers/readFixture.js | 14 + .../debugger/src/actions/tests/navigation.spec.js | 29 + .../src/actions/tests/pending-breakpoints.spec.js | 294 + .../debugger/src/actions/tests/preview.spec.js | 217 + .../src/actions/tests/sources-tree.spec.js | 17 + .../client/debugger/src/actions/tests/tabs.spec.js | 187 + .../client/debugger/src/actions/tests/ui.spec.js | 90 + devtools/client/debugger/src/actions/threads.js | 44 + devtools/client/debugger/src/actions/toolbox.js | 43 + devtools/client/debugger/src/actions/tracing.js | 49 + devtools/client/debugger/src/actions/ui.js | 290 + .../debugger/src/actions/utils/create-store.js | 72 + .../src/actions/utils/middleware/context.js | 33 + .../debugger/src/actions/utils/middleware/log.js | 111 + .../src/actions/utils/middleware/moz.build | 15 + .../src/actions/utils/middleware/promise.js | 61 + .../debugger/src/actions/utils/middleware/thunk.js | 22 + .../src/actions/utils/middleware/timing.js | 26 + .../src/actions/utils/middleware/wait-service.js | 62 + .../client/debugger/src/actions/utils/moz.build | 12 + devtools/client/debugger/src/client/README.md | 47 + devtools/client/debugger/src/client/firefox.js | 215 + .../client/debugger/src/client/firefox/commands.js | 537 + .../client/debugger/src/client/firefox/create.js | 392 + .../client/debugger/src/client/firefox/moz.build | 11 + devtools/client/debugger/src/client/moz.build | 12 + .../debugger/src/components/A11yIntention.css | 7 + .../debugger/src/components/A11yIntention.js | 37 + devtools/client/debugger/src/components/App.css | 130 + devtools/client/debugger/src/components/App.js | 336 + .../src/components/Editor/BlackboxLines.js | 138 + .../debugger/src/components/Editor/Breakpoint.js | 183 + .../debugger/src/components/Editor/Breakpoints.css | 153 + .../debugger/src/components/Editor/Breakpoints.js | 96 + .../src/components/Editor/ColumnBreakpoint.js | 140 + .../src/components/Editor/ColumnBreakpoints.js | 75 + .../src/components/Editor/ConditionalPanel.css | 39 + .../src/components/Editor/ConditionalPanel.js | 274 + .../debugger/src/components/Editor/DebugLine.js | 138 + .../debugger/src/components/Editor/Editor.css | 220 + .../debugger/src/components/Editor/EditorMenu.js | 111 + .../debugger/src/components/Editor/EmptyLines.js | 88 + .../debugger/src/components/Editor/Exception.js | 96 + .../debugger/src/components/Editor/Exceptions.js | 67 + .../debugger/src/components/Editor/Footer.css | 85 + .../debugger/src/components/Editor/Footer.js | 302 + .../src/components/Editor/HighlightCalls.css | 15 + .../src/components/Editor/HighlightCalls.js | 110 + .../src/components/Editor/HighlightLine.js | 183 + .../src/components/Editor/HighlightLines.js | 74 + .../src/components/Editor/InlinePreview.css | 29 + .../src/components/Editor/InlinePreview.js | 66 + .../src/components/Editor/InlinePreviewRow.js | 101 + .../src/components/Editor/InlinePreviews.js | 83 + .../debugger/src/components/Editor/Preview.css | 111 + .../components/Editor/Preview/ExceptionPopup.js | 164 + .../src/components/Editor/Preview/Popup.css | 209 + .../src/components/Editor/Preview/Popup.js | 382 + .../src/components/Editor/Preview/index.js | 136 + .../src/components/Editor/Preview/moz.build | 12 + .../components/Editor/Preview/tests/Popup.spec.js | 107 + .../src/components/Editor/SearchInFileBar.css | 39 + .../src/components/Editor/SearchInFileBar.js | 371 + .../client/debugger/src/components/Editor/Tab.js | 282 + .../client/debugger/src/components/Editor/Tabs.css | 125 + .../client/debugger/src/components/Editor/Tabs.js | 332 + .../client/debugger/src/components/Editor/index.js | 808 + .../src/components/Editor/menus/breakpoints.js | 293 + .../debugger/src/components/Editor/menus/editor.js | 403 + .../debugger/src/components/Editor/menus/moz.build | 12 + .../debugger/src/components/Editor/menus/source.js | 3 + .../debugger/src/components/Editor/moz.build | 34 + .../components/Editor/tests/Breakpoints.spec.js | 54 + .../Editor/tests/ConditionalPanel.spec.js | 77 + .../src/components/Editor/tests/DebugLine.spec.js | 85 + .../src/components/Editor/tests/Footer.spec.js | 67 + .../tests/__snapshots__/Breakpoints.spec.js.snap | 35 + .../__snapshots__/ConditionalPanel.spec.js.snap | 630 + .../Editor/tests/__snapshots__/Footer.spec.js.snap | 105 + .../src/components/PrimaryPanes/Outline.css | 205 + .../src/components/PrimaryPanes/Outline.js | 372 + .../src/components/PrimaryPanes/OutlineFilter.css | 30 + .../src/components/PrimaryPanes/OutlineFilter.js | 63 + .../src/components/PrimaryPanes/ProjectSearch.css | 165 + .../src/components/PrimaryPanes/ProjectSearch.js | 327 + .../src/components/PrimaryPanes/Sources.css | 219 + .../src/components/PrimaryPanes/SourcesTree.js | 510 + .../src/components/PrimaryPanes/SourcesTreeItem.js | 457 + .../debugger/src/components/PrimaryPanes/index.js | 132 + .../debugger/src/components/PrimaryPanes/moz.build | 15 + .../PrimaryPanes/tests/ProjectSearch.spec.js | 326 + .../tests/__snapshots__/ProjectSearch.spec.js.snap | 1111 + .../debugger/src/components/QuickOpenModal.css | 28 + .../debugger/src/components/QuickOpenModal.js | 524 + .../SecondaryPanes/Breakpoints/Breakpoint.js | 219 + .../Breakpoints/BreakpointHeading.js | 88 + .../Breakpoints/BreakpointHeadingsContextMenu.js | 77 + .../SecondaryPanes/Breakpoints/Breakpoints.css | 249 + .../Breakpoints/BreakpointsContextMenu.js | 365 + .../SecondaryPanes/Breakpoints/ExceptionOption.js | 31 + .../components/SecondaryPanes/Breakpoints/index.js | 152 + .../SecondaryPanes/Breakpoints/moz.build | 15 + .../Breakpoints/tests/Breakpoint.spec.js | 104 + .../tests/BreakpointsContextMenu.spec.js | 134 + .../Breakpoints/tests/ExceptionOption.spec.js | 22 + .../tests/__snapshots__/Breakpoint.spec.js.snap | 231 + .../__snapshots__/ExceptionOption.spec.js.snap | 19 + .../src/components/SecondaryPanes/CommandBar.css | 33 + .../src/components/SecondaryPanes/CommandBar.js | 433 + .../SecondaryPanes/DOMMutationBreakpoints.css | 76 + .../SecondaryPanes/DOMMutationBreakpoints.js | 175 + .../components/SecondaryPanes/EventListeners.css | 154 + .../components/SecondaryPanes/EventListeners.js | 295 + .../src/components/SecondaryPanes/Expressions.css | 175 + .../src/components/SecondaryPanes/Expressions.js | 395 + .../src/components/SecondaryPanes/Frames/Frame.js | 197 + .../SecondaryPanes/Frames/FrameIndent.js | 13 + .../components/SecondaryPanes/Frames/FrameMenu.js | 105 + .../components/SecondaryPanes/Frames/Frames.css | 185 + .../src/components/SecondaryPanes/Frames/Group.css | 38 + .../src/components/SecondaryPanes/Frames/Group.js | 197 + .../src/components/SecondaryPanes/Frames/index.js | 231 + .../src/components/SecondaryPanes/Frames/moz.build | 14 + .../SecondaryPanes/Frames/tests/Frame.spec.js | 155 + .../SecondaryPanes/Frames/tests/FrameMenu.spec.js | 117 + .../SecondaryPanes/Frames/tests/Frames.spec.js | 295 + .../SecondaryPanes/Frames/tests/Group.spec.js | 134 + .../Frames/tests/__snapshots__/Frame.spec.js.snap | 1196 + .../Frames/tests/__snapshots__/Frames.spec.js.snap | 1651 + .../Frames/tests/__snapshots__/Group.spec.js.snap | 2440 + .../src/components/SecondaryPanes/Scopes.css | 104 + .../src/components/SecondaryPanes/Scopes.js | 311 + .../components/SecondaryPanes/SecondaryPanes.css | 86 + .../src/components/SecondaryPanes/Thread.js | 70 + .../src/components/SecondaryPanes/Threads.css | 63 + .../src/components/SecondaryPanes/Threads.js | 38 + .../src/components/SecondaryPanes/WhyPaused.css | 58 + .../src/components/SecondaryPanes/WhyPaused.js | 183 + .../components/SecondaryPanes/XHRBreakpoints.css | 131 + .../components/SecondaryPanes/XHRBreakpoints.js | 361 + .../src/components/SecondaryPanes/index.js | 537 + .../src/components/SecondaryPanes/moz.build | 22 + .../SecondaryPanes/tests/CommandBar.spec.js | 77 + .../SecondaryPanes/tests/EventListeners.spec.js | 134 + .../SecondaryPanes/tests/Expressions.spec.js | 75 + .../SecondaryPanes/tests/XHRBreakpoints.spec.js | 345 + .../__snapshots__/EventListeners.spec.js.snap | 408 + .../tests/__snapshots__/Expressions.spec.js.snap | 199 + .../__snapshots__/XHRBreakpoints.spec.js.snap | 621 + .../debugger/src/components/ShortcutsModal.css | 47 + .../debugger/src/components/ShortcutsModal.js | 135 + .../client/debugger/src/components/WelcomeBox.css | 83 + .../client/debugger/src/components/WelcomeBox.js | 94 + devtools/client/debugger/src/components/moz.build | 19 + .../src/components/shared/AccessibleImage.css | 194 + .../src/components/shared/AccessibleImage.js | 24 + .../debugger/src/components/shared/Accordion.css | 73 + .../debugger/src/components/shared/Accordion.js | 74 + .../debugger/src/components/shared/Badge.css | 16 + .../client/debugger/src/components/shared/Badge.js | 17 + .../src/components/shared/BracketArrow.css | 64 + .../debugger/src/components/shared/BracketArrow.js | 28 + .../src/components/shared/Button/CloseButton.js | 30 + .../components/shared/Button/CommandBarButton.js | 56 + .../components/shared/Button/PaneToggleButton.js | 61 + .../debugger/src/components/shared/Button/index.js | 9 + .../src/components/shared/Button/moz.build | 15 + .../shared/Button/styles/CloseButton.css | 36 + .../shared/Button/styles/CommandBarButton.css | 61 + .../shared/Button/styles/PaneToggleButton.css | 29 + .../src/components/shared/Button/styles/moz.build | 8 + .../shared/Button/tests/CloseButton.spec.js | 24 + .../shared/Button/tests/CommandBarButton.spec.js | 36 + .../shared/Button/tests/PaneToggleButton.spec.js | 51 + .../tests/__snapshots__/CloseButton.spec.js.snap | 13 + .../__snapshots__/CommandBarButton.spec.js.snap | 18 + .../__snapshots__/PaneToggleButton.spec.js.snap | 13 + .../debugger/src/components/shared/Dropdown.css | 96 + .../debugger/src/components/shared/Dropdown.js | 71 + .../debugger/src/components/shared/Modal.css | 51 + .../client/debugger/src/components/shared/Modal.js | 73 + .../debugger/src/components/shared/Popover.css | 32 + .../debugger/src/components/shared/Popover.js | 299 + .../src/components/shared/PreviewFunction.css | 23 + .../src/components/shared/PreviewFunction.js | 82 + .../debugger/src/components/shared/ResultList.css | 131 + .../debugger/src/components/shared/ResultList.js | 82 + .../debugger/src/components/shared/SearchInput.css | 225 + .../debugger/src/components/shared/SearchInput.js | 339 + .../debugger/src/components/shared/SmartGap.js | 166 + .../debugger/src/components/shared/SourceIcon.css | 176 + .../debugger/src/components/shared/SourceIcon.js | 69 + .../client/debugger/src/components/shared/menu.css | 55 + .../debugger/src/components/shared/moz.build | 23 + .../src/components/shared/tests/Accordion.spec.js | 40 + .../src/components/shared/tests/Badge.spec.js | 12 + .../components/shared/tests/BracketArrow.spec.js | 19 + .../src/components/shared/tests/Dropdown.spec.js | 16 + .../src/components/shared/tests/Modal.spec.js | 50 + .../src/components/shared/tests/Popover.spec.js | 200 + .../shared/tests/PreviewFunction.spec.js | 127 + .../src/components/shared/tests/ResultList.spec.js | 49 + .../components/shared/tests/SearchInput.spec.js | 126 + .../tests/__snapshots__/Accordion.spec.js.snap | 84 + .../shared/tests/__snapshots__/Badge.spec.js.snap | 9 + .../tests/__snapshots__/BracketArrow.spec.js.snap | 27 + .../tests/__snapshots__/Dropdown.spec.js.snap | 34 + .../shared/tests/__snapshots__/Modal.spec.js.snap | 13 + .../tests/__snapshots__/Popover.spec.js.snap | 549 + .../__snapshots__/PreviewFunction.spec.js.snap | 23 + .../tests/__snapshots__/ResultList.spec.js.snap | 55 + .../tests/__snapshots__/SearchInput.spec.js.snap | 267 + .../src/components/test/A11yIntention.spec.js | 33 + .../debugger/src/components/test/Outline.spec.js | 304 + .../src/components/test/OutlineFilter.spec.js | 45 + .../src/components/test/QuickOpenModal.spec.js | 898 + .../src/components/test/ShortcutsModal.spec.js | 32 + .../src/components/test/WelcomeBox.spec.js | 59 + .../debugger/src/components/test/WhyPaused.spec.js | 59 + .../test/__snapshots__/A11yIntention.spec.js.snap | 13 + .../test/__snapshots__/Outline.spec.js.snap | 505 + .../test/__snapshots__/OutlineFilter.spec.js.snap | 39 + .../test/__snapshots__/QuickOpenModal.spec.js.snap | 1694 + .../test/__snapshots__/ShortcutsModal.spec.js.snap | 190 + .../test/__snapshots__/WelcomeBox.spec.js.snap | 67 + .../test/__snapshots__/WhyPaused.spec.js.snap | 103 + .../client/debugger/src/components/variables.css | 45 + devtools/client/debugger/src/constants.js | 15 + devtools/client/debugger/src/context-menu/menu.js | 43 + .../client/debugger/src/context-menu/moz.build | 8 + devtools/client/debugger/src/debugger.css | 59 + devtools/client/debugger/src/main.js | 137 + devtools/client/debugger/src/moz.build | 21 + devtools/client/debugger/src/reducers/ast.js | 92 + .../client/debugger/src/reducers/breakpoints.js | 149 + .../debugger/src/reducers/event-listeners.js | 38 + .../client/debugger/src/reducers/exceptions.js | 78 + .../client/debugger/src/reducers/expressions.js | 133 + devtools/client/debugger/src/reducers/index.js | 84 + devtools/client/debugger/src/reducers/moz.build | 28 + devtools/client/debugger/src/reducers/pause.js | 409 + .../debugger/src/reducers/pending-breakpoints.js | 135 + devtools/client/debugger/src/reducers/preview.js | 30 + .../debugger/src/reducers/project-text-search.js | 82 + .../client/debugger/src/reducers/quick-open.js | 41 + .../client/debugger/src/reducers/source-actors.js | 90 + .../debugger/src/reducers/source-blackbox.js | 147 + .../debugger/src/reducers/sources-content.js | 139 + .../client/debugger/src/reducers/sources-tree.js | 585 + devtools/client/debugger/src/reducers/sources.js | 361 + devtools/client/debugger/src/reducers/tabs.js | 208 + .../src/reducers/tests/breakpoints.spec.js | 74 + .../debugger/src/reducers/tests/quick-open.spec.js | 59 + .../client/debugger/src/reducers/tests/ui.spec.js | 30 + devtools/client/debugger/src/reducers/threads.js | 69 + devtools/client/debugger/src/reducers/ui.js | 197 + devtools/client/debugger/src/selectors/ast.js | 32 + .../debugger/src/selectors/breakpointAtLocation.js | 121 + .../debugger/src/selectors/breakpointSources.js | 52 + .../client/debugger/src/selectors/breakpoints.js | 86 + .../debugger/src/selectors/event-listeners.js | 19 + .../client/debugger/src/selectors/exceptions.js | 58 + .../client/debugger/src/selectors/expressions.js | 34 + .../debugger/src/selectors/getCallStackFrames.js | 53 + devtools/client/debugger/src/selectors/index.js | 51 + .../client/debugger/src/selectors/isLineInScope.js | 22 + .../src/selectors/isSelectedFrameVisible.js | 40 + devtools/client/debugger/src/selectors/moz.build | 35 + devtools/client/debugger/src/selectors/pause.js | 267 + .../debugger/src/selectors/pending-breakpoints.js | 20 + devtools/client/debugger/src/selectors/preview.js | 11 + .../debugger/src/selectors/project-text-search.js | 19 + .../client/debugger/src/selectors/quick-open.js | 15 + .../client/debugger/src/selectors/source-actors.js | 111 + .../debugger/src/selectors/source-blackbox.js | 26 + .../debugger/src/selectors/sources-content.js | 48 + .../client/debugger/src/selectors/sources-tree.js | 151 + devtools/client/debugger/src/selectors/sources.js | 358 + devtools/client/debugger/src/selectors/tabs.js | 90 + .../visibleColumnBreakpoints.spec.js.snap | 165 + .../src/selectors/test/getCallStackFrames.spec.js | 166 + .../test/visibleColumnBreakpoints.spec.js | 145 + devtools/client/debugger/src/selectors/threads.js | 56 + devtools/client/debugger/src/selectors/ui.js | 85 + .../debugger/src/selectors/visibleBreakpoints.js | 55 + .../src/selectors/visibleColumnBreakpoints.js | 185 + .../src/test/__mocks__/request-animation-frame.js | 8 + .../client/debugger/src/test/fixtures/README.md | 3 + .../client/debugger/src/test/fixtures/foobar.json | 56 + .../client/debugger/src/test/fixtures/index.js | 3 + devtools/client/debugger/src/test/shim.js | 31 + devtools/client/debugger/src/test/tests-setup.js | 63 + .../client/debugger/src/utils/DevToolsUtils.js | 16 + devtools/client/debugger/src/utils/assert.js | 22 + devtools/client/debugger/src/utils/ast.js | 97 + devtools/client/debugger/src/utils/async-value.js | 27 + devtools/client/debugger/src/utils/bootstrap.js | 135 + .../src/utils/breakpoint/breakpointPositions.js | 20 + .../client/debugger/src/utils/breakpoint/index.js | 72 + .../client/debugger/src/utils/breakpoint/moz.build | 11 + .../src/utils/breakpoint/tests/index.spec.js | 28 + devtools/client/debugger/src/utils/build-query.js | 80 + devtools/client/debugger/src/utils/clipboard.js | 19 + devtools/client/debugger/src/utils/connect.js | 7 + devtools/client/debugger/src/utils/context.js | 63 + devtools/client/debugger/src/utils/dbg.js | 100 + .../debugger/src/utils/editor/create-editor.js | 44 + .../debugger/src/utils/editor/get-expression.js | 54 + .../src/utils/editor/get-token-location.js | 16 + devtools/client/debugger/src/utils/editor/index.js | 230 + .../client/debugger/src/utils/editor/moz.build | 17 + .../debugger/src/utils/editor/source-documents.js | 249 + .../debugger/src/utils/editor/source-editor.css | 271 + .../debugger/src/utils/editor/source-editor.js | 145 + .../debugger/src/utils/editor/source-search.js | 327 + .../tests/__snapshots__/create-editor.spec.js.snap | 60 + .../src/utils/editor/tests/create-editor.spec.js | 25 + .../debugger/src/utils/editor/tests/editor.spec.js | 203 + .../src/utils/editor/tests/get-expression.spec.js | 160 + .../utils/editor/tests/get-token-location.spec.js | 31 + .../utils/editor/tests/source-documents.spec.js | 215 + .../src/utils/editor/tests/source-search.spec.js | 182 + .../debugger/src/utils/editor/token-events.js | 95 + devtools/client/debugger/src/utils/environment.js | 15 + .../client/debugger/src/utils/evaluation-result.js | 19 + devtools/client/debugger/src/utils/expressions.js | 67 + devtools/client/debugger/src/utils/function.js | 37 + devtools/client/debugger/src/utils/indentation.js | 40 + devtools/client/debugger/src/utils/isMinified.js | 58 + devtools/client/debugger/src/utils/location.js | 134 + devtools/client/debugger/src/utils/log.js | 30 + .../client/debugger/src/utils/memoizableAction.js | 75 + devtools/client/debugger/src/utils/memoize.js | 63 + devtools/client/debugger/src/utils/memoizeLast.js | 27 + devtools/client/debugger/src/utils/moz.build | 54 + devtools/client/debugger/src/utils/path.js | 24 + .../src/utils/pause/frames/annotateFrames.js | 73 + .../src/utils/pause/frames/collapseFrames.js | 61 + .../debugger/src/utils/pause/frames/displayName.js | 97 + .../debugger/src/utils/pause/frames/getFrameUrl.js | 7 + .../src/utils/pause/frames/getLibraryFromUrl.js | 144 + .../debugger/src/utils/pause/frames/index.js | 9 + .../debugger/src/utils/pause/frames/moz.build | 15 + .../__snapshots__/collapseFrames.spec.js.snap | 57 + .../pause/frames/tests/annotateFrames.spec.js | 22 + .../pause/frames/tests/collapseFrames.spec.js | 37 + .../utils/pause/frames/tests/displayName.spec.js | 129 + .../pause/frames/tests/getLibraryFromUrl.spec.js | 127 + devtools/client/debugger/src/utils/pause/index.js | 5 + .../debugger/src/utils/pause/mapScopes/README.md | 191 + .../pause/mapScopes/buildGeneratedBindingList.js | 141 + .../src/utils/pause/mapScopes/filtering.js | 45 + .../mapScopes/findGeneratedBindingFromPosition.js | 305 + .../getApplicableBindingsForOriginalPosition.js | 112 + .../debugger/src/utils/pause/mapScopes/index.js | 583 + .../src/utils/pause/mapScopes/locColumn.js | 13 + .../src/utils/pause/mapScopes/mappingContains.js | 12 + .../debugger/src/utils/pause/mapScopes/moz.build | 19 + .../src/utils/pause/mapScopes/optimizedOut.js | 15 + .../src/utils/pause/mapScopes/positionCmp.js | 24 + .../src/utils/pause/mapScopes/rangeMetadata.js | 117 + devtools/client/debugger/src/utils/pause/moz.build | 15 + .../debugger/src/utils/pause/scopes/getScope.js | 101 + .../src/utils/pause/scopes/getVariables.js | 32 + .../debugger/src/utils/pause/scopes/index.js | 48 + .../debugger/src/utils/pause/scopes/moz.build | 13 + .../scopes/tests/getFramePopVariables.spec.js | 114 + .../src/utils/pause/scopes/tests/scopes.spec.js | 134 + .../debugger/src/utils/pause/scopes/utils.js | 55 + devtools/client/debugger/src/utils/pause/why.js | 40 + devtools/client/debugger/src/utils/prefs.js | 153 + devtools/client/debugger/src/utils/preview.js | 7 + devtools/client/debugger/src/utils/quick-open.js | 123 + devtools/client/debugger/src/utils/result-list.js | 26 + .../client/debugger/src/utils/selected-location.js | 16 + .../client/debugger/src/utils/shallow-equal.js | 51 + devtools/client/debugger/src/utils/source-maps.js | 122 + devtools/client/debugger/src/utils/source-queue.js | 37 + devtools/client/debugger/src/utils/source.js | 536 + .../debugger/src/utils/sources-tree/getURL.js | 180 + .../debugger/src/utils/sources-tree/moz.build | 9 + .../src/utils/sources-tree/tests/getUrl.spec.js | 50 + .../debugger/src/utils/sources-tree/utils.js | 44 + devtools/client/debugger/src/utils/tabs.js | 121 + devtools/client/debugger/src/utils/task.js | 44 + devtools/client/debugger/src/utils/telemetry.js | 72 + devtools/client/debugger/src/utils/test-head.js | 289 + devtools/client/debugger/src/utils/test-mockup.js | 270 + .../debugger/src/utils/tests/DevToolsUtils.spec.js | 41 + .../src/utils/tests/__snapshots__/ast.spec.js.snap | 53 + .../tests/__snapshots__/expressions.spec.js.snap | 25 + .../tests/__snapshots__/function.spec.js.snap | 25 + .../tests/__snapshots__/indentation.spec.js.snap | 27 + .../client/debugger/src/utils/tests/assert.spec.js | 30 + .../client/debugger/src/utils/tests/ast.spec.js | 34 + .../debugger/src/utils/tests/build-query.spec.js | 256 + .../debugger/src/utils/tests/clipboard.spec.js | 45 + .../debugger/src/utils/tests/expressions.spec.js | 67 + .../debugger/src/utils/tests/function.spec.js | 61 + .../debugger/src/utils/tests/indentation.spec.js | 61 + .../debugger/src/utils/tests/isMinified.spec.js | 18 + .../debugger/src/utils/tests/location.spec.js | 31 + .../client/debugger/src/utils/tests/log.spec.js | 35 + .../debugger/src/utils/tests/memoize.spec.js | 48 + .../debugger/src/utils/tests/memoizeLast.spec.js | 31 + .../client/debugger/src/utils/tests/path.spec.js | 49 + .../debugger/src/utils/tests/quick-open.spec.js | 35 + .../debugger/src/utils/tests/result-list.spec.js | 32 + .../client/debugger/src/utils/tests/source.spec.js | 367 + .../debugger/src/utils/tests/telemetry.spec.js | 13 + .../client/debugger/src/utils/tests/text.spec.js | 20 + .../client/debugger/src/utils/tests/ui.spec.js | 15 + .../client/debugger/src/utils/tests/url.spec.js | 89 + .../client/debugger/src/utils/tests/utils.spec.js | 87 + .../client/debugger/src/utils/tests/wasm.spec.js | 96 + devtools/client/debugger/src/utils/text.js | 58 + devtools/client/debugger/src/utils/ui.js | 48 + devtools/client/debugger/src/utils/url.js | 75 + devtools/client/debugger/src/utils/utils.js | 59 + devtools/client/debugger/src/utils/wasm.js | 168 + devtools/client/debugger/src/utils/worker.js | 49 + devtools/client/debugger/src/vendors.js | 29 + devtools/client/debugger/src/workers/moz.build | 12 + .../src/workers/parser/findOutOfScopeLocations.js | 132 + .../debugger/src/workers/parser/frameworks.js | 77 + .../debugger/src/workers/parser/getScopes/index.js | 63 + .../src/workers/parser/getScopes/visitor.js | 869 + .../debugger/src/workers/parser/getSymbols.js | 473 + .../client/debugger/src/workers/parser/index.js | 53 + .../src/workers/parser/mapAwaitExpression.js | 199 + .../debugger/src/workers/parser/mapBindings.js | 120 + .../debugger/src/workers/parser/mapExpression.js | 50 + .../src/workers/parser/mapOriginalExpression.js | 106 + .../client/debugger/src/workers/parser/moz.build | 10 + .../client/debugger/src/workers/parser/sources.js | 22 + .../findOutOfScopeLocations.spec.js.snap | 47 + .../tests/__snapshots__/getScopes.spec.js.snap | 18767 ++++ .../tests/__snapshots__/getSymbols.spec.js.snap | 1522 + .../tests/__snapshots__/validate.spec.js.snap | 3 + .../src/workers/parser/tests/contains.spec.js | 250 + .../parser/tests/findOutOfScopeLocations.spec.js | 75 + .../workers/parser/tests/fixtures/allSymbols.js | 33 + .../src/workers/parser/tests/fixtures/async.js | 10 + .../workers/parser/tests/fixtures/call-sites.js | 4 + .../parser/tests/fixtures/callExpressions.js | 7 + .../src/workers/parser/tests/fixtures/calls.js | 21 + .../src/workers/parser/tests/fixtures/class.js | 28 + .../src/workers/parser/tests/fixtures/component.js | 84 + .../parser/tests/fixtures/computed-props.js | 8 + .../workers/parser/tests/fixtures/control-flow.js | 39 + .../workers/parser/tests/fixtures/decorators.js | 2 + .../workers/parser/tests/fixtures/destructuring.js | 16 + .../src/workers/parser/tests/fixtures/es6.js | 1 + .../workers/parser/tests/fixtures/expression.js | 25 + .../src/workers/parser/tests/fixtures/flow.js | 5 + .../fixtures/frameworks/angular1FalsePositive.js | 11 + .../tests/fixtures/frameworks/angular1Module.js | 4 + .../tests/fixtures/frameworks/plainJavascript.js | 8 + .../tests/fixtures/frameworks/reactComponent.js | 3 + .../tests/fixtures/frameworks/reactComponentEs5.js | 3 + .../tests/fixtures/frameworks/reactLibrary.js | 19 + .../tests/fixtures/frameworks/reduxLibrary.js | 39 + .../tests/fixtures/frameworks/vueFileComponent.js | 3 + .../fixtures/frameworks/vueFileDeclarative.js | 6 + .../src/workers/parser/tests/fixtures/func.js | 50 + .../workers/parser/tests/fixtures/functionNames.js | 50 + .../workers/parser/tests/fixtures/generators.js | 4 + .../src/workers/parser/tests/fixtures/jsx.js | 5 + .../src/workers/parser/tests/fixtures/math.js | 15 + .../src/workers/parser/tests/fixtures/modules.js | 10 + .../parser/tests/fixtures/object-expressions.js | 6 + .../parser/tests/fixtures/optional-chaining.js | 3 + .../workers/parser/tests/fixtures/outOfScope.js | 62 + .../parser/tests/fixtures/outOfScopeComment.js | 4 + .../parser/tests/fixtures/parseScriptTags.html | 42 + .../parser/tests/fixtures/private-fields.js | 24 + .../src/workers/parser/tests/fixtures/proto.js | 14 + .../workers/parser/tests/fixtures/resolveToken.js | 40 + .../parser/tests/fixtures/scopes/arrow-function.js | 11 + .../parser/tests/fixtures/scopes/binding-types.js | 24 + .../tests/fixtures/scopes/block-statement.js | 13 + .../tests/fixtures/scopes/class-declaration.js | 14 + .../tests/fixtures/scopes/class-expression.js | 11 + .../parser/tests/fixtures/scopes/class-property.js | 10 + .../tests/fixtures/scopes/complex-nesting.js | 29 + .../parser/tests/fixtures/scopes/expressions.js | 6 + .../tests/fixtures/scopes/flowtype-bindings.js | 11 + .../fixtures/scopes/fn-body-lex-and-nonlex.js | 23 + .../parser/tests/fixtures/scopes/for-loops.js | 13 + .../tests/fixtures/scopes/function-declaration.js | 11 + .../tests/fixtures/scopes/function-expression.js | 7 + .../parser/tests/fixtures/scopes/jsx-component.js | 6 + .../fixtures/scopes/out-of-order-declarations.js | 21 + .../tests/fixtures/scopes/pattern-declarations.js | 2 + .../parser/tests/fixtures/scopes/simple-module.js | 11 + .../tests/fixtures/scopes/switch-statement.js | 22 + .../parser/tests/fixtures/scopes/try-catch.js | 9 + .../parser/tests/fixtures/scopes/ts-sample.ts | 41 + .../parser/tests/fixtures/scopes/tsx-sample.tsx | 41 + .../parser/tests/fixtures/scopes/vue-sample.vue | 26 + .../workers/parser/tests/fixtures/statements.js | 40 + .../parser/tests/fixtures/thisExpression.js | 11 + .../src/workers/parser/tests/fixtures/var.js | 21 + .../src/workers/parser/tests/framework.spec.js | 63 + .../src/workers/parser/tests/getScopes.spec.js | 227 + .../src/workers/parser/tests/getSymbols.spec.js | 49 + .../src/workers/parser/tests/helpers/index.js | 86 + .../src/workers/parser/tests/mapBindings.spec.js | 161 + .../src/workers/parser/tests/mapExpression.spec.js | 785 + .../parser/tests/mapOriginalExpression.spec.js | 93 + .../src/workers/parser/tests/sources.spec.js | 14 + .../src/workers/parser/tests/validate.spec.js | 15 + .../debugger/src/workers/parser/utils/ast.js | 225 + .../debugger/src/workers/parser/utils/contains.js | 29 + .../src/workers/parser/utils/formatSymbols.js | 65 + .../src/workers/parser/utils/getFunctionName.js | 96 + .../debugger/src/workers/parser/utils/helpers.js | 230 + .../src/workers/parser/utils/inferClassName.js | 93 + .../src/workers/parser/utils/simple-path.js | 147 + .../src/workers/parser/utils/tests/ast.spec.js | 41 + .../client/debugger/src/workers/parser/validate.js | 14 + .../client/debugger/src/workers/parser/worker.js | 30 + .../debugger/src/workers/pretty-print/LICENSE.md | 23 + .../debugger/src/workers/pretty-print/index.js | 30 + .../debugger/src/workers/pretty-print/moz.build | 10 + .../src/workers/pretty-print/pretty-fast.js | 1178 + .../tests/__snapshots__/prettyFast.spec.js.snap | 1974 + .../workers/pretty-print/tests/prettyFast.spec.js | 434 + .../debugger/src/workers/pretty-print/worker.js | 98 + .../debugger/src/workers/search/get-matches.js | 45 + .../client/debugger/src/workers/search/index.js | 17 + .../client/debugger/src/workers/search/moz.build | 10 + .../debugger/src/workers/search/project-search.js | 70 + .../src/workers/search/tests/get-matches.spec.js | 99 + .../client/debugger/src/workers/search/worker.js | 9 + .../client/debugger/test/mochitest/browser.ini | 297 + .../test/mochitest/browser_dbg-async-stepping.js | 23 + .../test/mochitest/browser_dbg-asyncstacks.js | 21 + .../test/mochitest/browser_dbg-audiocontext.js | 20 + .../browser_dbg-backgroundtask-debugging.js | 151 + .../debugger/test/mochitest/browser_dbg-bfcache.js | 98 + .../test/mochitest/browser_dbg-blackbox-all.js | 215 + .../mochitest/browser_dbg-blackbox-original.js | 53 + .../test/mochitest/browser_dbg-blackbox.js | 742 + .../mochitest/browser_dbg-breaking-from-console.js | 38 + .../test/mochitest/browser_dbg-breaking.js | 55 + .../browser_dbg-breakpoint-skipping-console.js | 20 + .../mochitest/browser_dbg-breakpoint-skipping.js | 87 + .../mochitest/browser_dbg-breakpoints-actions.js | 84 + .../mochitest/browser_dbg-breakpoints-columns.js | 131 + .../browser_dbg-breakpoints-cond-shortcut.js | 147 + .../browser_dbg-breakpoints-cond-source-maps.js | 45 + .../test/mochitest/browser_dbg-breakpoints-cond.js | 136 + .../browser_dbg-breakpoints-debugger-statement.js | 94 + .../browser_dbg-breakpoints-duplicate-functions.js | 38 + .../browser_dbg-breakpoints-in-evaled-sources.js | 92 + .../test/mochitest/browser_dbg-breakpoints-list.js | 189 + .../mochitest/browser_dbg-breakpoints-popup.js | 250 + ...bg-breakpoints-reloading-with-source-changes.js | 186 + .../mochitest/browser_dbg-breakpoints-reloading.js | 124 + ...browser_dbg-breakpoints-same-file-per-target.js | 114 + .../browser_dbg-breakpoints-scroll-to-log.js | 61 + ...wser_dbg-breakpoints-sourcemap-with-sections.js | 27 + .../test/mochitest/browser_dbg-breakpoints.js | 102 + ...browser_dbg-browser-toolbox-unselected-pause.js | 67 + .../browser_dbg-browser-toolbox-workers.js | 55 + .../test/mochitest/browser_dbg-call-stack.js | 115 + .../test/mochitest/browser_dbg-chrome-create.js | 61 + .../test/mochitest/browser_dbg-command-click.js | 39 + .../test/mochitest/browser_dbg-console-async.js | 50 + .../test/mochitest/browser_dbg-console-eval.js | 37 + .../test/mochitest/browser_dbg-console-link.js | 29 + .../mochitest/browser_dbg-console-map-bindings.js | 47 + .../debugger/test/mochitest/browser_dbg-console.js | 28 + .../browser_dbg-content-script-sources.js | 52 + .../browser_dbg-continue-to-here-click.js | 48 + .../test/mochitest/browser_dbg-continue-to-here.js | 58 + .../mochitest/browser_dbg-custom-formatters.js | 158 + .../test/mochitest/browser_dbg-debug-line.js | 46 + .../test/mochitest/browser_dbg-debugger-buttons.js | 97 + ...browser_dbg-dom-mutation-breakpoints-fission.js | 111 + .../browser_dbg-dom-mutation-breakpoints.js | 170 + .../mochitest/browser_dbg-eager-eval-skip-pause.js | 19 + .../test/mochitest/browser_dbg-editor-exception.js | 26 + .../test/mochitest/browser_dbg-editor-gutter.js | 144 + .../test/mochitest/browser_dbg-editor-highlight.js | 50 + .../test/mochitest/browser_dbg-editor-mode.js | 18 + .../test/mochitest/browser_dbg-editor-scroll.js | 48 + .../test/mochitest/browser_dbg-editor-select.js | 53 + .../test/mochitest/browser_dbg-ember-quickstart.js | 25 + .../test/mochitest/browser_dbg-es-module-worker.js | 75 + .../test/mochitest/browser_dbg-eval-throw.js | 18 + .../browser_dbg-event-breakpoints-fission.js | 81 + .../mochitest/browser_dbg-event-breakpoints.js | 294 + .../test/mochitest/browser_dbg-event-handler.js | 18 + .../mochitest/browser_dbg-expressions-error.js | 51 + .../mochitest/browser_dbg-expressions-focus.js | 30 + .../mochitest/browser_dbg-expressions-thread.js | 97 + .../mochitest/browser_dbg-expressions-watch.js | 91 + .../test/mochitest/browser_dbg-expressions.js | 73 + ...extension-inspectedWindow-debugger-statement.js | 88 + .../test/mochitest/browser_dbg-features-asm.js | 92 + .../browser_dbg-features-breakable-lines.js | 92 + .../browser_dbg-features-breakable-positions.js | 284 + .../mochitest/browser_dbg-features-breakpoints.js | 72 + ...ser_dbg-features-browser-toolbox-source-tree.js | 122 + .../browser_dbg-features-source-text-content.js | 565 + .../mochitest/browser_dbg-features-source-tree.js | 554 + .../test/mochitest/browser_dbg-features-tabs.js | 62 + .../test/mochitest/browser_dbg-features-wasm.js | 168 + .../browser_dbg-fission-frame-breakpoint.js | 50 + .../browser_dbg-fission-frame-pause-exceptions.js | 54 + .../mochitest/browser_dbg-fission-frame-sources.js | 47 + .../browser_dbg-fission-project-search.js | 52 + .../mochitest/browser_dbg-fission-switch-target.js | 32 + .../browser_dbg-gc-breakpoint-positions.js | 17 + .../test/mochitest/browser_dbg-gc-sources.js | 29 + .../test/mochitest/browser_dbg-go-to-line.js | 64 + .../test/mochitest/browser_dbg-highlights-calls.js | 31 + .../test/mochitest/browser_dbg-html-breakpoints.js | 54 + .../mochitest/browser_dbg-idb-run-to-completion.js | 15 + .../debugger/test/mochitest/browser_dbg-iframes.js | 60 + .../test/mochitest/browser_dbg-inline-cache.js | 146 + .../mochitest/browser_dbg-inline-exceptions.js | 28 + .../test/mochitest/browser_dbg-inline-preview.js | 111 + .../mochitest/browser_dbg-inline-script-offset.js | 40 + .../mochitest/browser_dbg-inspector-integration.js | 140 + ...-integration-reloading-compressed-sourcemaps.js | 22 + ...ntegration-reloading-uncompressed-sourcemaps.js | 22 + .../mochitest/browser_dbg-javascript-tracer.js | 226 + .../mochitest/browser_dbg-keyboard-navigation.js | 41 + .../browser_dbg-keyboard-shortcuts-modal.js | 49 + .../mochitest/browser_dbg-keyboard-shortcuts.js | 58 + .../test/mochitest/browser_dbg-layout-changes.js | 94 + .../test/mochitest/browser_dbg-link-reload.js | 65 + .../test/mochitest/browser_dbg-log-events.js | 25 + .../mochitest/browser_dbg-log-point-mapping.js | 44 + .../mochitest/browser_dbg-log-points-workers.js | 30 + .../test/mochitest/browser_dbg-log-points.js | 41 + .../browser_dbg-many-breakpoints-same-line.js | 93 + .../test/mochitest/browser_dbg-merge-scopes.js | 55 + .../browser_dbg-message-run-to-completion.js | 24 + .../test/mochitest/browser_dbg-minified.js | 33 + .../browser_dbg-navigation-when-paused.js | 42 + .../test/mochitest/browser_dbg-navigation.js | 73 + ...dbg-no-duplicate-breakpoints-on-frame-reload.js | 101 + .../test/mochitest/browser_dbg-old-breakpoint.js | 111 + .../test/mochitest/browser_dbg-outline-filter.js | 82 + .../test/mochitest/browser_dbg-outline-focus.js | 39 + .../test/mochitest/browser_dbg-outline-pretty.js | 30 + .../debugger/test/mochitest/browser_dbg-outline.js | 89 + .../test/mochitest/browser_dbg-overrides.js | 128 + .../test/mochitest/browser_dbg-pause-exceptions.js | 139 + .../test/mochitest/browser_dbg-pause-on-next.js | 21 + .../test/mochitest/browser_dbg-pause-points.js | 97 + .../test/mochitest/browser_dbg-pause-ux.js | 52 + .../mochitest/browser_dbg-paused-overlay-iframe.js | 76 + .../browser_dbg-paused-overlay-loading.js | 48 + .../test/mochitest/browser_dbg-paused-overlay.js | 73 + ...browser_dbg-pretty-print-breakpoints-columns.js | 119 + .../browser_dbg-pretty-print-breakpoints-delete.js | 113 + .../browser_dbg-pretty-print-breakpoints.js | 126 + .../mochitest/browser_dbg-pretty-print-console.js | 66 + .../mochitest/browser_dbg-pretty-print-flow.js | 78 + .../browser_dbg-pretty-print-inline-scripts.js | 256 + .../browser_dbg-pretty-print-paused-anonymous.js | 148 + .../mochitest/browser_dbg-pretty-print-paused.js | 35 + .../browser_dbg-pretty-print-sourcemap.js | 157 + .../test/mochitest/browser_dbg-pretty-print.js | 134 + .../test/mochitest/browser_dbg-preview-frame.js | 47 + .../test/mochitest/browser_dbg-preview-getter.js | 56 + .../test/mochitest/browser_dbg-preview-module.js | 36 + .../mochitest/browser_dbg-preview-source-maps.js | 45 + .../debugger/test/mochitest/browser_dbg-preview.js | 123 + .../test/mochitest/browser_dbg-project-root.js | 119 + .../test/mochitest/browser_dbg-project-search.js | 258 + .../test/mochitest/browser_dbg-quick-open.js | 166 + .../test/mochitest/browser_dbg-react-app.js | 34 + .../test/mochitest/browser_dbg-react-jsx.js | 20 + ...rowser_dbg-reducer-cleanup-on-target-removal.js | 174 + .../test/mochitest/browser_dbg-reloading.js | 39 + .../browser_dbg-remember-expanded-scopes.js | 41 + .../test/mochitest/browser_dbg-restart-frame.js | 34 + .../test/mochitest/browser_dbg-returnvalues.js | 67 + .../mochitest/browser_dbg-scopes-duplicated.js | 192 + .../test/mochitest/browser_dbg-scopes-mutations.js | 93 + .../test/mochitest/browser_dbg-scopes-xrays.js | 67 + .../debugger/test/mochitest/browser_dbg-scopes.js | 34 + .../browser_dbg-scroll-run-to-completion.js | 25 + .../mochitest/browser_dbg-search-file-paused.js | 71 + .../browser_dbg-search-file-retains-query.js | 40 + .../test/mochitest/browser_dbg-search-file.js | 146 + .../browser_dbg-settings-disable-javascript.js | 49 + .../test/mochitest/browser_dbg-slow-script.js | 91 + .../test/mochitest/browser_dbg-source-pragma.js | 26 + .../mochitest/browser_dbg-sourceURL-breakpoint.js | 18 + .../browser_dbg-sourcemapped-breakpoint-console.js | 86 + .../mochitest/browser_dbg-sourcemapped-preview.js | 206 + .../mochitest/browser_dbg-sourcemapped-scopes.js | 1646 + .../mochitest/browser_dbg-sourcemapped-stepping.js | 158 + .../mochitest/browser_dbg-sourcemapped-toggle.js | 48 + .../test/mochitest/browser_dbg-sourcemaps-bogus.js | 63 + .../browser_dbg-sourcemaps-breakpoints.js | 35 + .../mochitest/browser_dbg-sourcemaps-disabled.js | 23 + .../mochitest/browser_dbg-sourcemaps-ignorelist.js | 75 + .../mochitest/browser_dbg-sourcemaps-indexed.js | 51 + .../mochitest/browser_dbg-sourcemaps-redirect.js | 54 + .../browser_dbg-sourcemaps-reloading-quickly.js | 28 + .../mochitest/browser_dbg-sourcemaps-reloading.js | 62 + .../test/mochitest/browser_dbg-sourcemaps.js | 124 + .../test/mochitest/browser_dbg-sourcemaps2.js | 51 + .../test/mochitest/browser_dbg-sourcemaps3.js | 65 + .../browser_dbg-sources-project-search.js | 134 + .../mochitest/browser_dbg-state-based-panels.js | 164 + .../test/mochitest/browser_dbg-step-in-navigate.js | 34 + .../mochitest/browser_dbg-step-in-uninitialized.js | 47 + .../test/mochitest/browser_dbg-stepping.js | 47 + .../test/mochitest/browser_dbg-tabs-keyboard.js | 29 + .../mochitest/browser_dbg-tabs-pretty-print.js | 46 + .../browser_dbg-tabs-without-urls-selected.js | 28 + .../mochitest/browser_dbg-tabs-without-urls.js | 46 + .../debugger/test/mochitest/browser_dbg-tabs.js | 46 + .../test/mochitest/browser_dbg-toggling-tools.js | 19 + .../test/mochitest/browser_dbg-ua-widgets.js | 47 + .../test/mochitest/browser_dbg-unselected-pause.js | 203 + .../test/mochitest/browser_dbg-watchpoints.js | 122 + ...rowser_dbg-windowless-service-workers-reload.js | 32 + .../browser_dbg-windowless-service-workers.js | 174 + ...wser_dbg-windowless-workers-early-breakpoint.js | 40 + .../mochitest/browser_dbg-windowless-workers.js | 165 + .../test/mochitest/browser_dbg-worker-exception.js | 26 + .../test/mochitest/browser_dbg-worker-module.js | 19 + .../test/mochitest/browser_dbg-worker-nested.js | 15 + .../test/mochitest/browser_dbg-worker-scopes.js | 102 + .../test/mochitest/browser_dbg-wrong-fetch.js | 27 + .../test/mochitest/browser_dbg-xhr-breakpoints.js | 236 + .../mochitest/browser_dbg-xhr-run-to-completion.js | 54 + .../debugger/test/mochitest/examples/README.md | 14 + .../client/debugger/test/mochitest/examples/asm.js | 10 + .../debugger/test/mochitest/examples/async.js | 10 + .../test/mochitest/examples/big-sourcemap.html | 40 + .../examples/big-sourcemap_files/bundle.js | 53505 ++++++++++++ .../examples/big-sourcemap_files/bundle.js.map | 1 + .../test/mochitest/examples/collected-bundle.js | 76 + .../test/mochitest/examples/collected-bundle2.js | 75 + .../mochitest/examples/collected-bundle2.js.map | 1 + .../examples/collected-bundle2.js^headers^ | 1 + .../test/mochitest/examples/different_html.sjs | 31 + .../test/mochitest/examples/doc-all-workers.html | 32 + .../debugger/test/mochitest/examples/doc-asm.html | 20 + .../test/mochitest/examples/doc-async.html | 16 + .../test/mochitest/examples/doc-audiocontext.html | 49 + .../test/mochitest/examples/doc-bfcache1.html | 7 + .../test/mochitest/examples/doc-bfcache2.html | 6 + .../test/mochitest/examples/doc-blackbox-all.html | 15 + .../test/mochitest/examples/doc-command-click.html | 12 + .../examples/doc-content-script-sources.html | 13 + .../examples/doc-debugger-statements.html | 31 + .../test/mochitest/examples/doc-dom-mutation.html | 21 + .../examples/doc-duplicate-functions.html | 27 + .../test/mochitest/examples/doc-early-xhr.html | 16 + .../test/mochitest/examples/doc-editor-scroll.html | 17 + .../test/mochitest/examples/doc-eval-throw.html | 9 + .../examples/doc-event-breakpoints-fission.html | 23 + .../mochitest/examples/doc-event-breakpoints.html | 27 + .../test/mochitest/examples/doc-event-handler.html | 10 + .../test/mochitest/examples/doc-exceptions.html | 10 + .../test/mochitest/examples/doc-frames-async.html | 21 + .../test/mochitest/examples/doc-frames.html | 21 + .../examples/doc-gc-breakpoint-positions.html | 23 + .../test/mochitest/examples/doc-gc-sources.html | 26 + .../mochitest/examples/doc-html-breakpoints.html | 25 + .../examples/doc-idb-run-to-completion.html | 30 + .../test/mochitest/examples/doc-iframes.html | 20 + .../mochitest/examples/doc-inline-preview.html | 16 + .../examples/doc-inline-script-offset.html | 15 + .../test/mochitest/examples/doc-merge-scopes.html | 29 + .../doc-message-run-to-completion-frame.html | 1 + .../examples/doc-message-run-to-completion.html | 19 + .../test/mochitest/examples/doc-minified.html | 20 + .../test/mochitest/examples/doc-minified2.html | 21 + .../test/mochitest/examples/doc-module-worker.html | 10 + .../examples/doc-navigation-when-paused.html | 17 + .../test/mochitest/examples/doc-nested-worker.html | 11 + .../test/mochitest/examples/doc-on-load.html | 21 + .../test/mochitest/examples/doc-pause-points.html | 16 + .../examples/doc-pretty-print-inline-scripts.html | 44 + .../test/mochitest/examples/doc-pretty.html | 14 + .../mochitest/examples/doc-preview-getter.html | 11 + .../test/mochitest/examples/doc-preview.html | 27 + .../test/mochitest/examples/doc-react-jsx.html | 111 + .../test/mochitest/examples/doc-react.html | 10 + .../test/mochitest/examples/doc-reload-link.html | 5 + .../examples/doc-remember-expanded-scopes.html | 7 + .../test/mochitest/examples/doc-return-values.html | 50 + .../test/mochitest/examples/doc-scopes-xrays.html | 11 + .../test/mochitest/examples/doc-script-mutate.html | 18 + .../mochitest/examples/doc-script-switching.html | 19 + .../mochitest/examples/doc-scripts-debugger.html | 20 + .../test/mochitest/examples/doc-scripts.html | 35 + .../examples/doc-scroll-run-to-completion.html | 27 + .../mochitest/examples/doc-service-workers.html | 39 + .../test/mochitest/examples/doc-slow-script.html | 18 + .../test/mochitest/examples/doc-source-pragma.html | 7 + .../examples/doc-sourceURL-breakpoint.html | 9 + .../mochitest/examples/doc-sourcemap-bogus.html | 15 + .../test/mochitest/examples/doc-sourcemapped.html | 574 + .../examples/doc-sourcemaps-ignorelist.html | 14 + .../mochitest/examples/doc-sourcemaps-indexed.html | 21 + .../test/mochitest/examples/doc-sourcemaps.html | 15 + .../test/mochitest/examples/doc-sourcemaps2.html | 21 + .../test/mochitest/examples/doc-sourcemaps3.html | 16 + .../test/mochitest/examples/doc-sources.html | 25 + .../examples/doc-step-in-uninitialized.html | 11 + .../test/mochitest/examples/doc-strict.html | 21 + .../mochitest/examples/doc-wasm-sourcemaps.html | 23 + .../test/mochitest/examples/doc-watchpoints.html | 31 + .../doc-windowless-workers-early-breakpoint.html | 19 + .../mochitest/examples/doc-windowless-workers.html | 25 + .../mochitest/examples/doc-worker-exception.html | 10 + .../test/mochitest/examples/doc-worker-scopes.html | 15 + .../examples/doc-xhr-run-to-completion.html | 41 + .../debugger/test/mochitest/examples/doc-xhr.html | 14 + .../examples/doc_dbg-custom-formatters.html | 31 + .../doc_dbg-fission-frame-pause-exceptions.html | 20 + .../doc_dbg-fission-frame-sources-frame.html | 12 + .../examples/doc_dbg-fission-frame-sources.html | 13 + .../examples/doc_dbg-fission-pause-exceptions.html | 13 + ...doc_dbg-same-source-distinct-threads-frame.html | 13 + .../doc_dbg-same-source-distinct-threads.html | 21 + .../test/mochitest/examples/dom-mutation.js | 26 + .../test/mochitest/examples/dom-mutation.js.map | 1 + .../examples/ember/quickstart/.editorconfig | 20 + .../mochitest/examples/ember/quickstart/.ember-cli | 9 + .../examples/ember/quickstart/.eslintrc.js | 38 + .../mochitest/examples/ember/quickstart/.gitignore | 23 + .../examples/ember/quickstart/.travis.yml | 26 + .../examples/ember/quickstart/.watchmanconfig | 3 + .../ember/quickstart/dist/assets/quickstart.css | 0 .../ember/quickstart/dist/assets/quickstart.js | 277 + .../ember/quickstart/dist/assets/quickstart.map | 1 + .../ember/quickstart/dist/assets/test-support.css | 471 + .../ember/quickstart/dist/assets/test-support.js | 12050 +++ .../ember/quickstart/dist/assets/test-support.map | 1 + .../examples/ember/quickstart/dist/assets/tests.js | 62 + .../ember/quickstart/dist/assets/tests.map | 1 + .../ember/quickstart/dist/assets/vendor.css | 97 + .../ember/quickstart/dist/assets/vendor.js | 86407 +++++++++++++++++++ .../ember/quickstart/dist/assets/vendor.map | 1 + .../examples/ember/quickstart/dist/index.html | 26 + .../examples/ember/quickstart/dist/robots.txt | 3 + .../examples/ember/quickstart/dist/testem.js | 19 + .../debugger/test/mochitest/examples/entry.js | 16 + .../test/mochitest/examples/event-breakpoints.js | 69 + .../debugger/test/mochitest/examples/exceptions.js | 88 + .../debugger/test/mochitest/examples/fetch.js | 5 + .../debugger/test/mochitest/examples/frames.js | 24 + .../mochitest/examples/html-breakpoints-slow.js | 3 + .../test/mochitest/examples/inline-preview.js | 60 + .../test/mochitest/examples/inner-worker.js | 8 + .../debugger/test/mochitest/examples/long.js | 76 + .../examples/map-with-failed-original-request.js | 26 + .../examples/map-with-failed-original-request.map | 1 + .../debugger/test/mochitest/examples/math.min.js | 3 + .../mochitest/examples/nested/nested-source.js | 3 + .../test/mochitest/examples/non-existant-map.js | 8 + .../debugger/test/mochitest/examples/opts.js | 3 + .../test/mochitest/examples/outer-worker.js | 8 + .../debugger/test/mochitest/examples/output.js | 5 + .../test/mochitest/examples/pause-points.js | 43 + .../debugger/test/mochitest/examples/pretty.js | 10 + .../test/mochitest/examples/preview-getter.js | 15 + .../debugger/test/mochitest/examples/preview.js | 66 + .../test/mochitest/examples/react/.gitignore | 20 + .../test/mochitest/examples/react/README.md | 4 + .../examples/react/build/asset-manifest.json | 4 + .../test/mochitest/examples/react/build/index.html | 1 + .../test/mochitest/examples/react/build/main.js | 6762 ++ .../mochitest/examples/react/build/main.js.map | 1 + .../examples/react/build/service-worker.js | 1 + .../mochitest/examples/react/config-overrides.js | 16 + .../test/mochitest/examples/react/package.json | 21 + .../mochitest/examples/react/public/index.html | 25 + .../test/mochitest/examples/react/src/App.js | 25 + .../test/mochitest/examples/react/src/index.js | 5 + .../test/mochitest/examples/react/yarn.lock | 7090 ++ .../mochitest/examples/reload/code_reload_1.js | 3 + .../test/mochitest/examples/same-script.js | 9 + .../test/mochitest/examples/scopes-worker.js | 13 + .../test/mochitest/examples/script-mutate.js | 20 + .../test/mochitest/examples/script-switching-01.js | 9 + .../test/mochitest/examples/script-switching-02.js | 14 + .../test/mochitest/examples/service-worker.sjs | 38 + .../test/mochitest/examples/shared-worker.js | 1 + .../test/mochitest/examples/simple-worker.js | 11 + .../debugger/test/mochitest/examples/simple1.js | 63 + .../debugger/test/mochitest/examples/simple2.js | 6 + .../debugger/test/mochitest/examples/simple3.js | 19 + .../debugger/test/mochitest/examples/simple4.js | 15 + .../test/mochitest/examples/sjs_slow-load.sjs | 31 + .../test/mochitest/examples/source-pragma.js | 6 + .../test/mochitest/examples/source-pragma.js.map | 10 + .../cache/f67752e2d3a8fd18a75558156ccfd8c764b544a1 | 0 .../test/mochitest/examples/sourcemapped/README.md | 16 + .../test/mochitest/examples/sourcemapped/build.js | 82 + .../examples/sourcemapped/builds/parcel/index.js | 69 + .../sourcemapped/builds/parcel/package.json | 6 + .../examples/sourcemapped/builds/parcel/yarn.lock | 4128 + .../sourcemapped/builds/rollup-babel6/index.js | 82 + .../sourcemapped/builds/rollup-babel6/package.json | 12 + .../sourcemapped/builds/rollup-babel6/yarn.lock | 755 + .../sourcemapped/builds/rollup-babel7/index.js | 82 + .../sourcemapped/builds/rollup-babel7/package.json | 13 + .../sourcemapped/builds/rollup-babel7/yarn.lock | 1115 + .../examples/sourcemapped/builds/rollup/index.js | 76 + .../sourcemapped/builds/rollup/package.json | 11 + .../examples/sourcemapped/builds/rollup/yarn.lock | 337 + .../sourcemapped/builds/webpack3-babel6/index.js | 81 + .../builds/webpack3-babel6/package.json | 12 + .../sourcemapped/builds/webpack3-babel6/yarn.lock | 2823 + .../sourcemapped/builds/webpack3-babel7/index.js | 81 + .../builds/webpack3-babel7/package.json | 13 + .../sourcemapped/builds/webpack3-babel7/yarn.lock | 3089 + .../examples/sourcemapped/builds/webpack3/index.js | 65 + .../sourcemapped/builds/webpack3/package.json | 10 + .../sourcemapped/builds/webpack3/yarn.lock | 2202 + .../sourcemapped/builds/webpack4-babel6/index.js | 82 + .../builds/webpack4-babel6/package.json | 12 + .../sourcemapped/builds/webpack4-babel6/yarn.lock | 2787 + .../sourcemapped/builds/webpack4-babel7/index.js | 82 + .../builds/webpack4-babel7/package.json | 13 + .../sourcemapped/builds/webpack4-babel7/yarn.lock | 3047 + .../examples/sourcemapped/builds/webpack4/index.js | 66 + .../sourcemapped/builds/webpack4/package.json | 10 + .../sourcemapped/builds/webpack4/yarn.lock | 2194 + .../fixtures/babel-bindings-with-flow/input.js | 10 + .../fixtures/babel-bindings-with-flow/src/mod.js | 1 + .../sourcemapped/fixtures/babel-classes/input.js | 15 + .../fixtures/babel-flowtype-bindings/input.js | 10 + .../fixtures/babel-flowtype-bindings/src/mod.js | 2 + .../sourcemapped/fixtures/classes/input.js | 22 + .../sourcemapped/fixtures/esmodules-cjs/input.js | 41 + .../fixtures/esmodules-cjs/src/mod1.js | 1 + .../fixtures/esmodules-cjs/src/mod10.js | 1 + .../fixtures/esmodules-cjs/src/mod11.js | 1 + .../fixtures/esmodules-cjs/src/mod12.js | 2 + .../fixtures/esmodules-cjs/src/mod2.js | 1 + .../fixtures/esmodules-cjs/src/mod3.js | 1 + .../fixtures/esmodules-cjs/src/mod4.js | 2 + .../fixtures/esmodules-cjs/src/mod5.js | 1 + .../fixtures/esmodules-cjs/src/mod6.js | 1 + .../fixtures/esmodules-cjs/src/mod7.js | 1 + .../fixtures/esmodules-cjs/src/mod8.js | 2 + .../fixtures/esmodules-cjs/src/mod9.js | 1 + .../fixtures/esmodules-cjs/src/optimized-out.js | 1 + .../sourcemapped/fixtures/esmodules-es6/input.js | 41 + .../fixtures/esmodules-es6/src/mod1.js | 1 + .../fixtures/esmodules-es6/src/mod10.js | 1 + .../fixtures/esmodules-es6/src/mod11.js | 1 + .../fixtures/esmodules-es6/src/mod12.js | 2 + .../fixtures/esmodules-es6/src/mod2.js | 1 + .../fixtures/esmodules-es6/src/mod3.js | 1 + .../fixtures/esmodules-es6/src/mod4.js | 2 + .../fixtures/esmodules-es6/src/mod5.js | 1 + .../fixtures/esmodules-es6/src/mod6.js | 1 + .../fixtures/esmodules-es6/src/mod7.js | 1 + .../fixtures/esmodules-es6/src/mod8.js | 2 + .../fixtures/esmodules-es6/src/mod9.js | 1 + .../fixtures/esmodules-es6/src/optimized-out.js | 1 + .../sourcemapped/fixtures/esmodules/input.js | 41 + .../sourcemapped/fixtures/esmodules/src/mod1.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod10.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod11.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod12.js | 2 + .../sourcemapped/fixtures/esmodules/src/mod2.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod3.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod4.js | 2 + .../sourcemapped/fixtures/esmodules/src/mod5.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod6.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod7.js | 1 + .../sourcemapped/fixtures/esmodules/src/mod8.js | 2 + .../sourcemapped/fixtures/esmodules/src/mod9.js | 1 + .../fixtures/esmodules/src/optimized-out.js | 1 + .../sourcemapped/fixtures/eval-maps/input.js | 16 + .../sourcemapped/fixtures/for-loops/input.js | 15 + .../examples/sourcemapped/fixtures/for-of/input.js | 12 + .../sourcemapped/fixtures/functions/input.js | 14 + .../sourcemapped/fixtures/lex-and-nonlex/input.js | 9 + .../fixtures/line-start-bindings-es6/input.js | 23 + .../sourcemapped/fixtures/modules-cjs/input.js | 8 + .../out-of-order-declarations-cjs/input.js | 17 + .../out-of-order-declarations-cjs/src/mod.js | 1 + .../sourcemapped/fixtures/shadowed-vars/input.js | 21 + .../step-over-for-of-array-closure/input.js | 10 + .../fixtures/step-over-for-of-array/input.js | 10 + .../fixtures/step-over-for-of-closure/input.js | 13 + .../fixtures/step-over-for-of/input.js | 11 + .../fixtures/step-over-function-params/input.js | 8 + .../fixtures/step-over-regenerator-await/input.js | 15 + .../sourcemapped/fixtures/switches/input.js | 13 + .../fixtures/this-arguments-bindings/input.js | 14 + .../sourcemapped/fixtures/try-catches/input.js | 10 + .../sourcemapped/fixtures/type-module/input.js | 8 + .../sourcemapped/fixtures/type-script-cjs/input.js | 10 + .../fixtures/typescript-classes/input.ts | 51 + .../fixtures/typescript-classes/src/mod.ts | 8 + .../fixtures/webpack-functions/input.js | 12 + .../fixtures/webpack-line-mappings/input.js | 18 + .../fixtures/webpack-line-mappings/src/mod1.js | 1 + .../output/parcel/babel-bindings-with-flow.js | 132 + .../output/parcel/babel-bindings-with-flow.map | 1 + .../sourcemapped/output/parcel/babel-classes.js | 132 + .../sourcemapped/output/parcel/babel-classes.map | 1 + .../output/parcel/babel-flowtype-bindings.js | 131 + .../output/parcel/babel-flowtype-bindings.map | 1 + .../examples/sourcemapped/output/parcel/classes.js | 137 + .../sourcemapped/output/parcel/classes.map | 1 + .../sourcemapped/output/parcel/esmodules-cjs.js | 259 + .../sourcemapped/output/parcel/esmodules-cjs.map | 1 + .../sourcemapped/output/parcel/esmodules-es6.js | 259 + .../sourcemapped/output/parcel/esmodules-es6.map | 1 + .../sourcemapped/output/parcel/esmodules.js | 259 + .../sourcemapped/output/parcel/esmodules.map | 1 + .../sourcemapped/output/parcel/eval-maps.js | 130 + .../sourcemapped/output/parcel/eval-maps.map | 1 + .../sourcemapped/output/parcel/for-loops.js | 130 + .../sourcemapped/output/parcel/for-loops.map | 1 + .../examples/sourcemapped/output/parcel/for-of.js | 127 + .../examples/sourcemapped/output/parcel/for-of.map | 1 + .../sourcemapped/output/parcel/functions.js | 129 + .../sourcemapped/output/parcel/functions.map | 1 + .../sourcemapped/output/parcel/lex-and-nonlex.js | 124 + .../sourcemapped/output/parcel/lex-and-nonlex.map | 1 + .../output/parcel/line-start-bindings-es6.js | 137 + .../output/parcel/line-start-bindings-es6.map | 1 + .../sourcemapped/output/parcel/modules-cjs.js | 117 + .../sourcemapped/output/parcel/modules-cjs.map | 1 + .../output/parcel/out-of-order-declarations-cjs.js | 144 + .../parcel/out-of-order-declarations-cjs.map | 1 + .../sourcemapped/output/parcel/shadowed-vars.js | 136 + .../sourcemapped/output/parcel/shadowed-vars.map | 1 + .../parcel/step-over-for-of-array-closure.js | 125 + .../parcel/step-over-for-of-array-closure.map | 1 + .../output/parcel/step-over-for-of-array.js | 125 + .../output/parcel/step-over-for-of-array.map | 1 + .../output/parcel/step-over-for-of-closure.js | 128 + .../output/parcel/step-over-for-of-closure.map | 1 + .../sourcemapped/output/parcel/step-over-for-of.js | 126 + .../output/parcel/step-over-for-of.map | 1 + .../output/parcel/step-over-function-params.js | 123 + .../output/parcel/step-over-function-params.map | 1 + .../output/parcel/step-over-regenerator-await.js | 130 + .../output/parcel/step-over-regenerator-await.map | 1 + .../sourcemapped/output/parcel/switches.js | 129 + .../sourcemapped/output/parcel/switches.map | 1 + .../output/parcel/this-arguments-bindings.js | 129 + .../output/parcel/this-arguments-bindings.map | 1 + .../sourcemapped/output/parcel/try-catches.js | 125 + .../sourcemapped/output/parcel/try-catches.map | 1 + .../sourcemapped/output/parcel/type-module.js | 123 + .../sourcemapped/output/parcel/type-module.map | 1 + .../sourcemapped/output/parcel/type-script-cjs.js | 119 + .../sourcemapped/output/parcel/type-script-cjs.map | 1 + .../output/parcel/typescript-classes.js | 221 + .../output/parcel/typescript-classes.map | 1 + .../output/parcel/webpack-functions.js | 126 + .../output/parcel/webpack-functions.map | 1 + .../output/parcel/webpack-line-mappings.js | 147 + .../output/parcel/webpack-line-mappings.map | 1 + .../rollup-babel6/babel-bindings-with-flow.js | 17 + .../rollup-babel6/babel-bindings-with-flow.js.map | 1 + .../output/rollup-babel6/babel-classes.js | 37 + .../output/rollup-babel6/babel-classes.js.map | 1 + .../rollup-babel6/babel-flowtype-bindings.js | 15 + .../rollup-babel6/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/rollup-babel6/classes.js | 49 + .../output/rollup-babel6/classes.js.map | 1 + .../output/rollup-babel6/esmodules-es6.js | 57 + .../output/rollup-babel6/esmodules-es6.js.map | 1 + .../sourcemapped/output/rollup-babel6/esmodules.js | 57 + .../output/rollup-babel6/esmodules.js.map | 1 + .../sourcemapped/output/rollup-babel6/eval-maps.js | 18 + .../output/rollup-babel6/eval-maps.js.map | 1 + .../sourcemapped/output/rollup-babel6/for-loops.js | 23 + .../output/rollup-babel6/for-loops.js.map | 1 + .../sourcemapped/output/rollup-babel6/for-of.js | 21 + .../output/rollup-babel6/for-of.js.map | 1 + .../sourcemapped/output/rollup-babel6/functions.js | 22 + .../output/rollup-babel6/functions.js.map | 1 + .../output/rollup-babel6/lex-and-nonlex.js | 21 + .../output/rollup-babel6/lex-and-nonlex.js.map | 1 + .../rollup-babel6/line-start-bindings-es6.js | 20 + .../rollup-babel6/line-start-bindings-es6.js.map | 1 + .../output/rollup-babel6/shadowed-vars.js | 17 + .../output/rollup-babel6/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 26 + .../step-over-for-of-array-closure.js.map | 1 + .../output/rollup-babel6/step-over-for-of-array.js | 20 + .../rollup-babel6/step-over-for-of-array.js.map | 1 + .../rollup-babel6/step-over-for-of-closure.js | 48 + .../rollup-babel6/step-over-for-of-closure.js.map | 1 + .../output/rollup-babel6/step-over-for-of.js | 40 + .../output/rollup-babel6/step-over-for-of.js.map | 1 + .../rollup-babel6/step-over-function-params.js | 25 + .../rollup-babel6/step-over-function-params.js.map | 1 + .../rollup-babel6/step-over-regenerator-await.js | 47 + .../step-over-regenerator-await.js.map | 1 + .../sourcemapped/output/rollup-babel6/switches.js | 19 + .../output/rollup-babel6/switches.js.map | 1 + .../rollup-babel6/this-arguments-bindings.js | 25 + .../rollup-babel6/this-arguments-bindings.js.map | 1 + .../output/rollup-babel6/try-catches.js | 16 + .../output/rollup-babel6/try-catches.js.map | 1 + .../output/rollup-babel6/type-module.js | 16 + .../output/rollup-babel6/type-module.js.map | 1 + .../output/rollup-babel6/webpack-functions.js | 19 + .../output/rollup-babel6/webpack-functions.js.map | 1 + .../output/rollup-babel6/webpack-line-mappings.js | 28 + .../rollup-babel6/webpack-line-mappings.js.map | 1 + .../rollup-babel7/babel-bindings-with-flow.js | 15 + .../rollup-babel7/babel-bindings-with-flow.js.map | 1 + .../output/rollup-babel7/babel-classes.js | 71 + .../output/rollup-babel7/babel-classes.js.map | 1 + .../rollup-babel7/babel-flowtype-bindings.js | 14 + .../rollup-babel7/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/rollup-babel7/classes.js | 70 + .../output/rollup-babel7/classes.js.map | 1 + .../output/rollup-babel7/esmodules-es6.js | 55 + .../output/rollup-babel7/esmodules-es6.js.map | 1 + .../sourcemapped/output/rollup-babel7/esmodules.js | 55 + .../output/rollup-babel7/esmodules.js.map | 1 + .../sourcemapped/output/rollup-babel7/eval-maps.js | 16 + .../output/rollup-babel7/eval-maps.js.map | 1 + .../sourcemapped/output/rollup-babel7/for-loops.js | 26 + .../output/rollup-babel7/for-loops.js.map | 1 + .../sourcemapped/output/rollup-babel7/for-of.js | 21 + .../output/rollup-babel7/for-of.js.map | 1 + .../sourcemapped/output/rollup-babel7/functions.js | 23 + .../output/rollup-babel7/functions.js.map | 1 + .../output/rollup-babel7/lex-and-nonlex.js | 25 + .../output/rollup-babel7/lex-and-nonlex.js.map | 1 + .../rollup-babel7/line-start-bindings-es6.js | 18 + .../rollup-babel7/line-start-bindings-es6.js.map | 1 + .../output/rollup-babel7/shadowed-vars.js | 16 + .../output/rollup-babel7/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 26 + .../step-over-for-of-array-closure.js.map | 1 + .../output/rollup-babel7/step-over-for-of-array.js | 20 + .../rollup-babel7/step-over-for-of-array.js.map | 1 + .../rollup-babel7/step-over-for-of-closure.js | 27 + .../rollup-babel7/step-over-for-of-closure.js.map | 1 + .../output/rollup-babel7/step-over-for-of.js | 19 + .../output/rollup-babel7/step-over-for-of.js.map | 1 + .../rollup-babel7/step-over-function-params.js | 30 + .../rollup-babel7/step-over-function-params.js.map | 1 + .../rollup-babel7/step-over-regenerator-await.js | 81 + .../step-over-regenerator-await.js.map | 1 + .../sourcemapped/output/rollup-babel7/switches.js | 20 + .../output/rollup-babel7/switches.js.map | 1 + .../rollup-babel7/this-arguments-bindings.js | 26 + .../rollup-babel7/this-arguments-bindings.js.map | 1 + .../output/rollup-babel7/try-catches.js | 16 + .../output/rollup-babel7/try-catches.js.map | 1 + .../output/rollup-babel7/type-module.js | 16 + .../output/rollup-babel7/type-module.js.map | 1 + .../output/rollup-babel7/webpack-functions.js | 19 + .../output/rollup-babel7/webpack-functions.js.map | 1 + .../output/rollup-babel7/webpack-line-mappings.js | 30 + .../rollup-babel7/webpack-line-mappings.js.map | 1 + .../examples/sourcemapped/output/rollup/classes.js | 27 + .../sourcemapped/output/rollup/classes.js.map | 1 + .../sourcemapped/output/rollup/esmodules-es6.js | 57 + .../output/rollup/esmodules-es6.js.map | 1 + .../sourcemapped/output/rollup/esmodules.js | 57 + .../sourcemapped/output/rollup/esmodules.js.map | 1 + .../sourcemapped/output/rollup/eval-maps.js | 18 + .../sourcemapped/output/rollup/eval-maps.js.map | 1 + .../sourcemapped/output/rollup/for-loops.js | 22 + .../sourcemapped/output/rollup/for-loops.js.map | 1 + .../examples/sourcemapped/output/rollup/for-of.js | 18 + .../sourcemapped/output/rollup/for-of.js.map | 1 + .../sourcemapped/output/rollup/functions.js | 22 + .../sourcemapped/output/rollup/functions.js.map | 1 + .../sourcemapped/output/rollup/lex-and-nonlex.js | 17 + .../output/rollup/lex-and-nonlex.js.map | 1 + .../output/rollup/line-start-bindings-es6.js | 20 + .../output/rollup/line-start-bindings-es6.js.map | 1 + .../sourcemapped/output/rollup/shadowed-vars.js | 16 + .../output/rollup/shadowed-vars.js.map | 1 + .../rollup/step-over-for-of-array-closure.js | 18 + .../rollup/step-over-for-of-array-closure.js.map | 1 + .../output/rollup/step-over-for-of-array.js | 18 + .../output/rollup/step-over-for-of-array.js.map | 1 + .../output/rollup/step-over-for-of-closure.js | 21 + .../output/rollup/step-over-for-of-closure.js.map | 1 + .../sourcemapped/output/rollup/step-over-for-of.js | 19 + .../output/rollup/step-over-for-of.js.map | 1 + .../output/rollup/step-over-function-params.js | 16 + .../output/rollup/step-over-function-params.js.map | 1 + .../output/rollup/step-over-regenerator-await.js | 23 + .../rollup/step-over-regenerator-await.js.map | 1 + .../sourcemapped/output/rollup/switches.js | 18 + .../sourcemapped/output/rollup/switches.js.map | 1 + .../output/rollup/this-arguments-bindings.js | 22 + .../output/rollup/this-arguments-bindings.js.map | 1 + .../sourcemapped/output/rollup/try-catches.js | 16 + .../sourcemapped/output/rollup/try-catches.js.map | 1 + .../sourcemapped/output/rollup/type-module.js | 16 + .../sourcemapped/output/rollup/type-module.js.map | 1 + .../output/rollup/typescript-classes.js | 97 + .../output/rollup/typescript-classes.js.map | 1 + .../output/rollup/webpack-functions.js | 20 + .../output/rollup/webpack-functions.js.map | 1 + .../output/rollup/webpack-line-mappings.js | 26 + .../output/rollup/webpack-line-mappings.js.map | 1 + .../webpack3-babel6/babel-bindings-with-flow.js | 96 + .../babel-bindings-with-flow.js.map | 1 + .../output/webpack3-babel6/babel-classes.js | 107 + .../output/webpack3-babel6/babel-classes.js.map | 1 + .../webpack3-babel6/babel-flowtype-bindings.js | 95 + .../webpack3-babel6/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/webpack3-babel6/classes.js | 121 + .../output/webpack3-babel6/classes.js.map | 1 + .../output/webpack3-babel6/esmodules-cjs.js | 280 + .../output/webpack3-babel6/esmodules-cjs.js.map | 1 + .../output/webpack3-babel6/esmodules-es6.js | 224 + .../output/webpack3-babel6/esmodules-es6.js.map | 1 + .../output/webpack3-babel6/esmodules.js | 217 + .../output/webpack3-babel6/esmodules.js.map | 1 + .../output/webpack3-babel6/eval-maps.js | 93 + .../output/webpack3-babel6/eval-maps.js.map | 1 + .../output/webpack3-babel6/for-loops.js | 94 + .../output/webpack3-babel6/for-loops.js.map | 1 + .../sourcemapped/output/webpack3-babel6/for-of.js | 92 + .../output/webpack3-babel6/for-of.js.map | 1 + .../output/webpack3-babel6/functions.js | 91 + .../output/webpack3-babel6/functions.js.map | 1 + .../output/webpack3-babel6/lex-and-nonlex.js | 90 + .../output/webpack3-babel6/lex-and-nonlex.js.map | 1 + .../webpack3-babel6/line-start-bindings-es6.js | 100 + .../webpack3-babel6/line-start-bindings-es6.js.map | 1 + .../output/webpack3-babel6/modules-cjs.js | 85 + .../output/webpack3-babel6/modules-cjs.js.map | 1 + .../out-of-order-declarations-cjs.js | 115 + .../out-of-order-declarations-cjs.js.map | 1 + .../output/webpack3-babel6/shadowed-vars.js | 102 + .../output/webpack3-babel6/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 95 + .../step-over-for-of-array-closure.js.map | 1 + .../webpack3-babel6/step-over-for-of-array.js | 89 + .../webpack3-babel6/step-over-for-of-array.js.map | 1 + .../webpack3-babel6/step-over-for-of-closure.js | 117 + .../step-over-for-of-closure.js.map | 1 + .../output/webpack3-babel6/step-over-for-of.js | 109 + .../output/webpack3-babel6/step-over-for-of.js.map | 1 + .../webpack3-babel6/step-over-function-params.js | 95 + .../step-over-function-params.js.map | 1 + .../webpack3-babel6/step-over-regenerator-await.js | 116 + .../step-over-regenerator-await.js.map | 1 + .../output/webpack3-babel6/switches.js | 91 + .../output/webpack3-babel6/switches.js.map | 1 + .../webpack3-babel6/this-arguments-bindings.js | 94 + .../webpack3-babel6/this-arguments-bindings.js.map | 1 + .../output/webpack3-babel6/try-catches.js | 87 + .../output/webpack3-babel6/try-catches.js.map | 1 + .../output/webpack3-babel6/type-module.js | 84 + .../output/webpack3-babel6/type-module.js.map | 1 + .../output/webpack3-babel6/type-script-cjs.js | 87 + .../output/webpack3-babel6/type-script-cjs.js.map | 1 + .../output/webpack3-babel6/typescript-classes.js | 75 + .../webpack3-babel6/typescript-classes.js.map | 1 + .../output/webpack3-babel6/webpack-functions.js | 88 + .../webpack3-babel6/webpack-functions.js.map | 1 + .../webpack3-babel6/webpack-line-mappings.js | 105 + .../webpack3-babel6/webpack-line-mappings.js.map | 1 + .../webpack3-babel7/babel-bindings-with-flow.js | 94 + .../babel-bindings-with-flow.js.map | 1 + .../output/webpack3-babel7/babel-classes.js | 112 + .../output/webpack3-babel7/babel-classes.js.map | 1 + .../webpack3-babel7/babel-flowtype-bindings.js | 92 + .../webpack3-babel7/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/webpack3-babel7/classes.js | 125 + .../output/webpack3-babel7/classes.js.map | 1 + .../output/webpack3-babel7/esmodules-cjs.js | 290 + .../output/webpack3-babel7/esmodules-cjs.js.map | 1 + .../output/webpack3-babel7/esmodules-es6.js | 217 + .../output/webpack3-babel7/esmodules-es6.js.map | 1 + .../output/webpack3-babel7/esmodules.js | 210 + .../output/webpack3-babel7/esmodules.js.map | 1 + .../output/webpack3-babel7/eval-maps.js | 89 + .../output/webpack3-babel7/eval-maps.js.map | 1 + .../output/webpack3-babel7/for-loops.js | 97 + .../output/webpack3-babel7/for-loops.js.map | 1 + .../sourcemapped/output/webpack3-babel7/for-of.js | 91 + .../output/webpack3-babel7/for-of.js.map | 1 + .../output/webpack3-babel7/functions.js | 92 + .../output/webpack3-babel7/functions.js.map | 1 + .../output/webpack3-babel7/lex-and-nonlex.js | 90 + .../output/webpack3-babel7/lex-and-nonlex.js.map | 1 + .../webpack3-babel7/line-start-bindings-es6.js | 97 + .../webpack3-babel7/line-start-bindings-es6.js.map | 1 + .../output/webpack3-babel7/modules-cjs.js | 85 + .../output/webpack3-babel7/modules-cjs.js.map | 1 + .../out-of-order-declarations-cjs.js | 118 + .../out-of-order-declarations-cjs.js.map | 1 + .../output/webpack3-babel7/shadowed-vars.js | 101 + .../output/webpack3-babel7/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 95 + .../step-over-for-of-array-closure.js.map | 1 + .../webpack3-babel7/step-over-for-of-array.js | 89 + .../webpack3-babel7/step-over-for-of-array.js.map | 1 + .../webpack3-babel7/step-over-for-of-closure.js | 96 + .../step-over-for-of-closure.js.map | 1 + .../output/webpack3-babel7/step-over-for-of.js | 88 + .../output/webpack3-babel7/step-over-for-of.js.map | 1 + .../webpack3-babel7/step-over-function-params.js | 100 + .../step-over-function-params.js.map | 1 + .../webpack3-babel7/step-over-regenerator-await.js | 118 + .../step-over-regenerator-await.js.map | 1 + .../output/webpack3-babel7/switches.js | 92 + .../output/webpack3-babel7/switches.js.map | 1 + .../webpack3-babel7/this-arguments-bindings.js | 95 + .../webpack3-babel7/this-arguments-bindings.js.map | 1 + .../output/webpack3-babel7/try-catches.js | 87 + .../output/webpack3-babel7/try-catches.js.map | 1 + .../output/webpack3-babel7/type-module.js | 84 + .../output/webpack3-babel7/type-module.js.map | 1 + .../output/webpack3-babel7/type-script-cjs.js | 87 + .../output/webpack3-babel7/type-script-cjs.js.map | 1 + .../output/webpack3-babel7/webpack-functions.js | 88 + .../webpack3-babel7/webpack-functions.js.map | 1 + .../webpack3-babel7/webpack-line-mappings.js | 106 + .../webpack3-babel7/webpack-line-mappings.js.map | 1 + .../sourcemapped/output/webpack3/classes.js | 100 + .../sourcemapped/output/webpack3/classes.js.map | 1 + .../sourcemapped/output/webpack3/esmodules-cjs.js | 236 + .../output/webpack3/esmodules-cjs.js.map | 1 + .../sourcemapped/output/webpack3/esmodules-es6.js | 236 + .../output/webpack3/esmodules-es6.js.map | 1 + .../sourcemapped/output/webpack3/esmodules.js | 236 + .../sourcemapped/output/webpack3/esmodules.js.map | 1 + .../sourcemapped/output/webpack3/eval-maps.js | 94 + .../sourcemapped/output/webpack3/eval-maps.js.map | 1 + .../sourcemapped/output/webpack3/for-loops.js | 93 + .../sourcemapped/output/webpack3/for-loops.js.map | 1 + .../sourcemapped/output/webpack3/for-of.js | 90 + .../sourcemapped/output/webpack3/for-of.js.map | 1 + .../sourcemapped/output/webpack3/functions.js | 92 + .../sourcemapped/output/webpack3/functions.js.map | 1 + .../sourcemapped/output/webpack3/lex-and-nonlex.js | 87 + .../output/webpack3/lex-and-nonlex.js.map | 1 + .../output/webpack3/line-start-bindings-es6.js | 101 + .../output/webpack3/line-start-bindings-es6.js.map | 1 + .../sourcemapped/output/webpack3/modules-cjs.js | 83 + .../output/webpack3/modules-cjs.js.map | 1 + .../webpack3/out-of-order-declarations-cjs.js | 104 + .../webpack3/out-of-order-declarations-cjs.js.map | 1 + .../sourcemapped/output/webpack3/shadowed-vars.js | 98 + .../output/webpack3/shadowed-vars.js.map | 1 + .../webpack3/step-over-for-of-array-closure.js | 88 + .../webpack3/step-over-for-of-array-closure.js.map | 1 + .../output/webpack3/step-over-for-of-array.js | 88 + .../output/webpack3/step-over-for-of-array.js.map | 1 + .../output/webpack3/step-over-for-of-closure.js | 91 + .../webpack3/step-over-for-of-closure.js.map | 1 + .../output/webpack3/step-over-for-of.js | 89 + .../output/webpack3/step-over-for-of.js.map | 1 + .../output/webpack3/step-over-function-params.js | 86 + .../webpack3/step-over-function-params.js.map | 1 + .../output/webpack3/step-over-regenerator-await.js | 93 + .../webpack3/step-over-regenerator-await.js.map | 1 + .../sourcemapped/output/webpack3/switches.js | 91 + .../sourcemapped/output/webpack3/switches.js.map | 1 + .../output/webpack3/this-arguments-bindings.js | 92 + .../output/webpack3/this-arguments-bindings.js.map | 1 + .../sourcemapped/output/webpack3/try-catches.js | 88 + .../output/webpack3/try-catches.js.map | 1 + .../sourcemapped/output/webpack3/type-module.js | 85 + .../output/webpack3/type-module.js.map | 1 + .../output/webpack3/type-script-cjs.js | 85 + .../output/webpack3/type-script-cjs.js.map | 1 + .../output/webpack3/typescript-classes.js | 179 + .../output/webpack3/typescript-classes.js.map | 1 + .../output/webpack3/webpack-functions.js | 90 + .../output/webpack3/webpack-functions.js.map | 1 + .../output/webpack3/webpack-line-mappings.js | 105 + .../output/webpack3/webpack-line-mappings.js.map | 1 + .../webpack4-babel6/babel-bindings-with-flow.js | 129 + .../babel-bindings-with-flow.js.map | 1 + .../output/webpack4-babel6/babel-classes.js | 134 + .../output/webpack4-babel6/babel-classes.js.map | 1 + .../webpack4-babel6/babel-flowtype-bindings.js | 128 + .../webpack4-babel6/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/webpack4-babel6/classes.js | 148 + .../output/webpack4-babel6/classes.js.map | 1 + .../output/webpack4-babel6/esmodules-cjs.js | 362 + .../output/webpack4-babel6/esmodules-cjs.js.map | 1 + .../output/webpack4-babel6/esmodules-es6.js | 309 + .../output/webpack4-babel6/esmodules-es6.js.map | 1 + .../output/webpack4-babel6/esmodules.js | 309 + .../output/webpack4-babel6/esmodules.js.map | 1 + .../output/webpack4-babel6/eval-maps.js | 120 + .../output/webpack4-babel6/eval-maps.js.map | 1 + .../output/webpack4-babel6/for-loops.js | 121 + .../output/webpack4-babel6/for-loops.js.map | 1 + .../sourcemapped/output/webpack4-babel6/for-of.js | 119 + .../output/webpack4-babel6/for-of.js.map | 1 + .../output/webpack4-babel6/functions.js | 118 + .../output/webpack4-babel6/functions.js.map | 1 + .../output/webpack4-babel6/lex-and-nonlex.js | 117 + .../output/webpack4-babel6/lex-and-nonlex.js.map | 1 + .../webpack4-babel6/line-start-bindings-es6.js | 127 + .../webpack4-babel6/line-start-bindings-es6.js.map | 1 + .../output/webpack4-babel6/modules-cjs.js | 112 + .../output/webpack4-babel6/modules-cjs.js.map | 1 + .../out-of-order-declarations-cjs.js | 147 + .../out-of-order-declarations-cjs.js.map | 1 + .../output/webpack4-babel6/shadowed-vars.js | 129 + .../output/webpack4-babel6/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 122 + .../step-over-for-of-array-closure.js.map | 1 + .../webpack4-babel6/step-over-for-of-array.js | 116 + .../webpack4-babel6/step-over-for-of-array.js.map | 1 + .../webpack4-babel6/step-over-for-of-closure.js | 144 + .../step-over-for-of-closure.js.map | 1 + .../output/webpack4-babel6/step-over-for-of.js | 136 + .../output/webpack4-babel6/step-over-for-of.js.map | 1 + .../webpack4-babel6/step-over-function-params.js | 122 + .../step-over-function-params.js.map | 1 + .../webpack4-babel6/step-over-regenerator-await.js | 143 + .../step-over-regenerator-await.js.map | 1 + .../output/webpack4-babel6/switches.js | 118 + .../output/webpack4-babel6/switches.js.map | 1 + .../webpack4-babel6/this-arguments-bindings.js | 121 + .../webpack4-babel6/this-arguments-bindings.js.map | 1 + .../output/webpack4-babel6/try-catches.js | 114 + .../output/webpack4-babel6/try-catches.js.map | 1 + .../output/webpack4-babel6/type-module.js | 111 + .../output/webpack4-babel6/type-module.js.map | 1 + .../output/webpack4-babel6/type-script-cjs.js | 114 + .../output/webpack4-babel6/type-script-cjs.js.map | 1 + .../output/webpack4-babel6/webpack-functions.js | 115 + .../webpack4-babel6/webpack-functions.js.map | 1 + .../webpack4-babel6/webpack-line-mappings.js | 138 + .../webpack4-babel6/webpack-line-mappings.js.map | 1 + .../webpack4-babel7/babel-bindings-with-flow.js | 127 + .../babel-bindings-with-flow.js.map | 1 + .../output/webpack4-babel7/babel-classes.js | 139 + .../output/webpack4-babel7/babel-classes.js.map | 1 + .../webpack4-babel7/babel-flowtype-bindings.js | 125 + .../webpack4-babel7/babel-flowtype-bindings.js.map | 1 + .../sourcemapped/output/webpack4-babel7/classes.js | 152 + .../output/webpack4-babel7/classes.js.map | 1 + .../output/webpack4-babel7/esmodules-cjs.js | 372 + .../output/webpack4-babel7/esmodules-cjs.js.map | 1 + .../output/webpack4-babel7/esmodules-es6.js | 302 + .../output/webpack4-babel7/esmodules-es6.js.map | 1 + .../output/webpack4-babel7/esmodules.js | 302 + .../output/webpack4-babel7/esmodules.js.map | 1 + .../output/webpack4-babel7/eval-maps.js | 116 + .../output/webpack4-babel7/eval-maps.js.map | 1 + .../output/webpack4-babel7/for-loops.js | 124 + .../output/webpack4-babel7/for-loops.js.map | 1 + .../sourcemapped/output/webpack4-babel7/for-of.js | 118 + .../output/webpack4-babel7/for-of.js.map | 1 + .../output/webpack4-babel7/functions.js | 119 + .../output/webpack4-babel7/functions.js.map | 1 + .../output/webpack4-babel7/lex-and-nonlex.js | 117 + .../output/webpack4-babel7/lex-and-nonlex.js.map | 1 + .../webpack4-babel7/line-start-bindings-es6.js | 124 + .../webpack4-babel7/line-start-bindings-es6.js.map | 1 + .../output/webpack4-babel7/modules-cjs.js | 112 + .../output/webpack4-babel7/modules-cjs.js.map | 1 + .../out-of-order-declarations-cjs.js | 150 + .../out-of-order-declarations-cjs.js.map | 1 + .../output/webpack4-babel7/shadowed-vars.js | 128 + .../output/webpack4-babel7/shadowed-vars.js.map | 1 + .../step-over-for-of-array-closure.js | 122 + .../step-over-for-of-array-closure.js.map | 1 + .../webpack4-babel7/step-over-for-of-array.js | 116 + .../webpack4-babel7/step-over-for-of-array.js.map | 1 + .../webpack4-babel7/step-over-for-of-closure.js | 123 + .../step-over-for-of-closure.js.map | 1 + .../output/webpack4-babel7/step-over-for-of.js | 115 + .../output/webpack4-babel7/step-over-for-of.js.map | 1 + .../webpack4-babel7/step-over-function-params.js | 127 + .../step-over-function-params.js.map | 1 + .../webpack4-babel7/step-over-regenerator-await.js | 145 + .../step-over-regenerator-await.js.map | 1 + .../output/webpack4-babel7/switches.js | 119 + .../output/webpack4-babel7/switches.js.map | 1 + .../webpack4-babel7/this-arguments-bindings.js | 122 + .../webpack4-babel7/this-arguments-bindings.js.map | 1 + .../output/webpack4-babel7/try-catches.js | 114 + .../output/webpack4-babel7/try-catches.js.map | 1 + .../output/webpack4-babel7/type-module.js | 111 + .../output/webpack4-babel7/type-module.js.map | 1 + .../output/webpack4-babel7/type-script-cjs.js | 114 + .../output/webpack4-babel7/type-script-cjs.js.map | 1 + .../output/webpack4-babel7/webpack-functions.js | 115 + .../webpack4-babel7/webpack-functions.js.map | 1 + .../webpack4-babel7/webpack-line-mappings.js | 139 + .../webpack4-babel7/webpack-line-mappings.js.map | 1 + .../sourcemapped/output/webpack4/classes.js | 127 + .../sourcemapped/output/webpack4/classes.js.map | 1 + .../sourcemapped/output/webpack4/esmodules-cjs.js | 321 + .../output/webpack4/esmodules-cjs.js.map | 1 + .../sourcemapped/output/webpack4/esmodules-es6.js | 321 + .../output/webpack4/esmodules-es6.js.map | 1 + .../sourcemapped/output/webpack4/esmodules.js | 321 + .../sourcemapped/output/webpack4/esmodules.js.map | 1 + .../sourcemapped/output/webpack4/eval-maps.js | 121 + .../sourcemapped/output/webpack4/eval-maps.js.map | 1 + .../sourcemapped/output/webpack4/for-loops.js | 120 + .../sourcemapped/output/webpack4/for-loops.js.map | 1 + .../sourcemapped/output/webpack4/for-of.js | 117 + .../sourcemapped/output/webpack4/for-of.js.map | 1 + .../sourcemapped/output/webpack4/functions.js | 119 + .../sourcemapped/output/webpack4/functions.js.map | 1 + .../sourcemapped/output/webpack4/lex-and-nonlex.js | 114 + .../output/webpack4/lex-and-nonlex.js.map | 1 + .../output/webpack4/line-start-bindings-es6.js | 128 + .../output/webpack4/line-start-bindings-es6.js.map | 1 + .../sourcemapped/output/webpack4/modules-cjs.js | 110 + .../output/webpack4/modules-cjs.js.map | 1 + .../webpack4/out-of-order-declarations-cjs.js | 137 + .../webpack4/out-of-order-declarations-cjs.js.map | 1 + .../sourcemapped/output/webpack4/shadowed-vars.js | 125 + .../output/webpack4/shadowed-vars.js.map | 1 + .../webpack4/step-over-for-of-array-closure.js | 115 + .../webpack4/step-over-for-of-array-closure.js.map | 1 + .../output/webpack4/step-over-for-of-array.js | 115 + .../output/webpack4/step-over-for-of-array.js.map | 1 + .../output/webpack4/step-over-for-of-closure.js | 118 + .../webpack4/step-over-for-of-closure.js.map | 1 + .../output/webpack4/step-over-for-of.js | 116 + .../output/webpack4/step-over-for-of.js.map | 1 + .../output/webpack4/step-over-function-params.js | 113 + .../webpack4/step-over-function-params.js.map | 1 + .../output/webpack4/step-over-regenerator-await.js | 120 + .../webpack4/step-over-regenerator-await.js.map | 1 + .../sourcemapped/output/webpack4/switches.js | 118 + .../sourcemapped/output/webpack4/switches.js.map | 1 + .../output/webpack4/this-arguments-bindings.js | 119 + .../output/webpack4/this-arguments-bindings.js.map | 1 + .../sourcemapped/output/webpack4/try-catches.js | 115 + .../output/webpack4/try-catches.js.map | 1 + .../sourcemapped/output/webpack4/type-module.js | 112 + .../output/webpack4/type-module.js.map | 1 + .../output/webpack4/type-script-cjs.js | 112 + .../output/webpack4/type-script-cjs.js.map | 1 + .../output/webpack4/typescript-classes.js | 211 + .../output/webpack4/typescript-classes.js.map | 1 + .../output/webpack4/webpack-functions.js | 117 + .../output/webpack4/webpack-functions.js.map | 1 + .../output/webpack4/webpack-line-mappings.js | 138 + .../output/webpack4/webpack-line-mappings.js.map | 1 + .../mochitest/examples/sourcemapped/package.json | 16 + .../examples/sourcemapped/polyfill-bundle.js | 9037 ++ .../mochitest/examples/sourcemapped/tsconfig.json | 10 + .../test/mochitest/examples/sourcemapped/yarn.lock | 2177 + .../mochitest/examples/sourcemaps-indexed/main.js | 15 + .../examples/sourcemaps-indexed/main.js.map | 30 + .../examples/sourcemaps-indexed/main.min.js | 2 + .../sourcemaps-reload-compressed/README.md | 6 + .../sourcemaps-reload-compressed/package.json | 20 + .../v1/bundle-with-another-original.js | 2 + .../v1/bundle-with-another-original.js.map | 1 + .../sourcemaps-reload-compressed/v1/bundle.js | 2 + .../sourcemaps-reload-compressed/v1/bundle.js.map | 1 + .../sourcemaps-reload-compressed/v1/iframe.html | 29 + .../sourcemaps-reload-compressed/v1/index.html | 74 + .../sourcemaps-reload-compressed/v1/onload.js | 21 + .../v1/original-with-no-update.js | 9 + .../sourcemaps-reload-compressed/v1/original.js | 10 + .../sourcemaps-reload-compressed/v1/query.js.x=1 | 1 + .../sourcemaps-reload-compressed/v1/query.js.x=2 | 1 + .../sourcemaps-reload-compressed/v1/query2.js.y=3 | 1 + .../v1/removed-original.js | 5 + .../v1/replaced-bundle.js | 2 + .../v1/replaced-bundle.js.map | 1 + .../sourcemaps-reload-compressed/v1/same-url.sjs | 20 + .../sourcemaps-reload-compressed/v1/script.js | 8 + .../v1/test-functions.js | 14 + .../v1/webpack.config.js | 49 + .../v2/another-original.js | 15 + .../v2/bundle-with-another-original.js | 2 + .../v2/bundle-with-another-original.js.map | 1 + .../sourcemaps-reload-compressed/v2/bundle.js | 2 + .../sourcemaps-reload-compressed/v2/bundle.js.map | 1 + .../sourcemaps-reload-compressed/v2/iframe.html | 29 + .../sourcemaps-reload-compressed/v2/index.html | 32 + .../v2/new-original.js | 6 + .../v2/original-with-no-update.js | 9 + .../sourcemaps-reload-compressed/v2/original.js | 13 + .../v2/replaced-bundle.js | 2 + .../v2/replaced-bundle.js.map | 1 + .../sourcemaps-reload-compressed/v2/script.js | 22 + .../v2/webpack.config.js | 54 + .../sourcemaps-reload-compressed/v3/bundle.js | 2 + .../sourcemaps-reload-compressed/v3/bundle.js.map | 1 + .../sourcemaps-reload-compressed/v3/index.html | 17 + .../sourcemaps-reload-compressed/v3/original.js | 3 + .../v3/webpack.config.js | 31 + .../sourcemaps-reload-uncompressed/README.md | 11 + .../sourcemaps-reload-uncompressed/package.json | 19 + .../v1/bundle-with-another-original.js | 89 + .../v1/bundle-with-another-original.js.map | 1 + .../sourcemaps-reload-uncompressed/v1/bundle.js | 90 + .../v1/bundle.js.map | 1 + .../sourcemaps-reload-uncompressed/v1/iframe.html | 29 + .../sourcemaps-reload-uncompressed/v1/index.html | 77 + .../sourcemaps-reload-uncompressed/v1/onload.js | 21 + .../v1/original-with-no-update.js | 9 + .../sourcemaps-reload-uncompressed/v1/original.js | 10 + .../sourcemaps-reload-uncompressed/v1/query.js.x=1 | 1 + .../sourcemaps-reload-uncompressed/v1/query.js.x=2 | 1 + .../v1/query2.js.y=3 | 1 + .../v1/react-component-module.js | 2 + .../v1/removed-original.js | 5 + .../v1/replaced-bundle.js | 85 + .../v1/replaced-bundle.js.map | 1 + .../sourcemaps-reload-uncompressed/v1/same-url.sjs | 20 + .../sourcemaps-reload-uncompressed/v1/script.js | 8 + .../v1/test-functions.js | 14 + .../v1/webpack.config.js | 49 + .../v2/another-original.js | 15 + .../v2/bundle-with-another-original.js | 110 + .../v2/bundle-with-another-original.js.map | 1 + .../sourcemaps-reload-uncompressed/v2/bundle.js | 93 + .../v2/bundle.js.map | 1 + .../sourcemaps-reload-uncompressed/v2/iframe.html | 29 + .../sourcemaps-reload-uncompressed/v2/index.html | 32 + .../v2/new-original.js | 6 + .../v2/original-with-no-update.js | 9 + .../sourcemaps-reload-uncompressed/v2/original.js | 13 + .../v2/replaced-bundle.js | 86 + .../v2/replaced-bundle.js.map | 1 + .../sourcemaps-reload-uncompressed/v2/script.js | 22 + .../v2/webpack.config.js | 54 + .../sourcemaps-reload-uncompressed/v3/bundle.js | 83 + .../v3/bundle.js.map | 1 + .../sourcemaps-reload-uncompressed/v3/index.html | 17 + .../sourcemaps-reload-uncompressed/v3/original.js | 3 + .../v3/webpack.config.js | 31 + .../examples/sourcemaps-with-ignorelist/bundle.js | 35 + .../sourcemaps-with-ignorelist/bundle.js.map | 1 + .../sourcemaps-with-ignorelist/package.json | 15 + .../sourcemaps-with-ignorelist/rollup.config.js | 14 + .../sourcemaps-with-ignorelist/src/index.js | 11 + .../sourcemaps-with-ignorelist/src/original-1.js | 4 + .../sourcemaps-with-ignorelist/src/original-2.js | 4 + .../sourcemaps-with-ignorelist/src/original-3.js | 4 + .../sourcemaps-with-ignorelist/src/original-4.js | 4 + .../sourcemaps-with-ignorelist/src/original-5.js | 3 + .../examples/sourcemaps-with-sections/xbundle.js | 7 + .../sourcemaps-with-sections/xbundle.js.map | 25 + .../test/mochitest/examples/sourcemaps/bundle.js | 96 + .../mochitest/examples/sourcemaps/bundle.js.map | 21 + .../test/mochitest/examples/sourcemaps2/main.js | 15 + .../mochitest/examples/sourcemaps2/main.js.map | 1 + .../mochitest/examples/sourcemaps2/main.min.js | 2 + .../test/mochitest/examples/sourcemaps3/.babelrc | 1 + .../test/mochitest/examples/sourcemaps3/.gitignore | 2 + .../test/mochitest/examples/sourcemaps3/bundle.js | 2 + .../mochitest/examples/sourcemaps3/bundle.js.map | 1 + .../mochitest/examples/sourcemaps3/package.json | 19 + .../test/mochitest/examples/sourcemaps3/sorted.js | 43 + .../test/mochitest/examples/sourcemaps3/test.js | 7 + .../examples/sourcemaps3/webpack.config.js | 31 + .../debugger/test/mochitest/examples/sum/sum.js | 3 + .../test/mochitest/examples/sum/sum.min.js | 2 + .../test/mochitest/examples/sum/sum.min.js.map | 1 + .../debugger/test/mochitest/examples/times2.js | 3 + .../debugger/test/mochitest/examples/top-level.js | 3 + .../debugger/test/mochitest/examples/trigger-gc.js | 4 + .../mochitest/examples/wasm-sourcemaps/README.md | 20 + .../test/mochitest/examples/wasm-sourcemaps/fib.c | 17 + .../examples/wasm-sourcemaps/fib.debug.wasm | Bin 0 -> 1333 bytes .../mochitest/examples/wasm-sourcemaps/fib.wasm | Bin 0 -> 1516 bytes .../examples/wasm-sourcemaps/fib.wasm.map | 1 + .../test/mochitest/examples/webpack.config.js | 8 + .../test/mochitest/examples/worker-exception.js | 4 + devtools/client/debugger/test/mochitest/head.js | 255 + .../integration-tests/1-reload-same-original.js | 140 + .../2-reload-replaced-original.js | 128 + .../3-reload-changed-generated.js | 179 + .../test/mochitest/integration-tests/README.md | 29 + .../client/debugger/test/mochitest/shared-head.js | 2719 + .../client/debugger/test/xpcshell/.eslintrc.js | 10 + .../test_sourcetree_utils_getRelativePath.js | 70 + .../client/debugger/test/xpcshell/xpcshell.ini | 6 + devtools/client/debugger/webpack.config.js | 112 + devtools/client/debugger/yarn.lock | 8696 ++ 1853 files changed, 454256 insertions(+) create mode 100644 devtools/client/debugger/.remarkignore create mode 100644 devtools/client/debugger/.remarkrc create mode 100644 devtools/client/debugger/babel.config.js create mode 100644 devtools/client/debugger/bin/bundle.js create mode 100644 devtools/client/debugger/bin/module-manifest.json create mode 100644 devtools/client/debugger/bin/watch.js create mode 100644 devtools/client/debugger/configs/mozilla-central-mappings.js create mode 100644 devtools/client/debugger/dist/moz.build create mode 100644 devtools/client/debugger/dist/parser-worker.js create mode 100644 devtools/client/debugger/dist/pretty-print-worker.js create mode 100644 devtools/client/debugger/dist/search-worker.js create mode 100644 devtools/client/debugger/dist/vendors.css create mode 100644 devtools/client/debugger/dist/vendors.js create mode 100644 devtools/client/debugger/images/arrow-down.svg create mode 100644 devtools/client/debugger/images/arrow-up.svg create mode 100644 devtools/client/debugger/images/arrow.svg create mode 100644 devtools/client/debugger/images/blackBox.svg create mode 100644 devtools/client/debugger/images/breadcrumbs-divider.svg create mode 100644 devtools/client/debugger/images/breakpoint.svg create mode 100644 devtools/client/debugger/images/case-match.svg create mode 100644 devtools/client/debugger/images/column-marker.svg create mode 100644 devtools/client/debugger/images/command-chevron.svg create mode 100644 devtools/client/debugger/images/disable-pausing.svg create mode 100644 devtools/client/debugger/images/enable-pausing.svg create mode 100644 devtools/client/debugger/images/file-small.svg create mode 100644 devtools/client/debugger/images/folder.svg create mode 100644 devtools/client/debugger/images/globe-small.svg create mode 100644 devtools/client/debugger/images/globe.svg create mode 100644 devtools/client/debugger/images/help.svg create mode 100644 devtools/client/debugger/images/home.svg create mode 100644 devtools/client/debugger/images/loader.svg create mode 100644 devtools/client/debugger/images/markup-breakpoint.svg create mode 100644 devtools/client/debugger/images/next-circle.svg create mode 100644 devtools/client/debugger/images/next.svg create mode 100644 devtools/client/debugger/images/pane-collapse.svg create mode 100644 devtools/client/debugger/images/pane-expand.svg create mode 100644 devtools/client/debugger/images/pause.svg create mode 100644 devtools/client/debugger/images/plus.svg create mode 100644 devtools/client/debugger/images/prettyPrint.svg create mode 100644 devtools/client/debugger/images/regex-match.svg create mode 100644 devtools/client/debugger/images/reload.svg create mode 100644 devtools/client/debugger/images/search.svg create mode 100644 devtools/client/debugger/images/sources/aframe.svg create mode 100644 devtools/client/debugger/images/sources/angular.svg create mode 100644 devtools/client/debugger/images/sources/babel.svg create mode 100644 devtools/client/debugger/images/sources/backbone.svg create mode 100644 devtools/client/debugger/images/sources/choo.svg create mode 100644 devtools/client/debugger/images/sources/coffeescript.svg create mode 100644 devtools/client/debugger/images/sources/dojo.svg create mode 100644 devtools/client/debugger/images/sources/ember.svg create mode 100644 devtools/client/debugger/images/sources/express.svg create mode 100644 devtools/client/debugger/images/sources/extension.svg create mode 100644 devtools/client/debugger/images/sources/immutable.svg create mode 100644 devtools/client/debugger/images/sources/javascript.svg create mode 100644 devtools/client/debugger/images/sources/jquery.svg create mode 100644 devtools/client/debugger/images/sources/lodash.svg create mode 100644 devtools/client/debugger/images/sources/marko.svg create mode 100644 devtools/client/debugger/images/sources/mobx.svg create mode 100644 devtools/client/debugger/images/sources/nextjs.svg create mode 100644 devtools/client/debugger/images/sources/node.svg create mode 100644 devtools/client/debugger/images/sources/nuxtjs.svg create mode 100644 devtools/client/debugger/images/sources/preact.svg create mode 100644 devtools/client/debugger/images/sources/pug.svg create mode 100644 devtools/client/debugger/images/sources/react.svg create mode 100644 devtools/client/debugger/images/sources/redux.svg create mode 100644 devtools/client/debugger/images/sources/rxjs.svg create mode 100644 devtools/client/debugger/images/sources/sencha-extjs.svg create mode 100644 devtools/client/debugger/images/sources/typescript.svg create mode 100644 devtools/client/debugger/images/sources/underscore.svg create mode 100644 devtools/client/debugger/images/sources/vuejs.svg create mode 100644 devtools/client/debugger/images/sources/webpack.svg create mode 100644 devtools/client/debugger/images/stepIn.svg create mode 100644 devtools/client/debugger/images/stepOut.svg create mode 100644 devtools/client/debugger/images/tab.svg create mode 100644 devtools/client/debugger/images/trace.svg create mode 100644 devtools/client/debugger/images/webconsole-logpoint.svg create mode 100644 devtools/client/debugger/images/whole-word-match.svg create mode 100644 devtools/client/debugger/images/window.svg create mode 100644 devtools/client/debugger/images/worker.svg create mode 100644 devtools/client/debugger/index.html create mode 100644 devtools/client/debugger/jest-test.config.js create mode 100644 devtools/client/debugger/jest.config.js create mode 100644 devtools/client/debugger/moz.build create mode 100644 devtools/client/debugger/package.json create mode 100644 devtools/client/debugger/panel.js create mode 100644 devtools/client/debugger/src/.eslintignore create mode 100644 devtools/client/debugger/src/.eslintrc.js create mode 100644 devtools/client/debugger/src/actions/README.md create mode 100644 devtools/client/debugger/src/actions/ast/index.js create mode 100644 devtools/client/debugger/src/actions/ast/moz.build create mode 100644 devtools/client/debugger/src/actions/ast/setInScopeLines.js create mode 100644 devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js create mode 100644 devtools/client/debugger/src/actions/breakpoints/breakpointPositions.js create mode 100644 devtools/client/debugger/src/actions/breakpoints/index.js create mode 100644 devtools/client/debugger/src/actions/breakpoints/modify.js create mode 100644 devtools/client/debugger/src/actions/breakpoints/moz.build create mode 100644 devtools/client/debugger/src/actions/breakpoints/syncBreakpoint.js create mode 100644 devtools/client/debugger/src/actions/breakpoints/tests/__snapshots__/breakpoints.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js create mode 100644 devtools/client/debugger/src/actions/event-listeners.js create mode 100644 devtools/client/debugger/src/actions/exceptions.js create mode 100644 devtools/client/debugger/src/actions/expressions.js create mode 100644 devtools/client/debugger/src/actions/file-search.js create mode 100644 devtools/client/debugger/src/actions/index.js create mode 100644 devtools/client/debugger/src/actions/moz.build create mode 100644 devtools/client/debugger/src/actions/navigation.js create mode 100644 devtools/client/debugger/src/actions/pause/breakOnNext.js create mode 100644 devtools/client/debugger/src/actions/pause/commands.js create mode 100644 devtools/client/debugger/src/actions/pause/continueToHere.js create mode 100644 devtools/client/debugger/src/actions/pause/expandScopes.js create mode 100644 devtools/client/debugger/src/actions/pause/fetchFrames.js create mode 100644 devtools/client/debugger/src/actions/pause/fetchScopes.js create mode 100644 devtools/client/debugger/src/actions/pause/highlightCalls.js create mode 100644 devtools/client/debugger/src/actions/pause/index.js create mode 100644 devtools/client/debugger/src/actions/pause/inlinePreview.js create mode 100644 devtools/client/debugger/src/actions/pause/mapDisplayNames.js create mode 100644 devtools/client/debugger/src/actions/pause/mapFrames.js create mode 100644 devtools/client/debugger/src/actions/pause/mapScopes.js create mode 100644 devtools/client/debugger/src/actions/pause/moz.build create mode 100644 devtools/client/debugger/src/actions/pause/pauseOnExceptions.js create mode 100644 devtools/client/debugger/src/actions/pause/paused.js create mode 100644 devtools/client/debugger/src/actions/pause/resetBreakpointsPaneState.js create mode 100644 devtools/client/debugger/src/actions/pause/resumed.js create mode 100644 devtools/client/debugger/src/actions/pause/selectFrame.js create mode 100644 devtools/client/debugger/src/actions/pause/skipPausing.js create mode 100644 devtools/client/debugger/src/actions/pause/tests/__snapshots__/pauseOnExceptions.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/pause/tests/pause.spec.js create mode 100644 devtools/client/debugger/src/actions/pause/tests/pauseOnExceptions.spec.js create mode 100644 devtools/client/debugger/src/actions/pause/tests/skipPausing.spec.js create mode 100644 devtools/client/debugger/src/actions/preview.js create mode 100644 devtools/client/debugger/src/actions/project-text-search.js create mode 100644 devtools/client/debugger/src/actions/quick-open.js create mode 100644 devtools/client/debugger/src/actions/source-actors.js create mode 100644 devtools/client/debugger/src/actions/sources-tree.js create mode 100644 devtools/client/debugger/src/actions/sources/blackbox.js create mode 100644 devtools/client/debugger/src/actions/sources/breakableLines.js create mode 100644 devtools/client/debugger/src/actions/sources/index.js create mode 100644 devtools/client/debugger/src/actions/sources/loadSourceText.js create mode 100644 devtools/client/debugger/src/actions/sources/moz.build create mode 100644 devtools/client/debugger/src/actions/sources/newSources.js create mode 100644 devtools/client/debugger/src/actions/sources/prettyPrint.js create mode 100644 devtools/client/debugger/src/actions/sources/select.js create mode 100644 devtools/client/debugger/src/actions/sources/symbols.js create mode 100644 devtools/client/debugger/src/actions/sources/tests/blackbox.spec.js create mode 100644 devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js create mode 100644 devtools/client/debugger/src/actions/sources/tests/newSources.spec.js create mode 100644 devtools/client/debugger/src/actions/sources/tests/select.spec.js create mode 100644 devtools/client/debugger/src/actions/tabs.js create mode 100644 devtools/client/debugger/src/actions/tests/__snapshots__/expressions.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/tests/__snapshots__/pending-breakpoints.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap create mode 100644 devtools/client/debugger/src/actions/tests/expressions.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/fixtures/immutable.js create mode 100644 devtools/client/debugger/src/actions/tests/fixtures/reactComponent.js create mode 100644 devtools/client/debugger/src/actions/tests/fixtures/reactFuncComponent.js create mode 100644 devtools/client/debugger/src/actions/tests/fixtures/scopes.js create mode 100644 devtools/client/debugger/src/actions/tests/helpers/breakpoints.js create mode 100644 devtools/client/debugger/src/actions/tests/helpers/mockCommandClient.js create mode 100644 devtools/client/debugger/src/actions/tests/helpers/readFixture.js create mode 100644 devtools/client/debugger/src/actions/tests/navigation.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/pending-breakpoints.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/preview.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/sources-tree.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/tabs.spec.js create mode 100644 devtools/client/debugger/src/actions/tests/ui.spec.js create mode 100644 devtools/client/debugger/src/actions/threads.js create mode 100644 devtools/client/debugger/src/actions/toolbox.js create mode 100644 devtools/client/debugger/src/actions/tracing.js create mode 100644 devtools/client/debugger/src/actions/ui.js create mode 100644 devtools/client/debugger/src/actions/utils/create-store.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/context.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/log.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/moz.build create mode 100644 devtools/client/debugger/src/actions/utils/middleware/promise.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/thunk.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/timing.js create mode 100644 devtools/client/debugger/src/actions/utils/middleware/wait-service.js create mode 100644 devtools/client/debugger/src/actions/utils/moz.build create mode 100644 devtools/client/debugger/src/client/README.md create mode 100644 devtools/client/debugger/src/client/firefox.js create mode 100644 devtools/client/debugger/src/client/firefox/commands.js create mode 100644 devtools/client/debugger/src/client/firefox/create.js create mode 100644 devtools/client/debugger/src/client/firefox/moz.build create mode 100644 devtools/client/debugger/src/client/moz.build create mode 100644 devtools/client/debugger/src/components/A11yIntention.css create mode 100644 devtools/client/debugger/src/components/A11yIntention.js create mode 100644 devtools/client/debugger/src/components/App.css create mode 100644 devtools/client/debugger/src/components/App.js create mode 100644 devtools/client/debugger/src/components/Editor/BlackboxLines.js create mode 100644 devtools/client/debugger/src/components/Editor/Breakpoint.js create mode 100644 devtools/client/debugger/src/components/Editor/Breakpoints.css create mode 100644 devtools/client/debugger/src/components/Editor/Breakpoints.js create mode 100644 devtools/client/debugger/src/components/Editor/ColumnBreakpoint.js create mode 100644 devtools/client/debugger/src/components/Editor/ColumnBreakpoints.js create mode 100644 devtools/client/debugger/src/components/Editor/ConditionalPanel.css create mode 100644 devtools/client/debugger/src/components/Editor/ConditionalPanel.js create mode 100644 devtools/client/debugger/src/components/Editor/DebugLine.js create mode 100644 devtools/client/debugger/src/components/Editor/Editor.css create mode 100644 devtools/client/debugger/src/components/Editor/EditorMenu.js create mode 100644 devtools/client/debugger/src/components/Editor/EmptyLines.js create mode 100644 devtools/client/debugger/src/components/Editor/Exception.js create mode 100644 devtools/client/debugger/src/components/Editor/Exceptions.js create mode 100644 devtools/client/debugger/src/components/Editor/Footer.css create mode 100644 devtools/client/debugger/src/components/Editor/Footer.js create mode 100644 devtools/client/debugger/src/components/Editor/HighlightCalls.css create mode 100644 devtools/client/debugger/src/components/Editor/HighlightCalls.js create mode 100644 devtools/client/debugger/src/components/Editor/HighlightLine.js create mode 100644 devtools/client/debugger/src/components/Editor/HighlightLines.js create mode 100644 devtools/client/debugger/src/components/Editor/InlinePreview.css create mode 100644 devtools/client/debugger/src/components/Editor/InlinePreview.js create mode 100644 devtools/client/debugger/src/components/Editor/InlinePreviewRow.js create mode 100644 devtools/client/debugger/src/components/Editor/InlinePreviews.js create mode 100644 devtools/client/debugger/src/components/Editor/Preview.css create mode 100644 devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js create mode 100644 devtools/client/debugger/src/components/Editor/Preview/Popup.css create mode 100644 devtools/client/debugger/src/components/Editor/Preview/Popup.js create mode 100644 devtools/client/debugger/src/components/Editor/Preview/index.js create mode 100644 devtools/client/debugger/src/components/Editor/Preview/moz.build create mode 100644 devtools/client/debugger/src/components/Editor/Preview/tests/Popup.spec.js create mode 100644 devtools/client/debugger/src/components/Editor/SearchInFileBar.css create mode 100644 devtools/client/debugger/src/components/Editor/SearchInFileBar.js create mode 100644 devtools/client/debugger/src/components/Editor/Tab.js create mode 100644 devtools/client/debugger/src/components/Editor/Tabs.css create mode 100644 devtools/client/debugger/src/components/Editor/Tabs.js create mode 100644 devtools/client/debugger/src/components/Editor/index.js create mode 100644 devtools/client/debugger/src/components/Editor/menus/breakpoints.js create mode 100644 devtools/client/debugger/src/components/Editor/menus/editor.js create mode 100644 devtools/client/debugger/src/components/Editor/menus/moz.build create mode 100644 devtools/client/debugger/src/components/Editor/menus/source.js create mode 100644 devtools/client/debugger/src/components/Editor/moz.build create mode 100644 devtools/client/debugger/src/components/Editor/tests/Breakpoints.spec.js create mode 100644 devtools/client/debugger/src/components/Editor/tests/ConditionalPanel.spec.js create mode 100644 devtools/client/debugger/src/components/Editor/tests/DebugLine.spec.js create mode 100644 devtools/client/debugger/src/components/Editor/tests/Footer.spec.js create mode 100644 devtools/client/debugger/src/components/Editor/tests/__snapshots__/Breakpoints.spec.js.snap create mode 100644 devtools/client/debugger/src/components/Editor/tests/__snapshots__/ConditionalPanel.spec.js.snap create mode 100644 devtools/client/debugger/src/components/Editor/tests/__snapshots__/Footer.spec.js.snap create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/Outline.css create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/Outline.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/OutlineFilter.css create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/OutlineFilter.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/ProjectSearch.css create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/ProjectSearch.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/Sources.css create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/SourcesTree.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/SourcesTreeItem.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/index.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/moz.build create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/tests/ProjectSearch.spec.js create mode 100644 devtools/client/debugger/src/components/PrimaryPanes/tests/__snapshots__/ProjectSearch.spec.js.snap create mode 100644 devtools/client/debugger/src/components/QuickOpenModal.css create mode 100644 devtools/client/debugger/src/components/QuickOpenModal.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoint.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/BreakpointHeading.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/BreakpointHeadingsContextMenu.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/BreakpointsContextMenu.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/ExceptionOption.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/index.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/moz.build create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/tests/Breakpoint.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/tests/BreakpointsContextMenu.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/tests/ExceptionOption.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/tests/__snapshots__/Breakpoint.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Breakpoints/tests/__snapshots__/ExceptionOption.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/CommandBar.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/CommandBar.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/DOMMutationBreakpoints.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/DOMMutationBreakpoints.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/EventListeners.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/EventListeners.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Expressions.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Expressions.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/Frame.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameIndent.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/FrameMenu.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/Frames.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/Group.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/index.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/moz.build create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frame.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/FrameMenu.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Frames.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/Group.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frame.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Frames.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Frames/tests/__snapshots__/Group.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Scopes.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Scopes.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/SecondaryPanes.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Thread.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Threads.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/Threads.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/XHRBreakpoints.css create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/XHRBreakpoints.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/index.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/moz.build create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/CommandBar.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/EventListeners.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/Expressions.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/XHRBreakpoints.spec.js create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/EventListeners.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/Expressions.spec.js.snap create mode 100644 devtools/client/debugger/src/components/SecondaryPanes/tests/__snapshots__/XHRBreakpoints.spec.js.snap create mode 100644 devtools/client/debugger/src/components/ShortcutsModal.css create mode 100644 devtools/client/debugger/src/components/ShortcutsModal.js create mode 100644 devtools/client/debugger/src/components/WelcomeBox.css create mode 100644 devtools/client/debugger/src/components/WelcomeBox.js create mode 100644 devtools/client/debugger/src/components/moz.build create mode 100644 devtools/client/debugger/src/components/shared/AccessibleImage.css create mode 100644 devtools/client/debugger/src/components/shared/AccessibleImage.js create mode 100644 devtools/client/debugger/src/components/shared/Accordion.css create mode 100644 devtools/client/debugger/src/components/shared/Accordion.js create mode 100644 devtools/client/debugger/src/components/shared/Badge.css create mode 100644 devtools/client/debugger/src/components/shared/Badge.js create mode 100644 devtools/client/debugger/src/components/shared/BracketArrow.css create mode 100644 devtools/client/debugger/src/components/shared/BracketArrow.js create mode 100644 devtools/client/debugger/src/components/shared/Button/CloseButton.js create mode 100644 devtools/client/debugger/src/components/shared/Button/CommandBarButton.js create mode 100644 devtools/client/debugger/src/components/shared/Button/PaneToggleButton.js create mode 100644 devtools/client/debugger/src/components/shared/Button/index.js create mode 100644 devtools/client/debugger/src/components/shared/Button/moz.build create mode 100644 devtools/client/debugger/src/components/shared/Button/styles/CloseButton.css create mode 100644 devtools/client/debugger/src/components/shared/Button/styles/CommandBarButton.css create mode 100644 devtools/client/debugger/src/components/shared/Button/styles/PaneToggleButton.css create mode 100644 devtools/client/debugger/src/components/shared/Button/styles/moz.build create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/CloseButton.spec.js create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/CommandBarButton.spec.js create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/PaneToggleButton.spec.js create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/__snapshots__/CloseButton.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/__snapshots__/CommandBarButton.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/Button/tests/__snapshots__/PaneToggleButton.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/Dropdown.css create mode 100644 devtools/client/debugger/src/components/shared/Dropdown.js create mode 100644 devtools/client/debugger/src/components/shared/Modal.css create mode 100644 devtools/client/debugger/src/components/shared/Modal.js create mode 100644 devtools/client/debugger/src/components/shared/Popover.css create mode 100644 devtools/client/debugger/src/components/shared/Popover.js create mode 100644 devtools/client/debugger/src/components/shared/PreviewFunction.css create mode 100644 devtools/client/debugger/src/components/shared/PreviewFunction.js create mode 100644 devtools/client/debugger/src/components/shared/ResultList.css create mode 100644 devtools/client/debugger/src/components/shared/ResultList.js create mode 100644 devtools/client/debugger/src/components/shared/SearchInput.css create mode 100644 devtools/client/debugger/src/components/shared/SearchInput.js create mode 100644 devtools/client/debugger/src/components/shared/SmartGap.js create mode 100644 devtools/client/debugger/src/components/shared/SourceIcon.css create mode 100644 devtools/client/debugger/src/components/shared/SourceIcon.js create mode 100644 devtools/client/debugger/src/components/shared/menu.css create mode 100644 devtools/client/debugger/src/components/shared/moz.build create mode 100644 devtools/client/debugger/src/components/shared/tests/Accordion.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/Badge.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/BracketArrow.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/Dropdown.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/Modal.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/Popover.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/PreviewFunction.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/ResultList.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/SearchInput.spec.js create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/Accordion.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/Badge.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/BracketArrow.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/Dropdown.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/Modal.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/Popover.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/PreviewFunction.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/ResultList.spec.js.snap create mode 100644 devtools/client/debugger/src/components/shared/tests/__snapshots__/SearchInput.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/A11yIntention.spec.js create mode 100644 devtools/client/debugger/src/components/test/Outline.spec.js create mode 100644 devtools/client/debugger/src/components/test/OutlineFilter.spec.js create mode 100644 devtools/client/debugger/src/components/test/QuickOpenModal.spec.js create mode 100644 devtools/client/debugger/src/components/test/ShortcutsModal.spec.js create mode 100644 devtools/client/debugger/src/components/test/WelcomeBox.spec.js create mode 100644 devtools/client/debugger/src/components/test/WhyPaused.spec.js create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/A11yIntention.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/Outline.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/OutlineFilter.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/QuickOpenModal.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/ShortcutsModal.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/WelcomeBox.spec.js.snap create mode 100644 devtools/client/debugger/src/components/test/__snapshots__/WhyPaused.spec.js.snap create mode 100644 devtools/client/debugger/src/components/variables.css create mode 100644 devtools/client/debugger/src/constants.js create mode 100644 devtools/client/debugger/src/context-menu/menu.js create mode 100644 devtools/client/debugger/src/context-menu/moz.build create mode 100644 devtools/client/debugger/src/debugger.css create mode 100644 devtools/client/debugger/src/main.js create mode 100644 devtools/client/debugger/src/moz.build create mode 100644 devtools/client/debugger/src/reducers/ast.js create mode 100644 devtools/client/debugger/src/reducers/breakpoints.js create mode 100644 devtools/client/debugger/src/reducers/event-listeners.js create mode 100644 devtools/client/debugger/src/reducers/exceptions.js create mode 100644 devtools/client/debugger/src/reducers/expressions.js create mode 100644 devtools/client/debugger/src/reducers/index.js create mode 100644 devtools/client/debugger/src/reducers/moz.build create mode 100644 devtools/client/debugger/src/reducers/pause.js create mode 100644 devtools/client/debugger/src/reducers/pending-breakpoints.js create mode 100644 devtools/client/debugger/src/reducers/preview.js create mode 100644 devtools/client/debugger/src/reducers/project-text-search.js create mode 100644 devtools/client/debugger/src/reducers/quick-open.js create mode 100644 devtools/client/debugger/src/reducers/source-actors.js create mode 100644 devtools/client/debugger/src/reducers/source-blackbox.js create mode 100644 devtools/client/debugger/src/reducers/sources-content.js create mode 100644 devtools/client/debugger/src/reducers/sources-tree.js create mode 100644 devtools/client/debugger/src/reducers/sources.js create mode 100644 devtools/client/debugger/src/reducers/tabs.js create mode 100644 devtools/client/debugger/src/reducers/tests/breakpoints.spec.js create mode 100644 devtools/client/debugger/src/reducers/tests/quick-open.spec.js create mode 100644 devtools/client/debugger/src/reducers/tests/ui.spec.js create mode 100644 devtools/client/debugger/src/reducers/threads.js create mode 100644 devtools/client/debugger/src/reducers/ui.js create mode 100644 devtools/client/debugger/src/selectors/ast.js create mode 100644 devtools/client/debugger/src/selectors/breakpointAtLocation.js create mode 100644 devtools/client/debugger/src/selectors/breakpointSources.js create mode 100644 devtools/client/debugger/src/selectors/breakpoints.js create mode 100644 devtools/client/debugger/src/selectors/event-listeners.js create mode 100644 devtools/client/debugger/src/selectors/exceptions.js create mode 100644 devtools/client/debugger/src/selectors/expressions.js create mode 100644 devtools/client/debugger/src/selectors/getCallStackFrames.js create mode 100644 devtools/client/debugger/src/selectors/index.js create mode 100644 devtools/client/debugger/src/selectors/isLineInScope.js create mode 100644 devtools/client/debugger/src/selectors/isSelectedFrameVisible.js create mode 100644 devtools/client/debugger/src/selectors/moz.build create mode 100644 devtools/client/debugger/src/selectors/pause.js create mode 100644 devtools/client/debugger/src/selectors/pending-breakpoints.js create mode 100644 devtools/client/debugger/src/selectors/preview.js create mode 100644 devtools/client/debugger/src/selectors/project-text-search.js create mode 100644 devtools/client/debugger/src/selectors/quick-open.js create mode 100644 devtools/client/debugger/src/selectors/source-actors.js create mode 100644 devtools/client/debugger/src/selectors/source-blackbox.js create mode 100644 devtools/client/debugger/src/selectors/sources-content.js create mode 100644 devtools/client/debugger/src/selectors/sources-tree.js create mode 100644 devtools/client/debugger/src/selectors/sources.js create mode 100644 devtools/client/debugger/src/selectors/tabs.js create mode 100644 devtools/client/debugger/src/selectors/test/__snapshots__/visibleColumnBreakpoints.spec.js.snap create mode 100644 devtools/client/debugger/src/selectors/test/getCallStackFrames.spec.js create mode 100644 devtools/client/debugger/src/selectors/test/visibleColumnBreakpoints.spec.js create mode 100644 devtools/client/debugger/src/selectors/threads.js create mode 100644 devtools/client/debugger/src/selectors/ui.js create mode 100644 devtools/client/debugger/src/selectors/visibleBreakpoints.js create mode 100644 devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js create mode 100644 devtools/client/debugger/src/test/__mocks__/request-animation-frame.js create mode 100644 devtools/client/debugger/src/test/fixtures/README.md create mode 100644 devtools/client/debugger/src/test/fixtures/foobar.json create mode 100644 devtools/client/debugger/src/test/fixtures/index.js create mode 100644 devtools/client/debugger/src/test/shim.js create mode 100644 devtools/client/debugger/src/test/tests-setup.js create mode 100644 devtools/client/debugger/src/utils/DevToolsUtils.js create mode 100644 devtools/client/debugger/src/utils/assert.js create mode 100644 devtools/client/debugger/src/utils/ast.js create mode 100644 devtools/client/debugger/src/utils/async-value.js create mode 100644 devtools/client/debugger/src/utils/bootstrap.js create mode 100644 devtools/client/debugger/src/utils/breakpoint/breakpointPositions.js create mode 100644 devtools/client/debugger/src/utils/breakpoint/index.js create mode 100644 devtools/client/debugger/src/utils/breakpoint/moz.build create mode 100644 devtools/client/debugger/src/utils/breakpoint/tests/index.spec.js create mode 100644 devtools/client/debugger/src/utils/build-query.js create mode 100644 devtools/client/debugger/src/utils/clipboard.js create mode 100644 devtools/client/debugger/src/utils/connect.js create mode 100644 devtools/client/debugger/src/utils/context.js create mode 100644 devtools/client/debugger/src/utils/dbg.js create mode 100644 devtools/client/debugger/src/utils/editor/create-editor.js create mode 100644 devtools/client/debugger/src/utils/editor/get-expression.js create mode 100644 devtools/client/debugger/src/utils/editor/get-token-location.js create mode 100644 devtools/client/debugger/src/utils/editor/index.js create mode 100644 devtools/client/debugger/src/utils/editor/moz.build create mode 100644 devtools/client/debugger/src/utils/editor/source-documents.js create mode 100644 devtools/client/debugger/src/utils/editor/source-editor.css create mode 100644 devtools/client/debugger/src/utils/editor/source-editor.js create mode 100644 devtools/client/debugger/src/utils/editor/source-search.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/__snapshots__/create-editor.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/editor/tests/create-editor.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/editor.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/get-expression.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/get-token-location.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/source-documents.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/tests/source-search.spec.js create mode 100644 devtools/client/debugger/src/utils/editor/token-events.js create mode 100644 devtools/client/debugger/src/utils/environment.js create mode 100644 devtools/client/debugger/src/utils/evaluation-result.js create mode 100644 devtools/client/debugger/src/utils/expressions.js create mode 100644 devtools/client/debugger/src/utils/function.js create mode 100644 devtools/client/debugger/src/utils/indentation.js create mode 100644 devtools/client/debugger/src/utils/isMinified.js create mode 100644 devtools/client/debugger/src/utils/location.js create mode 100644 devtools/client/debugger/src/utils/log.js create mode 100644 devtools/client/debugger/src/utils/memoizableAction.js create mode 100644 devtools/client/debugger/src/utils/memoize.js create mode 100644 devtools/client/debugger/src/utils/memoizeLast.js create mode 100644 devtools/client/debugger/src/utils/moz.build create mode 100644 devtools/client/debugger/src/utils/path.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/annotateFrames.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/collapseFrames.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/displayName.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/getFrameUrl.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/getLibraryFromUrl.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/index.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/moz.build create mode 100644 devtools/client/debugger/src/utils/pause/frames/tests/__snapshots__/collapseFrames.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/pause/frames/tests/annotateFrames.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/tests/collapseFrames.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/tests/displayName.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/frames/tests/getLibraryFromUrl.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/index.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/README.md create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/buildGeneratedBindingList.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/filtering.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/findGeneratedBindingFromPosition.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/getApplicableBindingsForOriginalPosition.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/index.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/locColumn.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/mappingContains.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/moz.build create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/optimizedOut.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/positionCmp.js create mode 100644 devtools/client/debugger/src/utils/pause/mapScopes/rangeMetadata.js create mode 100644 devtools/client/debugger/src/utils/pause/moz.build create mode 100644 devtools/client/debugger/src/utils/pause/scopes/getScope.js create mode 100644 devtools/client/debugger/src/utils/pause/scopes/getVariables.js create mode 100644 devtools/client/debugger/src/utils/pause/scopes/index.js create mode 100644 devtools/client/debugger/src/utils/pause/scopes/moz.build create mode 100644 devtools/client/debugger/src/utils/pause/scopes/tests/getFramePopVariables.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/scopes/tests/scopes.spec.js create mode 100644 devtools/client/debugger/src/utils/pause/scopes/utils.js create mode 100644 devtools/client/debugger/src/utils/pause/why.js create mode 100644 devtools/client/debugger/src/utils/prefs.js create mode 100644 devtools/client/debugger/src/utils/preview.js create mode 100644 devtools/client/debugger/src/utils/quick-open.js create mode 100644 devtools/client/debugger/src/utils/result-list.js create mode 100644 devtools/client/debugger/src/utils/selected-location.js create mode 100644 devtools/client/debugger/src/utils/shallow-equal.js create mode 100644 devtools/client/debugger/src/utils/source-maps.js create mode 100644 devtools/client/debugger/src/utils/source-queue.js create mode 100644 devtools/client/debugger/src/utils/source.js create mode 100644 devtools/client/debugger/src/utils/sources-tree/getURL.js create mode 100644 devtools/client/debugger/src/utils/sources-tree/moz.build create mode 100644 devtools/client/debugger/src/utils/sources-tree/tests/getUrl.spec.js create mode 100644 devtools/client/debugger/src/utils/sources-tree/utils.js create mode 100644 devtools/client/debugger/src/utils/tabs.js create mode 100644 devtools/client/debugger/src/utils/task.js create mode 100644 devtools/client/debugger/src/utils/telemetry.js create mode 100644 devtools/client/debugger/src/utils/test-head.js create mode 100644 devtools/client/debugger/src/utils/test-mockup.js create mode 100644 devtools/client/debugger/src/utils/tests/DevToolsUtils.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/__snapshots__/ast.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/tests/__snapshots__/expressions.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/tests/__snapshots__/function.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/tests/__snapshots__/indentation.spec.js.snap create mode 100644 devtools/client/debugger/src/utils/tests/assert.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/ast.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/build-query.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/clipboard.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/expressions.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/function.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/indentation.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/isMinified.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/location.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/log.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/memoize.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/memoizeLast.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/path.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/quick-open.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/result-list.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/source.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/telemetry.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/text.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/ui.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/url.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/utils.spec.js create mode 100644 devtools/client/debugger/src/utils/tests/wasm.spec.js create mode 100644 devtools/client/debugger/src/utils/text.js create mode 100644 devtools/client/debugger/src/utils/ui.js create mode 100644 devtools/client/debugger/src/utils/url.js create mode 100644 devtools/client/debugger/src/utils/utils.js create mode 100644 devtools/client/debugger/src/utils/wasm.js create mode 100644 devtools/client/debugger/src/utils/worker.js create mode 100644 devtools/client/debugger/src/vendors.js create mode 100644 devtools/client/debugger/src/workers/moz.build create mode 100644 devtools/client/debugger/src/workers/parser/findOutOfScopeLocations.js create mode 100644 devtools/client/debugger/src/workers/parser/frameworks.js create mode 100644 devtools/client/debugger/src/workers/parser/getScopes/index.js create mode 100644 devtools/client/debugger/src/workers/parser/getScopes/visitor.js create mode 100644 devtools/client/debugger/src/workers/parser/getSymbols.js create mode 100644 devtools/client/debugger/src/workers/parser/index.js create mode 100644 devtools/client/debugger/src/workers/parser/mapAwaitExpression.js create mode 100644 devtools/client/debugger/src/workers/parser/mapBindings.js create mode 100644 devtools/client/debugger/src/workers/parser/mapExpression.js create mode 100644 devtools/client/debugger/src/workers/parser/mapOriginalExpression.js create mode 100644 devtools/client/debugger/src/workers/parser/moz.build create mode 100644 devtools/client/debugger/src/workers/parser/sources.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/__snapshots__/findOutOfScopeLocations.spec.js.snap create mode 100644 devtools/client/debugger/src/workers/parser/tests/__snapshots__/getScopes.spec.js.snap create mode 100644 devtools/client/debugger/src/workers/parser/tests/__snapshots__/getSymbols.spec.js.snap create mode 100644 devtools/client/debugger/src/workers/parser/tests/__snapshots__/validate.spec.js.snap create mode 100644 devtools/client/debugger/src/workers/parser/tests/contains.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/findOutOfScopeLocations.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/allSymbols.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/async.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/call-sites.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/callExpressions.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/calls.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/class.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/component.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/computed-props.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/control-flow.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/decorators.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/destructuring.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/es6.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/expression.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/flow.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/angular1FalsePositive.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/angular1Module.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/plainJavascript.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/reactComponent.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/reactComponentEs5.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/reactLibrary.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/reduxLibrary.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/vueFileComponent.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/frameworks/vueFileDeclarative.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/func.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/functionNames.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/generators.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/jsx.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/math.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/modules.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/object-expressions.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/optional-chaining.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/outOfScope.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/outOfScopeComment.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/parseScriptTags.html create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/private-fields.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/proto.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/resolveToken.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/arrow-function.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/binding-types.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/block-statement.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-declaration.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-expression.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-property.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/complex-nesting.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/expressions.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/flowtype-bindings.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/fn-body-lex-and-nonlex.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/for-loops.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-declaration.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-expression.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/jsx-component.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/out-of-order-declarations.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/pattern-declarations.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/simple-module.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/switch-statement.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/try-catch.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/ts-sample.ts create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/tsx-sample.tsx create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/vue-sample.vue create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/statements.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/thisExpression.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/fixtures/var.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/framework.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/getScopes.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/getSymbols.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/helpers/index.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/mapBindings.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/mapExpression.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/mapOriginalExpression.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/sources.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/tests/validate.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/ast.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/contains.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/formatSymbols.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/getFunctionName.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/helpers.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/inferClassName.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/simple-path.js create mode 100644 devtools/client/debugger/src/workers/parser/utils/tests/ast.spec.js create mode 100644 devtools/client/debugger/src/workers/parser/validate.js create mode 100644 devtools/client/debugger/src/workers/parser/worker.js create mode 100644 devtools/client/debugger/src/workers/pretty-print/LICENSE.md create mode 100644 devtools/client/debugger/src/workers/pretty-print/index.js create mode 100644 devtools/client/debugger/src/workers/pretty-print/moz.build create mode 100644 devtools/client/debugger/src/workers/pretty-print/pretty-fast.js create mode 100644 devtools/client/debugger/src/workers/pretty-print/tests/__snapshots__/prettyFast.spec.js.snap create mode 100644 devtools/client/debugger/src/workers/pretty-print/tests/prettyFast.spec.js create mode 100644 devtools/client/debugger/src/workers/pretty-print/worker.js create mode 100644 devtools/client/debugger/src/workers/search/get-matches.js create mode 100644 devtools/client/debugger/src/workers/search/index.js create mode 100644 devtools/client/debugger/src/workers/search/moz.build create mode 100644 devtools/client/debugger/src/workers/search/project-search.js create mode 100644 devtools/client/debugger/src/workers/search/tests/get-matches.spec.js create mode 100644 devtools/client/debugger/src/workers/search/worker.js create mode 100644 devtools/client/debugger/test/mochitest/browser.ini create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-async-stepping.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-asyncstacks.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-audiocontext.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-bfcache.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-blackbox-all.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-blackbox-original.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-blackbox.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breaking-from-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breaking.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-actions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-columns.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-shortcut.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-source-maps.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-debugger-statement.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-duplicate-functions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-in-evaled-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-list.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading-with-source-changes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-same-file-per-target.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-scroll-to-log.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-sourcemap-with-sections.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-unselected-pause.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-chrome-create.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-command-click.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-console-async.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-console-eval.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-console-link.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-content-script-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here-click.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-custom-formatters.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-debug-line.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-debugger-buttons.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints-fission.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-eager-eval-skip-pause.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-exception.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-gutter.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-highlight.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-mode.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-scroll.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-editor-select.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-ember-quickstart.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-eval-throw.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints-fission.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-event-handler.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-expressions-error.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-expressions-focus.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-expressions-thread.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-expressions-watch.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-expressions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-extension-inspectedWindow-debugger-statement.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-asm.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-lines.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-positions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-browser-toolbox-source-tree.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-source-text-content.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-source-tree.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-tabs.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-features-wasm.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-breakpoint.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-pause-exceptions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-fission-project-search.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-fission-switch-target.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-gc-breakpoint-positions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-gc-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-go-to-line.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-highlights-calls.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-html-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-idb-run-to-completion.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-iframes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-inline-cache.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-inline-exceptions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-inline-preview.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-inline-script-offset.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-inspector-integration.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-compressed-sourcemaps.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-uncompressed-sourcemaps.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-javascript-tracer.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-keyboard-navigation.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts-modal.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-layout-changes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-log-events.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-log-points.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-many-breakpoints-same-line.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-merge-scopes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-message-run-to-completion.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-minified.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-navigation-when-paused.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-navigation.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-no-duplicate-breakpoints-on-frame-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-old-breakpoint.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-outline-filter.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-outline-focus.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-outline-pretty.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-outline.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-overrides.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pause-exceptions.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pause-on-next.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pause-points.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pause-ux.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-iframe.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-loading.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-columns.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-delete.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-flow.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-inline-scripts.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-sourcemap.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-pretty-print.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-preview-frame.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-preview-getter.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-preview-module.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-preview-source-maps.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-preview.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-project-root.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-project-search.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-quick-open.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-react-app.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-react-jsx.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-reducer-cleanup-on-target-removal.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-reloading.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-remember-expanded-scopes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-restart-frame.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-returnvalues.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-scopes-duplicated.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-scopes-mutations.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-scopes-xrays.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-scopes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-scroll-run-to-completion.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-search-file-paused.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-search-file-retains-query.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-search-file.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-settings-disable-javascript.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-slow-script.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourceURL-breakpoint.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-preview.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-scopes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-stepping.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-toggle.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-bogus.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-disabled.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-ignorelist.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-indexed.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-redirect.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading-quickly.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps2.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps3.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-sources-project-search.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-step-in-uninitialized.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-stepping.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-tabs-keyboard.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-tabs-pretty-print.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls-selected.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-tabs.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-toggling-tools.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-ua-widgets.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-unselected-pause.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-watchpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-windowless-service-workers.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers-early-breakpoint.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-windowless-workers.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-worker-exception.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-worker-module.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-worker-nested.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-worker-scopes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-wrong-fetch.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-xhr-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg-xhr-run-to-completion.js create mode 100644 devtools/client/debugger/test/mochitest/examples/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/asm.js create mode 100644 devtools/client/debugger/test/mochitest/examples/async.js create mode 100644 devtools/client/debugger/test/mochitest/examples/big-sourcemap.html create mode 100644 devtools/client/debugger/test/mochitest/examples/big-sourcemap_files/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/big-sourcemap_files/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/collected-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/collected-bundle2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/collected-bundle2.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/collected-bundle2.js^headers^ create mode 100644 devtools/client/debugger/test/mochitest/examples/different_html.sjs create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-all-workers.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-asm.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-async.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-audiocontext.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-bfcache1.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-bfcache2.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-blackbox-all.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-command-click.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-content-script-sources.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-debugger-statements.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-dom-mutation.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-duplicate-functions.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-early-xhr.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-editor-scroll.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-eval-throw.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-event-breakpoints-fission.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-event-breakpoints.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-event-handler.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-exceptions.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-frames-async.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-frames.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-gc-breakpoint-positions.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-gc-sources.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-html-breakpoints.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-idb-run-to-completion.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-iframes.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-inline-preview.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-inline-script-offset.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-merge-scopes.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-message-run-to-completion-frame.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-message-run-to-completion.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-minified.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-minified2.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-module-worker.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-navigation-when-paused.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-nested-worker.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-on-load.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-pause-points.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-pretty-print-inline-scripts.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-pretty.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-preview-getter.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-preview.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-react-jsx.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-react.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-reload-link.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-remember-expanded-scopes.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-return-values.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-scopes-xrays.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-script-mutate.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-script-switching.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-scripts-debugger.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-scripts.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-scroll-run-to-completion.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-service-workers.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-slow-script.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-source-pragma.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourceURL-breakpoint.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemap-bogus.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemapped.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemaps-ignorelist.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemaps-indexed.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemaps.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemaps2.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sourcemaps3.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-sources.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-step-in-uninitialized.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-strict.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-wasm-sourcemaps.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-watchpoints.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-windowless-workers-early-breakpoint.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-windowless-workers.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-worker-exception.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-worker-scopes.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-xhr-run-to-completion.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc-xhr.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-custom-formatters.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-fission-frame-pause-exceptions.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-fission-frame-sources-frame.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-fission-frame-sources.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-fission-pause-exceptions.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-same-source-distinct-threads-frame.html create mode 100644 devtools/client/debugger/test/mochitest/examples/doc_dbg-same-source-distinct-threads.html create mode 100644 devtools/client/debugger/test/mochitest/examples/dom-mutation.js create mode 100644 devtools/client/debugger/test/mochitest/examples/dom-mutation.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.editorconfig create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.ember-cli create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.eslintrc.js create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.gitignore create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.travis.yml create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/.watchmanconfig create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/quickstart.css create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/quickstart.js create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/quickstart.map create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/test-support.css create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/test-support.js create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/test-support.map create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/tests.js create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/tests.map create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/vendor.css create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/vendor.js create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/assets/vendor.map create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/robots.txt create mode 100644 devtools/client/debugger/test/mochitest/examples/ember/quickstart/dist/testem.js create mode 100644 devtools/client/debugger/test/mochitest/examples/entry.js create mode 100644 devtools/client/debugger/test/mochitest/examples/event-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/examples/exceptions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/fetch.js create mode 100644 devtools/client/debugger/test/mochitest/examples/frames.js create mode 100644 devtools/client/debugger/test/mochitest/examples/html-breakpoints-slow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/inline-preview.js create mode 100644 devtools/client/debugger/test/mochitest/examples/inner-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/long.js create mode 100644 devtools/client/debugger/test/mochitest/examples/map-with-failed-original-request.js create mode 100644 devtools/client/debugger/test/mochitest/examples/map-with-failed-original-request.map create mode 100644 devtools/client/debugger/test/mochitest/examples/math.min.js create mode 100644 devtools/client/debugger/test/mochitest/examples/nested/nested-source.js create mode 100644 devtools/client/debugger/test/mochitest/examples/non-existant-map.js create mode 100644 devtools/client/debugger/test/mochitest/examples/opts.js create mode 100644 devtools/client/debugger/test/mochitest/examples/outer-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/output.js create mode 100644 devtools/client/debugger/test/mochitest/examples/pause-points.js create mode 100644 devtools/client/debugger/test/mochitest/examples/pretty.js create mode 100644 devtools/client/debugger/test/mochitest/examples/preview-getter.js create mode 100644 devtools/client/debugger/test/mochitest/examples/preview.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/.gitignore create mode 100644 devtools/client/debugger/test/mochitest/examples/react/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/react/build/asset-manifest.json create mode 100644 devtools/client/debugger/test/mochitest/examples/react/build/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/react/build/main.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/build/main.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/react/build/service-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/config-overrides.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/react/public/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/react/src/App.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/src/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/react/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/reload/code_reload_1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/same-script.js create mode 100644 devtools/client/debugger/test/mochitest/examples/scopes-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/script-mutate.js create mode 100644 devtools/client/debugger/test/mochitest/examples/script-switching-01.js create mode 100644 devtools/client/debugger/test/mochitest/examples/script-switching-02.js create mode 100644 devtools/client/debugger/test/mochitest/examples/service-worker.sjs create mode 100644 devtools/client/debugger/test/mochitest/examples/shared-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/simple-worker.js create mode 100644 devtools/client/debugger/test/mochitest/examples/simple1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/simple2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/simple3.js create mode 100644 devtools/client/debugger/test/mochitest/examples/simple4.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sjs_slow-load.sjs create mode 100644 devtools/client/debugger/test/mochitest/examples/source-pragma.js create mode 100644 devtools/client/debugger/test/mochitest/examples/source-pragma.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/.rpt2_cache/120bf459f95b8b447674b99c6fe5d040b99b6a97/types/cache/f67752e2d3a8fd18a75558156ccfd8c764b544a1 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/build.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/parcel/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/parcel/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/parcel/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel6/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel6/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel6/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel7/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel7/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup-babel7/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/rollup/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel6/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel6/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel6/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3-babel7/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack3/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel6/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel6/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel6/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4-babel7/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/builds/webpack4/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/babel-bindings-with-flow/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/babel-bindings-with-flow/src/mod.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/babel-classes/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/babel-flowtype-bindings/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/babel-flowtype-bindings/src/mod.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/classes/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod10.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod11.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod12.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod3.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod4.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod5.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod7.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod8.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/mod9.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-cjs/src/optimized-out.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod10.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod11.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod12.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod3.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod4.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod5.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod7.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod8.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/mod9.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules-es6/src/optimized-out.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod10.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod11.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod12.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod3.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod4.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod5.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod7.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod8.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/mod9.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/esmodules/src/optimized-out.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/eval-maps/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/for-loops/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/for-of/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/functions/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/lex-and-nonlex/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/line-start-bindings-es6/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/modules-cjs/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/out-of-order-declarations-cjs/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/out-of-order-declarations-cjs/src/mod.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/shadowed-vars/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-for-of-array-closure/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-for-of-array/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-for-of-closure/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-for-of/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-function-params/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/step-over-regenerator-await/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/switches/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/this-arguments-bindings/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/try-catches/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/type-module/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/type-script-cjs/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/typescript-classes/input.ts create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/typescript-classes/src/mod.ts create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/webpack-functions/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/webpack-line-mappings/input.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/fixtures/webpack-line-mappings/src/mod1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-bindings-with-flow.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-classes.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/babel-flowtype-bindings.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/classes.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules-cjs.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules-es6.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/esmodules.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/eval-maps.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/for-loops.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/for-of.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/functions.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/lex-and-nonlex.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/line-start-bindings-es6.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/modules-cjs.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/out-of-order-declarations-cjs.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/shadowed-vars.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-array-closure.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-array.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of-closure.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-for-of.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-function-params.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/step-over-regenerator-await.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/switches.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/this-arguments-bindings.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/try-catches.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/type-module.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/type-script-cjs.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/typescript-classes.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/webpack-functions.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/parcel/webpack-line-mappings.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel6/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup-babel7/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/typescript-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/typescript-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/rollup/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/typescript-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/typescript-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel6/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3-babel7/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/typescript-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/typescript-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack3/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel6/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-bindings-with-flow.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-bindings-with-flow.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-flowtype-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/babel-flowtype-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4-babel7/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/esmodules.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/eval-maps.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/eval-maps.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/for-loops.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/for-loops.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/lex-and-nonlex.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/lex-and-nonlex.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/line-start-bindings-es6.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/line-start-bindings-es6.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/modules-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/modules-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/out-of-order-declarations-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/out-of-order-declarations-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/shadowed-vars.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/shadowed-vars.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-array-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-array-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-array.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-array.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-closure.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of-closure.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-for-of.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-function-params.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-function-params.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-regenerator-await.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/step-over-regenerator-await.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/switches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/switches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/this-arguments-bindings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/this-arguments-bindings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/try-catches.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/try-catches.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/type-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/type-module.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/type-script-cjs.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/type-script-cjs.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/typescript-classes.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/typescript-classes.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/webpack-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/webpack-functions.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/webpack-line-mappings.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/output/webpack4/webpack-line-mappings.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/polyfill-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/tsconfig.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemapped/yarn.lock create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-indexed/main.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-indexed/main.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-indexed/main.min.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/bundle-with-another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/bundle-with-another-original.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/iframe.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/onload.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/original-with-no-update.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/query.js.x=1 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/query.js.x=2 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/query2.js.y=3 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/removed-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/replaced-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/replaced-bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/same-url.sjs create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/script.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/test-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v1/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/bundle-with-another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/bundle-with-another-original.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/iframe.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/new-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/original-with-no-update.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/replaced-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/replaced-bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/script.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v2/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v3/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v3/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v3/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v3/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-compressed/v3/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/bundle-with-another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/bundle-with-another-original.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/iframe.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/onload.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/original-with-no-update.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/query.js.x=1 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/query.js.x=2 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/query2.js.y=3 create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/react-component-module.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/removed-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/replaced-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/replaced-bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/same-url.sjs create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/script.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/test-functions.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v1/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/bundle-with-another-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/bundle-with-another-original.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/iframe.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/new-original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/original-with-no-update.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/replaced-bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/replaced-bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/script.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v2/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v3/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v3/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v3/index.html create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v3/original.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-reload-uncompressed/v3/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/rollup.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/index.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/original-1.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/original-2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/original-3.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/original-4.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-ignorelist/src/original-5.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-sections/xbundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps-with-sections/xbundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps2/main.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps2/main.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps2/main.min.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/.babelrc create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/.gitignore create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/bundle.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/bundle.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/package.json create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/sorted.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/test.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sourcemaps3/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sum/sum.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sum/sum.min.js create mode 100644 devtools/client/debugger/test/mochitest/examples/sum/sum.min.js.map create mode 100644 devtools/client/debugger/test/mochitest/examples/times2.js create mode 100644 devtools/client/debugger/test/mochitest/examples/top-level.js create mode 100644 devtools/client/debugger/test/mochitest/examples/trigger-gc.js create mode 100644 devtools/client/debugger/test/mochitest/examples/wasm-sourcemaps/README.md create mode 100644 devtools/client/debugger/test/mochitest/examples/wasm-sourcemaps/fib.c create mode 100644 devtools/client/debugger/test/mochitest/examples/wasm-sourcemaps/fib.debug.wasm create mode 100644 devtools/client/debugger/test/mochitest/examples/wasm-sourcemaps/fib.wasm create mode 100644 devtools/client/debugger/test/mochitest/examples/wasm-sourcemaps/fib.wasm.map create mode 100644 devtools/client/debugger/test/mochitest/examples/webpack.config.js create mode 100644 devtools/client/debugger/test/mochitest/examples/worker-exception.js create mode 100644 devtools/client/debugger/test/mochitest/head.js create mode 100644 devtools/client/debugger/test/mochitest/integration-tests/1-reload-same-original.js create mode 100644 devtools/client/debugger/test/mochitest/integration-tests/2-reload-replaced-original.js create mode 100644 devtools/client/debugger/test/mochitest/integration-tests/3-reload-changed-generated.js create mode 100644 devtools/client/debugger/test/mochitest/integration-tests/README.md create mode 100644 devtools/client/debugger/test/mochitest/shared-head.js create mode 100644 devtools/client/debugger/test/xpcshell/.eslintrc.js create mode 100644 devtools/client/debugger/test/xpcshell/test_sourcetree_utils_getRelativePath.js create mode 100644 devtools/client/debugger/test/xpcshell/xpcshell.ini create mode 100644 devtools/client/debugger/webpack.config.js create mode 100644 devtools/client/debugger/yarn.lock (limited to 'devtools/client/debugger') diff --git a/devtools/client/debugger/.remarkignore b/devtools/client/debugger/.remarkignore new file mode 100644 index 0000000000..7453613c87 --- /dev/null +++ b/devtools/client/debugger/.remarkignore @@ -0,0 +1,2 @@ +src/utils/pause/mapScopes/README.md +src/test/mochitest/examples/sourcemapped/README.md diff --git a/devtools/client/debugger/.remarkrc b/devtools/client/debugger/.remarkrc new file mode 100644 index 0000000000..4970e65248 --- /dev/null +++ b/devtools/client/debugger/.remarkrc @@ -0,0 +1,17 @@ +{ + "plugins": [ + "preset-lint-recommended", + ["lint-list-item-bullet-indent", false], + ["lint-list-item-indent", false], + ["lint-ordered-list-marker-style", false], + ["lint-no-unused-definitions", false], + ["lint-no-shortcut-reference-link", false], + ["lint-no-shortcut-reference-image", false], + ["lint-no-table-indentation", true], + ["lint-table-cell-padding", "consistent"], + ["lint-table-pipes", false], + ["validate-links", { + "repository": "" + }] + ] +} diff --git a/devtools/client/debugger/babel.config.js b/devtools/client/debugger/babel.config.js new file mode 100644 index 0000000000..b7aa764535 --- /dev/null +++ b/devtools/client/debugger/babel.config.js @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +/* global __dirname */ + +/** + * NOTE: This file does not apply to builds in MC. This config is used for + * our Jest tests and for webpack bundle builds. + */ +module.exports = { + sourceType: "unambiguous", + overrides: [ + { + test: [ + "./src", + "./packages/*/index.js", + "./packages/*/src", + /[/\\]node_modules[/\\]devtools-/, + /[/\\]node_modules[/\\]react-aria-components[/\\]/, + "../../shared", + "../shared/worker-utils.js", + ], + presets: [ + "@babel/preset-react", + [ + "@babel/preset-env", + { + targets: { + browsers: ["last 1 Chrome version", "last 1 Firefox version"], + }, + modules: "commonjs", + }, + ], + ], + plugins: [ + "@babel/plugin-proposal-class-static-block", + "@babel/plugin-proposal-class-properties", + "@babel/plugin-proposal-optional-chaining", + "@babel/plugin-proposal-nullish-coalescing-operator", + "@babel/plugin-proposal-private-methods", + "@babel/plugin-proposal-private-property-in-object", + [ + "module-resolver", + { + alias: { + "devtools/client/shared/vendor/react": "react", + "devtools/client/shared/vendor/react-dom": "react-dom", + "devtools/client/shared/vendor/react-dom-factories": + "react-dom-factories", + "devtools/client/shared/vendor/react-prop-types": "prop-types", + // Map all require("devtools/...") to the real devtools root. + "^devtools\\/(.*)": `${__dirname}/../../\\1`, + "^resource://devtools/(.*)": `${__dirname}/../../\\1`, + }, + }, + ], + ], + env: { + test: { + presets: [ + [ + "@babel/preset-env", + { + targets: { + node: 7, + }, + modules: "commonjs", + }, + ], + ], + }, + }, + }, + { + test: ["../shared/components"], + plugins: [ + "@babel/plugin-proposal-class-static-block", + "@babel/plugin-proposal-class-properties", + "@babel/plugin-proposal-optional-chaining", + "@babel/plugin-proposal-nullish-coalescing-operator", + "@babel/plugin-proposal-private-methods", + "@babel/plugin-proposal-private-property-in-object", + "transform-amd-to-commonjs", + ], + }, + ], +}; diff --git a/devtools/client/debugger/bin/bundle.js b/devtools/client/debugger/bin/bundle.js new file mode 100644 index 0000000000..ed36ea1810 --- /dev/null +++ b/devtools/client/debugger/bin/bundle.js @@ -0,0 +1,125 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +const path = require("path"); +const { rollup } = require("rollup"); +const nodeResolve = require("@rollup/plugin-node-resolve"); +const commonjs = require("@rollup/plugin-commonjs"); +const injectProcessEnv = require("rollup-plugin-inject-process-env"); +const nodePolyfills = require("rollup-plugin-node-polyfills"); + +const webpack = require("webpack"); + +const projectPath = path.resolve(__dirname, ".."); +const bundlePath = path.join(projectPath, "./dist"); + +process.env.NODE_ENV = "production"; + +function getEntry(filename) { + return path.join(__dirname, "..", filename); +} + +/** + * The `bundle` module will build the following: + * - vendors.js and vendors.css: + * Bundle for all the external packages still used by the Debugger frontend. + * Source at devtools/client/debugger/src/vendors.js + * - parser-worker.js, pretty-print-worker.js, search-worker: + * Workers used only by the debugger. + * Sources at devtools/client/debugger/src/workers/* + */ +(async function bundle() { + const rollupSucceeded = await bundleRollup(); + const webpackSucceeded = await bundleWebpack(); + const failed = !rollupSucceeded || !webpackSucceeded; + process.exit(failed ? 1 : 0); +})(); + +/** + * Generates all dist/*-worker.js files + */ +async function bundleRollup() { + console.log(`[bundle|rollup] Start bundling…`); + + let success = true; + + // We need to handle workers 1 by 1 to be able to generate umd bundles. + const entries = { + "parser-worker": getEntry("src/workers/parser/worker.js"), + "pretty-print-worker": getEntry("src/workers/pretty-print/worker.js"), + "search-worker": getEntry("src/workers/search/worker.js"), + }; + + for (const [entryName, input] of Object.entries(entries)) { + let bundle; + try { + // create a bundle + bundle = await rollup({ + input: { + [entryName]: input, + }, + plugins: [ + commonjs({ + transformMixedEsModules: true, + }), + injectProcessEnv({ NODE_ENV: "production" }), + nodeResolve(), + // read-wasm.js is part of source-map and is only for Node environment. + // we need to ignore it, otherwise __dirname is inlined with the path the bundle + // is generated from, which makes the verify-bundle task fail + nodePolyfills({ exclude: [/read-wasm\.js/] }), + ], + }); + await bundle.write({ + dir: bundlePath, + entryFileNames: "[name].js", + format: "umd", + }); + } catch (error) { + success = false; + // do some error reporting + console.error("[bundle|rollup] Something went wrong.", error); + } + if (bundle) { + // closes the bundle + await bundle.close(); + } + } + + console.log(`[bundle|rollup] Done bundling`); + return success; +} + +/** + * Generates vendors.js and vendors.css + * Should be removed in Bug 1826501 + */ +async function bundleWebpack() { + let success = true; + console.log(`[bundle|webpack] Start bundling…`); + process.env.TARGET = "firefox-panel"; + process.env.OUTPUT_PATH = bundlePath; + + const webpackConfig = require(path.resolve(projectPath, "webpack.config.js")); + const webpackCompiler = webpack(webpackConfig); + + const result = await new Promise(resolve => { + webpackCompiler.run((error, stats) => resolve(stats)); + }); + + if (result?.hasErrors()) { + success = false; + console.log( + "[bundle|webpack] Something went wrong. The error was written to assets-error.log" + ); + + fs.writeFileSync( + "assets-error.log", + JSON.stringify(result.toJson("verbose"), null, 2) + ); + } + + console.log(`[bundle|webpack] Done bundling`); + return success; +} diff --git a/devtools/client/debugger/bin/module-manifest.json b/devtools/client/debugger/bin/module-manifest.json new file mode 100644 index 0000000000..4a812a746e --- /dev/null +++ b/devtools/client/debugger/bin/module-manifest.json @@ -0,0 +1,2565 @@ +{ + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-splitter/src/SplitBox.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-splitter/src/SplitBox.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab-list.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab-list.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../devtools-contextmenu/menu.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../devtools-contextmenu/menu.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-components/src/tree.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-components/src/tree.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/object-inspector/components/ObjectInspector.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/object-inspector/components/ObjectInspector.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/reps/reps.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/reps/reps.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + } + } + ], + "modules": { + "byIdentifier": { + "external \"devtools/client/shared/vendor/react-prop-types\"": 0, + "external \"devtools/client/shared/vendor/react-dom-factories\"": 1, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/rep-utils.js": 2, + "../../@babel/types/lib/index.js": 3, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/constants.js": 4, + "../../@babel/types/lib/validators/generated/index.js": 5, + "external \"devtools/client/shared/vendor/react\"": 6, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-utils/index.js": 7, + "../../lodash/_root.js": 8, + "../../lodash/isArray.js": 9, + "../../@babel/types/lib/builders/generated/index.js": 10, + "../../lodash/isObjectLike.js": 11, + "../../source-map/lib/util.js": 12, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-utils/src/privileged-network-request.js": 13, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-utils/src/worker-utils.js": 14, + "../../webpack/buildin/global.js": 15, + "../../@babel/types/lib/definitions/index.js": 16, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/url-state-machine.js": 17, + "../../lodash/_baseGetTag.js": 18, + "../../lodash/_Symbol.js": 19, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/ast.js": 20, + "../../lodash/isObject.js": 21, + "../../webpack/buildin/module.js": 22, + "../../@babel/types/lib/definitions/utils.js": 23, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/rep.js": 24, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/string.js": 25, + "../../lodash/_getNative.js": 26, + "../../@babel/types/lib/constants/index.js": 27, + "../../lodash/isSymbol.js": 28, + "../../lodash/_getTag.js": 29, + "../../@babel/types/lib/validators/isValidIdentifier.js": 30, + "../../@babel/types/lib/clone/cloneNode.js": 31, + "../../source-map/lib/source-map-generator.js": 32, + "../../source-map/lib/base64-vlq.js": 33, + "../../source-map/lib/array-set.js": 34, + "../../process/browser.js": 35, + "../../charenc/charenc.js": 36, + "external \"Services\"": 37, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/array.js": 38, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/prop-rep.js": 39, + "../../lodash/_ListCache.js": 40, + "../../lodash/_assocIndexOf.js": 41, + "../../lodash/eq.js": 42, + "../../lodash/_freeGlobal.js": 43, + "../../lodash/_nativeCreate.js": 44, + "../../lodash/_getMapData.js": 45, + "../../lodash/_copyObject.js": 46, + "../../lodash/keys.js": 47, + "../../lodash/isBuffer.js": 48, + "../../lodash/_baseUnary.js": 49, + "../../lodash/_nodeUtil.js": 50, + "../../lodash/_isPrototype.js": 51, + "../../lodash/isArrayLike.js": 52, + "../../@babel/types/lib/retrievers/getBindingIdentifiers.js": 53, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/helpers.js": 54, + "../../@babel/generator/lib/index.js": 55, + "../../lodash/toInteger.js": 56, + "../../lodash/toString.js": 57, + "../../buffer/index.js": 58, + "../../lodash/_toKey.js": 59, + "../../../packages/devtools-source-map/node_modules/source-map/source-map.js": 60, + "../../../packages/devtools-source-map/node_modules/source-map/lib/util.js": 61, + "../../node-libs-browser/node_modules/punycode/punycode.js": 62, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/urlencoded.js": 63, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/index.js": 64, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/utils/event-emitter.js": 65, + "../../fuzzaldrin-plus/lib/scorer.js": 66, + "../../@babel/types/lib/utils/shallowEqual.js": 68, + "../../lodash/_Stack.js": 69, + "../../lodash/_Map.js": 70, + "../../lodash/_getRawTag.js": 71, + "../../lodash/_objectToString.js": 72, + "../../lodash/_MapCache.js": 73, + "../../lodash/isArguments.js": 74, + "../../lodash/_isIndex.js": 75, + "../../lodash/isTypedArray.js": 76, + "../../lodash/isLength.js": 77, + "../../lodash/_getSymbols.js": 78, + "../../lodash/_getPrototype.js": 79, + "../../lodash/_cloneArrayBuffer.js": 80, + "../../@babel/types/lib/definitions/core.js": 81, + "../../@babel/types/lib/validators/is.js": 82, + "../../@babel/types/lib/validators/isType.js": 83, + "../../@babel/types/lib/definitions/es2015.js": 84, + "../../@babel/types/lib/utils/inherit.js": 85, + "../../lodash/_baseFindIndex.js": 86, + "../../lodash/_setToArray.js": 87, + "../../source-map/source-map.js": 88, + "../../source-map/lib/base64.js": 89, + "../../source-map/lib/mapping-list.js": 90, + "../../source-map/lib/source-map-consumer.js": 91, + "../../source-map/lib/binary-search.js": 92, + "../../source-map/lib/quick-sort.js": 93, + "../../source-map/lib/source-node.js": 94, + "../../lodash/_baseToString.js": 95, + "../../lodash/_arrayMap.js": 96, + "../../@babel/generator/lib/generators/types.js": 97, + "../../base64-js/index.js": 98, + "../../ieee754/index.js": 99, + "../../isarray/index.js": 100, + "../../lodash/_isKey.js": 101, + "../../babel-loader/lib/index.js??ref--1!../../devtools-environment/index.js": 102, + "external \"devtools/shared/flags\"": 103, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/sourceMapRequests.js": 104, + "../../md5/md5.js": 105, + "../../crypt/crypt.js": 106, + "../../is-buffer/index.js": 107, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-components/index.js": 108, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-components/src/tree.js": 109, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-components/src/tree.css": 110, + "../../fuzzaldrin-plus/lib/pathScorer.js": 111, + "external \"devtools/client/shared/vendor/react-dom\"": 112, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/grip.js": 113, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/utils/node.js": 114, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/reducer.js": 115, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/utils/index.js": 116, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/getSymbols.js": 117, + "../../@babel/types/lib/validators/buildMatchMemberExpression.js": 118, + "../../@babel/types/lib/validators/matchesPattern.js": 119, + "../../lodash/isFunction.js": 120, + "../../lodash/_toSource.js": 121, + "../../lodash/_assignValue.js": 122, + "../../lodash/_baseAssignValue.js": 123, + "../../lodash/_arrayLikeKeys.js": 124, + "../../lodash/_baseKeys.js": 125, + "../../lodash/_overArg.js": 126, + "../../lodash/keysIn.js": 127, + "../../lodash/stubArray.js": 128, + "../../lodash/_getSymbolsIn.js": 129, + "../../lodash/_arrayPush.js": 130, + "../../lodash/_getAllKeys.js": 131, + "../../lodash/_baseGetAllKeys.js": 132, + "../../lodash/_Set.js": 133, + "../../lodash/_Uint8Array.js": 134, + "../../esutils/lib/code.js": 135, + "../../@babel/types/lib/validators/validate.js": 136, + "../../@babel/types/lib/validators/isNode.js": 137, + "../../@babel/types/lib/modifications/flow/removeTypeDuplicates.js": 138, + "../../@babel/types/lib/clone/clone.js": 139, + "../../@babel/types/lib/comments/addComments.js": 140, + "../../@babel/types/lib/comments/inheritInnerComments.js": 141, + "../../lodash/_SetCache.js": 142, + "../../lodash/_cacheHas.js": 143, + "../../@babel/types/lib/comments/inheritLeadingComments.js": 144, + "../../@babel/types/lib/comments/inheritsComments.js": 145, + "../../@babel/types/lib/comments/inheritTrailingComments.js": 146, + "../../@babel/types/lib/converters/toBlock.js": 147, + "../../@babel/types/lib/converters/toIdentifier.js": 148, + "../../@babel/types/lib/modifications/removePropertiesDeep.js": 149, + "../../@babel/types/lib/traverse/traverseFast.js": 150, + "../../@babel/types/lib/modifications/removeProperties.js": 151, + "../../@babel/types/lib/validators/isLet.js": 152, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/simple-path.js": 153, + "../../lodash/isEmpty.js": 154, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/sources.js": 155, + "../../@babel/generator/lib/node/index.js": 156, + "../../@babel/generator/lib/generators/modules.js": 157, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/getFunctionName.js": 158, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/frameworks.js": 159, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/getScopes/index.js": 160, + "../../lodash/get.js": 161, + "../../lodash/_baseGet.js": 162, + "../../lodash/_castPath.js": 163, + "../../lodash/_baseIteratee.js": 164, + "../../lodash/_baseIsEqual.js": 165, + "../../lodash/_equalArrays.js": 166, + "../../lodash/_isStrictComparable.js": 167, + "../../lodash/_matchesStrictComparable.js": 168, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/contains.js": 169, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/search/get-matches.js": 170, + "../../../packages/devtools-source-map/node_modules/source-map/lib/source-map-generator.js": 171, + "../../../packages/devtools-source-map/node_modules/source-map/lib/base64-vlq.js": 172, + "../../webidl-conversions/lib/index.js": 173, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/utils.js": 174, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/infra.js": 175, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/URLSearchParams.js": 176, + "../../../packages/devtools-source-map/node_modules/source-map/lib/array-set.js": 177, + "../../../packages/devtools-source-map/node_modules/source-map/lib/read-wasm-browser.js": 178, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/createConsumer.js": 179, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/wasmAssetBrowser.js": 180, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/wasmXScopes.js": 181, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/index.js": 182, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/index.js": 183, + "../../fuzzaldrin-plus/lib/query.js": 184, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/tabs/tab-list.js": 185, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/tabs/tab.js": 186, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/tabs/tab-panels.js": 187, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/big-int.js": 188, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/function.js": 189, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/shared/dom-node-constants.js": 190, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/error.js": 191, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/grip-array.js": 192, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/shared/grip-length-bubble.js": 193, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/grip-map.js": 194, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/grip-map-entry.js": 195, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/utils/load-properties.js": 196, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/utils/client.js": 197, + "multi ../../../src/workers/parser/worker.js": 198, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/worker.js": 199, + "../../@babel/types/lib/validators/react/isReactComponent.js": 200, + "../../@babel/types/lib/validators/react/isCompatTag.js": 201, + "../../@babel/types/lib/builders/react/buildChildren.js": 202, + "../../@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js": 203, + "../../@babel/types/lib/builders/builder.js": 204, + "../../lodash/clone.js": 205, + "../../lodash/_baseClone.js": 206, + "../../lodash/_listCacheClear.js": 207, + "../../lodash/_listCacheDelete.js": 208, + "../../lodash/_listCacheGet.js": 209, + "../../lodash/_listCacheHas.js": 210, + "../../lodash/_listCacheSet.js": 211, + "../../lodash/_stackClear.js": 212, + "../../lodash/_stackDelete.js": 213, + "../../lodash/_stackGet.js": 214, + "../../lodash/_stackHas.js": 215, + "../../lodash/_stackSet.js": 216, + "../../lodash/_baseIsNative.js": 217, + "../../lodash/_isMasked.js": 218, + "../../lodash/_coreJsData.js": 219, + "../../lodash/_getValue.js": 220, + "../../lodash/_mapCacheClear.js": 221, + "../../lodash/_Hash.js": 222, + "../../lodash/_hashClear.js": 223, + "../../lodash/_hashDelete.js": 224, + "../../lodash/_hashGet.js": 225, + "../../lodash/_hashHas.js": 226, + "../../lodash/_hashSet.js": 227, + "../../lodash/_mapCacheDelete.js": 228, + "../../lodash/_isKeyable.js": 229, + "../../lodash/_mapCacheGet.js": 230, + "../../lodash/_mapCacheHas.js": 231, + "../../lodash/_mapCacheSet.js": 232, + "../../lodash/_arrayEach.js": 233, + "../../lodash/_defineProperty.js": 234, + "../../lodash/_baseAssign.js": 235, + "../../lodash/_baseTimes.js": 236, + "../../lodash/_baseIsArguments.js": 237, + "../../lodash/stubFalse.js": 238, + "../../lodash/_baseIsTypedArray.js": 239, + "../../lodash/_nativeKeys.js": 240, + "../../lodash/_baseAssignIn.js": 241, + "../../lodash/_baseKeysIn.js": 242, + "../../lodash/_nativeKeysIn.js": 243, + "../../lodash/_cloneBuffer.js": 244, + "../../lodash/_copyArray.js": 245, + "../../lodash/_copySymbols.js": 246, + "../../lodash/_arrayFilter.js": 247, + "../../lodash/_copySymbolsIn.js": 248, + "../../lodash/_getAllKeysIn.js": 249, + "../../lodash/_DataView.js": 250, + "../../lodash/_Promise.js": 251, + "../../lodash/_WeakMap.js": 252, + "../../lodash/_initCloneArray.js": 253, + "../../lodash/_initCloneByTag.js": 254, + "../../lodash/_cloneDataView.js": 255, + "../../lodash/_cloneRegExp.js": 256, + "../../lodash/_cloneSymbol.js": 257, + "../../lodash/_cloneTypedArray.js": 258, + "../../lodash/_initCloneObject.js": 259, + "../../lodash/_baseCreate.js": 260, + "../../lodash/isMap.js": 261, + "../../lodash/_baseIsMap.js": 262, + "../../lodash/isSet.js": 263, + "../../lodash/_baseIsSet.js": 264, + "../../to-fast-properties/index.js": 265, + "../../esutils/lib/utils.js": 266, + "../../esutils/lib/ast.js": 267, + "../../esutils/lib/keyword.js": 268, + "../../@babel/types/lib/definitions/flow.js": 269, + "../../@babel/types/lib/definitions/jsx.js": 270, + "../../@babel/types/lib/definitions/misc.js": 271, + "../../@babel/types/lib/definitions/experimental.js": 272, + "../../@babel/types/lib/definitions/typescript.js": 273, + "../../@babel/types/lib/asserts/assertNode.js": 274, + "../../@babel/types/lib/asserts/generated/index.js": 275, + "../../@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js": 276, + "../../@babel/types/lib/builders/flow/createUnionTypeAnnotation.js": 277, + "../../@babel/types/lib/clone/cloneDeep.js": 278, + "../../@babel/types/lib/clone/cloneWithoutLoc.js": 279, + "../../@babel/types/lib/comments/addComment.js": 280, + "../../lodash/uniq.js": 281, + "../../lodash/_baseUniq.js": 282, + "../../lodash/_setCacheAdd.js": 283, + "../../lodash/_setCacheHas.js": 284, + "../../lodash/_arrayIncludes.js": 285, + "../../lodash/_baseIndexOf.js": 286, + "../../lodash/_baseIsNaN.js": 287, + "../../lodash/_strictIndexOf.js": 288, + "../../lodash/_arrayIncludesWith.js": 289, + "../../lodash/_createSet.js": 290, + "../../lodash/noop.js": 291, + "../../@babel/types/lib/comments/removeComments.js": 292, + "../../@babel/types/lib/constants/generated/index.js": 293, + "../../@babel/types/lib/converters/ensureBlock.js": 294, + "../../@babel/types/lib/converters/toBindingIdentifierName.js": 295, + "../../@babel/types/lib/converters/toComputedKey.js": 296, + "../../@babel/types/lib/converters/toExpression.js": 297, + "../../@babel/types/lib/converters/toKeyAlias.js": 298, + "../../@babel/types/lib/converters/toSequenceExpression.js": 299, + "../../@babel/types/lib/converters/gatherSequenceExpressions.js": 300, + "../../@babel/types/lib/converters/toStatement.js": 301, + "../../@babel/types/lib/converters/valueToNode.js": 302, + "../../lodash/isPlainObject.js": 303, + "../../lodash/isRegExp.js": 304, + "../../lodash/_baseIsRegExp.js": 305, + "../../@babel/types/lib/modifications/appendToMemberExpression.js": 306, + "../../@babel/types/lib/modifications/inherits.js": 307, + "../../@babel/types/lib/modifications/prependToMemberExpression.js": 308, + "../../@babel/types/lib/retrievers/getOuterBindingIdentifiers.js": 309, + "../../@babel/types/lib/traverse/traverse.js": 310, + "../../@babel/types/lib/validators/isBinding.js": 311, + "../../@babel/types/lib/validators/isBlockScoped.js": 312, + "../../@babel/types/lib/validators/isImmutable.js": 313, + "../../@babel/types/lib/validators/isNodesEquivalent.js": 314, + "../../@babel/types/lib/validators/isReferenced.js": 315, + "../../@babel/types/lib/validators/isScope.js": 316, + "../../@babel/types/lib/validators/isSpecifierDefault.js": 317, + "../../@babel/types/lib/validators/isValidES3Identifier.js": 318, + "../../@babel/types/lib/validators/isVar.js": 319, + "../../parse-script-tags/dist/index.js": 320, + "../../parse-script-tags/node_modules/babylon/lib/index.js": 321, + "../../parse-script-tags/dist/customParse.js": 322, + "../../parse-script-tags/dist/parseScriptFragment.js": 323, + "../../@babel/parser/lib/index.js": 324, + "../../@babel/generator/lib/source-map.js": 325, + "../../@babel/generator/lib/printer.js": 326, + "../../lodash/isInteger.js": 327, + "../../lodash/toFinite.js": 328, + "../../lodash/toNumber.js": 329, + "../../lodash/repeat.js": 330, + "../../lodash/_baseRepeat.js": 331, + "../../lodash/_isIterateeCall.js": 332, + "../../@babel/generator/lib/buffer.js": 333, + "../../trim-right/index.js": 334, + "../../@babel/generator/lib/node/whitespace.js": 335, + "../../@babel/generator/lib/node/parentheses.js": 336, + "../../@babel/generator/lib/generators/index.js": 337, + "../../@babel/generator/lib/generators/template-literals.js": 338, + "../../@babel/generator/lib/generators/expressions.js": 339, + "../../@babel/generator/lib/generators/statements.js": 340, + "../../@babel/generator/lib/generators/classes.js": 341, + "../../@babel/generator/lib/generators/methods.js": 342, + "../../@babel/generator/node_modules/jsesc/jsesc.js": 343, + "../../@babel/generator/lib/generators/flow.js": 344, + "../../@babel/generator/lib/generators/base.js": 345, + "../../@babel/generator/lib/generators/jsx.js": 346, + "../../@babel/generator/lib/generators/typescript.js": 347, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/inferClassName.js": 348, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/getScopes/visitor.js": 349, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/findOutOfScopeLocations.js": 350, + "../../lodash/_stringToPath.js": 351, + "../../lodash/_memoizeCapped.js": 352, + "../../lodash/memoize.js": 353, + "../../lodash/findIndex.js": 354, + "../../lodash/_baseMatches.js": 355, + "../../lodash/_baseIsMatch.js": 356, + "../../lodash/_baseIsEqualDeep.js": 357, + "../../lodash/_arraySome.js": 358, + "../../lodash/_equalByTag.js": 359, + "../../lodash/_mapToArray.js": 360, + "../../lodash/_equalObjects.js": 361, + "../../lodash/_getMatchData.js": 362, + "../../lodash/_baseMatchesProperty.js": 363, + "../../lodash/hasIn.js": 364, + "../../lodash/_baseHasIn.js": 365, + "../../lodash/_hasPath.js": 366, + "../../lodash/identity.js": 367, + "../../lodash/property.js": 368, + "../../lodash/_baseProperty.js": 369, + "../../lodash/_basePropertyDeep.js": 370, + "../../lodash/findLastIndex.js": 371, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/steps.js": 372, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/utils/closest.js": 373, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/validate.js": 374, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/mapExpression.js": 375, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/mapOriginalExpression.js": 376, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/mapBindings.js": 377, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/parser/mapAwaitExpression.js": 378, + "multi ../../../src/workers/pretty-print/worker.js": 379, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/pretty-print/worker.js": 380, + "../../pretty-fast/pretty-fast.js": 381, + "../../pretty-fast/node_modules/acorn/dist/acorn.js": 382, + "multi ../../../src/workers/search/worker.js": 383, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/search/worker.js": 384, + "../../babel-loader/lib/index.js??ref--1!../../../src/utils/assert.js": 385, + "../../babel-loader/lib/index.js??ref--1!../../../src/utils/build-query.js": 386, + "../../lodash/escapeRegExp.js": 387, + "../../babel-loader/lib/index.js??ref--1!../../../src/workers/search/project-search.js": 388, + "multi ../../../packages/devtools-source-map/src/worker.js": 389, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/worker.js": 390, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/source-map.js": 391, + "../../../packages/devtools-source-map/node_modules/source-map/lib/base64.js": 392, + "../../../packages/devtools-source-map/node_modules/source-map/lib/url-browser.js": 393, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/public-api.js": 394, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/URL.js": 395, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/URL-impl.js": 396, + "../../tr46/index.js": 397, + "../../tr46/lib/regexes.js": 398, + "../../json-loader/index.js!../../tr46/lib/mappingTable.json": 399, + "../../../packages/devtools-source-map/node_modules/whatwg-url/lib/URLSearchParams-impl.js": 400, + "../../lodash.sortby/index.js": 401, + "../../../packages/devtools-source-map/node_modules/source-map/lib/mapping-list.js": 402, + "../../../packages/devtools-source-map/node_modules/source-map/lib/source-map-consumer.js": 403, + "../../../packages/devtools-source-map/node_modules/source-map/lib/binary-search.js": 404, + "../../../packages/devtools-source-map/node_modules/source-map/lib/wasm.js": 405, + "../../../packages/devtools-source-map/node_modules/source-map/lib/source-node.js": 406, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/assert.js": 407, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/fetchSourceMap.js": 408, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/wasmRemap.js": 409, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/convertToJSON.js": 410, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/getOriginalStackFrames.js": 411, + "multi ../../../packages/devtools-source-map/src/index.js": 412, + "multi ../../../src/vendors.js": 413, + "../../babel-loader/lib/index.js??ref--1!../../../src/vendors.js": 414, + "../../babel-loader/lib/index.js??ref--1!../../devtools-config/index.js": 415, + "../../babel-loader/lib/index.js??ref--1!../../devtools-config/src/feature.js": 416, + "external \"devtools/client/shared/vendor/lodash\"": 417, + "../../node-libs-browser/mock/empty.js": 418, + "../../path-browserify/index.js": 419, + "../../babel-loader/lib/index.js??ref--1!../../devtools-contextmenu/menu.js": 420, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/menu/index.js": 421, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/utils/promise.js": 422, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/menu/menu-item.js": 423, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/prefs.js": 424, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/key-shortcuts.js": 425, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/zoom-keys.js": 426, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/async-storage.js": 427, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/source-utils.js": 428, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/utils/telemetry.js": 429, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/unicode-url.js": 430, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../devtools-contextmenu/menu.css": 431, + "../../fuzzaldrin-plus/lib/fuzzaldrin.js": 432, + "../../fuzzaldrin-plus/lib/filter.js": 433, + "../../fuzzaldrin-plus/lib/matcher.js": 434, + "../../react-transition-group/Transition.js": 435, + "../../react-lifecycles-compat/react-lifecycles-compat.es.js": 436, + "../../react-transition-group/utils/PropTypes.js": 437, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/tabs/index.js": 438, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/prop-types/ref.js": 439, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab.css": 440, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../react-aria-components/src/tabs/tab-list.css": 441, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/tabs/tabs.js": 442, + "../../babel-loader/lib/index.js??ref--1!../../react-aria-components/src/utils/unique-id.js": 443, + "../../reselect/es/index.js": 444, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-splitter/index.js": 445, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-splitter/src/SplitBox.js": 446, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-splitter/src/Draggable.js": 447, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-splitter/src/SplitBox.css": 448, + "../../lodash-move/lib/index.js": 449, + "../../babel-loader/lib/index.js??ref--1!../../../src/components/shared/Svg.js": 450, + "../../babel-loader/lib/index.js??ref--1!../../../images/Svg.js": 451, + "../../svg-inline-react/lib/index.js": 452, + "../../svg-inline-react/lib/util.js": 453, + "../../svg-inline-loader/index.js!../../../images/breakpoint.svg": 454, + "../../svg-inline-loader/index.js!../../../images/column-marker.svg": 455, + "multi ../../../packages/devtools-reps/src/index.js": 456, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/index.js": 457, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/reps/reps.css": 458, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/undefined.js": 459, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/null.js": 460, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/number.js": 461, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/object.js": 462, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/symbol.js": 463, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/infinity.js": 464, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/nan.js": 465, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/accessor.js": 466, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/accessible.js": 467, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/attribute.js": 468, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/date-time.js": 469, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/document.js": 470, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/document-type.js": 471, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/event.js": 472, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/promise.js": 473, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/regexp.js": 474, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/stylesheet.js": 475, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/comment-node.js": 476, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/element-node.js": 477, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/text-node.js": 478, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/window.js": 479, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/object-with-text.js": 480, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/reps/object-with-url.js": 481, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/index.js": 482, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/components/ObjectInspector.js": 483, + "external \"devtools/client/shared/vendor/react-redux\"": 484, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/actions.js": 485, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-reps/src/object-inspector/components/ObjectInspector.css": 486, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/components/ObjectInspectorItem.js": 487, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-reps/src/object-inspector/utils/selection.js": 488, + "../../css-loader/lib/css-base.js": 489, + "external \"devtools/client/framework/menu\"": 490, + "external \"devtools/client/framework/menu-item\"": 491, + "../../whatwg-url/lib/url-state-machine.js": 492, + "../../whatwg-url/lib/urlencoded.js": 493, + "../../whatwg-url/lib/utils.js": 494, + "../../whatwg-url/lib/infra.js": 495, + "../../whatwg-url/lib/URLSearchParams.js": 496, + "../../whatwg-url/lib/public-api.js": 497, + "../../whatwg-url/lib/URL.js": 498, + "../../whatwg-url/lib/URL-impl.js": 499, + "../../whatwg-url/lib/URLSearchParams-impl.js": 500, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/plural-form.js": 501, + "multi ../../whatwg-url/lib/public-api.js": 502, + "external \"devtools/client/shared/vendor/whatwg-url\"": 503, + "external \"resource://devtools/client/shared/vendor/whatwg-url\"": 504, + "external \"\\n(() => { \\n importScripts \\\"resource://devtools/client/shared/vendor/whatwg-url\\\";\\n return { URL: self.URL }\\n})()\\n\"": 505, + "external \"\\n(() => { \\n importScripts(\\\"resource://devtools/client/shared/vendor/whatwg-url.js\\\");\\n return { URL: self.URL }\\n})()\\n\"": 506, + "external \"\\n(() => { \\n importScripts(\\\"resource://devtools/client/shared/vendor/whatwg-url.js\\\");\\n return { URL }\\n})()\\n\"": 507, + "external \"\\n(() => { \\n console.log('>> yo',importScripts(\\\"resource://devtools/client/shared/vendor/whatwg-url.js\\\"));\\n return { URL }\\n})()\\n\"": 508, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/wasmDwarfExpressions.js": 509, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-wasm-dwarf/index.js": 510, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-wasm-dwarf/src/wasmAssetBrowser.js": 511, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-wasm-dwarf/src/convertToJSON.js": 512, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-wasm-dwarf/src/wasmXScopes.js": 513, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-wasm-dwarf/src/wasmDwarfExpressions.js": 514, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-source-map/src/utils/assetRootBrowser.js": 515, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/async-store-helper.js": 516, + "../../@babel/types/lib/validators/isPlaceholderType.js": 517, + "../../@babel/types/lib/definitions/placeholders.js": 518, + "../../webpack/buildin/harmony-module.js": 519, + "../../babel-loader/lib/index.js??ref--1!../../devtools-modules/src/saveAs.js": 520, + "../../punycode/punycode.js": 521, + "../../babel-loader/lib/index.js??ref--1!../../../../../shared/dom-node-constants.js": 522, + "../../@babel/helper-validator-identifier/lib/index.js": 523, + "../../@babel/helper-validator-identifier/lib/identifier.js": 524, + "../../@babel/helper-validator-identifier/lib/keyword.js": 525, + "../../@babel/types/lib/clone/cloneDeepWithoutLoc.js": 526, + "../../../packages/devtools-reps/node_modules/React/index.js": 527, + "../../../packages/devtools-reps/node_modules/React/cjs/react.production.min.js": 528, + "../../object-assign/index.js": 529, + "../../fbjs/lib/invariant.js": 530, + "../../fbjs/lib/emptyObject.js": 531, + "../../fbjs/lib/emptyFunction.js": 532, + "external \"\\n(() => {\\n let factory;\\n function define(...args) {\\n if (factory) {\\n throw new Error(\\\"expected a single define call\\\");\\n }\\n\\n if (\\n args.length !== 2 ||\\n !Array.isArray(args[0]) ||\\n args[0].length !== 0 ||\\n typeof args[1] !== \\\"function\\\"\\n ) {\\n throw new Error(\\\"whatwg-url had unexpected factory arguments.\\\");\\n }\\n\\n factory = args[1];\\n }\\n define.amd = true;\\n\\n const existingDefine = Object.getOwnPropertyDescriptor(globalThis, \\\"define\\\");\\n globalThis.define = define;\\n let err;\\n try {\\n importScripts(\\\"resource://devtools/client/shared/vendor/whatwg-url.js\\\");\\n\\n if (!factory) {\\n throw new Error(\\\"Failed to load whatwg-url factory\\\");\\n }\\n } finally {\\n if (existingDefine) {\\n Object.defineProperty(globalThis, \\\"define\\\", existingDefine);\\n } else {\\n delete globalThis.define;\\n }\\n\\n }\\n\\n return factory();\\n})()\\n\"": 533, + "../../@babel/types/lib/builders/flow/createFlowUnionType.js": 534, + "../../@babel/types/lib/builders/typescript/createTSUnionType.js": 535, + "../../@babel/types/lib/modifications/typescript/removeTypeDuplicates.js": 536, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/utils/event-emitter.js": 537, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/index.js": 538, + "../../../packages/devtools-modules/src/prefs.js": 539, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/utils/promise.js": 540, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/key-shortcuts.js": 541, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/zoom-keys.js": 542, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/async-storage.js": 543, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/source-utils.js": 544, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/utils/telemetry.js": 545, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/unicode-url.js": 546, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/plural-form.js": 547, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/saveAs.js": 548, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-modules/src/async-store-helper.js": 549, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-config/index.js": 550, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-config/src/feature.js": 551, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-contextmenu/menu.js": 552, + "../../extract-text-webpack-plugin/dist/loader.js??ref--3-0!../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-contextmenu/menu.css": 553, + "../../babel-loader/lib/index.js??ref--1!../../../packages/devtools-environment/index.js": 554, + "../../babel-loader/lib/index.js??ref--1!../../../src/context-menu/menu.js": 555, + "../../babel-loader/lib/index.js??ref--1!../../../../framework/menu.js": 556, + "../../babel-loader/lib/index.js??ref--1!../../../../framework/menu-item.js": 557, + "../../babel-loader/lib/index.js??ref--1!../../../../shared/telemetry.js": 558, + "../node_modules/@babel/types/lib/index.js": 2, + "../node_modules/@babel/types/lib/validators/generated/index.js": 559, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-utils/index.js": 560, + "../node_modules/@babel/types/lib/builders/generated/index.js": 561, + "../node_modules/lodash/_root.js": 562, + "../node_modules/lodash/isArray.js": 563, + "../node_modules/@babel/types/lib/definitions/index.js": 564, + "../node_modules/lodash/isObjectLike.js": 565, + "../node_modules/source-map/lib/util.js": 566, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-utils/src/privileged-network-request.js": 567, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-utils/src/worker-utils.js": 568, + "../node_modules/lodash/_baseGetTag.js": 569, + "../node_modules/lodash/_Symbol.js": 570, + "../node_modules/@babel/types/lib/definitions/utils.js": 571, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/ast.js": 572, + "../node_modules/lodash/isObject.js": 573, + "../node_modules/lodash/_getNative.js": 574, + "../node_modules/@babel/types/lib/constants/index.js": 575, + "../node_modules/@babel/types/lib/clone/cloneNode.js": 576, + "../node_modules/lodash/isSymbol.js": 577, + "../node_modules/lodash/_getTag.js": 578, + "../node_modules/@babel/types/lib/validators/is.js": 579, + "../node_modules/@babel/types/lib/validators/isValidIdentifier.js": 580, + "../node_modules/source-map/lib/source-map-generator.js": 581, + "../node_modules/source-map/lib/base64-vlq.js": 582, + "../node_modules/source-map/lib/array-set.js": 583, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/index.js": 584, + "../node_modules/charenc/charenc.js": 585, + "../node_modules/lodash/_ListCache.js": 586, + "../node_modules/lodash/_assocIndexOf.js": 587, + "../node_modules/lodash/eq.js": 588, + "../node_modules/lodash/_freeGlobal.js": 589, + "../node_modules/webpack/buildin/global.js": 590, + "../node_modules/lodash/_nativeCreate.js": 591, + "../node_modules/lodash/_getMapData.js": 592, + "../node_modules/lodash/_copyObject.js": 593, + "../node_modules/lodash/keys.js": 594, + "../node_modules/lodash/isBuffer.js": 595, + "../node_modules/lodash/_baseUnary.js": 596, + "../node_modules/lodash/_nodeUtil.js": 597, + "../node_modules/lodash/_isPrototype.js": 598, + "../node_modules/lodash/isArrayLike.js": 599, + "../node_modules/@babel/types/lib/definitions/core.js": 600, + "../node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js": 601, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/helpers.js": 602, + "../node_modules/@babel/generator/lib/index.js": 603, + "../node_modules/lodash/toInteger.js": 604, + "../node_modules/lodash/toString.js": 605, + "../node_modules/lodash/_toKey.js": 606, + "../node_modules/process/browser.js": 607, + "../packages/devtools-source-map/node_modules/source-map/source-map.js": 608, + "../packages/devtools-source-map/node_modules/source-map/lib/util.js": 609, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-wasm-dwarf/index.js": 610, + "../node_modules/fuzzaldrin-plus/lib/scorer.js": 611, + "../node_modules/@babel/types/lib/utils/shallowEqual.js": 612, + "../node_modules/lodash/_Stack.js": 613, + "../node_modules/lodash/_Map.js": 614, + "../node_modules/lodash/_getRawTag.js": 615, + "../node_modules/lodash/_objectToString.js": 616, + "../node_modules/lodash/_MapCache.js": 617, + "../node_modules/lodash/isArguments.js": 618, + "../node_modules/webpack/buildin/module.js": 619, + "../node_modules/lodash/_isIndex.js": 620, + "../node_modules/lodash/isTypedArray.js": 621, + "../node_modules/lodash/isLength.js": 622, + "../node_modules/lodash/_getSymbols.js": 623, + "../node_modules/lodash/_getPrototype.js": 624, + "../node_modules/lodash/_cloneArrayBuffer.js": 625, + "../node_modules/@babel/types/lib/validators/isType.js": 626, + "../node_modules/@babel/types/lib/validators/validate.js": 627, + "../node_modules/@babel/types/lib/definitions/es2015.js": 628, + "../node_modules/@babel/types/lib/utils/inherit.js": 629, + "../node_modules/lodash/_baseFindIndex.js": 630, + "../node_modules/lodash/_setToArray.js": 631, + "../node_modules/source-map/source-map.js": 632, + "../node_modules/source-map/lib/base64.js": 633, + "../node_modules/source-map/lib/mapping-list.js": 634, + "../node_modules/source-map/lib/source-map-consumer.js": 635, + "../node_modules/source-map/lib/binary-search.js": 636, + "../node_modules/source-map/lib/quick-sort.js": 637, + "../node_modules/source-map/lib/source-node.js": 638, + "../node_modules/lodash/_baseToString.js": 639, + "../node_modules/lodash/_arrayMap.js": 640, + "../node_modules/lodash/_isKey.js": 641, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-environment/index.js": 642, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/sourceMapRequests.js": 643, + "../node_modules/md5/md5.js": 644, + "../node_modules/crypt/crypt.js": 645, + "../node_modules/is-buffer/index.js": 646, + "../node_modules/fuzzaldrin-plus/lib/pathScorer.js": 647, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/getSymbols.js": 648, + "../node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js": 649, + "../node_modules/@babel/types/lib/validators/matchesPattern.js": 650, + "../node_modules/lodash/isFunction.js": 651, + "../node_modules/lodash/_toSource.js": 652, + "../node_modules/lodash/_assignValue.js": 653, + "../node_modules/lodash/_baseAssignValue.js": 654, + "../node_modules/lodash/_arrayLikeKeys.js": 655, + "../node_modules/lodash/_baseKeys.js": 656, + "../node_modules/lodash/_overArg.js": 657, + "../node_modules/lodash/keysIn.js": 658, + "../node_modules/lodash/stubArray.js": 659, + "../node_modules/lodash/_getSymbolsIn.js": 660, + "../node_modules/lodash/_arrayPush.js": 661, + "../node_modules/lodash/_getAllKeys.js": 662, + "../node_modules/lodash/_baseGetAllKeys.js": 663, + "../node_modules/lodash/_Set.js": 664, + "../node_modules/lodash/_Uint8Array.js": 665, + "../node_modules/@babel/types/lib/validators/isPlaceholderType.js": 666, + "../node_modules/@babel/helper-validator-identifier/lib/index.js": 667, + "../node_modules/@babel/types/lib/definitions/placeholders.js": 668, + "../node_modules/@babel/types/lib/validators/isNode.js": 669, + "../node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js": 670, + "../node_modules/@babel/types/lib/comments/addComments.js": 671, + "../node_modules/@babel/types/lib/comments/inheritInnerComments.js": 672, + "../node_modules/lodash/_SetCache.js": 673, + "../node_modules/lodash/_cacheHas.js": 674, + "../node_modules/@babel/types/lib/comments/inheritLeadingComments.js": 675, + "../node_modules/@babel/types/lib/comments/inheritsComments.js": 676, + "../node_modules/@babel/types/lib/comments/inheritTrailingComments.js": 677, + "../node_modules/@babel/types/lib/converters/toBlock.js": 678, + "../node_modules/@babel/types/lib/converters/toIdentifier.js": 679, + "../node_modules/@babel/types/lib/modifications/removePropertiesDeep.js": 680, + "../node_modules/@babel/types/lib/traverse/traverseFast.js": 681, + "../node_modules/@babel/types/lib/modifications/removeProperties.js": 682, + "../node_modules/@babel/types/lib/validators/isLet.js": 683, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/simple-path.js": 684, + "../node_modules/@babel/parser/lib/index.js": 685, + "../node_modules/lodash/isEmpty.js": 686, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/sources.js": 687, + "../node_modules/@babel/generator/lib/node/index.js": 688, + "../node_modules/@babel/generator/lib/generators/modules.js": 689, + "../node_modules/@babel/generator/lib/generators/types.js": 690, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/getFunctionName.js": 691, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/getScopes/index.js": 692, + "../node_modules/lodash/_baseIteratee.js": 693, + "../node_modules/lodash/_baseIsEqual.js": 694, + "../node_modules/lodash/_equalArrays.js": 695, + "../node_modules/lodash/_isStrictComparable.js": 696, + "../node_modules/lodash/_matchesStrictComparable.js": 697, + "../node_modules/lodash/_baseGet.js": 698, + "../node_modules/lodash/_castPath.js": 699, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/contains.js": 700, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/search/get-matches.js": 701, + "../packages/devtools-source-map/node_modules/source-map/lib/source-map-generator.js": 702, + "../packages/devtools-source-map/node_modules/source-map/lib/base64-vlq.js": 703, + "../packages/devtools-source-map/node_modules/source-map/lib/array-set.js": 704, + "../packages/devtools-source-map/node_modules/source-map/lib/read-wasm-browser.js": 705, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/createConsumer.js": 706, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-wasm-dwarf/src/wasmAssetBrowser.js": 707, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/index.js": 708, + "../node_modules/fuzzaldrin-plus/lib/query.js": 709, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/tabs/tab-list.js": 710, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/tabs/tab.js": 711, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/tabs/tab-panels.js": 712, + "multi workers/parser/worker.js": 713, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/worker.js": 714, + "../node_modules/@babel/types/lib/validators/react/isReactComponent.js": 715, + "../node_modules/@babel/types/lib/validators/react/isCompatTag.js": 716, + "../node_modules/@babel/types/lib/builders/react/buildChildren.js": 717, + "../node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js": 718, + "../node_modules/@babel/types/lib/builders/builder.js": 719, + "../node_modules/lodash/clone.js": 720, + "../node_modules/lodash/_baseClone.js": 721, + "../node_modules/lodash/_listCacheClear.js": 722, + "../node_modules/lodash/_listCacheDelete.js": 723, + "../node_modules/lodash/_listCacheGet.js": 724, + "../node_modules/lodash/_listCacheHas.js": 725, + "../node_modules/lodash/_listCacheSet.js": 726, + "../node_modules/lodash/_stackClear.js": 727, + "../node_modules/lodash/_stackDelete.js": 728, + "../node_modules/lodash/_stackGet.js": 729, + "../node_modules/lodash/_stackHas.js": 730, + "../node_modules/lodash/_stackSet.js": 731, + "../node_modules/lodash/_baseIsNative.js": 732, + "../node_modules/lodash/_isMasked.js": 733, + "../node_modules/lodash/_coreJsData.js": 734, + "../node_modules/lodash/_getValue.js": 735, + "../node_modules/lodash/_mapCacheClear.js": 736, + "../node_modules/lodash/_Hash.js": 737, + "../node_modules/lodash/_hashClear.js": 738, + "../node_modules/lodash/_hashDelete.js": 739, + "../node_modules/lodash/_hashGet.js": 740, + "../node_modules/lodash/_hashHas.js": 741, + "../node_modules/lodash/_hashSet.js": 742, + "../node_modules/lodash/_mapCacheDelete.js": 743, + "../node_modules/lodash/_isKeyable.js": 744, + "../node_modules/lodash/_mapCacheGet.js": 745, + "../node_modules/lodash/_mapCacheHas.js": 746, + "../node_modules/lodash/_mapCacheSet.js": 747, + "../node_modules/lodash/_arrayEach.js": 748, + "../node_modules/lodash/_defineProperty.js": 749, + "../node_modules/lodash/_baseAssign.js": 750, + "../node_modules/lodash/_baseTimes.js": 751, + "../node_modules/lodash/_baseIsArguments.js": 752, + "../node_modules/lodash/stubFalse.js": 753, + "../node_modules/lodash/_baseIsTypedArray.js": 754, + "../node_modules/lodash/_nativeKeys.js": 755, + "../node_modules/lodash/_baseAssignIn.js": 756, + "../node_modules/lodash/_baseKeysIn.js": 757, + "../node_modules/lodash/_nativeKeysIn.js": 758, + "../node_modules/lodash/_cloneBuffer.js": 759, + "../node_modules/lodash/_copyArray.js": 760, + "../node_modules/lodash/_copySymbols.js": 761, + "../node_modules/lodash/_arrayFilter.js": 762, + "../node_modules/lodash/_copySymbolsIn.js": 763, + "../node_modules/lodash/_getAllKeysIn.js": 764, + "../node_modules/lodash/_DataView.js": 765, + "../node_modules/lodash/_Promise.js": 766, + "../node_modules/lodash/_WeakMap.js": 767, + "../node_modules/lodash/_initCloneArray.js": 768, + "../node_modules/lodash/_initCloneByTag.js": 769, + "../node_modules/lodash/_cloneDataView.js": 770, + "../node_modules/lodash/_cloneRegExp.js": 771, + "../node_modules/lodash/_cloneSymbol.js": 772, + "../node_modules/lodash/_cloneTypedArray.js": 773, + "../node_modules/lodash/_initCloneObject.js": 774, + "../node_modules/lodash/_baseCreate.js": 775, + "../node_modules/lodash/isMap.js": 776, + "../node_modules/lodash/_baseIsMap.js": 777, + "../node_modules/lodash/isSet.js": 778, + "../node_modules/lodash/_baseIsSet.js": 779, + "../node_modules/to-fast-properties/index.js": 780, + "../node_modules/@babel/helper-validator-identifier/lib/identifier.js": 781, + "../node_modules/@babel/helper-validator-identifier/lib/keyword.js": 782, + "../node_modules/@babel/types/lib/definitions/flow.js": 783, + "../node_modules/@babel/types/lib/definitions/jsx.js": 784, + "../node_modules/@babel/types/lib/definitions/misc.js": 785, + "../node_modules/@babel/types/lib/definitions/experimental.js": 786, + "../node_modules/@babel/types/lib/definitions/typescript.js": 787, + "../node_modules/@babel/types/lib/asserts/assertNode.js": 788, + "../node_modules/@babel/types/lib/asserts/generated/index.js": 789, + "../node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js": 790, + "../node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js": 791, + "../node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js": 792, + "../node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js": 793, + "../node_modules/@babel/types/lib/clone/clone.js": 794, + "../node_modules/@babel/types/lib/clone/cloneDeep.js": 795, + "../node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js": 796, + "../node_modules/@babel/types/lib/clone/cloneWithoutLoc.js": 797, + "../node_modules/@babel/types/lib/comments/addComment.js": 798, + "../node_modules/lodash/uniq.js": 799, + "../node_modules/lodash/_baseUniq.js": 800, + "../node_modules/lodash/_setCacheAdd.js": 801, + "../node_modules/lodash/_setCacheHas.js": 802, + "../node_modules/lodash/_arrayIncludes.js": 803, + "../node_modules/lodash/_baseIndexOf.js": 804, + "../node_modules/lodash/_baseIsNaN.js": 805, + "../node_modules/lodash/_strictIndexOf.js": 806, + "../node_modules/lodash/_arrayIncludesWith.js": 807, + "../node_modules/lodash/_createSet.js": 808, + "../node_modules/lodash/noop.js": 809, + "../node_modules/@babel/types/lib/comments/removeComments.js": 810, + "../node_modules/@babel/types/lib/constants/generated/index.js": 811, + "../node_modules/@babel/types/lib/converters/ensureBlock.js": 812, + "../node_modules/@babel/types/lib/converters/toBindingIdentifierName.js": 813, + "../node_modules/@babel/types/lib/converters/toComputedKey.js": 814, + "../node_modules/@babel/types/lib/converters/toExpression.js": 815, + "../node_modules/@babel/types/lib/converters/toKeyAlias.js": 816, + "../node_modules/@babel/types/lib/converters/toSequenceExpression.js": 817, + "../node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js": 818, + "../node_modules/@babel/types/lib/converters/toStatement.js": 819, + "../node_modules/@babel/types/lib/converters/valueToNode.js": 820, + "../node_modules/lodash/isPlainObject.js": 821, + "../node_modules/lodash/isRegExp.js": 822, + "../node_modules/lodash/_baseIsRegExp.js": 823, + "../node_modules/@babel/types/lib/modifications/appendToMemberExpression.js": 824, + "../node_modules/@babel/types/lib/modifications/inherits.js": 825, + "../node_modules/@babel/types/lib/modifications/prependToMemberExpression.js": 826, + "../node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js": 827, + "../node_modules/@babel/types/lib/traverse/traverse.js": 828, + "../node_modules/@babel/types/lib/validators/isBinding.js": 829, + "../node_modules/@babel/types/lib/validators/isBlockScoped.js": 830, + "../node_modules/@babel/types/lib/validators/isImmutable.js": 831, + "../node_modules/@babel/types/lib/validators/isNodesEquivalent.js": 832, + "../node_modules/@babel/types/lib/validators/isReferenced.js": 833, + "../node_modules/@babel/types/lib/validators/isScope.js": 834, + "../node_modules/@babel/types/lib/validators/isSpecifierDefault.js": 835, + "../node_modules/@babel/types/lib/validators/isValidES3Identifier.js": 836, + "../node_modules/@babel/types/lib/validators/isVar.js": 837, + "../node_modules/parse-script-tags/dist/index.js": 838, + "../node_modules/parse-script-tags/dist/customParse.js": 839, + "../node_modules/parse-script-tags/dist/parseScriptFragment.js": 840, + "../node_modules/@babel/generator/lib/source-map.js": 841, + "../node_modules/@babel/generator/lib/printer.js": 842, + "../node_modules/lodash/isInteger.js": 843, + "../node_modules/lodash/toFinite.js": 844, + "../node_modules/lodash/toNumber.js": 845, + "../node_modules/lodash/repeat.js": 846, + "../node_modules/lodash/_baseRepeat.js": 847, + "../node_modules/lodash/_isIterateeCall.js": 848, + "../node_modules/@babel/generator/lib/buffer.js": 849, + "../node_modules/@babel/generator/lib/node/whitespace.js": 850, + "../node_modules/@babel/generator/lib/node/parentheses.js": 851, + "../node_modules/@babel/generator/lib/generators/index.js": 852, + "../node_modules/@babel/generator/lib/generators/template-literals.js": 853, + "../node_modules/@babel/generator/lib/generators/expressions.js": 854, + "../node_modules/@babel/generator/lib/generators/statements.js": 855, + "../node_modules/@babel/generator/lib/generators/classes.js": 856, + "../node_modules/@babel/generator/lib/generators/methods.js": 857, + "../node_modules/jsesc/jsesc.js": 858, + "../node_modules/buffer/index.js": 859, + "../node_modules/base64-js/index.js": 860, + "../node_modules/ieee754/index.js": 861, + "../node_modules/isarray/index.js": 862, + "../node_modules/@babel/generator/lib/generators/flow.js": 863, + "../node_modules/@babel/generator/lib/generators/base.js": 864, + "../node_modules/@babel/generator/lib/generators/jsx.js": 865, + "../node_modules/@babel/generator/lib/generators/typescript.js": 866, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/inferClassName.js": 867, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/frameworks.js": 868, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/getScopes/visitor.js": 869, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/findOutOfScopeLocations.js": 870, + "../node_modules/lodash/findIndex.js": 871, + "../node_modules/lodash/_baseMatches.js": 872, + "../node_modules/lodash/_baseIsMatch.js": 873, + "../node_modules/lodash/_baseIsEqualDeep.js": 874, + "../node_modules/lodash/_arraySome.js": 875, + "../node_modules/lodash/_equalByTag.js": 876, + "../node_modules/lodash/_mapToArray.js": 877, + "../node_modules/lodash/_equalObjects.js": 878, + "../node_modules/lodash/_getMatchData.js": 879, + "../node_modules/lodash/_baseMatchesProperty.js": 880, + "../node_modules/lodash/get.js": 881, + "../node_modules/lodash/_stringToPath.js": 882, + "../node_modules/lodash/_memoizeCapped.js": 883, + "../node_modules/lodash/memoize.js": 884, + "../node_modules/lodash/hasIn.js": 885, + "../node_modules/lodash/_baseHasIn.js": 886, + "../node_modules/lodash/_hasPath.js": 887, + "../node_modules/lodash/identity.js": 888, + "../node_modules/lodash/property.js": 889, + "../node_modules/lodash/_baseProperty.js": 890, + "../node_modules/lodash/_basePropertyDeep.js": 891, + "../node_modules/lodash/findLastIndex.js": 892, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/steps.js": 893, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/utils/closest.js": 894, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/validate.js": 895, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/mapExpression.js": 896, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/mapOriginalExpression.js": 897, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/mapBindings.js": 898, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/parser/mapAwaitExpression.js": 899, + "multi workers/pretty-print/worker.js": 900, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/pretty-print/worker.js": 901, + "../node_modules/pretty-fast/pretty-fast.js": 902, + "../node_modules/pretty-fast/node_modules/acorn/dist/acorn.js": 903, + "multi workers/search/worker.js": 904, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/search/worker.js": 905, + "../node_modules/babel-loader/lib/index.js??ref--1!utils/assert.js": 906, + "../node_modules/babel-loader/lib/index.js??ref--1!utils/build-query.js": 907, + "../node_modules/lodash/escapeRegExp.js": 908, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/search/project-search.js": 909, + "multi ../packages/devtools-source-map/src/worker.js": 910, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/worker.js": 911, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/source-map.js": 912, + "../packages/devtools-source-map/node_modules/source-map/lib/base64.js": 913, + "../packages/devtools-source-map/node_modules/source-map/lib/url-browser.js": 914, + "../packages/devtools-source-map/node_modules/source-map/lib/mapping-list.js": 915, + "../packages/devtools-source-map/node_modules/source-map/lib/source-map-consumer.js": 916, + "../packages/devtools-source-map/node_modules/source-map/lib/binary-search.js": 917, + "../packages/devtools-source-map/node_modules/source-map/lib/wasm.js": 918, + "../packages/devtools-source-map/node_modules/source-map/lib/source-node.js": 919, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/assert.js": 920, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/fetchSourceMap.js": 921, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/wasmRemap.js": 922, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-wasm-dwarf/src/convertToJSON.js": 923, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-wasm-dwarf/src/wasmXScopes.js": 924, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-wasm-dwarf/src/wasmDwarfExpressions.js": 925, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/getOriginalStackFrames.js": 926, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/assetRootBrowser.js": 927, + "multi ../packages/devtools-source-map/src/index.js": 928, + "multi vendors.js": 929, + "../node_modules/babel-loader/lib/index.js??ref--1!vendors.js": 930, + "../node_modules/fuzzaldrin-plus/lib/fuzzaldrin.js": 931, + "../node_modules/fuzzaldrin-plus/lib/filter.js": 932, + "../node_modules/fuzzaldrin-plus/lib/matcher.js": 933, + "../node_modules/react-transition-group/Transition.js": 934, + "../node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js": 935, + "../node_modules/react-transition-group/utils/PropTypes.js": 936, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/tabs/index.js": 937, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/prop-types/ref.js": 938, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab.css": 939, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab-list.css": 940, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/tabs/tabs.js": 941, + "../node_modules/babel-loader/lib/index.js??ref--1!../node_modules/react-aria-components/src/utils/unique-id.js": 942, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-splitter/index.js": 944, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-splitter/src/SplitBox.js": 945, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-splitter/src/Draggable.js": 946, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../packages/devtools-splitter/src/SplitBox.css": 947, + "../node_modules/lodash-move/lib/index.js": 948, + "../node_modules/css-loader/lib/css-base.js": 949, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!workers/parser/worker.js": 950, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!workers/pretty-print/worker.js": 951, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!workers/search/worker.js": 952, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!../packages/devtools-source-map/src/worker.js": 953, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!../packages/devtools-source-map/src/index.js": 954, + "../node_modules/babel-loader/lib/index.js?ignore=src/lib!vendors.js": 955, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-utils/src/network-request.js": 956, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab.css": 957, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab-list.css": 958, + "../node_modules/extract-text-webpack-plugin/dist/loader.js??ref--3-0!../node_modules/css-loader/index.js??ref--3-1!../packages/devtools-splitter/src/SplitBox.css": 959, + "../node_modules/babel-loader/lib/index.js??ref--1!../../../shared/DevToolsUtils.js": 960, + "../node_modules/babel-loader/lib/index.js??ref--1!utils/utils.js": 961, + "../node_modules/timers-browserify/main.js": 962, + "../node_modules/setimmediate/setImmediate.js": 963, + "../node_modules/babel-loader/lib/index.js??ref--1!../../../shared/flags.js": 964, + "../node_modules/babel-loader/lib/index.js??ref--1!../../../shared/platform/stack.js": 965, + "../node_modules/babel-loader/lib/index.js??ref--1!../../../shared/ThreadSafeDevToolsUtils.js": 966, + "../node_modules/babel-loader/lib/index.js??ref--1!../../../shared/webconsole/network-helper.js": 967, + "../node_modules/babel-loader/lib/index.js??ref--1!utils/environment.js": 968, + "../node_modules/pretty-fast/node_modules/acorn/dist/acorn.mjs": 969, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/generated/index.js": 970, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/generated/index.js": 971, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/index.js": 972, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/utils.js": 973, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/constants/index.js": 974, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/clone/cloneNode.js": 975, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/is.js": 976, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isValidIdentifier.js": 977, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/core.js": 978, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js": 979, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/utils/shallowEqual.js": 980, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isType.js": 981, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/validate.js": 982, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/es2015.js": 983, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/utils/inherit.js": 984, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/index.js": 985, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js": 986, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/matchesPattern.js": 987, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isPlaceholderType.js": 988, + "../node_modules/parse-script-tags/node_modules/@babel/helper-validator-identifier/lib/index.js": 989, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/placeholders.js": 990, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isNode.js": 991, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js": 992, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/addComments.js": 993, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/inheritInnerComments.js": 994, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/inheritLeadingComments.js": 995, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/inheritsComments.js": 996, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/inheritTrailingComments.js": 997, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toBlock.js": 998, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toIdentifier.js": 999, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js": 1000, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/traverse/traverseFast.js": 1001, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/removeProperties.js": 1002, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isLet.js": 1003, + "../node_modules/@babel/types/lib/builders/generated/uppercase.js": 1004, + "../node_modules/@babel/types/lib/ast-types/generated/index.js": 1005, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/react/isReactComponent.js": 1006, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/react/isCompatTag.js": 1007, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/react/buildChildren.js": 1008, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js": 1009, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/builder.js": 1010, + "../node_modules/parse-script-tags/node_modules/@babel/helper-validator-identifier/lib/identifier.js": 1011, + "../node_modules/parse-script-tags/node_modules/@babel/helper-validator-identifier/lib/keyword.js": 1012, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/flow.js": 1013, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/jsx.js": 1014, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/misc.js": 1015, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/experimental.js": 1016, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/definitions/typescript.js": 1017, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/asserts/assertNode.js": 1018, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/asserts/generated/index.js": 1019, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js": 1020, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js": 1021, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js": 1022, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js": 1023, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/clone/clone.js": 1024, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/clone/cloneDeep.js": 1025, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js": 1026, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js": 1027, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/addComment.js": 1028, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/comments/removeComments.js": 1029, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/constants/generated/index.js": 1030, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/ensureBlock.js": 1031, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js": 1032, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toComputedKey.js": 1033, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toExpression.js": 1034, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toKeyAlias.js": 1035, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toSequenceExpression.js": 1036, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js": 1037, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/toStatement.js": 1038, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/converters/valueToNode.js": 1039, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js": 1040, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/inherits.js": 1041, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js": 1042, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js": 1043, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/traverse/traverse.js": 1044, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isBinding.js": 1045, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isBlockScoped.js": 1046, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isImmutable.js": 1047, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isNodesEquivalent.js": 1048, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isReferenced.js": 1049, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isScope.js": 1050, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isSpecifierDefault.js": 1051, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isValidES3Identifier.js": 1052, + "../node_modules/parse-script-tags/node_modules/@babel/types/lib/validators/isVar.js": 1053, + "../node_modules/parse-script-tags/node_modules/@babel/parser/lib/index.js": 1054, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/worker-handler.js": 1055, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/network-request.js": 1056, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/worker-dispatcher.js": 1057, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/utils/privileged-network-request.js": 1058, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/worker-utils.js": 1059, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/url-state-machine.js": 1060, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/urlencoded.js": 1061, + "../packages/devtools-source-map/node_modules/webidl-conversions/lib/index.js": 1062, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/utils.js": 1063, + "../node_modules/node-libs-browser/node_modules/punycode/punycode.js": 1064, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/infra.js": 1065, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/URLSearchParams.js": 1066, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/public-api.js": 1067, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/URL.js": 1068, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/URL-impl.js": 1069, + "../packages/devtools-source-map/node_modules/tr46/index.js": 1070, + "../packages/devtools-source-map/node_modules/tr46/lib/regexes.js": 1071, + "../node_modules/json-loader/index.js!../packages/devtools-source-map/node_modules/tr46/lib/mappingTable.json": 1072, + "../packages/devtools-source-map/node_modules/whatwg-url/lib/URLSearchParams-impl.js": 1073, + "../node_modules/lodash.sortby/index.js": 1074, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/wasm-dwarf/wasmXScopes.js": 1075, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/wasm-dwarf/wasmDwarfExpressions.js": 1076, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/wasm-dwarf/wasmAsset.js": 1077, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/wasm-dwarf/convertToJSON.js": 1078, + "../node_modules/node-libs-browser/mock/empty.js": 1079, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/assets.js": 1080, + "../packages/devtools-source-map/node_modules/source-map/lib/mappings.wasm": 1081, + "../packages/devtools-source-map/wasm/dwarf_to_json.wasm": 1082, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/devtools-source-map/src/wasm-dwarf/wasmAssetBrowser.js": 1083, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/md5.js": 1084, + "../../../../node_modules/is-buffer/index.js": 1085, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/util.js": 1086, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/source-map.js": 1087, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/source-map-generator.js": 1088, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/base64-vlq.js": 1089, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/array-set.js": 1090, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/read-wasm-browser.js": 1091, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/base64.js": 1092, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/mapping-list.js": 1093, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/source-map-consumer.js": 1094, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/binary-search.js": 1095, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/wasm.js": 1096, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/source-node.js": 1097, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/read-wasm.js": 1098, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/source-map/lib/url.js": 1099, + "../node_modules/babel-loader/lib/index.js??ref--1!../../shared/vendor/whatwg-url.js": 1100, + "../node_modules/path-browserify/index.js": 1101, + "../node_modules/babel-loader/lib/index.js??ref--1!../packages/pretty-fast/pretty-fast.js": 1102, + "../node_modules/acorn/dist/acorn.mjs": 1103, + "../packages/pretty-fast/node_modules/acorn/dist/acorn.mjs": 1104, + "../node_modules/babel-loader/lib/index.js??ref--1!workers/pretty-print/pretty-fast.js": 1105, + "../node_modules/acorn/dist/acorn.es.js": 1106, + "../node_modules/@babel/generator/node_modules/source-map/lib/util.js": 1107, + "../node_modules/@babel/generator/node_modules/source-map/lib/source-map-generator.js": 1108, + "../node_modules/@babel/generator/node_modules/source-map/lib/base64-vlq.js": 1109, + "../node_modules/@babel/generator/node_modules/source-map/lib/array-set.js": 1110, + "../node_modules/source-map/lib/read-wasm.js": 1111, + "../node_modules/@babel/generator/node_modules/source-map/source-map.js": 1112, + "../node_modules/@babel/generator/node_modules/source-map/lib/base64.js": 1113, + "../node_modules/@babel/generator/node_modules/source-map/lib/mapping-list.js": 1114, + "../node_modules/@babel/generator/node_modules/source-map/lib/source-map-consumer.js": 1115, + "../node_modules/@babel/generator/node_modules/source-map/lib/binary-search.js": 1116, + "../node_modules/@babel/generator/node_modules/source-map/lib/quick-sort.js": 1117, + "../node_modules/@babel/generator/node_modules/source-map/lib/source-node.js": 1118, + "../node_modules/source-map/lib/wasm.js": 1119, + "external \"devtools/client/shared/vendor/micromatch/micromatch\"": 1120, + "../node_modules/node-libs-browser/node_modules/buffer/index.js": 1121, + "../node_modules/node-libs-browser/node_modules/base64-js/index.js": 1122, + "../node_modules/node-libs-browser/node_modules/ieee754/index.js": 1123 + }, + "usedIds": { + "0": 0, + "1": 1, + "2": 2, + "3": 3, + "4": 4, + "5": 5, + "6": 6, + "7": 7, + "8": 8, + "9": 9, + "10": 10, + "11": 11, + "12": 12, + "13": 13, + "14": 14, + "15": 15, + "16": 16, + "17": 17, + "18": 18, + "19": 19, + "20": 20, + "21": 21, + "22": 22, + "23": 23, + "24": 24, + "25": 25, + "26": 26, + "27": 27, + "28": 28, + "29": 29, + "30": 30, + "31": 31, + "32": 32, + "33": 33, + "34": 34, + "35": 35, + "36": 36, + "37": 37, + "38": 38, + "39": 39, + "40": 40, + "41": 41, + "42": 42, + "43": 43, + "44": 44, + "45": 45, + "46": 46, + "47": 47, + "48": 48, + "49": 49, + "50": 50, + "51": 51, + "52": 52, + "53": 53, + "54": 54, + "55": 55, + "56": 56, + "57": 57, + "58": 58, + "59": 59, + "60": 60, + "61": 61, + "62": 62, + "63": 63, + "64": 64, + "65": 65, + "66": 66, + "67": 67, + "68": 68, + "69": 69, + "70": 70, + "71": 71, + "72": 72, + "73": 73, + "74": 74, + "75": 75, + "76": 76, + "77": 77, + "78": 78, + "79": 79, + "80": 80, + "81": 81, + "82": 82, + "83": 83, + "84": 84, + "85": 85, + "86": 86, + "87": 87, + "88": 88, + "89": 89, + "90": 90, + "91": 91, + "92": 92, + "93": 93, + "94": 94, + "95": 95, + "96": 96, + "97": 97, + "98": 98, + "99": 99, + "100": 100, + "101": 101, + "102": 102, + "103": 103, + "104": 104, + "105": 105, + "106": 106, + "107": 107, + "108": 108, + "109": 109, + "110": 110, + "111": 111, + "112": 112, + "113": 113, + "114": 114, + "115": 115, + "116": 116, + "117": 117, + "118": 118, + "119": 119, + "120": 120, + "121": 121, + "122": 122, + "123": 123, + "124": 124, + "125": 125, + "126": 126, + "127": 127, + "128": 128, + "129": 129, + "130": 130, + "131": 131, + "132": 132, + "133": 133, + "134": 134, + "135": 135, + "136": 136, + "137": 137, + "138": 138, + "139": 139, + "140": 140, + "141": 141, + "142": 142, + "143": 143, + "144": 144, + "145": 145, + "146": 146, + "147": 147, + "148": 148, + "149": 149, + "150": 150, + "151": 151, + "152": 152, + "153": 153, + "154": 154, + "155": 155, + "156": 156, + "157": 157, + "158": 158, + "159": 159, + "160": 160, + "161": 161, + "162": 162, + "163": 163, + "164": 164, + "165": 165, + "166": 166, + "167": 167, + "168": 168, + "169": 169, + "170": 170, + "171": 171, + "172": 172, + "173": 173, + "174": 174, + "175": 175, + "176": 176, + "177": 177, + "178": 178, + "179": 179, + "180": 180, + "181": 181, + "182": 182, + "183": 183, + "184": 184, + "185": 185, + "186": 186, + "187": 187, + "188": 188, + "189": 189, + "190": 190, + "191": 191, + "192": 192, + "193": 193, + "194": 194, + "195": 195, + "196": 196, + "197": 197, + "198": 198, + "199": 199, + "200": 200, + "201": 201, + "202": 202, + "203": 203, + "204": 204, + "205": 205, + "206": 206, + "207": 207, + "208": 208, + "209": 209, + "210": 210, + "211": 211, + "212": 212, + "213": 213, + "214": 214, + "215": 215, + "216": 216, + "217": 217, + "218": 218, + "219": 219, + "220": 220, + "221": 221, + "222": 222, + "223": 223, + "224": 224, + "225": 225, + "226": 226, + "227": 227, + "228": 228, + "229": 229, + "230": 230, + "231": 231, + "232": 232, + "233": 233, + "234": 234, + "235": 235, + "236": 236, + "237": 237, + "238": 238, + "239": 239, + "240": 240, + "241": 241, + "242": 242, + "243": 243, + "244": 244, + "245": 245, + "246": 246, + "247": 247, + "248": 248, + "249": 249, + "250": 250, + "251": 251, + "252": 252, + "253": 253, + "254": 254, + "255": 255, + "256": 256, + "257": 257, + "258": 258, + "259": 259, + "260": 260, + "261": 261, + "262": 262, + "263": 263, + "264": 264, + "265": 265, + "266": 266, + "267": 267, + "268": 268, + "269": 269, + "270": 270, + "271": 271, + "272": 272, + "273": 273, + "274": 274, + "275": 275, + "276": 276, + "277": 277, + "278": 278, + "279": 279, + "280": 280, + "281": 281, + "282": 282, + "283": 283, + "284": 284, + "285": 285, + "286": 286, + "287": 287, + "288": 288, + "289": 289, + "290": 290, + "291": 291, + "292": 292, + "293": 293, + "294": 294, + "295": 295, + "296": 296, + "297": 297, + "298": 298, + "299": 299, + "300": 300, + "301": 301, + "302": 302, + "303": 303, + "304": 304, + "305": 305, + "306": 306, + "307": 307, + "308": 308, + "309": 309, + "310": 310, + "311": 311, + "312": 312, + "313": 313, + "314": 314, + "315": 315, + "316": 316, + "317": 317, + "318": 318, + "319": 319, + "320": 320, + "321": 321, + "322": 322, + "323": 323, + "324": 324, + "325": 325, + "326": 326, + "327": 327, + "328": 328, + "329": 329, + "330": 330, + "331": 331, + "332": 332, + "333": 333, + "334": 334, + "335": 335, + "336": 336, + "337": 337, + "338": 338, + "339": 339, + "340": 340, + "341": 341, + "342": 342, + "343": 343, + "344": 344, + "345": 345, + "346": 346, + "347": 347, + "348": 348, + "349": 349, + "350": 350, + "351": 351, + "352": 352, + "353": 353, + "354": 354, + "355": 355, + "356": 356, + "357": 357, + "358": 358, + "359": 359, + "360": 360, + "361": 361, + "362": 362, + "363": 363, + "364": 364, + "365": 365, + "366": 366, + "367": 367, + "368": 368, + "369": 369, + "370": 370, + "371": 371, + "372": 372, + "373": 373, + "374": 374, + "375": 375, + "376": 376, + "377": 377, + "378": 378, + "379": 379, + "380": 380, + "381": 381, + "382": 382, + "383": 383, + "384": 384, + "385": 385, + "386": 386, + "387": 387, + "388": 388, + "389": 389, + "390": 390, + "391": 391, + "392": 392, + "393": 393, + "394": 394, + "395": 395, + "396": 396, + "397": 397, + "398": 398, + "399": 399, + "400": 400, + "401": 401, + "402": 402, + "403": 403, + "404": 404, + "405": 405, + "406": 406, + "407": 407, + "408": 408, + "409": 409, + "410": 410, + "411": 411, + "412": 412, + "413": 413, + "414": 414, + "415": 415, + "416": 416, + "417": 417, + "418": 418, + "419": 419, + "420": 420, + "421": 421, + "422": 422, + "423": 423, + "424": 424, + "425": 425, + "426": 426, + "427": 427, + "428": 428, + "429": 429, + "430": 430, + "431": 431, + "432": 432, + "433": 433, + "434": 434, + "435": 435, + "436": 436, + "437": 437, + "438": 438, + "439": 439, + "440": 440, + "441": 441, + "442": 442, + "443": 443, + "444": 444, + "445": 445, + "446": 446, + "447": 447, + "448": 448, + "449": 449, + "450": 450, + "451": 451, + "452": 452, + "453": 453, + "454": 454, + "455": 455, + "456": 456, + "457": 457, + "458": 458, + "459": 459, + "460": 460, + "461": 461, + "462": 462, + "463": 463, + "464": 464, + "465": 465, + "466": 466, + "467": 467, + "468": 468, + "469": 469, + "470": 470, + "471": 471, + "472": 472, + "473": 473, + "474": 474, + "475": 475, + "476": 476, + "477": 477, + "478": 478, + "479": 479, + "480": 480, + "481": 481, + "482": 482, + "483": 483, + "484": 484, + "485": 485, + "486": 486, + "487": 487, + "488": 488, + "489": 489, + "490": 490, + "491": 491, + "492": 492, + "493": 493, + "494": 494, + "495": 495, + "496": 496, + "497": 497, + "498": 498, + "499": 499, + "500": 500, + "501": 501, + "502": 502, + "503": 503, + "504": 504, + "505": 505, + "506": 506, + "507": 507, + "508": 508, + "509": 509, + "510": 510, + "511": 511, + "512": 512, + "513": 513, + "514": 514, + "515": 515, + "516": 516, + "517": 517, + "518": 518, + "519": 519, + "520": 520, + "521": 521, + "522": 522, + "523": 523, + "524": 524, + "525": 525, + "526": 526, + "527": 527, + "528": 528, + "529": 529, + "530": 530, + "531": 531, + "532": 532, + "533": 533, + "534": 534, + "535": 535, + "536": 536, + "537": 537, + "538": 538, + "539": 539, + "540": 540, + "541": 541, + "542": 542, + "543": 543, + "544": 544, + "545": 545, + "546": 546, + "547": 547, + "548": 548, + "549": 549, + "550": 550, + "551": 551, + "552": 552, + "553": 553, + "554": 554, + "555": 555, + "556": 556, + "557": 557, + "558": 558, + "559": 559, + "560": 560, + "561": 561, + "562": 562, + "563": 563, + "564": 564, + "565": 565, + "566": 566, + "567": 567, + "568": 568, + "569": 569, + "570": 570, + "571": 571, + "572": 572, + "573": 573, + "574": 574, + "575": 575, + "576": 576, + "577": 577, + "578": 578, + "579": 579, + "580": 580, + "581": 581, + "582": 582, + "583": 583, + "584": 584, + "585": 585, + "586": 586, + "587": 587, + "588": 588, + "589": 589, + "590": 590, + "591": 591, + "592": 592, + "593": 593, + "594": 594, + "595": 595, + "596": 596, + "597": 597, + "598": 598, + "599": 599, + "600": 600, + "601": 601, + "602": 602, + "603": 603, + "604": 604, + "605": 605, + "606": 606, + "607": 607, + "608": 608, + "609": 609, + "610": 610, + "611": 611, + "612": 612, + "613": 613, + "614": 614, + "615": 615, + "616": 616, + "617": 617, + "618": 618, + "619": 619, + "620": 620, + "621": 621, + "622": 622, + "623": 623, + "624": 624, + "625": 625, + "626": 626, + "627": 627, + "628": 628, + "629": 629, + "630": 630, + "631": 631, + "632": 632, + "633": 633, + "634": 634, + "635": 635, + "636": 636, + "637": 637, + "638": 638, + "639": 639, + "640": 640, + "641": 641, + "642": 642, + "643": 643, + "644": 644, + "645": 645, + "646": 646, + "647": 647, + "648": 648, + "649": 649, + "650": 650, + "651": 651, + "652": 652, + "653": 653, + "654": 654, + "655": 655, + "656": 656, + "657": 657, + "658": 658, + "659": 659, + "660": 660, + "661": 661, + "662": 662, + "663": 663, + "664": 664, + "665": 665, + "666": 666, + "667": 667, + "668": 668, + "669": 669, + "670": 670, + "671": 671, + "672": 672, + "673": 673, + "674": 674, + "675": 675, + "676": 676, + "677": 677, + "678": 678, + "679": 679, + "680": 680, + "681": 681, + "682": 682, + "683": 683, + "684": 684, + "685": 685, + "686": 686, + "687": 687, + "688": 688, + "689": 689, + "690": 690, + "691": 691, + "692": 692, + "693": 693, + "694": 694, + "695": 695, + "696": 696, + "697": 697, + "698": 698, + "699": 699, + "700": 700, + "701": 701, + "702": 702, + "703": 703, + "704": 704, + "705": 705, + "706": 706, + "707": 707, + "708": 708, + "709": 709, + "710": 710, + "711": 711, + "712": 712, + "713": 713, + "714": 714, + "715": 715, + "716": 716, + "717": 717, + "718": 718, + "719": 719, + "720": 720, + "721": 721, + "722": 722, + "723": 723, + "724": 724, + "725": 725, + "726": 726, + "727": 727, + "728": 728, + "729": 729, + "730": 730, + "731": 731, + "732": 732, + "733": 733, + "734": 734, + "735": 735, + "736": 736, + "737": 737, + "738": 738, + "739": 739, + "740": 740, + "741": 741, + "742": 742, + "743": 743, + "744": 744, + "745": 745, + "746": 746, + "747": 747, + "748": 748, + "749": 749, + "750": 750, + "751": 751, + "752": 752, + "753": 753, + "754": 754, + "755": 755, + "756": 756, + "757": 757, + "758": 758, + "759": 759, + "760": 760, + "761": 761, + "762": 762, + "763": 763, + "764": 764, + "765": 765, + "766": 766, + "767": 767, + "768": 768, + "769": 769, + "770": 770, + "771": 771, + "772": 772, + "773": 773, + "774": 774, + "775": 775, + "776": 776, + "777": 777, + "778": 778, + "779": 779, + "780": 780, + "781": 781, + "782": 782, + "783": 783, + "784": 784, + "785": 785, + "786": 786, + "787": 787, + "788": 788, + "789": 789, + "790": 790, + "791": 791, + "792": 792, + "793": 793, + "794": 794, + "795": 795, + "796": 796, + "797": 797, + "798": 798, + "799": 799, + "800": 800, + "801": 801, + "802": 802, + "803": 803, + "804": 804, + "805": 805, + "806": 806, + "807": 807, + "808": 808, + "809": 809, + "810": 810, + "811": 811, + "812": 812, + "813": 813, + "814": 814, + "815": 815, + "816": 816, + "817": 817, + "818": 818, + "819": 819, + "820": 820, + "821": 821, + "822": 822, + "823": 823, + "824": 824, + "825": 825, + "826": 826, + "827": 827, + "828": 828, + "829": 829, + "830": 830, + "831": 831, + "832": 832, + "833": 833, + "834": 834, + "835": 835, + "836": 836, + "837": 837, + "838": 838, + "839": 839, + "840": 840, + "841": 841, + "842": 842, + "843": 843, + "844": 844, + "845": 845, + "846": 846, + "847": 847, + "848": 848, + "849": 849, + "850": 850, + "851": 851, + "852": 852, + "853": 853, + "854": 854, + "855": 855, + "856": 856, + "857": 857, + "858": 858, + "859": 859, + "860": 860, + "861": 861, + "862": 862, + "863": 863, + "864": 864, + "865": 865, + "866": 866, + "867": 867, + "868": 868, + "869": 869, + "870": 870, + "871": 871, + "872": 872, + "873": 873, + "874": 874, + "875": 875, + "876": 876, + "877": 877, + "878": 878, + "879": 879, + "880": 880, + "881": 881, + "882": 882, + "883": 883, + "884": 884, + "885": 885, + "886": 886, + "887": 887, + "888": 888, + "889": 889, + "890": 890, + "891": 891, + "892": 892, + "893": 893, + "894": 894, + "895": 895, + "896": 896, + "897": 897, + "898": 898, + "899": 899, + "900": 900, + "901": 901, + "902": 902, + "903": 903, + "904": 904, + "905": 905, + "906": 906, + "907": 907, + "908": 908, + "909": 909, + "910": 910, + "911": 911, + "912": 912, + "913": 913, + "914": 914, + "915": 915, + "916": 916, + "917": 917, + "918": 918, + "919": 919, + "920": 920, + "921": 921, + "922": 922, + "923": 923, + "924": 924, + "925": 925, + "926": 926, + "927": 927, + "928": 928, + "929": 929, + "930": 930, + "931": 931, + "932": 932, + "933": 933, + "934": 934, + "935": 935, + "936": 936, + "937": 937, + "938": 938, + "939": 939, + "940": 940, + "941": 941, + "942": 942, + "943": 943, + "944": 944, + "945": 945, + "946": 946, + "947": 947, + "948": 948, + "949": 949, + "950": 950, + "951": 951, + "952": 952, + "953": 953, + "954": 954, + "955": 955, + "956": 956, + "957": 957, + "958": 958, + "959": 959, + "960": 960, + "961": 961, + "962": 962, + "963": 963, + "964": 964, + "965": 965, + "966": 966, + "967": 967, + "968": 968, + "969": 969, + "970": 970, + "971": 971, + "972": 972, + "973": 973, + "974": 974, + "975": 975, + "976": 976, + "977": 977, + "978": 978, + "979": 979, + "980": 980, + "981": 981, + "982": 982, + "983": 983, + "984": 984, + "985": 985, + "986": 986, + "987": 987, + "988": 988, + "989": 989, + "990": 990, + "991": 991, + "992": 992, + "993": 993, + "994": 994, + "995": 995, + "996": 996, + "997": 997, + "998": 998, + "999": 999, + "1000": 1000, + "1001": 1001, + "1002": 1002, + "1003": 1003, + "1004": 1004, + "1005": 1005, + "1006": 1006, + "1007": 1007, + "1008": 1008, + "1009": 1009, + "1010": 1010, + "1011": 1011, + "1012": 1012, + "1013": 1013, + "1014": 1014, + "1015": 1015, + "1016": 1016, + "1017": 1017, + "1018": 1018, + "1019": 1019, + "1020": 1020, + "1021": 1021, + "1022": 1022, + "1023": 1023, + "1024": 1024, + "1025": 1025, + "1026": 1026, + "1027": 1027, + "1028": 1028, + "1029": 1029, + "1030": 1030, + "1031": 1031, + "1032": 1032, + "1033": 1033, + "1034": 1034, + "1035": 1035, + "1036": 1036, + "1037": 1037, + "1038": 1038, + "1039": 1039, + "1040": 1040, + "1041": 1041, + "1042": 1042, + "1043": 1043, + "1044": 1044, + "1045": 1045, + "1046": 1046, + "1047": 1047, + "1048": 1048, + "1049": 1049, + "1050": 1050, + "1051": 1051, + "1052": 1052, + "1053": 1053, + "1054": 1054, + "1055": 1055, + "1056": 1056, + "1057": 1057, + "1058": 1058, + "1059": 1059, + "1060": 1060, + "1061": 1061, + "1062": 1062, + "1063": 1063, + "1064": 1064, + "1065": 1065, + "1066": 1066, + "1067": 1067, + "1068": 1068, + "1069": 1069, + "1070": 1070, + "1071": 1071, + "1072": 1072, + "1073": 1073, + "1074": 1074, + "1075": 1075, + "1076": 1076, + "1077": 1077, + "1078": 1078, + "1079": 1079, + "1080": 1080, + "1081": 1081, + "1082": 1082, + "1083": 1083, + "1084": 1084, + "1085": 1085, + "1086": 1086, + "1087": 1087, + "1088": 1088, + "1089": 1089, + "1090": 1090, + "1091": 1091, + "1092": 1092, + "1093": 1093, + "1094": 1094, + "1095": 1095, + "1096": 1096, + "1097": 1097, + "1098": 1098, + "1099": 1099, + "1100": 1100, + "1101": 1101, + "1102": 1102, + "1103": 1103, + "1104": 1104, + "1105": 1105, + "1106": 1106, + "1107": 1107, + "1108": 1108, + "1109": 1109, + "1110": 1110, + "1111": 1111, + "1112": 1112, + "1113": 1113, + "1114": 1114, + "1115": 1115, + "1116": 1116, + "1117": 1117, + "1118": 1118, + "1119": 1119, + "1120": 1120, + "1121": 1121, + "1122": 1122, + "1123": 1123 + } + }, + "chunks": { + "byName": { + "parser-worker": 0, + "vendors": 1, + "reps": 2, + "source-map-worker": 3, + "search-worker": 4, + "pretty-print-worker": 5, + "source-map-index": 6, + "whatwg-url": 7 + }, + "byBlocks": {}, + "usedIds": { + "1": 1 + } + }, + "extract-text-webpack-plugin ../../extract-text-webpack-plugin/dist ../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-contextmenu/menu.css": [ + { + "modules": { + "byIdentifier": { + "../../css-loader/index.js??ref--3-1!../../postcss-loader/lib/index.js!../../../packages/devtools-contextmenu/menu.css": 0, + "../../css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../packages/devtools-splitter/src/SplitBox.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../packages/devtools-splitter/src/SplitBox.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab-list.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../node_modules/postcss-loader/lib/index.js!../node_modules/react-aria-components/src/tabs/tab-list.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../packages/devtools-splitter/src/SplitBox.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../packages/devtools-splitter/src/SplitBox.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ], + "extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab-list.css": [ + { + "modules": { + "byIdentifier": { + "../node_modules/css-loader/index.js??ref--3-1!../node_modules/react-aria-components/src/tabs/tab-list.css": 0, + "../node_modules/css-loader/lib/css-base.js": 1 + }, + "usedIds": { + "0": 0, + "1": 1 + } + }, + "chunks": { + "byName": {}, + "byBlocks": {}, + "usedIds": { + "0": 0 + } + } + } + ] +} \ No newline at end of file diff --git a/devtools/client/debugger/bin/watch.js b/devtools/client/debugger/bin/watch.js new file mode 100644 index 0000000000..d4d02e18ca --- /dev/null +++ b/devtools/client/debugger/bin/watch.js @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +var chokidar = require("chokidar"); +var shell = require("shelljs"); +var path = require("path"); + +const geckoPath = path.join(__dirname, "../../../.."); +const srcPath = path.join(__dirname, "../src"); +function watch() { + console.log("Watching for src changes"); + const watcher = chokidar.watch(srcPath); + let working = false; + watcher.on("change", filePath => { + const relPath = path.relative(srcPath, filePath); + console.log(`Updating ${relPath}`); + if (working) { + return; + } + working = true; + const start = new Date(); + + shell.exec(`cd ${geckoPath}; ./mach build faster; cd -;`, { silent: true }); + working = false; + const end = Math.round((new Date() - start) / 1000); + console.log(` Built in ${end}s`); + }); +} + +watch(); diff --git a/devtools/client/debugger/configs/mozilla-central-mappings.js b/devtools/client/debugger/configs/mozilla-central-mappings.js new file mode 100644 index 0000000000..d82b50bae3 --- /dev/null +++ b/devtools/client/debugger/configs/mozilla-central-mappings.js @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +module.exports = { + "./source-editor": "devtools/client/sourceeditor/editor", + "../editor/source-editor": "devtools/client/sourceeditor/editor", + react: "devtools/client/shared/vendor/react", + "react-dom": "devtools/client/shared/vendor/react-dom", + "react-dom-factories": "devtools/client/shared/vendor/react-dom-factories", + "react-redux": "devtools/client/shared/vendor/react-redux", + redux: "devtools/client/shared/vendor/redux", + "prop-types": "devtools/client/shared/vendor/react-prop-types", + "devtools-modules/src/menu": "devtools/client/framework/menu", + "devtools-modules/src/menu/menu-item": "devtools/client/framework/menu-item", + "wasmparser/dist/cjs/WasmParser": "devtools/client/shared/vendor/WasmParser", + "wasmparser/dist/cjs/WasmDis": "devtools/client/shared/vendor/WasmDis", + "devtools/client/shared/vendor/micromatch/micromatch": "devtools/client/shared/vendor/micromatch/micromatch", +}; diff --git a/devtools/client/debugger/dist/moz.build b/devtools/client/debugger/dist/moz.build new file mode 100644 index 0000000000..64187f8ff6 --- /dev/null +++ b/devtools/client/debugger/dist/moz.build @@ -0,0 +1,11 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DevToolsModules( + "parser-worker.js", + "pretty-print-worker.js", + "search-worker.js", + "vendors.js", +) diff --git a/devtools/client/debugger/dist/parser-worker.js b/devtools/client/debugger/dist/parser-worker.js new file mode 100644 index 0000000000..1fd38ba914 --- /dev/null +++ b/devtools/client/debugger/dist/parser-worker.js @@ -0,0 +1,73552 @@ +(function (factory) { + typeof define === 'function' && define.amd ? define(factory) : + factory(); +})((function () { 'use strict'; + + (function() { + const env = {"NODE_ENV":"production"}; + try { + if (process) { + process.env = Object.assign({}, process.env); + Object.assign(process.env, env); + return; + } + } catch (e) {} // avoid ReferenceError: process is not defined + globalThis.process = { env:env }; + })(); + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + var lib$6 = {}; + + var isReactComponent$4 = {}; + + var buildMatchMemberExpression$3 = {}; + + var matchesPattern$3 = {}; + + var generated$8 = {}; + + var shallowEqual$3 = {}; + + Object.defineProperty(shallowEqual$3, "__esModule", { + value: true + }); + shallowEqual$3.default = shallowEqual$2; + + function shallowEqual$2(actual, expected) { + const keys = Object.keys(expected); + + for (const key of keys) { + if (actual[key] !== expected[key]) { + return false; + } + } + + return true; + } + + Object.defineProperty(generated$8, "__esModule", { + value: true + }); + generated$8.isArrayExpression = isArrayExpression$2; + generated$8.isAssignmentExpression = isAssignmentExpression$3; + generated$8.isBinaryExpression = isBinaryExpression$2; + generated$8.isInterpreterDirective = isInterpreterDirective$1; + generated$8.isDirective = isDirective$1; + generated$8.isDirectiveLiteral = isDirectiveLiteral$1; + generated$8.isBlockStatement = isBlockStatement$2; + generated$8.isBreakStatement = isBreakStatement$1; + generated$8.isCallExpression = isCallExpression$5; + generated$8.isCatchClause = isCatchClause$1; + generated$8.isConditionalExpression = isConditionalExpression$2; + generated$8.isContinueStatement = isContinueStatement$1; + generated$8.isDebuggerStatement = isDebuggerStatement$1; + generated$8.isDoWhileStatement = isDoWhileStatement$1; + generated$8.isEmptyStatement = isEmptyStatement$2; + generated$8.isExpressionStatement = isExpressionStatement$3; + generated$8.isFile = isFile$2; + generated$8.isForInStatement = isForInStatement$2; + generated$8.isForStatement = isForStatement$3; + generated$8.isFunctionDeclaration = isFunctionDeclaration$1; + generated$8.isFunctionExpression = isFunctionExpression$1; + generated$8.isIdentifier = isIdentifier$4; + generated$8.isIfStatement = isIfStatement$3; + generated$8.isLabeledStatement = isLabeledStatement$1; + generated$8.isStringLiteral = isStringLiteral$2; + generated$8.isNumericLiteral = isNumericLiteral$1; + generated$8.isNullLiteral = isNullLiteral$1; + generated$8.isBooleanLiteral = isBooleanLiteral$1; + generated$8.isRegExpLiteral = isRegExpLiteral$1; + generated$8.isLogicalExpression = isLogicalExpression$2; + generated$8.isMemberExpression = isMemberExpression$5; + generated$8.isNewExpression = isNewExpression$4; + generated$8.isProgram = isProgram$2; + generated$8.isObjectExpression = isObjectExpression$2; + generated$8.isObjectMethod = isObjectMethod$1; + generated$8.isObjectProperty = isObjectProperty$1; + generated$8.isRestElement = isRestElement$1; + generated$8.isReturnStatement = isReturnStatement$2; + generated$8.isSequenceExpression = isSequenceExpression$2; + generated$8.isParenthesizedExpression = isParenthesizedExpression$1; + generated$8.isSwitchCase = isSwitchCase$1; + generated$8.isSwitchStatement = isSwitchStatement$2; + generated$8.isThisExpression = isThisExpression$1; + generated$8.isThrowStatement = isThrowStatement$2; + generated$8.isTryStatement = isTryStatement$1; + generated$8.isUnaryExpression = isUnaryExpression$1; + generated$8.isUpdateExpression = isUpdateExpression$1; + generated$8.isVariableDeclaration = isVariableDeclaration$1; + generated$8.isVariableDeclarator = isVariableDeclarator$2; + generated$8.isWhileStatement = isWhileStatement$2; + generated$8.isWithStatement = isWithStatement$1; + generated$8.isAssignmentPattern = isAssignmentPattern$2; + generated$8.isArrayPattern = isArrayPattern$1; + generated$8.isArrowFunctionExpression = isArrowFunctionExpression$2; + generated$8.isClassBody = isClassBody$1; + generated$8.isClassExpression = isClassExpression$2; + generated$8.isClassDeclaration = isClassDeclaration$3; + generated$8.isExportAllDeclaration = isExportAllDeclaration$1; + generated$8.isExportDefaultDeclaration = isExportDefaultDeclaration$3; + generated$8.isExportNamedDeclaration = isExportNamedDeclaration$2; + generated$8.isExportSpecifier = isExportSpecifier$1; + generated$8.isForOfStatement = isForOfStatement$2; + generated$8.isImportDeclaration = isImportDeclaration$1; + generated$8.isImportDefaultSpecifier = isImportDefaultSpecifier$2; + generated$8.isImportNamespaceSpecifier = isImportNamespaceSpecifier$2; + generated$8.isImportSpecifier = isImportSpecifier$1; + generated$8.isMetaProperty = isMetaProperty$1; + generated$8.isClassMethod = isClassMethod$1; + generated$8.isObjectPattern = isObjectPattern$2; + generated$8.isSpreadElement = isSpreadElement$1; + generated$8.isSuper = isSuper$1; + generated$8.isTaggedTemplateExpression = isTaggedTemplateExpression$2; + generated$8.isTemplateElement = isTemplateElement$1; + generated$8.isTemplateLiteral = isTemplateLiteral$1; + generated$8.isYieldExpression = isYieldExpression$2; + generated$8.isAwaitExpression = isAwaitExpression$2; + generated$8.isImport = isImport$1; + generated$8.isBigIntLiteral = isBigIntLiteral$1; + generated$8.isExportNamespaceSpecifier = isExportNamespaceSpecifier$2; + generated$8.isOptionalMemberExpression = isOptionalMemberExpression$3; + generated$8.isOptionalCallExpression = isOptionalCallExpression$3; + generated$8.isClassProperty = isClassProperty$1; + generated$8.isClassPrivateProperty = isClassPrivateProperty$1; + generated$8.isClassPrivateMethod = isClassPrivateMethod$1; + generated$8.isPrivateName = isPrivateName$1; + generated$8.isAnyTypeAnnotation = isAnyTypeAnnotation$1; + generated$8.isArrayTypeAnnotation = isArrayTypeAnnotation$2; + generated$8.isBooleanTypeAnnotation = isBooleanTypeAnnotation$1; + generated$8.isBooleanLiteralTypeAnnotation = isBooleanLiteralTypeAnnotation$1; + generated$8.isNullLiteralTypeAnnotation = isNullLiteralTypeAnnotation$1; + generated$8.isClassImplements = isClassImplements$1; + generated$8.isDeclareClass = isDeclareClass$1; + generated$8.isDeclareFunction = isDeclareFunction$1; + generated$8.isDeclareInterface = isDeclareInterface$1; + generated$8.isDeclareModule = isDeclareModule$1; + generated$8.isDeclareModuleExports = isDeclareModuleExports$1; + generated$8.isDeclareTypeAlias = isDeclareTypeAlias$1; + generated$8.isDeclareOpaqueType = isDeclareOpaqueType$1; + generated$8.isDeclareVariable = isDeclareVariable$1; + generated$8.isDeclareExportDeclaration = isDeclareExportDeclaration$1; + generated$8.isDeclareExportAllDeclaration = isDeclareExportAllDeclaration$1; + generated$8.isDeclaredPredicate = isDeclaredPredicate$1; + generated$8.isExistsTypeAnnotation = isExistsTypeAnnotation$1; + generated$8.isFunctionTypeAnnotation = isFunctionTypeAnnotation$1; + generated$8.isFunctionTypeParam = isFunctionTypeParam$1; + generated$8.isGenericTypeAnnotation = isGenericTypeAnnotation$1; + generated$8.isInferredPredicate = isInferredPredicate$1; + generated$8.isInterfaceExtends = isInterfaceExtends$1; + generated$8.isInterfaceDeclaration = isInterfaceDeclaration$1; + generated$8.isInterfaceTypeAnnotation = isInterfaceTypeAnnotation$1; + generated$8.isIntersectionTypeAnnotation = isIntersectionTypeAnnotation$2; + generated$8.isMixedTypeAnnotation = isMixedTypeAnnotation$1; + generated$8.isEmptyTypeAnnotation = isEmptyTypeAnnotation$1; + generated$8.isNullableTypeAnnotation = isNullableTypeAnnotation$2; + generated$8.isNumberLiteralTypeAnnotation = isNumberLiteralTypeAnnotation$1; + generated$8.isNumberTypeAnnotation = isNumberTypeAnnotation$1; + generated$8.isObjectTypeAnnotation = isObjectTypeAnnotation$1; + generated$8.isObjectTypeInternalSlot = isObjectTypeInternalSlot$1; + generated$8.isObjectTypeCallProperty = isObjectTypeCallProperty$1; + generated$8.isObjectTypeIndexer = isObjectTypeIndexer$1; + generated$8.isObjectTypeProperty = isObjectTypeProperty$1; + generated$8.isObjectTypeSpreadProperty = isObjectTypeSpreadProperty$1; + generated$8.isOpaqueType = isOpaqueType$1; + generated$8.isQualifiedTypeIdentifier = isQualifiedTypeIdentifier$1; + generated$8.isStringLiteralTypeAnnotation = isStringLiteralTypeAnnotation$1; + generated$8.isStringTypeAnnotation = isStringTypeAnnotation$1; + generated$8.isSymbolTypeAnnotation = isSymbolTypeAnnotation$1; + generated$8.isThisTypeAnnotation = isThisTypeAnnotation$1; + generated$8.isTupleTypeAnnotation = isTupleTypeAnnotation$1; + generated$8.isTypeofTypeAnnotation = isTypeofTypeAnnotation$1; + generated$8.isTypeAlias = isTypeAlias$1; + generated$8.isTypeAnnotation = isTypeAnnotation$2; + generated$8.isTypeCastExpression = isTypeCastExpression$1; + generated$8.isTypeParameter = isTypeParameter$1; + generated$8.isTypeParameterDeclaration = isTypeParameterDeclaration$1; + generated$8.isTypeParameterInstantiation = isTypeParameterInstantiation$1; + generated$8.isUnionTypeAnnotation = isUnionTypeAnnotation$2; + generated$8.isVariance = isVariance$1; + generated$8.isVoidTypeAnnotation = isVoidTypeAnnotation$1; + generated$8.isEnumDeclaration = isEnumDeclaration$1; + generated$8.isEnumBooleanBody = isEnumBooleanBody$1; + generated$8.isEnumNumberBody = isEnumNumberBody$1; + generated$8.isEnumStringBody = isEnumStringBody$1; + generated$8.isEnumSymbolBody = isEnumSymbolBody$1; + generated$8.isEnumBooleanMember = isEnumBooleanMember$1; + generated$8.isEnumNumberMember = isEnumNumberMember$1; + generated$8.isEnumStringMember = isEnumStringMember$1; + generated$8.isEnumDefaultedMember = isEnumDefaultedMember$1; + generated$8.isIndexedAccessType = isIndexedAccessType$1; + generated$8.isOptionalIndexedAccessType = isOptionalIndexedAccessType; + generated$8.isJSXAttribute = isJSXAttribute$1; + generated$8.isJSXClosingElement = isJSXClosingElement$1; + generated$8.isJSXElement = isJSXElement$1; + generated$8.isJSXEmptyExpression = isJSXEmptyExpression$1; + generated$8.isJSXExpressionContainer = isJSXExpressionContainer$1; + generated$8.isJSXSpreadChild = isJSXSpreadChild$1; + generated$8.isJSXIdentifier = isJSXIdentifier$1; + generated$8.isJSXMemberExpression = isJSXMemberExpression$1; + generated$8.isJSXNamespacedName = isJSXNamespacedName$1; + generated$8.isJSXOpeningElement = isJSXOpeningElement$1; + generated$8.isJSXSpreadAttribute = isJSXSpreadAttribute$1; + generated$8.isJSXText = isJSXText$1; + generated$8.isJSXFragment = isJSXFragment$1; + generated$8.isJSXOpeningFragment = isJSXOpeningFragment$1; + generated$8.isJSXClosingFragment = isJSXClosingFragment$1; + generated$8.isNoop = isNoop$1; + generated$8.isPlaceholder = isPlaceholder$1; + generated$8.isV8IntrinsicIdentifier = isV8IntrinsicIdentifier$1; + generated$8.isArgumentPlaceholder = isArgumentPlaceholder$1; + generated$8.isBindExpression = isBindExpression$1; + generated$8.isImportAttribute = isImportAttribute$1; + generated$8.isDecorator = isDecorator$1; + generated$8.isDoExpression = isDoExpression$1; + generated$8.isExportDefaultSpecifier = isExportDefaultSpecifier$2; + generated$8.isRecordExpression = isRecordExpression$1; + generated$8.isTupleExpression = isTupleExpression$1; + generated$8.isDecimalLiteral = isDecimalLiteral; + generated$8.isStaticBlock = isStaticBlock; + generated$8.isModuleExpression = isModuleExpression; + generated$8.isTopicReference = isTopicReference; + generated$8.isPipelineTopicExpression = isPipelineTopicExpression$1; + generated$8.isPipelineBareFunction = isPipelineBareFunction$1; + generated$8.isPipelinePrimaryTopicReference = isPipelinePrimaryTopicReference$1; + generated$8.isTSParameterProperty = isTSParameterProperty$1; + generated$8.isTSDeclareFunction = isTSDeclareFunction$1; + generated$8.isTSDeclareMethod = isTSDeclareMethod$1; + generated$8.isTSQualifiedName = isTSQualifiedName$1; + generated$8.isTSCallSignatureDeclaration = isTSCallSignatureDeclaration$1; + generated$8.isTSConstructSignatureDeclaration = isTSConstructSignatureDeclaration$1; + generated$8.isTSPropertySignature = isTSPropertySignature$1; + generated$8.isTSMethodSignature = isTSMethodSignature$1; + generated$8.isTSIndexSignature = isTSIndexSignature$1; + generated$8.isTSAnyKeyword = isTSAnyKeyword$1; + generated$8.isTSBooleanKeyword = isTSBooleanKeyword$1; + generated$8.isTSBigIntKeyword = isTSBigIntKeyword$1; + generated$8.isTSIntrinsicKeyword = isTSIntrinsicKeyword; + generated$8.isTSNeverKeyword = isTSNeverKeyword$1; + generated$8.isTSNullKeyword = isTSNullKeyword$1; + generated$8.isTSNumberKeyword = isTSNumberKeyword$1; + generated$8.isTSObjectKeyword = isTSObjectKeyword$1; + generated$8.isTSStringKeyword = isTSStringKeyword$1; + generated$8.isTSSymbolKeyword = isTSSymbolKeyword$1; + generated$8.isTSUndefinedKeyword = isTSUndefinedKeyword$1; + generated$8.isTSUnknownKeyword = isTSUnknownKeyword$1; + generated$8.isTSVoidKeyword = isTSVoidKeyword$1; + generated$8.isTSThisType = isTSThisType$1; + generated$8.isTSFunctionType = isTSFunctionType$1; + generated$8.isTSConstructorType = isTSConstructorType$1; + generated$8.isTSTypeReference = isTSTypeReference$1; + generated$8.isTSTypePredicate = isTSTypePredicate$1; + generated$8.isTSTypeQuery = isTSTypeQuery$1; + generated$8.isTSTypeLiteral = isTSTypeLiteral$1; + generated$8.isTSArrayType = isTSArrayType$2; + generated$8.isTSTupleType = isTSTupleType$1; + generated$8.isTSOptionalType = isTSOptionalType$2; + generated$8.isTSRestType = isTSRestType$2; + generated$8.isTSNamedTupleMember = isTSNamedTupleMember; + generated$8.isTSUnionType = isTSUnionType$2; + generated$8.isTSIntersectionType = isTSIntersectionType$2; + generated$8.isTSConditionalType = isTSConditionalType$1; + generated$8.isTSInferType = isTSInferType$1; + generated$8.isTSParenthesizedType = isTSParenthesizedType$1; + generated$8.isTSTypeOperator = isTSTypeOperator$1; + generated$8.isTSIndexedAccessType = isTSIndexedAccessType$1; + generated$8.isTSMappedType = isTSMappedType$1; + generated$8.isTSLiteralType = isTSLiteralType$1; + generated$8.isTSExpressionWithTypeArguments = isTSExpressionWithTypeArguments$1; + generated$8.isTSInterfaceDeclaration = isTSInterfaceDeclaration$1; + generated$8.isTSInterfaceBody = isTSInterfaceBody$1; + generated$8.isTSTypeAliasDeclaration = isTSTypeAliasDeclaration$1; + generated$8.isTSAsExpression = isTSAsExpression$2; + generated$8.isTSTypeAssertion = isTSTypeAssertion$2; + generated$8.isTSEnumDeclaration = isTSEnumDeclaration$1; + generated$8.isTSEnumMember = isTSEnumMember$1; + generated$8.isTSModuleDeclaration = isTSModuleDeclaration$1; + generated$8.isTSModuleBlock = isTSModuleBlock$1; + generated$8.isTSImportType = isTSImportType$1; + generated$8.isTSImportEqualsDeclaration = isTSImportEqualsDeclaration$1; + generated$8.isTSExternalModuleReference = isTSExternalModuleReference$1; + generated$8.isTSNonNullExpression = isTSNonNullExpression$2; + generated$8.isTSExportAssignment = isTSExportAssignment$1; + generated$8.isTSNamespaceExportDeclaration = isTSNamespaceExportDeclaration$1; + generated$8.isTSTypeAnnotation = isTSTypeAnnotation$1; + generated$8.isTSTypeParameterInstantiation = isTSTypeParameterInstantiation$1; + generated$8.isTSTypeParameterDeclaration = isTSTypeParameterDeclaration$1; + generated$8.isTSTypeParameter = isTSTypeParameter$1; + generated$8.isExpression = isExpression$1; + generated$8.isBinary = isBinary$3; + generated$8.isScopable = isScopable$1; + generated$8.isBlockParent = isBlockParent$1; + generated$8.isBlock = isBlock$1; + generated$8.isStatement = isStatement$3; + generated$8.isTerminatorless = isTerminatorless$1; + generated$8.isCompletionStatement = isCompletionStatement$1; + generated$8.isConditional = isConditional$2; + generated$8.isLoop = isLoop$3; + generated$8.isWhile = isWhile$1; + generated$8.isExpressionWrapper = isExpressionWrapper$1; + generated$8.isFor = isFor$3; + generated$8.isForXStatement = isForXStatement$1; + generated$8.isFunction = isFunction$7; + generated$8.isFunctionParent = isFunctionParent$1; + generated$8.isPureish = isPureish$1; + generated$8.isDeclaration = isDeclaration$1; + generated$8.isPatternLike = isPatternLike$1; + generated$8.isLVal = isLVal$1; + generated$8.isTSEntityName = isTSEntityName$1; + generated$8.isLiteral = isLiteral$3; + generated$8.isImmutable = isImmutable$5; + generated$8.isUserWhitespacable = isUserWhitespacable$1; + generated$8.isMethod = isMethod$1; + generated$8.isObjectMember = isObjectMember$1; + generated$8.isProperty = isProperty$1; + generated$8.isUnaryLike = isUnaryLike$2; + generated$8.isPattern = isPattern$1; + generated$8.isClass = isClass$1; + generated$8.isModuleDeclaration = isModuleDeclaration$1; + generated$8.isExportDeclaration = isExportDeclaration$2; + generated$8.isModuleSpecifier = isModuleSpecifier$1; + generated$8.isPrivate = isPrivate$1; + generated$8.isFlow = isFlow$1; + generated$8.isFlowType = isFlowType$1; + generated$8.isFlowBaseAnnotation = isFlowBaseAnnotation$1; + generated$8.isFlowDeclaration = isFlowDeclaration$1; + generated$8.isFlowPredicate = isFlowPredicate$1; + generated$8.isEnumBody = isEnumBody$1; + generated$8.isEnumMember = isEnumMember$1; + generated$8.isJSX = isJSX$1; + generated$8.isTSTypeElement = isTSTypeElement$1; + generated$8.isTSType = isTSType$1; + generated$8.isTSBaseType = isTSBaseType$1; + generated$8.isNumberLiteral = isNumberLiteral$1; + generated$8.isRegexLiteral = isRegexLiteral$1; + generated$8.isRestProperty = isRestProperty$1; + generated$8.isSpreadProperty = isSpreadProperty$1; + + var _shallowEqual$1 = shallowEqual$3; + + function isArrayExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isAssignmentExpression$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AssignmentExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBinaryExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BinaryExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isInterpreterDirective$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterpreterDirective") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDirective$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Directive") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDirectiveLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DirectiveLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBlockStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BlockStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBreakStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BreakStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isCallExpression$5(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "CallExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isCatchClause$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "CatchClause") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isConditionalExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ConditionalExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isContinueStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ContinueStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDebuggerStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DebuggerStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDoWhileStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DoWhileStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEmptyStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EmptyStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExpressionStatement$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExpressionStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFile$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "File") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isForInStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForInStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isForStatement$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunctionDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunctionExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isIdentifier$4(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Identifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isIfStatement$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "IfStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isLabeledStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "LabeledStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isStringLiteral$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNumericLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumericLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNullLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBooleanLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isRegExpLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RegExpLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isLogicalExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "LogicalExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isMemberExpression$5(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNewExpression$4(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NewExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isProgram$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Program") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectMethod$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isRestElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RestElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isReturnStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ReturnStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSequenceExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SequenceExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isParenthesizedExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ParenthesizedExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSwitchCase$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SwitchCase") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSwitchStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SwitchStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isThisExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThisExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isThrowStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThrowStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTryStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TryStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isUnaryExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UnaryExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isUpdateExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UpdateExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isVariableDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VariableDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isVariableDeclarator$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VariableDeclarator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isWhileStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "WhileStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isWithStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "WithStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isAssignmentPattern$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AssignmentPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isArrayPattern$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isArrowFunctionExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrowFunctionExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassDeclaration$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportAllDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportAllDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportDefaultDeclaration$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportDefaultDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportNamedDeclaration$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportNamedDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isForOfStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForOfStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImportDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImportDefaultSpecifier$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportDefaultSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImportNamespaceSpecifier$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportNamespaceSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImportSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isMetaProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MetaProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassMethod$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectPattern$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSpreadElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SpreadElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSuper$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Super") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTaggedTemplateExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TaggedTemplateExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTemplateElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TemplateElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTemplateLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TemplateLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isYieldExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "YieldExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isAwaitExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AwaitExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImport$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Import") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBigIntLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BigIntLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportNamespaceSpecifier$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportNamespaceSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isOptionalMemberExpression$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OptionalMemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isOptionalCallExpression$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OptionalCallExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassPrivateProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassPrivateProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassPrivateMethod$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassPrivateMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPrivateName$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PrivateName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isAnyTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AnyTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isArrayTypeAnnotation$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBooleanTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBooleanLiteralTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNullLiteralTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClassImplements$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassImplements") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareClass$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareClass") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareFunction$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareInterface$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareInterface") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareModule$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareModule") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareModuleExports$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareModuleExports") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareTypeAlias$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareTypeAlias") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareOpaqueType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareOpaqueType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareVariable$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareVariable") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareExportDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareExportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclareExportAllDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareExportAllDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclaredPredicate$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclaredPredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExistsTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExistsTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunctionTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunctionTypeParam$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionTypeParam") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isGenericTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "GenericTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isInferredPredicate$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InferredPredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isInterfaceExtends$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceExtends") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isInterfaceDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isInterfaceTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isIntersectionTypeAnnotation$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "IntersectionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isMixedTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MixedTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEmptyTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EmptyTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNullableTypeAnnotation$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullableTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNumberLiteralTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNumberTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeInternalSlot$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeInternalSlot") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeCallProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeCallProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeIndexer$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeIndexer") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeSpreadProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeSpreadProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isOpaqueType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OpaqueType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isQualifiedTypeIdentifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "QualifiedTypeIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isStringLiteralTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isStringTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSymbolTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SymbolTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isThisTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThisTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTupleTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TupleTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeofTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeofTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeAlias$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeAlias") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeAnnotation$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeCastExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeCastExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeParameter$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameter") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeParameterDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameterDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTypeParameterInstantiation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameterInstantiation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isUnionTypeAnnotation$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UnionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isVariance$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Variance") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isVoidTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VoidTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumBooleanBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumBooleanBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumNumberBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumNumberBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumStringBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumStringBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumSymbolBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumSymbolBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumBooleanMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumBooleanMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumNumberMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumNumberMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumStringMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumStringMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumDefaultedMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumDefaultedMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isIndexedAccessType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "IndexedAccessType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isOptionalIndexedAccessType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OptionalIndexedAccessType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXAttribute$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXClosingElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXClosingElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXEmptyExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXEmptyExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXExpressionContainer$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXExpressionContainer") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXSpreadChild$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXSpreadChild") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXIdentifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXMemberExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXMemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXNamespacedName$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXNamespacedName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXOpeningElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXOpeningElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXSpreadAttribute$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXSpreadAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXText$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXText") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXFragment$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXOpeningFragment$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXOpeningFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSXClosingFragment$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXClosingFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNoop$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Noop") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPlaceholder$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Placeholder") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isV8IntrinsicIdentifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "V8IntrinsicIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isArgumentPlaceholder$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArgumentPlaceholder") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBindExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BindExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImportAttribute$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDecorator$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Decorator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDoExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DoExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportDefaultSpecifier$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportDefaultSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isRecordExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RecordExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTupleExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TupleExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDecimalLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DecimalLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isStaticBlock(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StaticBlock") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isModuleExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ModuleExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTopicReference(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TopicReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPipelineTopicExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelineTopicExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPipelineBareFunction$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelineBareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPipelinePrimaryTopicReference$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelinePrimaryTopicReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSParameterProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSParameterProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSDeclareFunction$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSDeclareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSDeclareMethod$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSDeclareMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSQualifiedName$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSQualifiedName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSCallSignatureDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSCallSignatureDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSConstructSignatureDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConstructSignatureDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSPropertySignature$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSPropertySignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSMethodSignature$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSMethodSignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSIndexSignature$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIndexSignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSAnyKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSAnyKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSBooleanKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSBooleanKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSBigIntKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSBigIntKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSIntrinsicKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIntrinsicKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNeverKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNeverKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNullKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNullKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNumberKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNumberKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSObjectKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSObjectKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSStringKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSStringKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSSymbolKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSSymbolKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSUndefinedKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUndefinedKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSUnknownKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUnknownKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSVoidKeyword$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSVoidKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSThisType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSThisType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSFunctionType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSFunctionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSConstructorType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConstructorType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeReference$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypePredicate$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypePredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeQuery$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeQuery") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSArrayType$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSArrayType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTupleType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTupleType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSOptionalType$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSOptionalType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSRestType$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSRestType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNamedTupleMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNamedTupleMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSUnionType$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUnionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSIntersectionType$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIntersectionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSConditionalType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConditionalType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSInferType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInferType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSParenthesizedType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSParenthesizedType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeOperator$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeOperator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSIndexedAccessType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIndexedAccessType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSMappedType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSMappedType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSLiteralType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSLiteralType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSExpressionWithTypeArguments$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExpressionWithTypeArguments") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSInterfaceDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInterfaceDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSInterfaceBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInterfaceBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAliasDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAliasDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSAsExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSAsExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAssertion$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAssertion") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSEnumDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSEnumDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSEnumMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSEnumMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSModuleDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSModuleDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSModuleBlock$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSModuleBlock") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSImportType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSImportType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSImportEqualsDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSImportEqualsDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSExternalModuleReference$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExternalModuleReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNonNullExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNonNullExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSExportAssignment$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExportAssignment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSNamespaceExportDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNamespaceExportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameterInstantiation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameterInstantiation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameterDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameterDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameter$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameter") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ArrayExpression" === nodeType || "AssignmentExpression" === nodeType || "BinaryExpression" === nodeType || "CallExpression" === nodeType || "ConditionalExpression" === nodeType || "FunctionExpression" === nodeType || "Identifier" === nodeType || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "LogicalExpression" === nodeType || "MemberExpression" === nodeType || "NewExpression" === nodeType || "ObjectExpression" === nodeType || "SequenceExpression" === nodeType || "ParenthesizedExpression" === nodeType || "ThisExpression" === nodeType || "UnaryExpression" === nodeType || "UpdateExpression" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassExpression" === nodeType || "MetaProperty" === nodeType || "Super" === nodeType || "TaggedTemplateExpression" === nodeType || "TemplateLiteral" === nodeType || "YieldExpression" === nodeType || "AwaitExpression" === nodeType || "Import" === nodeType || "BigIntLiteral" === nodeType || "OptionalMemberExpression" === nodeType || "OptionalCallExpression" === nodeType || "TypeCastExpression" === nodeType || "JSXElement" === nodeType || "JSXFragment" === nodeType || "BindExpression" === nodeType || "DoExpression" === nodeType || "RecordExpression" === nodeType || "TupleExpression" === nodeType || "DecimalLiteral" === nodeType || "ModuleExpression" === nodeType || "TopicReference" === nodeType || "PipelineTopicExpression" === nodeType || "PipelineBareFunction" === nodeType || "PipelinePrimaryTopicReference" === nodeType || "TSAsExpression" === nodeType || "TSTypeAssertion" === nodeType || "TSNonNullExpression" === nodeType || nodeType === "Placeholder" && ("Expression" === node.expectedNode || "Identifier" === node.expectedNode || "StringLiteral" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBinary$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BinaryExpression" === nodeType || "LogicalExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isScopable$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BlockStatement" === nodeType || "CatchClause" === nodeType || "DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "Program" === nodeType || "ObjectMethod" === nodeType || "SwitchStatement" === nodeType || "WhileStatement" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassExpression" === nodeType || "ClassDeclaration" === nodeType || "ForOfStatement" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType || "StaticBlock" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBlockParent$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BlockStatement" === nodeType || "CatchClause" === nodeType || "DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "Program" === nodeType || "ObjectMethod" === nodeType || "SwitchStatement" === nodeType || "WhileStatement" === nodeType || "ArrowFunctionExpression" === nodeType || "ForOfStatement" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType || "StaticBlock" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isBlock$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BlockStatement" === nodeType || "Program" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isStatement$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BlockStatement" === nodeType || "BreakStatement" === nodeType || "ContinueStatement" === nodeType || "DebuggerStatement" === nodeType || "DoWhileStatement" === nodeType || "EmptyStatement" === nodeType || "ExpressionStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "IfStatement" === nodeType || "LabeledStatement" === nodeType || "ReturnStatement" === nodeType || "SwitchStatement" === nodeType || "ThrowStatement" === nodeType || "TryStatement" === nodeType || "VariableDeclaration" === nodeType || "WhileStatement" === nodeType || "WithStatement" === nodeType || "ClassDeclaration" === nodeType || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ForOfStatement" === nodeType || "ImportDeclaration" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType || "EnumDeclaration" === nodeType || "TSDeclareFunction" === nodeType || "TSInterfaceDeclaration" === nodeType || "TSTypeAliasDeclaration" === nodeType || "TSEnumDeclaration" === nodeType || "TSModuleDeclaration" === nodeType || "TSImportEqualsDeclaration" === nodeType || "TSExportAssignment" === nodeType || "TSNamespaceExportDeclaration" === nodeType || nodeType === "Placeholder" && ("Statement" === node.expectedNode || "Declaration" === node.expectedNode || "BlockStatement" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTerminatorless$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BreakStatement" === nodeType || "ContinueStatement" === nodeType || "ReturnStatement" === nodeType || "ThrowStatement" === nodeType || "YieldExpression" === nodeType || "AwaitExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isCompletionStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("BreakStatement" === nodeType || "ContinueStatement" === nodeType || "ReturnStatement" === nodeType || "ThrowStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isConditional$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ConditionalExpression" === nodeType || "IfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isLoop$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "WhileStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isWhile$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("DoWhileStatement" === nodeType || "WhileStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExpressionWrapper$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ExpressionStatement" === nodeType || "ParenthesizedExpression" === nodeType || "TypeCastExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFor$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ForInStatement" === nodeType || "ForStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isForXStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ForInStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunction$7(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "ObjectMethod" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFunctionParent$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "ObjectMethod" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPureish$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "ArrowFunctionExpression" === nodeType || "BigIntLiteral" === nodeType || "DecimalLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("FunctionDeclaration" === nodeType || "VariableDeclaration" === nodeType || "ClassDeclaration" === nodeType || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ImportDeclaration" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType || "EnumDeclaration" === nodeType || "TSDeclareFunction" === nodeType || "TSInterfaceDeclaration" === nodeType || "TSTypeAliasDeclaration" === nodeType || "TSEnumDeclaration" === nodeType || "TSModuleDeclaration" === nodeType || nodeType === "Placeholder" && "Declaration" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPatternLike$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("Identifier" === nodeType || "RestElement" === nodeType || "AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || nodeType === "Placeholder" && ("Pattern" === node.expectedNode || "Identifier" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isLVal$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("Identifier" === nodeType || "MemberExpression" === nodeType || "RestElement" === nodeType || "AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || "TSParameterProperty" === nodeType || nodeType === "Placeholder" && ("Pattern" === node.expectedNode || "Identifier" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSEntityName$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("Identifier" === nodeType || "TSQualifiedName" === nodeType || nodeType === "Placeholder" && "Identifier" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isLiteral$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "TemplateLiteral" === nodeType || "BigIntLiteral" === nodeType || "DecimalLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isImmutable$5(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "BigIntLiteral" === nodeType || "JSXAttribute" === nodeType || "JSXClosingElement" === nodeType || "JSXElement" === nodeType || "JSXExpressionContainer" === nodeType || "JSXSpreadChild" === nodeType || "JSXOpeningElement" === nodeType || "JSXText" === nodeType || "JSXFragment" === nodeType || "JSXOpeningFragment" === nodeType || "JSXClosingFragment" === nodeType || "DecimalLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isUserWhitespacable$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ObjectMethod" === nodeType || "ObjectProperty" === nodeType || "ObjectTypeInternalSlot" === nodeType || "ObjectTypeCallProperty" === nodeType || "ObjectTypeIndexer" === nodeType || "ObjectTypeProperty" === nodeType || "ObjectTypeSpreadProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isMethod$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ObjectMethod" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isObjectMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ObjectMethod" === nodeType || "ObjectProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isProperty$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ObjectProperty" === nodeType || "ClassProperty" === nodeType || "ClassPrivateProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isUnaryLike$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("UnaryExpression" === nodeType || "SpreadElement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPattern$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || nodeType === "Placeholder" && "Pattern" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isClass$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ClassExpression" === nodeType || "ClassDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isModuleDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ImportDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isExportDeclaration$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isModuleSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ExportSpecifier" === nodeType || "ImportDefaultSpecifier" === nodeType || "ImportNamespaceSpecifier" === nodeType || "ImportSpecifier" === nodeType || "ExportNamespaceSpecifier" === nodeType || "ExportDefaultSpecifier" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isPrivate$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("ClassPrivateProperty" === nodeType || "ClassPrivateMethod" === nodeType || "PrivateName" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFlow$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("AnyTypeAnnotation" === nodeType || "ArrayTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "BooleanLiteralTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "ClassImplements" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "DeclaredPredicate" === nodeType || "ExistsTypeAnnotation" === nodeType || "FunctionTypeAnnotation" === nodeType || "FunctionTypeParam" === nodeType || "GenericTypeAnnotation" === nodeType || "InferredPredicate" === nodeType || "InterfaceExtends" === nodeType || "InterfaceDeclaration" === nodeType || "InterfaceTypeAnnotation" === nodeType || "IntersectionTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NullableTypeAnnotation" === nodeType || "NumberLiteralTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "ObjectTypeAnnotation" === nodeType || "ObjectTypeInternalSlot" === nodeType || "ObjectTypeCallProperty" === nodeType || "ObjectTypeIndexer" === nodeType || "ObjectTypeProperty" === nodeType || "ObjectTypeSpreadProperty" === nodeType || "OpaqueType" === nodeType || "QualifiedTypeIdentifier" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || "TypeAlias" === nodeType || "TypeAnnotation" === nodeType || "TypeCastExpression" === nodeType || "TypeParameter" === nodeType || "TypeParameterDeclaration" === nodeType || "TypeParameterInstantiation" === nodeType || "UnionTypeAnnotation" === nodeType || "Variance" === nodeType || "VoidTypeAnnotation" === nodeType || "IndexedAccessType" === nodeType || "OptionalIndexedAccessType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFlowType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("AnyTypeAnnotation" === nodeType || "ArrayTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "BooleanLiteralTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "ExistsTypeAnnotation" === nodeType || "FunctionTypeAnnotation" === nodeType || "GenericTypeAnnotation" === nodeType || "InterfaceTypeAnnotation" === nodeType || "IntersectionTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NullableTypeAnnotation" === nodeType || "NumberLiteralTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "ObjectTypeAnnotation" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || "UnionTypeAnnotation" === nodeType || "VoidTypeAnnotation" === nodeType || "IndexedAccessType" === nodeType || "OptionalIndexedAccessType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFlowBaseAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("AnyTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "VoidTypeAnnotation" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFlowDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isFlowPredicate$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("DeclaredPredicate" === nodeType || "InferredPredicate" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumBody$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("EnumBooleanBody" === nodeType || "EnumNumberBody" === nodeType || "EnumStringBody" === nodeType || "EnumSymbolBody" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isEnumMember$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("EnumBooleanMember" === nodeType || "EnumNumberMember" === nodeType || "EnumStringMember" === nodeType || "EnumDefaultedMember" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isJSX$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("JSXAttribute" === nodeType || "JSXClosingElement" === nodeType || "JSXElement" === nodeType || "JSXEmptyExpression" === nodeType || "JSXExpressionContainer" === nodeType || "JSXSpreadChild" === nodeType || "JSXIdentifier" === nodeType || "JSXMemberExpression" === nodeType || "JSXNamespacedName" === nodeType || "JSXOpeningElement" === nodeType || "JSXSpreadAttribute" === nodeType || "JSXText" === nodeType || "JSXFragment" === nodeType || "JSXOpeningFragment" === nodeType || "JSXClosingFragment" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSTypeElement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("TSCallSignatureDeclaration" === nodeType || "TSConstructSignatureDeclaration" === nodeType || "TSPropertySignature" === nodeType || "TSMethodSignature" === nodeType || "TSIndexSignature" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || "TSIntrinsicKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || "TSObjectKeyword" === nodeType || "TSStringKeyword" === nodeType || "TSSymbolKeyword" === nodeType || "TSUndefinedKeyword" === nodeType || "TSUnknownKeyword" === nodeType || "TSVoidKeyword" === nodeType || "TSThisType" === nodeType || "TSFunctionType" === nodeType || "TSConstructorType" === nodeType || "TSTypeReference" === nodeType || "TSTypePredicate" === nodeType || "TSTypeQuery" === nodeType || "TSTypeLiteral" === nodeType || "TSArrayType" === nodeType || "TSTupleType" === nodeType || "TSOptionalType" === nodeType || "TSRestType" === nodeType || "TSUnionType" === nodeType || "TSIntersectionType" === nodeType || "TSConditionalType" === nodeType || "TSInferType" === nodeType || "TSParenthesizedType" === nodeType || "TSTypeOperator" === nodeType || "TSIndexedAccessType" === nodeType || "TSMappedType" === nodeType || "TSLiteralType" === nodeType || "TSExpressionWithTypeArguments" === nodeType || "TSImportType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isTSBaseType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if ("TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || "TSIntrinsicKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || "TSObjectKeyword" === nodeType || "TSStringKeyword" === nodeType || "TSSymbolKeyword" === nodeType || "TSUndefinedKeyword" === nodeType || "TSUnknownKeyword" === nodeType || "TSVoidKeyword" === nodeType || "TSThisType" === nodeType || "TSLiteralType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isNumberLiteral$1(node, opts) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isRegexLiteral$1(node, opts) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RegexLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isRestProperty$1(node, opts) { + console.trace("The node type RestProperty has been renamed to RestElement"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RestProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + function isSpreadProperty$1(node, opts) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SpreadProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual$1.default)(node, opts); + } + } + + return false; + } + + Object.defineProperty(matchesPattern$3, "__esModule", { + value: true + }); + matchesPattern$3.default = matchesPattern$2; + + var _generated$M = generated$8; + + function matchesPattern$2(member, match, allowPartial) { + if (!(0, _generated$M.isMemberExpression)(member)) return false; + const parts = Array.isArray(match) ? match : match.split("."); + const nodes = []; + let node; + + for (node = member; (0, _generated$M.isMemberExpression)(node); node = node.object) { + nodes.push(node.property); + } + + nodes.push(node); + if (nodes.length < parts.length) return false; + if (!allowPartial && nodes.length > parts.length) return false; + + for (let i = 0, j = nodes.length - 1; i < parts.length; i++, j--) { + const node = nodes[j]; + let value; + + if ((0, _generated$M.isIdentifier)(node)) { + value = node.name; + } else if ((0, _generated$M.isStringLiteral)(node)) { + value = node.value; + } else if ((0, _generated$M.isThisExpression)(node)) { + value = "this"; + } else { + return false; + } + + if (parts[i] !== value) return false; + } + + return true; + } + + Object.defineProperty(buildMatchMemberExpression$3, "__esModule", { + value: true + }); + buildMatchMemberExpression$3.default = buildMatchMemberExpression$2; + + var _matchesPattern$1 = matchesPattern$3; + + function buildMatchMemberExpression$2(match, allowPartial) { + const parts = match.split("."); + return member => (0, _matchesPattern$1.default)(member, parts, allowPartial); + } + + Object.defineProperty(isReactComponent$4, "__esModule", { + value: true + }); + isReactComponent$4.default = void 0; + + var _buildMatchMemberExpression$1 = buildMatchMemberExpression$3; + + const isReactComponent$3 = (0, _buildMatchMemberExpression$1.default)("React.Component"); + var _default$8 = isReactComponent$3; + isReactComponent$4.default = _default$8; + + var isCompatTag$3 = {}; + + Object.defineProperty(isCompatTag$3, "__esModule", { + value: true + }); + isCompatTag$3.default = isCompatTag$2; + + function isCompatTag$2(tagName) { + return !!tagName && /^[a-z]/.test(tagName); + } + + var buildChildren$3 = {}; + + var cleanJSXElementLiteralChild$3 = {}; + + var generated$7 = {}; + + var builder$3 = {}; + + var definitions$1 = {}; + + let fastProto = null; + + // Creates an object with permanently fast properties in V8. See Toon Verwaest's + // post https://medium.com/@tverwaes/setting-up-prototypes-in-v8-ec9c9491dfe2#5f62 + // for more details. Use %HasFastProperties(object) and the Node.js flag + // --allow-natives-syntax to check whether an object has fast properties. + function FastObject(o) { + // A prototype object will have "fast properties" enabled once it is checked + // against the inline property cache of a function, e.g. fastProto.property: + // https://github.com/v8/v8/blob/6.0.122/test/mjsunit/fast-prototype.js#L48-L63 + if (fastProto !== null && typeof fastProto.property) { + const result = fastProto; + fastProto = FastObject.prototype = null; + return result; + } + fastProto = FastObject.prototype = o == null ? Object.create(null) : o; + return new FastObject; + } + + // Initialize the inline property cache of FastObject + FastObject(); + + var toFastProperties = function toFastproperties(o) { + return FastObject(o); + }; + + var global$1 = (typeof global !== "undefined" ? global : + typeof self !== "undefined" ? self : + typeof window !== "undefined" ? window : {}); + + // shim for using process in browser + // based off https://github.com/defunctzombie/node-process/blob/master/browser.js + + function defaultSetTimout() { + throw new Error('setTimeout has not been defined'); + } + function defaultClearTimeout () { + throw new Error('clearTimeout has not been defined'); + } + var cachedSetTimeout = defaultSetTimout; + var cachedClearTimeout = defaultClearTimeout; + if (typeof global$1.setTimeout === 'function') { + cachedSetTimeout = setTimeout; + } + if (typeof global$1.clearTimeout === 'function') { + cachedClearTimeout = clearTimeout; + } + + function runTimeout(fun) { + if (cachedSetTimeout === setTimeout) { + //normal enviroments in sane situations + return setTimeout(fun, 0); + } + // if setTimeout wasn't available but was latter defined + if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { + cachedSetTimeout = setTimeout; + return setTimeout(fun, 0); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedSetTimeout(fun, 0); + } catch(e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedSetTimeout.call(null, fun, 0); + } catch(e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error + return cachedSetTimeout.call(this, fun, 0); + } + } + + + } + function runClearTimeout(marker) { + if (cachedClearTimeout === clearTimeout) { + //normal enviroments in sane situations + return clearTimeout(marker); + } + // if clearTimeout wasn't available but was latter defined + if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { + cachedClearTimeout = clearTimeout; + return clearTimeout(marker); + } + try { + // when when somebody has screwed with setTimeout but no I.E. maddness + return cachedClearTimeout(marker); + } catch (e){ + try { + // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally + return cachedClearTimeout.call(null, marker); + } catch (e){ + // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. + // Some versions of I.E. have different rules for clearTimeout vs setTimeout + return cachedClearTimeout.call(this, marker); + } + } + + + + } + var queue = []; + var draining = false; + var currentQueue; + var queueIndex = -1; + + function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } + } + + function drainQueue() { + if (draining) { + return; + } + var timeout = runTimeout(cleanUpNextTick); + draining = true; + + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; + } + currentQueue = null; + draining = false; + runClearTimeout(timeout); + } + function nextTick(fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + runTimeout(drainQueue); + } + } + // v8 likes predictible objects + function Item(fun, array) { + this.fun = fun; + this.array = array; + } + Item.prototype.run = function () { + this.fun.apply(null, this.array); + }; + var title = 'browser'; + var platform = 'browser'; + var browser = true; + var env = {}; + var argv = []; + var version = ''; // empty string to avoid regexp issues + var versions = {}; + var release = {}; + var config = {}; + + function noop$3() {} + + var on = noop$3; + var addListener = noop$3; + var once = noop$3; + var off = noop$3; + var removeListener = noop$3; + var removeAllListeners = noop$3; + var emit = noop$3; + + function binding(name) { + throw new Error('process.binding is not supported'); + } + + function cwd () { return '/' } + function chdir (dir) { + throw new Error('process.chdir is not supported'); + }function umask() { return 0; } + + // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js + var performance = global$1.performance || {}; + var performanceNow = + performance.now || + performance.mozNow || + performance.msNow || + performance.oNow || + performance.webkitNow || + function(){ return (new Date()).getTime() }; + + // generate timestamp or delta + // see http://nodejs.org/api/process.html#process_process_hrtime + function hrtime(previousTimestamp){ + var clocktime = performanceNow.call(performance)*1e-3; + var seconds = Math.floor(clocktime); + var nanoseconds = Math.floor((clocktime%1)*1e9); + if (previousTimestamp) { + seconds = seconds - previousTimestamp[0]; + nanoseconds = nanoseconds - previousTimestamp[1]; + if (nanoseconds<0) { + seconds--; + nanoseconds += 1e9; + } + } + return [seconds,nanoseconds] + } + + var startTime = new Date(); + function uptime() { + var currentTime = new Date(); + var dif = currentTime - startTime; + return dif / 1000; + } + + var browser$1 = { + nextTick: nextTick, + title: title, + browser: browser, + env: env, + argv: argv, + version: version, + versions: versions, + on: on, + addListener: addListener, + once: once, + off: off, + removeListener: removeListener, + removeAllListeners: removeAllListeners, + emit: emit, + binding: binding, + cwd: cwd, + chdir: chdir, + umask: umask, + hrtime: hrtime, + platform: platform, + release: release, + config: config, + uptime: uptime + }; + + var process$1 = browser$1; + + var core$1 = {}; + + var is$1 = {}; + + var isType$2 = {}; + + var hasRequiredIsType$1; + + function requireIsType$1 () { + if (hasRequiredIsType$1) return isType$2; + hasRequiredIsType$1 = 1; + + Object.defineProperty(isType$2, "__esModule", { + value: true + }); + isType$2.default = isType; + + var _definitions = requireDefinitions$1(); + + function isType(nodeType, targetType) { + if (nodeType === targetType) return true; + if (_definitions.ALIAS_KEYS[targetType]) return false; + const aliases = _definitions.FLIPPED_ALIAS_KEYS[targetType]; + + if (aliases) { + if (aliases[0] === nodeType) return true; + + for (const alias of aliases) { + if (nodeType === alias) return true; + } + } + + return false; + } + return isType$2; + } + + var isPlaceholderType$1 = {}; + + var hasRequiredIsPlaceholderType$1; + + function requireIsPlaceholderType$1 () { + if (hasRequiredIsPlaceholderType$1) return isPlaceholderType$1; + hasRequiredIsPlaceholderType$1 = 1; + + Object.defineProperty(isPlaceholderType$1, "__esModule", { + value: true + }); + isPlaceholderType$1.default = isPlaceholderType; + + var _definitions = requireDefinitions$1(); + + function isPlaceholderType(placeholderType, targetType) { + if (placeholderType === targetType) return true; + const aliases = _definitions.PLACEHOLDERS_ALIAS[placeholderType]; + + if (aliases) { + for (const alias of aliases) { + if (targetType === alias) return true; + } + } + + return false; + } + return isPlaceholderType$1; + } + + var hasRequiredIs$1; + + function requireIs$1 () { + if (hasRequiredIs$1) return is$1; + hasRequiredIs$1 = 1; + + Object.defineProperty(is$1, "__esModule", { + value: true + }); + is$1.default = is; + + var _shallowEqual = shallowEqual$3; + + var _isType = requireIsType$1(); + + var _isPlaceholderType = requireIsPlaceholderType$1(); + + var _definitions = requireDefinitions$1(); + + function is(type, node, opts) { + if (!node) return false; + const matches = (0, _isType.default)(node.type, type); + + if (!matches) { + if (!opts && node.type === "Placeholder" && type in _definitions.FLIPPED_ALIAS_KEYS) { + return (0, _isPlaceholderType.default)(node.expectedNode, type); + } + + return false; + } + + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + return is$1; + } + + var isValidIdentifier$3 = {}; + + var lib$5 = {}; + + var identifier$2 = {}; + + Object.defineProperty(identifier$2, "__esModule", { + value: true + }); + identifier$2.isIdentifierStart = isIdentifierStart$3; + identifier$2.isIdentifierChar = isIdentifierChar$3; + identifier$2.isIdentifierName = isIdentifierName$1; + let nonASCIIidentifierStartChars$3 = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + let nonASCIIidentifierChars$3 = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + const nonASCIIidentifierStart$3 = new RegExp("[" + nonASCIIidentifierStartChars$3 + "]"); + const nonASCIIidentifier$3 = new RegExp("[" + nonASCIIidentifierStartChars$3 + nonASCIIidentifierChars$3 + "]"); + nonASCIIidentifierStartChars$3 = nonASCIIidentifierChars$3 = null; + const astralIdentifierStartCodes$3 = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1070, 4050, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 46, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 482, 44, 11, 6, 17, 0, 322, 29, 19, 43, 1269, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4152, 8, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; + const astralIdentifierCodes$3 = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 357, 0, 62, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + function isInAstralSet$3(code, set) { + let pos = 0x10000; + + for (let i = 0, length = set.length; i < length; i += 2) { + pos += set[i]; + if (pos > code) return false; + pos += set[i + 1]; + if (pos >= code) return true; + } + + return false; + } + + function isIdentifierStart$3(code) { + if (code < 65) return code === 36; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart$3.test(String.fromCharCode(code)); + } + + return isInAstralSet$3(code, astralIdentifierStartCodes$3); + } + + function isIdentifierChar$3(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier$3.test(String.fromCharCode(code)); + } + + return isInAstralSet$3(code, astralIdentifierStartCodes$3) || isInAstralSet$3(code, astralIdentifierCodes$3); + } + + function isIdentifierName$1(name) { + let isFirst = true; + + for (let i = 0; i < name.length; i++) { + let cp = name.charCodeAt(i); + + if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) { + const trail = name.charCodeAt(++i); + + if ((trail & 0xfc00) === 0xdc00) { + cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff); + } + } + + if (isFirst) { + isFirst = false; + + if (!isIdentifierStart$3(cp)) { + return false; + } + } else if (!isIdentifierChar$3(cp)) { + return false; + } + } + + return !isFirst; + } + + var keyword$1 = {}; + + Object.defineProperty(keyword$1, "__esModule", { + value: true + }); + keyword$1.isReservedWord = isReservedWord$3; + keyword$1.isStrictReservedWord = isStrictReservedWord$3; + keyword$1.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord$3; + keyword$1.isStrictBindReservedWord = isStrictBindReservedWord$3; + keyword$1.isKeyword = isKeyword$3; + const reservedWords$3 = { + keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], + strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], + strictBind: ["eval", "arguments"] + }; + const keywords$4 = new Set(reservedWords$3.keyword); + const reservedWordsStrictSet$3 = new Set(reservedWords$3.strict); + const reservedWordsStrictBindSet$3 = new Set(reservedWords$3.strictBind); + + function isReservedWord$3(word, inModule) { + return inModule && word === "await" || word === "enum"; + } + + function isStrictReservedWord$3(word, inModule) { + return isReservedWord$3(word, inModule) || reservedWordsStrictSet$3.has(word); + } + + function isStrictBindOnlyReservedWord$3(word) { + return reservedWordsStrictBindSet$3.has(word); + } + + function isStrictBindReservedWord$3(word, inModule) { + return isStrictReservedWord$3(word, inModule) || isStrictBindOnlyReservedWord$3(word); + } + + function isKeyword$3(word) { + return keywords$4.has(word); + } + + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "isIdentifierName", { + enumerable: true, + get: function () { + return _identifier.isIdentifierName; + } + }); + Object.defineProperty(exports, "isIdentifierChar", { + enumerable: true, + get: function () { + return _identifier.isIdentifierChar; + } + }); + Object.defineProperty(exports, "isIdentifierStart", { + enumerable: true, + get: function () { + return _identifier.isIdentifierStart; + } + }); + Object.defineProperty(exports, "isReservedWord", { + enumerable: true, + get: function () { + return _keyword.isReservedWord; + } + }); + Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindOnlyReservedWord; + } + }); + Object.defineProperty(exports, "isStrictBindReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindReservedWord; + } + }); + Object.defineProperty(exports, "isStrictReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictReservedWord; + } + }); + Object.defineProperty(exports, "isKeyword", { + enumerable: true, + get: function () { + return _keyword.isKeyword; + } + }); + + var _identifier = identifier$2; + + var _keyword = keyword$1; + } (lib$5)); + + Object.defineProperty(isValidIdentifier$3, "__esModule", { + value: true + }); + isValidIdentifier$3.default = isValidIdentifier$2; + + var _helperValidatorIdentifier$2 = lib$5; + + function isValidIdentifier$2(name, reserved = true) { + if (typeof name !== "string") return false; + + if (reserved) { + if ((0, _helperValidatorIdentifier$2.isKeyword)(name) || (0, _helperValidatorIdentifier$2.isStrictReservedWord)(name, true)) { + return false; + } + } + + return (0, _helperValidatorIdentifier$2.isIdentifierName)(name); + } + + var constants$1 = {}; + + Object.defineProperty(constants$1, "__esModule", { + value: true + }); + constants$1.NOT_LOCAL_BINDING = constants$1.BLOCK_SCOPED_SYMBOL = constants$1.INHERIT_KEYS = constants$1.UNARY_OPERATORS = constants$1.STRING_UNARY_OPERATORS = constants$1.NUMBER_UNARY_OPERATORS = constants$1.BOOLEAN_UNARY_OPERATORS = constants$1.ASSIGNMENT_OPERATORS = constants$1.BINARY_OPERATORS = constants$1.NUMBER_BINARY_OPERATORS = constants$1.BOOLEAN_BINARY_OPERATORS = constants$1.COMPARISON_BINARY_OPERATORS = constants$1.EQUALITY_BINARY_OPERATORS = constants$1.BOOLEAN_NUMBER_BINARY_OPERATORS = constants$1.UPDATE_OPERATORS = constants$1.LOGICAL_OPERATORS = constants$1.COMMENT_KEYS = constants$1.FOR_INIT_KEYS = constants$1.FLATTENABLE_KEYS = constants$1.STATEMENT_OR_BLOCK_KEYS = void 0; + const STATEMENT_OR_BLOCK_KEYS$1 = ["consequent", "body", "alternate"]; + constants$1.STATEMENT_OR_BLOCK_KEYS = STATEMENT_OR_BLOCK_KEYS$1; + const FLATTENABLE_KEYS$1 = ["body", "expressions"]; + constants$1.FLATTENABLE_KEYS = FLATTENABLE_KEYS$1; + const FOR_INIT_KEYS$1 = ["left", "init"]; + constants$1.FOR_INIT_KEYS = FOR_INIT_KEYS$1; + const COMMENT_KEYS$1 = ["leadingComments", "trailingComments", "innerComments"]; + constants$1.COMMENT_KEYS = COMMENT_KEYS$1; + const LOGICAL_OPERATORS$1 = ["||", "&&", "??"]; + constants$1.LOGICAL_OPERATORS = LOGICAL_OPERATORS$1; + const UPDATE_OPERATORS$1 = ["++", "--"]; + constants$1.UPDATE_OPERATORS = UPDATE_OPERATORS$1; + const BOOLEAN_NUMBER_BINARY_OPERATORS$1 = [">", "<", ">=", "<="]; + constants$1.BOOLEAN_NUMBER_BINARY_OPERATORS = BOOLEAN_NUMBER_BINARY_OPERATORS$1; + const EQUALITY_BINARY_OPERATORS$1 = ["==", "===", "!=", "!=="]; + constants$1.EQUALITY_BINARY_OPERATORS = EQUALITY_BINARY_OPERATORS$1; + const COMPARISON_BINARY_OPERATORS$1 = [...EQUALITY_BINARY_OPERATORS$1, "in", "instanceof"]; + constants$1.COMPARISON_BINARY_OPERATORS = COMPARISON_BINARY_OPERATORS$1; + const BOOLEAN_BINARY_OPERATORS$1 = [...COMPARISON_BINARY_OPERATORS$1, ...BOOLEAN_NUMBER_BINARY_OPERATORS$1]; + constants$1.BOOLEAN_BINARY_OPERATORS = BOOLEAN_BINARY_OPERATORS$1; + const NUMBER_BINARY_OPERATORS$1 = ["-", "/", "%", "*", "**", "&", "|", ">>", ">>>", "<<", "^"]; + constants$1.NUMBER_BINARY_OPERATORS = NUMBER_BINARY_OPERATORS$1; + const BINARY_OPERATORS$1 = ["+", ...NUMBER_BINARY_OPERATORS$1, ...BOOLEAN_BINARY_OPERATORS$1]; + constants$1.BINARY_OPERATORS = BINARY_OPERATORS$1; + const ASSIGNMENT_OPERATORS$1 = ["=", "+=", ...NUMBER_BINARY_OPERATORS$1.map(op => op + "="), ...LOGICAL_OPERATORS$1.map(op => op + "=")]; + constants$1.ASSIGNMENT_OPERATORS = ASSIGNMENT_OPERATORS$1; + const BOOLEAN_UNARY_OPERATORS$1 = ["delete", "!"]; + constants$1.BOOLEAN_UNARY_OPERATORS = BOOLEAN_UNARY_OPERATORS$1; + const NUMBER_UNARY_OPERATORS$1 = ["+", "-", "~"]; + constants$1.NUMBER_UNARY_OPERATORS = NUMBER_UNARY_OPERATORS$1; + const STRING_UNARY_OPERATORS$1 = ["typeof"]; + constants$1.STRING_UNARY_OPERATORS = STRING_UNARY_OPERATORS$1; + const UNARY_OPERATORS$1 = ["void", "throw", ...BOOLEAN_UNARY_OPERATORS$1, ...NUMBER_UNARY_OPERATORS$1, ...STRING_UNARY_OPERATORS$1]; + constants$1.UNARY_OPERATORS = UNARY_OPERATORS$1; + const INHERIT_KEYS$1 = { + optional: ["typeAnnotation", "typeParameters", "returnType"], + force: ["start", "loc", "end"] + }; + constants$1.INHERIT_KEYS = INHERIT_KEYS$1; + const BLOCK_SCOPED_SYMBOL$1 = Symbol.for("var used to be block scoped"); + constants$1.BLOCK_SCOPED_SYMBOL = BLOCK_SCOPED_SYMBOL$1; + const NOT_LOCAL_BINDING$1 = Symbol.for("should not be considered a local binding"); + constants$1.NOT_LOCAL_BINDING = NOT_LOCAL_BINDING$1; + + var utils$1 = {}; + + var validate$1 = {}; + + var hasRequiredValidate$1; + + function requireValidate$1 () { + if (hasRequiredValidate$1) return validate$1; + hasRequiredValidate$1 = 1; + + Object.defineProperty(validate$1, "__esModule", { + value: true + }); + validate$1.default = validate; + validate$1.validateField = validateField; + validate$1.validateChild = validateChild; + + var _definitions = requireDefinitions$1(); + + function validate(node, key, val) { + if (!node) return; + const fields = _definitions.NODE_FIELDS[node.type]; + if (!fields) return; + const field = fields[key]; + validateField(node, key, val, field); + validateChild(node, key, val); + } + + function validateField(node, key, val, field) { + if (!(field != null && field.validate)) return; + if (field.optional && val == null) return; + field.validate(node, key, val); + } + + function validateChild(node, key, val) { + if (val == null) return; + const validate = _definitions.NODE_PARENT_VALIDATIONS[val.type]; + if (!validate) return; + validate(node, key, val); + } + return validate$1; + } + + var hasRequiredUtils$1; + + function requireUtils$1 () { + if (hasRequiredUtils$1) return utils$1; + hasRequiredUtils$1 = 1; + + Object.defineProperty(utils$1, "__esModule", { + value: true + }); + utils$1.validate = validate; + utils$1.typeIs = typeIs; + utils$1.validateType = validateType; + utils$1.validateOptional = validateOptional; + utils$1.validateOptionalType = validateOptionalType; + utils$1.arrayOf = arrayOf; + utils$1.arrayOfType = arrayOfType; + utils$1.validateArrayOfType = validateArrayOfType; + utils$1.assertEach = assertEach; + utils$1.assertOneOf = assertOneOf; + utils$1.assertNodeType = assertNodeType; + utils$1.assertNodeOrValueType = assertNodeOrValueType; + utils$1.assertValueType = assertValueType; + utils$1.assertShape = assertShape; + utils$1.assertOptionalChainStart = assertOptionalChainStart; + utils$1.chain = chain; + utils$1.default = defineType; + utils$1.NODE_PARENT_VALIDATIONS = utils$1.DEPRECATED_KEYS = utils$1.BUILDER_KEYS = utils$1.NODE_FIELDS = utils$1.FLIPPED_ALIAS_KEYS = utils$1.ALIAS_KEYS = utils$1.VISITOR_KEYS = void 0; + + var _is = requireIs$1(); + + var _validate = requireValidate$1(); + + const VISITOR_KEYS = {}; + utils$1.VISITOR_KEYS = VISITOR_KEYS; + const ALIAS_KEYS = {}; + utils$1.ALIAS_KEYS = ALIAS_KEYS; + const FLIPPED_ALIAS_KEYS = {}; + utils$1.FLIPPED_ALIAS_KEYS = FLIPPED_ALIAS_KEYS; + const NODE_FIELDS = {}; + utils$1.NODE_FIELDS = NODE_FIELDS; + const BUILDER_KEYS = {}; + utils$1.BUILDER_KEYS = BUILDER_KEYS; + const DEPRECATED_KEYS = {}; + utils$1.DEPRECATED_KEYS = DEPRECATED_KEYS; + const NODE_PARENT_VALIDATIONS = {}; + utils$1.NODE_PARENT_VALIDATIONS = NODE_PARENT_VALIDATIONS; + + function getType(val) { + if (Array.isArray(val)) { + return "array"; + } else if (val === null) { + return "null"; + } else { + return typeof val; + } + } + + function validate(validate) { + return { + validate + }; + } + + function typeIs(typeName) { + return typeof typeName === "string" ? assertNodeType(typeName) : assertNodeType(...typeName); + } + + function validateType(typeName) { + return validate(typeIs(typeName)); + } + + function validateOptional(validate) { + return { + validate, + optional: true + }; + } + + function validateOptionalType(typeName) { + return { + validate: typeIs(typeName), + optional: true + }; + } + + function arrayOf(elementType) { + return chain(assertValueType("array"), assertEach(elementType)); + } + + function arrayOfType(typeName) { + return arrayOf(typeIs(typeName)); + } + + function validateArrayOfType(typeName) { + return validate(arrayOfType(typeName)); + } + + function assertEach(callback) { + function validator(node, key, val) { + if (!Array.isArray(val)) return; + + for (let i = 0; i < val.length; i++) { + const subkey = `${key}[${i}]`; + const v = val[i]; + callback(node, subkey, v); + if (process$1.env.BABEL_TYPES_8_BREAKING) (0, _validate.validateChild)(node, subkey, v); + } + } + + validator.each = callback; + return validator; + } + + function assertOneOf(...values) { + function validate(node, key, val) { + if (values.indexOf(val) < 0) { + throw new TypeError(`Property ${key} expected value to be one of ${JSON.stringify(values)} but got ${JSON.stringify(val)}`); + } + } + + validate.oneOf = values; + return validate; + } + + function assertNodeType(...types) { + function validate(node, key, val) { + for (const type of types) { + if ((0, _is.default)(type, val)) { + (0, _validate.validateChild)(node, key, val); + return; + } + } + + throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); + } + + validate.oneOfNodeTypes = types; + return validate; + } + + function assertNodeOrValueType(...types) { + function validate(node, key, val) { + for (const type of types) { + if (getType(val) === type || (0, _is.default)(type, val)) { + (0, _validate.validateChild)(node, key, val); + return; + } + } + + throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); + } + + validate.oneOfNodeOrValueTypes = types; + return validate; + } + + function assertValueType(type) { + function validate(node, key, val) { + const valid = getType(val) === type; + + if (!valid) { + throw new TypeError(`Property ${key} expected type of ${type} but got ${getType(val)}`); + } + } + + validate.type = type; + return validate; + } + + function assertShape(shape) { + function validate(node, key, val) { + const errors = []; + + for (const property of Object.keys(shape)) { + try { + (0, _validate.validateField)(node, property, val[property], shape[property]); + } catch (error) { + if (error instanceof TypeError) { + errors.push(error.message); + continue; + } + + throw error; + } + } + + if (errors.length) { + throw new TypeError(`Property ${key} of ${node.type} expected to have the following:\n${errors.join("\n")}`); + } + } + + validate.shapeOf = shape; + return validate; + } + + function assertOptionalChainStart() { + function validate(node) { + var _current; + + let current = node; + + while (node) { + const { + type + } = current; + + if (type === "OptionalCallExpression") { + if (current.optional) return; + current = current.callee; + continue; + } + + if (type === "OptionalMemberExpression") { + if (current.optional) return; + current = current.object; + continue; + } + + break; + } + + throw new TypeError(`Non-optional ${node.type} must chain from an optional OptionalMemberExpression or OptionalCallExpression. Found chain from ${(_current = current) == null ? void 0 : _current.type}`); + } + + return validate; + } + + function chain(...fns) { + function validate(...args) { + for (const fn of fns) { + fn(...args); + } + } + + validate.chainOf = fns; + + if (fns.length >= 2 && "type" in fns[0] && fns[0].type === "array" && !("each" in fns[1])) { + throw new Error(`An assertValueType("array") validator can only be followed by an assertEach(...) validator.`); + } + + return validate; + } + + const validTypeOpts = ["aliases", "builder", "deprecatedAlias", "fields", "inherits", "visitor", "validate"]; + const validFieldKeys = ["default", "optional", "validate"]; + + function defineType(type, opts = {}) { + const inherits = opts.inherits && store[opts.inherits] || {}; + let fields = opts.fields; + + if (!fields) { + fields = {}; + + if (inherits.fields) { + const keys = Object.getOwnPropertyNames(inherits.fields); + + for (const key of keys) { + const field = inherits.fields[key]; + const def = field.default; + + if (Array.isArray(def) ? def.length > 0 : def && typeof def === "object") { + throw new Error("field defaults can only be primitives or empty arrays currently"); + } + + fields[key] = { + default: Array.isArray(def) ? [] : def, + optional: field.optional, + validate: field.validate + }; + } + } + } + + const visitor = opts.visitor || inherits.visitor || []; + const aliases = opts.aliases || inherits.aliases || []; + const builder = opts.builder || inherits.builder || opts.visitor || []; + + for (const k of Object.keys(opts)) { + if (validTypeOpts.indexOf(k) === -1) { + throw new Error(`Unknown type option "${k}" on ${type}`); + } + } + + if (opts.deprecatedAlias) { + DEPRECATED_KEYS[opts.deprecatedAlias] = type; + } + + for (const key of visitor.concat(builder)) { + fields[key] = fields[key] || {}; + } + + for (const key of Object.keys(fields)) { + const field = fields[key]; + + if (field.default !== undefined && builder.indexOf(key) === -1) { + field.optional = true; + } + + if (field.default === undefined) { + field.default = null; + } else if (!field.validate && field.default != null) { + field.validate = assertValueType(getType(field.default)); + } + + for (const k of Object.keys(field)) { + if (validFieldKeys.indexOf(k) === -1) { + throw new Error(`Unknown field key "${k}" on ${type}.${key}`); + } + } + } + + VISITOR_KEYS[type] = opts.visitor = visitor; + BUILDER_KEYS[type] = opts.builder = builder; + NODE_FIELDS[type] = opts.fields = fields; + ALIAS_KEYS[type] = opts.aliases = aliases; + aliases.forEach(alias => { + FLIPPED_ALIAS_KEYS[alias] = FLIPPED_ALIAS_KEYS[alias] || []; + FLIPPED_ALIAS_KEYS[alias].push(type); + }); + + if (opts.validate) { + NODE_PARENT_VALIDATIONS[type] = opts.validate; + } + + store[type] = opts; + } + + const store = {}; + return utils$1; + } + + var hasRequiredCore$1; + + function requireCore$1 () { + if (hasRequiredCore$1) return core$1; + hasRequiredCore$1 = 1; + + Object.defineProperty(core$1, "__esModule", { + value: true + }); + core$1.classMethodOrDeclareMethodCommon = core$1.classMethodOrPropertyCommon = core$1.patternLikeCommon = core$1.functionDeclarationCommon = core$1.functionTypeAnnotationCommon = core$1.functionCommon = void 0; + + var _is = requireIs$1(); + + var _isValidIdentifier = isValidIdentifier$3; + + var _helperValidatorIdentifier = lib$5; + + var _constants = constants$1; + + var _utils = requireUtils$1(); + + (0, _utils.default)("ArrayExpression", { + fields: { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeOrValueType)("null", "Expression", "SpreadElement"))), + default: !process$1.env.BABEL_TYPES_8_BREAKING ? [] : undefined + } + }, + visitor: ["elements"], + aliases: ["Expression"] + }); + (0, _utils.default)("AssignmentExpression", { + fields: { + operator: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertValueType)("string"); + } + + const identifier = (0, _utils.assertOneOf)(..._constants.ASSIGNMENT_OPERATORS); + const pattern = (0, _utils.assertOneOf)("="); + return function (node, key, val) { + const validator = (0, _is.default)("Pattern", node.left) ? pattern : identifier; + validator(node, key, val); + }; + }() + }, + left: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("LVal") : (0, _utils.assertNodeType)("Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + builder: ["operator", "left", "right"], + visitor: ["left", "right"], + aliases: ["Expression"] + }); + (0, _utils.default)("BinaryExpression", { + builder: ["operator", "left", "right"], + fields: { + operator: { + validate: (0, _utils.assertOneOf)(..._constants.BINARY_OPERATORS) + }, + left: { + validate: function () { + const expression = (0, _utils.assertNodeType)("Expression"); + const inOp = (0, _utils.assertNodeType)("Expression", "PrivateName"); + + const validator = function (node, key, val) { + const validator = node.operator === "in" ? inOp : expression; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "PrivateName"]; + return validator; + }() + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + visitor: ["left", "right"], + aliases: ["Binary", "Expression"] + }); + (0, _utils.default)("InterpreterDirective", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("Directive", { + visitor: ["value"], + fields: { + value: { + validate: (0, _utils.assertNodeType)("DirectiveLiteral") + } + } + }); + (0, _utils.default)("DirectiveLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("BlockStatement", { + builder: ["body", "directives"], + visitor: ["directives", "body"], + fields: { + directives: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Directive"))), + default: [] + }, + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + }, + aliases: ["Scopable", "BlockParent", "Block", "Statement"] + }); + (0, _utils.default)("BreakStatement", { + visitor: ["label"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }, + aliases: ["Statement", "Terminatorless", "CompletionStatement"] + }); + (0, _utils.default)("CallExpression", { + visitor: ["callee", "arguments", "typeParameters", "typeArguments"], + builder: ["callee", "arguments"], + aliases: ["Expression"], + fields: Object.assign({ + callee: { + validate: (0, _utils.assertNodeType)("Expression", "V8IntrinsicIdentifier") + }, + arguments: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement", "JSXNamespacedName", "ArgumentPlaceholder"))) + } + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + optional: { + validate: (0, _utils.assertOneOf)(true, false), + optional: true + } + } : {}, { + typeArguments: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterInstantiation"), + optional: true + } + }) + }); + (0, _utils.default)("CatchClause", { + visitor: ["param", "body"], + fields: { + param: { + validate: (0, _utils.assertNodeType)("Identifier", "ArrayPattern", "ObjectPattern"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }, + aliases: ["Scopable", "BlockParent"] + }); + (0, _utils.default)("ConditionalExpression", { + visitor: ["test", "consequent", "alternate"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + consequent: { + validate: (0, _utils.assertNodeType)("Expression") + }, + alternate: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Expression", "Conditional"] + }); + (0, _utils.default)("ContinueStatement", { + visitor: ["label"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }, + aliases: ["Statement", "Terminatorless", "CompletionStatement"] + }); + (0, _utils.default)("DebuggerStatement", { + aliases: ["Statement"] + }); + (0, _utils.default)("DoWhileStatement", { + visitor: ["test", "body"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + }, + aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"] + }); + (0, _utils.default)("EmptyStatement", { + aliases: ["Statement"] + }); + (0, _utils.default)("ExpressionStatement", { + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Statement", "ExpressionWrapper"] + }); + (0, _utils.default)("File", { + builder: ["program", "comments", "tokens"], + visitor: ["program"], + fields: { + program: { + validate: (0, _utils.assertNodeType)("Program") + }, + comments: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? Object.assign(() => {}, { + each: { + oneOfNodeTypes: ["CommentBlock", "CommentLine"] + } + }) : (0, _utils.assertEach)((0, _utils.assertNodeType)("CommentBlock", "CommentLine")), + optional: true + }, + tokens: { + validate: (0, _utils.assertEach)(Object.assign(() => {}, { + type: "any" + })), + optional: true + } + } + }); + (0, _utils.default)("ForInStatement", { + visitor: ["left", "right", "body"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"], + fields: { + left: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("VariableDeclaration", "LVal") : (0, _utils.assertNodeType)("VariableDeclaration", "Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("ForStatement", { + visitor: ["init", "test", "update", "body"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop"], + fields: { + init: { + validate: (0, _utils.assertNodeType)("VariableDeclaration", "Expression"), + optional: true + }, + test: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + update: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + const functionCommon = { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Identifier", "Pattern", "RestElement"))) + }, + generator: { + default: false + }, + async: { + default: false + } + }; + core$1.functionCommon = functionCommon; + const functionTypeAnnotationCommon = { + returnType: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + } + }; + core$1.functionTypeAnnotationCommon = functionTypeAnnotationCommon; + const functionDeclarationCommon = Object.assign({}, functionCommon, { + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }); + core$1.functionDeclarationCommon = functionDeclarationCommon; + (0, _utils.default)("FunctionDeclaration", { + builder: ["id", "params", "body", "generator", "async"], + visitor: ["id", "params", "body", "returnType", "typeParameters"], + fields: Object.assign({}, functionDeclarationCommon, functionTypeAnnotationCommon, { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }), + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Statement", "Pureish", "Declaration"], + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return () => {}; + const identifier = (0, _utils.assertNodeType)("Identifier"); + return function (parent, key, node) { + if (!(0, _is.default)("ExportDefaultDeclaration", parent)) { + identifier(node, "id", node.id); + } + }; + }() + }); + (0, _utils.default)("FunctionExpression", { + inherits: "FunctionDeclaration", + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"], + fields: Object.assign({}, functionCommon, functionTypeAnnotationCommon, { + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + const patternLikeCommon = { + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))) + } + }; + core$1.patternLikeCommon = patternLikeCommon; + (0, _utils.default)("Identifier", { + builder: ["name"], + visitor: ["typeAnnotation", "decorators"], + aliases: ["Expression", "PatternLike", "LVal", "TSEntityName"], + fields: Object.assign({}, patternLikeCommon, { + name: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!(0, _isValidIdentifier.default)(val, false)) { + throw new TypeError(`"${val}" is not a valid identifier name`); + } + }, { + type: "string" + })) + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }), + + validate(parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const match = /\.(\w+)$/.exec(key); + if (!match) return; + const [, parentKey] = match; + const nonComp = { + computed: false + }; + + if (parentKey === "property") { + if ((0, _is.default)("MemberExpression", parent, nonComp)) return; + if ((0, _is.default)("OptionalMemberExpression", parent, nonComp)) return; + } else if (parentKey === "key") { + if ((0, _is.default)("Property", parent, nonComp)) return; + if ((0, _is.default)("Method", parent, nonComp)) return; + } else if (parentKey === "exported") { + if ((0, _is.default)("ExportSpecifier", parent)) return; + } else if (parentKey === "imported") { + if ((0, _is.default)("ImportSpecifier", parent, { + imported: node + })) return; + } else if (parentKey === "meta") { + if ((0, _is.default)("MetaProperty", parent, { + meta: node + })) return; + } + + if (((0, _helperValidatorIdentifier.isKeyword)(node.name) || (0, _helperValidatorIdentifier.isReservedWord)(node.name, false)) && node.name !== "this") { + throw new TypeError(`"${node.name}" is not a valid identifier`); + } + } + + }); + (0, _utils.default)("IfStatement", { + visitor: ["test", "consequent", "alternate"], + aliases: ["Statement", "Conditional"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + consequent: { + validate: (0, _utils.assertNodeType)("Statement") + }, + alternate: { + optional: true, + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("LabeledStatement", { + visitor: ["label", "body"], + aliases: ["Statement"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("StringLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("NumericLiteral", { + builder: ["value"], + deprecatedAlias: "NumberLiteral", + fields: { + value: { + validate: (0, _utils.assertValueType)("number") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("NullLiteral", { + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("BooleanLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("boolean") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("RegExpLiteral", { + builder: ["pattern", "flags"], + deprecatedAlias: "RegexLiteral", + aliases: ["Expression", "Pureish", "Literal"], + fields: { + pattern: { + validate: (0, _utils.assertValueType)("string") + }, + flags: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const invalid = /[^gimsuy]/.exec(val); + + if (invalid) { + throw new TypeError(`"${invalid[0]}" is not a valid RegExp flag`); + } + }, { + type: "string" + })), + default: "" + } + } + }); + (0, _utils.default)("LogicalExpression", { + builder: ["operator", "left", "right"], + visitor: ["left", "right"], + aliases: ["Binary", "Expression"], + fields: { + operator: { + validate: (0, _utils.assertOneOf)(..._constants.LOGICAL_OPERATORS) + }, + left: { + validate: (0, _utils.assertNodeType)("Expression") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("MemberExpression", { + builder: ["object", "property", "computed", ...(!process$1.env.BABEL_TYPES_8_BREAKING ? ["optional"] : [])], + visitor: ["object", "property"], + aliases: ["Expression", "LVal"], + fields: Object.assign({ + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + property: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "PrivateName"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "PrivateName"]; + return validator; + }() + }, + computed: { + default: false + } + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + optional: { + validate: (0, _utils.assertOneOf)(true, false), + optional: true + } + } : {}) + }); + (0, _utils.default)("NewExpression", { + inherits: "CallExpression" + }); + (0, _utils.default)("Program", { + visitor: ["directives", "body"], + builder: ["body", "directives", "sourceType", "interpreter"], + fields: { + sourceFile: { + validate: (0, _utils.assertValueType)("string") + }, + sourceType: { + validate: (0, _utils.assertOneOf)("script", "module"), + default: "script" + }, + interpreter: { + validate: (0, _utils.assertNodeType)("InterpreterDirective"), + default: null, + optional: true + }, + directives: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Directive"))), + default: [] + }, + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + }, + aliases: ["Scopable", "BlockParent", "Block"] + }); + (0, _utils.default)("ObjectExpression", { + visitor: ["properties"], + aliases: ["Expression"], + fields: { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ObjectMethod", "ObjectProperty", "SpreadElement"))) + } + } + }); + (0, _utils.default)("ObjectMethod", { + builder: ["kind", "key", "params", "body", "computed", "generator", "async"], + fields: Object.assign({}, functionCommon, functionTypeAnnotationCommon, { + kind: Object.assign({ + validate: (0, _utils.assertOneOf)("method", "get", "set") + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + default: "method" + } : {}), + computed: { + default: false + }, + key: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "StringLiteral", "NumericLiteral"]; + return validator; + }() + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }), + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + aliases: ["UserWhitespacable", "Function", "Scopable", "BlockParent", "FunctionParent", "Method", "ObjectMember"] + }); + (0, _utils.default)("ObjectProperty", { + builder: ["key", "value", "computed", "shorthand", ...(!process$1.env.BABEL_TYPES_8_BREAKING ? ["decorators"] : [])], + fields: { + computed: { + default: false + }, + key: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "StringLiteral", "NumericLiteral"]; + return validator; + }() + }, + value: { + validate: (0, _utils.assertNodeType)("Expression", "PatternLike") + }, + shorthand: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("boolean"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.computed) { + throw new TypeError("Property shorthand of ObjectProperty cannot be true if computed is true"); + } + }, { + type: "boolean" + }), function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && !(0, _is.default)("Identifier", node.key)) { + throw new TypeError("Property shorthand of ObjectProperty cannot be true if key is not an Identifier"); + } + }), + default: false + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }, + visitor: ["key", "value", "decorators"], + aliases: ["UserWhitespacable", "Property", "ObjectMember"], + validate: function () { + const pattern = (0, _utils.assertNodeType)("Identifier", "Pattern"); + const expression = (0, _utils.assertNodeType)("Expression"); + return function (parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const validator = (0, _is.default)("ObjectPattern", parent) ? pattern : expression; + validator(node, "value", node.value); + }; + }() + }); + (0, _utils.default)("RestElement", { + visitor: ["argument", "typeAnnotation"], + builder: ["argument"], + aliases: ["LVal", "PatternLike"], + deprecatedAlias: "RestProperty", + fields: Object.assign({}, patternLikeCommon, { + argument: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("LVal") : (0, _utils.assertNodeType)("Identifier", "ArrayPattern", "ObjectPattern", "MemberExpression") + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }), + + validate(parent, key) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const match = /(\w+)\[(\d+)\]/.exec(key); + if (!match) throw new Error("Internal Babel error: malformed key."); + const [, listKey, index] = match; + + if (parent[listKey].length > index + 1) { + throw new TypeError(`RestElement must be last element of ${listKey}`); + } + } + + }); + (0, _utils.default)("ReturnStatement", { + visitor: ["argument"], + aliases: ["Statement", "Terminatorless", "CompletionStatement"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + } + } + }); + (0, _utils.default)("SequenceExpression", { + visitor: ["expressions"], + fields: { + expressions: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression"))) + } + }, + aliases: ["Expression"] + }); + (0, _utils.default)("ParenthesizedExpression", { + visitor: ["expression"], + aliases: ["Expression", "ExpressionWrapper"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("SwitchCase", { + visitor: ["test", "consequent"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + consequent: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + } + }); + (0, _utils.default)("SwitchStatement", { + visitor: ["discriminant", "cases"], + aliases: ["Statement", "BlockParent", "Scopable"], + fields: { + discriminant: { + validate: (0, _utils.assertNodeType)("Expression") + }, + cases: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("SwitchCase"))) + } + } + }); + (0, _utils.default)("ThisExpression", { + aliases: ["Expression"] + }); + (0, _utils.default)("ThrowStatement", { + visitor: ["argument"], + aliases: ["Statement", "Terminatorless", "CompletionStatement"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("TryStatement", { + visitor: ["block", "handler", "finalizer"], + aliases: ["Statement"], + fields: { + block: { + validate: (0, _utils.chain)((0, _utils.assertNodeType)("BlockStatement"), Object.assign(function (node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!node.handler && !node.finalizer) { + throw new TypeError("TryStatement expects either a handler or finalizer, or both"); + } + }, { + oneOfNodeTypes: ["BlockStatement"] + })) + }, + handler: { + optional: true, + validate: (0, _utils.assertNodeType)("CatchClause") + }, + finalizer: { + optional: true, + validate: (0, _utils.assertNodeType)("BlockStatement") + } + } + }); + (0, _utils.default)("UnaryExpression", { + builder: ["operator", "argument", "prefix"], + fields: { + prefix: { + default: true + }, + argument: { + validate: (0, _utils.assertNodeType)("Expression") + }, + operator: { + validate: (0, _utils.assertOneOf)(..._constants.UNARY_OPERATORS) + } + }, + visitor: ["argument"], + aliases: ["UnaryLike", "Expression"] + }); + (0, _utils.default)("UpdateExpression", { + builder: ["operator", "argument", "prefix"], + fields: { + prefix: { + default: false + }, + argument: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("Expression") : (0, _utils.assertNodeType)("Identifier", "MemberExpression") + }, + operator: { + validate: (0, _utils.assertOneOf)(..._constants.UPDATE_OPERATORS) + } + }, + visitor: ["argument"], + aliases: ["Expression"] + }); + (0, _utils.default)("VariableDeclaration", { + builder: ["kind", "declarations"], + visitor: ["declarations"], + aliases: ["Statement", "Declaration"], + fields: { + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + kind: { + validate: (0, _utils.assertOneOf)("var", "let", "const") + }, + declarations: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("VariableDeclarator"))) + } + }, + + validate(parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + if (!(0, _is.default)("ForXStatement", parent, { + left: node + })) return; + + if (node.declarations.length !== 1) { + throw new TypeError(`Exactly one VariableDeclarator is required in the VariableDeclaration of a ${parent.type}`); + } + } + + }); + (0, _utils.default)("VariableDeclarator", { + visitor: ["id", "init"], + fields: { + id: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertNodeType)("LVal"); + } + + const normal = (0, _utils.assertNodeType)("Identifier", "ArrayPattern", "ObjectPattern"); + const without = (0, _utils.assertNodeType)("Identifier"); + return function (node, key, val) { + const validator = node.init ? normal : without; + validator(node, key, val); + }; + }() + }, + definite: { + optional: true, + validate: (0, _utils.assertValueType)("boolean") + }, + init: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("WhileStatement", { + visitor: ["test", "body"], + aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("WithStatement", { + visitor: ["object", "body"], + aliases: ["Statement"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("AssignmentPattern", { + visitor: ["left", "right", "decorators"], + builder: ["left", "right"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, patternLikeCommon, { + left: { + validate: (0, _utils.assertNodeType)("Identifier", "ObjectPattern", "ArrayPattern", "MemberExpression") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }) + }); + (0, _utils.default)("ArrayPattern", { + visitor: ["elements", "typeAnnotation"], + builder: ["elements"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, patternLikeCommon, { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeOrValueType)("null", "PatternLike"))) + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }) + }); + (0, _utils.default)("ArrowFunctionExpression", { + builder: ["params", "body", "async"], + visitor: ["params", "body", "returnType", "typeParameters"], + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"], + fields: Object.assign({}, functionCommon, functionTypeAnnotationCommon, { + expression: { + validate: (0, _utils.assertValueType)("boolean") + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement", "Expression") + } + }) + }); + (0, _utils.default)("ClassBody", { + visitor: ["body"], + fields: { + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ClassMethod", "ClassPrivateMethod", "ClassProperty", "ClassPrivateProperty", "TSDeclareMethod", "TSIndexSignature"))) + } + } + }); + (0, _utils.default)("ClassExpression", { + builder: ["id", "superClass", "body", "decorators"], + visitor: ["id", "body", "superClass", "mixins", "typeParameters", "superTypeParameters", "implements", "decorators"], + aliases: ["Scopable", "Class", "Expression"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("ClassBody") + }, + superClass: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + }, + superTypeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + }, + implements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSExpressionWithTypeArguments", "ClassImplements"))), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + mixins: { + validate: (0, _utils.assertNodeType)("InterfaceExtends"), + optional: true + } + } + }); + (0, _utils.default)("ClassDeclaration", { + inherits: "ClassExpression", + aliases: ["Scopable", "Class", "Statement", "Declaration"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("ClassBody") + }, + superClass: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + }, + superTypeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + }, + implements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSExpressionWithTypeArguments", "ClassImplements"))), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + mixins: { + validate: (0, _utils.assertNodeType)("InterfaceExtends"), + optional: true + }, + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + abstract: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }, + validate: function () { + const identifier = (0, _utils.assertNodeType)("Identifier"); + return function (parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!(0, _is.default)("ExportDefaultDeclaration", parent)) { + identifier(node, "id", node.id); + } + }; + }() + }); + (0, _utils.default)("ExportAllDeclaration", { + visitor: ["source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + source: { + validate: (0, _utils.assertNodeType)("StringLiteral") + }, + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("type", "value")), + assertions: { + optional: true, + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ImportAttribute"))) + } + } + }); + (0, _utils.default)("ExportDefaultDeclaration", { + visitor: ["declaration"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + declaration: { + validate: (0, _utils.assertNodeType)("FunctionDeclaration", "TSDeclareFunction", "ClassDeclaration", "Expression") + }, + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("value")) + } + }); + (0, _utils.default)("ExportNamedDeclaration", { + visitor: ["declaration", "specifiers", "source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + declaration: { + optional: true, + validate: (0, _utils.chain)((0, _utils.assertNodeType)("Declaration"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.specifiers.length) { + throw new TypeError("Only declaration or specifiers is allowed on ExportNamedDeclaration"); + } + }, { + oneOfNodeTypes: ["Declaration"] + }), function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.source) { + throw new TypeError("Cannot export a declaration from a source"); + } + }) + }, + assertions: { + optional: true, + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ImportAttribute"))) + }, + specifiers: { + default: [], + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)(function () { + const sourced = (0, _utils.assertNodeType)("ExportSpecifier", "ExportDefaultSpecifier", "ExportNamespaceSpecifier"); + const sourceless = (0, _utils.assertNodeType)("ExportSpecifier"); + if (!process$1.env.BABEL_TYPES_8_BREAKING) return sourced; + return function (node, key, val) { + const validator = node.source ? sourced : sourceless; + validator(node, key, val); + }; + }())) + }, + source: { + validate: (0, _utils.assertNodeType)("StringLiteral"), + optional: true + }, + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("type", "value")) + } + }); + (0, _utils.default)("ExportSpecifier", { + visitor: ["local", "exported"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + exported: { + validate: (0, _utils.assertNodeType)("Identifier", "StringLiteral") + } + } + }); + (0, _utils.default)("ForOfStatement", { + visitor: ["left", "right", "body"], + builder: ["left", "right", "body", "await"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"], + fields: { + left: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertNodeType)("VariableDeclaration", "LVal"); + } + + const declaration = (0, _utils.assertNodeType)("VariableDeclaration"); + const lval = (0, _utils.assertNodeType)("Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern"); + return function (node, key, val) { + if ((0, _is.default)("VariableDeclaration", val)) { + declaration(node, key, val); + } else { + lval(node, key, val); + } + }; + }() + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + }, + await: { + default: false + } + } + }); + (0, _utils.default)("ImportDeclaration", { + visitor: ["specifiers", "source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration"], + fields: { + assertions: { + optional: true, + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ImportAttribute"))) + }, + specifiers: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ImportSpecifier", "ImportDefaultSpecifier", "ImportNamespaceSpecifier"))) + }, + source: { + validate: (0, _utils.assertNodeType)("StringLiteral") + }, + importKind: { + validate: (0, _utils.assertOneOf)("type", "typeof", "value"), + optional: true + } + } + }); + (0, _utils.default)("ImportDefaultSpecifier", { + visitor: ["local"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ImportNamespaceSpecifier", { + visitor: ["local"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ImportSpecifier", { + visitor: ["local", "imported"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + imported: { + validate: (0, _utils.assertNodeType)("Identifier", "StringLiteral") + }, + importKind: { + validate: (0, _utils.assertOneOf)("type", "typeof"), + optional: true + } + } + }); + (0, _utils.default)("MetaProperty", { + visitor: ["meta", "property"], + aliases: ["Expression"], + fields: { + meta: { + validate: (0, _utils.chain)((0, _utils.assertNodeType)("Identifier"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + let property; + + switch (val.name) { + case "function": + property = "sent"; + break; + + case "new": + property = "target"; + break; + + case "import": + property = "meta"; + break; + } + + if (!(0, _is.default)("Identifier", node.property, { + name: property + })) { + throw new TypeError("Unrecognised MetaProperty"); + } + }, { + oneOfNodeTypes: ["Identifier"] + })) + }, + property: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + const classMethodOrPropertyCommon = { + abstract: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + accessibility: { + validate: (0, _utils.assertOneOf)("public", "private", "protected"), + optional: true + }, + static: { + default: false + }, + override: { + default: false + }, + computed: { + default: false + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + key: { + validate: (0, _utils.chain)(function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + return function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + }(), (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral", "Expression")) + } + }; + core$1.classMethodOrPropertyCommon = classMethodOrPropertyCommon; + const classMethodOrDeclareMethodCommon = Object.assign({}, functionCommon, classMethodOrPropertyCommon, { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Identifier", "Pattern", "RestElement", "TSParameterProperty"))) + }, + kind: { + validate: (0, _utils.assertOneOf)("get", "set", "method", "constructor"), + default: "method" + }, + access: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), (0, _utils.assertOneOf)("public", "private", "protected")), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }); + core$1.classMethodOrDeclareMethodCommon = classMethodOrDeclareMethodCommon; + (0, _utils.default)("ClassMethod", { + aliases: ["Function", "Scopable", "BlockParent", "FunctionParent", "Method"], + builder: ["kind", "key", "params", "body", "computed", "static", "generator", "async"], + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + fields: Object.assign({}, classMethodOrDeclareMethodCommon, functionTypeAnnotationCommon, { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + (0, _utils.default)("ObjectPattern", { + visitor: ["properties", "typeAnnotation", "decorators"], + builder: ["properties"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, patternLikeCommon, { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("RestElement", "ObjectProperty"))) + } + }) + }); + (0, _utils.default)("SpreadElement", { + visitor: ["argument"], + aliases: ["UnaryLike"], + deprecatedAlias: "SpreadProperty", + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("Super", { + aliases: ["Expression"] + }); + (0, _utils.default)("TaggedTemplateExpression", { + visitor: ["tag", "quasi", "typeParameters"], + builder: ["tag", "quasi"], + aliases: ["Expression"], + fields: { + tag: { + validate: (0, _utils.assertNodeType)("Expression") + }, + quasi: { + validate: (0, _utils.assertNodeType)("TemplateLiteral") + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("TemplateElement", { + builder: ["value", "tail"], + fields: { + value: { + validate: (0, _utils.assertShape)({ + raw: { + validate: (0, _utils.assertValueType)("string") + }, + cooked: { + validate: (0, _utils.assertValueType)("string"), + optional: true + } + }) + }, + tail: { + default: false + } + } + }); + (0, _utils.default)("TemplateLiteral", { + visitor: ["quasis", "expressions"], + aliases: ["Expression", "Literal"], + fields: { + quasis: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TemplateElement"))) + }, + expressions: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "TSType")), function (node, key, val) { + if (node.quasis.length !== val.length + 1) { + throw new TypeError(`Number of ${node.type} quasis should be exactly one more than the number of expressions.\nExpected ${val.length + 1} quasis but got ${node.quasis.length}`); + } + }) + } + } + }); + (0, _utils.default)("YieldExpression", { + builder: ["argument", "delegate"], + visitor: ["argument"], + aliases: ["Expression", "Terminatorless"], + fields: { + delegate: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("boolean"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && !node.argument) { + throw new TypeError("Property delegate of YieldExpression cannot be true if there is no argument"); + } + }, { + type: "boolean" + })), + default: false + }, + argument: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("AwaitExpression", { + builder: ["argument"], + visitor: ["argument"], + aliases: ["Expression", "Terminatorless"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("Import", { + aliases: ["Expression"] + }); + (0, _utils.default)("BigIntLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("ExportNamespaceSpecifier", { + visitor: ["exported"], + aliases: ["ModuleSpecifier"], + fields: { + exported: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("OptionalMemberExpression", { + builder: ["object", "property", "computed", "optional"], + visitor: ["object", "property"], + aliases: ["Expression"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + property: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier"]; + return validator; + }() + }, + computed: { + default: false + }, + optional: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertValueType)("boolean") : (0, _utils.chain)((0, _utils.assertValueType)("boolean"), (0, _utils.assertOptionalChainStart)()) + } + } + }); + (0, _utils.default)("OptionalCallExpression", { + visitor: ["callee", "arguments", "typeParameters", "typeArguments"], + builder: ["callee", "arguments", "optional"], + aliases: ["Expression"], + fields: { + callee: { + validate: (0, _utils.assertNodeType)("Expression") + }, + arguments: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement", "JSXNamespacedName", "ArgumentPlaceholder"))) + }, + optional: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertValueType)("boolean") : (0, _utils.chain)((0, _utils.assertValueType)("boolean"), (0, _utils.assertOptionalChainStart)()) + }, + typeArguments: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("ClassProperty", { + visitor: ["key", "value", "typeAnnotation", "decorators"], + builder: ["key", "value", "typeAnnotation", "decorators", "computed", "static"], + aliases: ["Property"], + fields: Object.assign({}, classMethodOrPropertyCommon, { + value: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + definite: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + readonly: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + variance: { + validate: (0, _utils.assertNodeType)("Variance"), + optional: true + } + }) + }); + (0, _utils.default)("ClassPrivateProperty", { + visitor: ["key", "value", "decorators", "typeAnnotation"], + builder: ["key", "value", "decorators", "static"], + aliases: ["Property", "Private"], + fields: { + key: { + validate: (0, _utils.assertNodeType)("PrivateName") + }, + value: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + readonly: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + definite: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + variance: { + validate: (0, _utils.assertNodeType)("Variance"), + optional: true + } + } + }); + (0, _utils.default)("ClassPrivateMethod", { + builder: ["kind", "key", "params", "body", "static"], + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + aliases: ["Function", "Scopable", "BlockParent", "FunctionParent", "Method", "Private"], + fields: Object.assign({}, classMethodOrDeclareMethodCommon, functionTypeAnnotationCommon, { + key: { + validate: (0, _utils.assertNodeType)("PrivateName") + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + (0, _utils.default)("PrivateName", { + visitor: ["id"], + aliases: ["Private"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + return core$1; + } + + var flow$4 = {}; + + var hasRequiredFlow$1; + + function requireFlow$1 () { + if (hasRequiredFlow$1) return flow$4; + hasRequiredFlow$1 = 1; + + var _utils = requireUtils$1(); + + const defineInterfaceishType = (name, typeParameterType = "TypeParameterDeclaration") => { + (0, _utils.default)(name, { + builder: ["id", "typeParameters", "extends", "body"], + visitor: ["id", "typeParameters", "extends", "mixins", "implements", "body"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)(typeParameterType), + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + mixins: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + implements: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ClassImplements")), + body: (0, _utils.validateType)("ObjectTypeAnnotation") + } + }); + }; + + (0, _utils.default)("AnyTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ArrayTypeAnnotation", { + visitor: ["elementType"], + aliases: ["Flow", "FlowType"], + fields: { + elementType: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("BooleanTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("BooleanLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("NullLiteralTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ClassImplements", { + visitor: ["id", "typeParameters"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + defineInterfaceishType("DeclareClass"); + (0, _utils.default)("DeclareFunction", { + visitor: ["id"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + predicate: (0, _utils.validateOptionalType)("DeclaredPredicate") + } + }); + defineInterfaceishType("DeclareInterface"); + (0, _utils.default)("DeclareModule", { + builder: ["id", "body", "kind"], + visitor: ["id", "body"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + body: (0, _utils.validateType)("BlockStatement"), + kind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("CommonJS", "ES")) + } + }); + (0, _utils.default)("DeclareModuleExports", { + visitor: ["typeAnnotation"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + typeAnnotation: (0, _utils.validateType)("TypeAnnotation") + } + }); + (0, _utils.default)("DeclareTypeAlias", { + visitor: ["id", "typeParameters", "right"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + right: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("DeclareOpaqueType", { + visitor: ["id", "typeParameters", "supertype"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + supertype: (0, _utils.validateOptionalType)("FlowType"), + impltype: (0, _utils.validateOptionalType)("FlowType") + } + }); + (0, _utils.default)("DeclareVariable", { + visitor: ["id"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + (0, _utils.default)("DeclareExportDeclaration", { + visitor: ["declaration", "specifiers", "source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + declaration: (0, _utils.validateOptionalType)("Flow"), + specifiers: (0, _utils.validateOptional)((0, _utils.arrayOfType)(["ExportSpecifier", "ExportNamespaceSpecifier"])), + source: (0, _utils.validateOptionalType)("StringLiteral"), + default: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("DeclareExportAllDeclaration", { + visitor: ["source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + source: (0, _utils.validateType)("StringLiteral"), + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("type", "value")) + } + }); + (0, _utils.default)("DeclaredPredicate", { + visitor: ["value"], + aliases: ["Flow", "FlowPredicate"], + fields: { + value: (0, _utils.validateType)("Flow") + } + }); + (0, _utils.default)("ExistsTypeAnnotation", { + aliases: ["Flow", "FlowType"] + }); + (0, _utils.default)("FunctionTypeAnnotation", { + visitor: ["typeParameters", "params", "rest", "returnType"], + aliases: ["Flow", "FlowType"], + fields: { + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + params: (0, _utils.validate)((0, _utils.arrayOfType)("FunctionTypeParam")), + rest: (0, _utils.validateOptionalType)("FunctionTypeParam"), + this: (0, _utils.validateOptionalType)("FunctionTypeParam"), + returnType: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("FunctionTypeParam", { + visitor: ["name", "typeAnnotation"], + aliases: ["Flow"], + fields: { + name: (0, _utils.validateOptionalType)("Identifier"), + typeAnnotation: (0, _utils.validateType)("FlowType"), + optional: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("GenericTypeAnnotation", { + visitor: ["id", "typeParameters"], + aliases: ["Flow", "FlowType"], + fields: { + id: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + (0, _utils.default)("InferredPredicate", { + aliases: ["Flow", "FlowPredicate"] + }); + (0, _utils.default)("InterfaceExtends", { + visitor: ["id", "typeParameters"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + defineInterfaceishType("InterfaceDeclaration"); + (0, _utils.default)("InterfaceTypeAnnotation", { + visitor: ["extends", "body"], + aliases: ["Flow", "FlowType"], + fields: { + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + body: (0, _utils.validateType)("ObjectTypeAnnotation") + } + }); + (0, _utils.default)("IntersectionTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("MixedTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("EmptyTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("NullableTypeAnnotation", { + visitor: ["typeAnnotation"], + aliases: ["Flow", "FlowType"], + fields: { + typeAnnotation: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("NumberLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("number")) + } + }); + (0, _utils.default)("NumberTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ObjectTypeAnnotation", { + visitor: ["properties", "indexers", "callProperties", "internalSlots"], + aliases: ["Flow", "FlowType"], + builder: ["properties", "indexers", "callProperties", "internalSlots", "exact"], + fields: { + properties: (0, _utils.validate)((0, _utils.arrayOfType)(["ObjectTypeProperty", "ObjectTypeSpreadProperty"])), + indexers: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeIndexer")), + callProperties: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeCallProperty")), + internalSlots: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeInternalSlot")), + exact: { + validate: (0, _utils.assertValueType)("boolean"), + default: false + }, + inexact: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeInternalSlot", { + visitor: ["id", "value", "optional", "static", "method"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + id: (0, _utils.validateType)("Identifier"), + value: (0, _utils.validateType)("FlowType"), + optional: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + method: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeCallProperty", { + visitor: ["value"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + value: (0, _utils.validateType)("FlowType"), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeIndexer", { + visitor: ["id", "key", "value", "variance"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + id: (0, _utils.validateOptionalType)("Identifier"), + key: (0, _utils.validateType)("FlowType"), + value: (0, _utils.validateType)("FlowType"), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + variance: (0, _utils.validateOptionalType)("Variance") + } + }); + (0, _utils.default)("ObjectTypeProperty", { + visitor: ["key", "value", "variance"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + key: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + value: (0, _utils.validateType)("FlowType"), + kind: (0, _utils.validate)((0, _utils.assertOneOf)("init", "get", "set")), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + proto: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + optional: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + variance: (0, _utils.validateOptionalType)("Variance"), + method: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeSpreadProperty", { + visitor: ["argument"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + argument: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("OpaqueType", { + visitor: ["id", "typeParameters", "supertype", "impltype"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + supertype: (0, _utils.validateOptionalType)("FlowType"), + impltype: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("QualifiedTypeIdentifier", { + visitor: ["id", "qualification"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)("Identifier"), + qualification: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]) + } + }); + (0, _utils.default)("StringLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("string")) + } + }); + (0, _utils.default)("StringTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("SymbolTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ThisTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("TupleTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("TypeofTypeAnnotation", { + visitor: ["argument"], + aliases: ["Flow", "FlowType"], + fields: { + argument: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeAlias", { + visitor: ["id", "typeParameters", "right"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + right: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeAnnotation", { + aliases: ["Flow"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeCastExpression", { + visitor: ["expression", "typeAnnotation"], + aliases: ["Flow", "ExpressionWrapper", "Expression"], + fields: { + expression: (0, _utils.validateType)("Expression"), + typeAnnotation: (0, _utils.validateType)("TypeAnnotation") + } + }); + (0, _utils.default)("TypeParameter", { + aliases: ["Flow"], + visitor: ["bound", "default", "variance"], + fields: { + name: (0, _utils.validate)((0, _utils.assertValueType)("string")), + bound: (0, _utils.validateOptionalType)("TypeAnnotation"), + default: (0, _utils.validateOptionalType)("FlowType"), + variance: (0, _utils.validateOptionalType)("Variance") + } + }); + (0, _utils.default)("TypeParameterDeclaration", { + aliases: ["Flow"], + visitor: ["params"], + fields: { + params: (0, _utils.validate)((0, _utils.arrayOfType)("TypeParameter")) + } + }); + (0, _utils.default)("TypeParameterInstantiation", { + aliases: ["Flow"], + visitor: ["params"], + fields: { + params: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("UnionTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("Variance", { + aliases: ["Flow"], + builder: ["kind"], + fields: { + kind: (0, _utils.validate)((0, _utils.assertOneOf)("minus", "plus")) + } + }); + (0, _utils.default)("VoidTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("EnumDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "body"], + fields: { + id: (0, _utils.validateType)("Identifier"), + body: (0, _utils.validateType)(["EnumBooleanBody", "EnumNumberBody", "EnumStringBody", "EnumSymbolBody"]) + } + }); + (0, _utils.default)("EnumBooleanBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicitType: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)("EnumBooleanMember"), + hasUnknownMembers: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("EnumNumberBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicitType: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)("EnumNumberMember"), + hasUnknownMembers: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("EnumStringBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicitType: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)(["EnumStringMember", "EnumDefaultedMember"]), + hasUnknownMembers: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("EnumSymbolBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + members: (0, _utils.validateArrayOfType)("EnumDefaultedMember"), + hasUnknownMembers: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("EnumBooleanMember", { + aliases: ["EnumMember"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("BooleanLiteral") + } + }); + (0, _utils.default)("EnumNumberMember", { + aliases: ["EnumMember"], + visitor: ["id", "init"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("NumericLiteral") + } + }); + (0, _utils.default)("EnumStringMember", { + aliases: ["EnumMember"], + visitor: ["id", "init"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("StringLiteral") + } + }); + (0, _utils.default)("EnumDefaultedMember", { + aliases: ["EnumMember"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + (0, _utils.default)("IndexedAccessType", { + visitor: ["objectType", "indexType"], + aliases: ["Flow", "FlowType"], + fields: { + objectType: (0, _utils.validateType)("FlowType"), + indexType: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("OptionalIndexedAccessType", { + visitor: ["objectType", "indexType"], + aliases: ["Flow", "FlowType"], + fields: { + objectType: (0, _utils.validateType)("FlowType"), + indexType: (0, _utils.validateType)("FlowType"), + optional: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + return flow$4; + } + + var jsx$4 = {}; + + var hasRequiredJsx$1; + + function requireJsx$1 () { + if (hasRequiredJsx$1) return jsx$4; + hasRequiredJsx$1 = 1; + + var _utils = requireUtils$1(); + + (0, _utils.default)("JSXAttribute", { + visitor: ["name", "value"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXNamespacedName") + }, + value: { + optional: true, + validate: (0, _utils.assertNodeType)("JSXElement", "JSXFragment", "StringLiteral", "JSXExpressionContainer") + } + } + }); + (0, _utils.default)("JSXClosingElement", { + visitor: ["name"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXMemberExpression", "JSXNamespacedName") + } + } + }); + (0, _utils.default)("JSXElement", { + builder: ["openingElement", "closingElement", "children", "selfClosing"], + visitor: ["openingElement", "children", "closingElement"], + aliases: ["JSX", "Immutable", "Expression"], + fields: { + openingElement: { + validate: (0, _utils.assertNodeType)("JSXOpeningElement") + }, + closingElement: { + optional: true, + validate: (0, _utils.assertNodeType)("JSXClosingElement") + }, + children: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXText", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement", "JSXFragment"))) + }, + selfClosing: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + } + }); + (0, _utils.default)("JSXEmptyExpression", { + aliases: ["JSX"] + }); + (0, _utils.default)("JSXExpressionContainer", { + visitor: ["expression"], + aliases: ["JSX", "Immutable"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression", "JSXEmptyExpression") + } + } + }); + (0, _utils.default)("JSXSpreadChild", { + visitor: ["expression"], + aliases: ["JSX", "Immutable"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("JSXIdentifier", { + builder: ["name"], + aliases: ["JSX"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("JSXMemberExpression", { + visitor: ["object", "property"], + aliases: ["JSX"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("JSXMemberExpression", "JSXIdentifier") + }, + property: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + } + } + }); + (0, _utils.default)("JSXNamespacedName", { + visitor: ["namespace", "name"], + aliases: ["JSX"], + fields: { + namespace: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + }, + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + } + } + }); + (0, _utils.default)("JSXOpeningElement", { + builder: ["name", "attributes", "selfClosing"], + visitor: ["name", "attributes"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXMemberExpression", "JSXNamespacedName") + }, + selfClosing: { + default: false + }, + attributes: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXAttribute", "JSXSpreadAttribute"))) + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("JSXSpreadAttribute", { + visitor: ["argument"], + aliases: ["JSX"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("JSXText", { + aliases: ["JSX", "Immutable"], + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("JSXFragment", { + builder: ["openingFragment", "closingFragment", "children"], + visitor: ["openingFragment", "children", "closingFragment"], + aliases: ["JSX", "Immutable", "Expression"], + fields: { + openingFragment: { + validate: (0, _utils.assertNodeType)("JSXOpeningFragment") + }, + closingFragment: { + validate: (0, _utils.assertNodeType)("JSXClosingFragment") + }, + children: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXText", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement", "JSXFragment"))) + } + } + }); + (0, _utils.default)("JSXOpeningFragment", { + aliases: ["JSX", "Immutable"] + }); + (0, _utils.default)("JSXClosingFragment", { + aliases: ["JSX", "Immutable"] + }); + return jsx$4; + } + + var misc$1 = {}; + + var placeholders$3 = {}; + + var hasRequiredPlaceholders$1; + + function requirePlaceholders$1 () { + if (hasRequiredPlaceholders$1) return placeholders$3; + hasRequiredPlaceholders$1 = 1; + + Object.defineProperty(placeholders$3, "__esModule", { + value: true + }); + placeholders$3.PLACEHOLDERS_FLIPPED_ALIAS = placeholders$3.PLACEHOLDERS_ALIAS = placeholders$3.PLACEHOLDERS = void 0; + + var _utils = requireUtils$1(); + + const PLACEHOLDERS = ["Identifier", "StringLiteral", "Expression", "Statement", "Declaration", "BlockStatement", "ClassBody", "Pattern"]; + placeholders$3.PLACEHOLDERS = PLACEHOLDERS; + const PLACEHOLDERS_ALIAS = { + Declaration: ["Statement"], + Pattern: ["PatternLike", "LVal"] + }; + placeholders$3.PLACEHOLDERS_ALIAS = PLACEHOLDERS_ALIAS; + + for (const type of PLACEHOLDERS) { + const alias = _utils.ALIAS_KEYS[type]; + if (alias != null && alias.length) PLACEHOLDERS_ALIAS[type] = alias; + } + + const PLACEHOLDERS_FLIPPED_ALIAS = {}; + placeholders$3.PLACEHOLDERS_FLIPPED_ALIAS = PLACEHOLDERS_FLIPPED_ALIAS; + Object.keys(PLACEHOLDERS_ALIAS).forEach(type => { + PLACEHOLDERS_ALIAS[type].forEach(alias => { + if (!Object.hasOwnProperty.call(PLACEHOLDERS_FLIPPED_ALIAS, alias)) { + PLACEHOLDERS_FLIPPED_ALIAS[alias] = []; + } + + PLACEHOLDERS_FLIPPED_ALIAS[alias].push(type); + }); + }); + return placeholders$3; + } + + var hasRequiredMisc$1; + + function requireMisc$1 () { + if (hasRequiredMisc$1) return misc$1; + hasRequiredMisc$1 = 1; + + var _utils = requireUtils$1(); + + var _placeholders = requirePlaceholders$1(); + + { + (0, _utils.default)("Noop", { + visitor: [] + }); + } + (0, _utils.default)("Placeholder", { + visitor: [], + builder: ["expectedNode", "name"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + expectedNode: { + validate: (0, _utils.assertOneOf)(..._placeholders.PLACEHOLDERS) + } + } + }); + (0, _utils.default)("V8IntrinsicIdentifier", { + builder: ["name"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + return misc$1; + } + + var experimental$1 = {}; + + var hasRequiredExperimental$1; + + function requireExperimental$1 () { + if (hasRequiredExperimental$1) return experimental$1; + hasRequiredExperimental$1 = 1; + + var _utils = requireUtils$1(); + + (0, _utils.default)("ArgumentPlaceholder", {}); + (0, _utils.default)("BindExpression", { + visitor: ["object", "callee"], + aliases: ["Expression"], + fields: !process$1.env.BABEL_TYPES_8_BREAKING ? { + object: { + validate: Object.assign(() => {}, { + oneOfNodeTypes: ["Expression"] + }) + }, + callee: { + validate: Object.assign(() => {}, { + oneOfNodeTypes: ["Expression"] + }) + } + } : { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + callee: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("ImportAttribute", { + visitor: ["key", "value"], + fields: { + key: { + validate: (0, _utils.assertNodeType)("Identifier", "StringLiteral") + }, + value: { + validate: (0, _utils.assertNodeType)("StringLiteral") + } + } + }); + (0, _utils.default)("Decorator", { + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("DoExpression", { + visitor: ["body"], + builder: ["body", "async"], + aliases: ["Expression"], + fields: { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + }, + async: { + validate: (0, _utils.assertValueType)("boolean"), + default: false + } + } + }); + (0, _utils.default)("ExportDefaultSpecifier", { + visitor: ["exported"], + aliases: ["ModuleSpecifier"], + fields: { + exported: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("RecordExpression", { + visitor: ["properties"], + aliases: ["Expression"], + fields: { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ObjectProperty", "SpreadElement"))) + } + } + }); + (0, _utils.default)("TupleExpression", { + fields: { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement"))), + default: [] + } + }, + visitor: ["elements"], + aliases: ["Expression"] + }); + (0, _utils.default)("DecimalLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("StaticBlock", { + visitor: ["body"], + fields: { + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + }, + aliases: ["Scopable", "BlockParent"] + }); + (0, _utils.default)("ModuleExpression", { + visitor: ["body"], + fields: { + body: { + validate: (0, _utils.assertNodeType)("Program") + } + }, + aliases: ["Expression"] + }); + (0, _utils.default)("TopicReference", { + aliases: ["Expression"] + }); + (0, _utils.default)("PipelineTopicExpression", { + builder: ["expression"], + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Expression"] + }); + (0, _utils.default)("PipelineBareFunction", { + builder: ["callee"], + visitor: ["callee"], + fields: { + callee: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Expression"] + }); + (0, _utils.default)("PipelinePrimaryTopicReference", { + aliases: ["Expression"] + }); + return experimental$1; + } + + var typescript$4 = {}; + + var hasRequiredTypescript$1; + + function requireTypescript$1 () { + if (hasRequiredTypescript$1) return typescript$4; + hasRequiredTypescript$1 = 1; + + var _utils = requireUtils$1(); + + var _core = requireCore$1(); + + var _is = requireIs$1(); + + const bool = (0, _utils.assertValueType)("boolean"); + const tSFunctionTypeAnnotationCommon = { + returnType: { + validate: (0, _utils.assertNodeType)("TSTypeAnnotation", "Noop"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterDeclaration", "Noop"), + optional: true + } + }; + (0, _utils.default)("TSParameterProperty", { + aliases: ["LVal"], + visitor: ["parameter"], + fields: { + accessibility: { + validate: (0, _utils.assertOneOf)("public", "private", "protected"), + optional: true + }, + readonly: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + parameter: { + validate: (0, _utils.assertNodeType)("Identifier", "AssignmentPattern") + }, + override: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + } + }); + (0, _utils.default)("TSDeclareFunction", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "params", "returnType"], + fields: Object.assign({}, _core.functionDeclarationCommon, tSFunctionTypeAnnotationCommon) + }); + (0, _utils.default)("TSDeclareMethod", { + visitor: ["decorators", "key", "typeParameters", "params", "returnType"], + fields: Object.assign({}, _core.classMethodOrDeclareMethodCommon, tSFunctionTypeAnnotationCommon) + }); + (0, _utils.default)("TSQualifiedName", { + aliases: ["TSEntityName"], + visitor: ["left", "right"], + fields: { + left: (0, _utils.validateType)("TSEntityName"), + right: (0, _utils.validateType)("Identifier") + } + }); + const signatureDeclarationCommon = { + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + parameters: (0, _utils.validateArrayOfType)(["Identifier", "RestElement"]), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation") + }; + const callConstructSignatureDeclaration = { + aliases: ["TSTypeElement"], + visitor: ["typeParameters", "parameters", "typeAnnotation"], + fields: signatureDeclarationCommon + }; + (0, _utils.default)("TSCallSignatureDeclaration", callConstructSignatureDeclaration); + (0, _utils.default)("TSConstructSignatureDeclaration", callConstructSignatureDeclaration); + const namedTypeElementCommon = { + key: (0, _utils.validateType)("Expression"), + computed: (0, _utils.validate)(bool), + optional: (0, _utils.validateOptional)(bool) + }; + (0, _utils.default)("TSPropertySignature", { + aliases: ["TSTypeElement"], + visitor: ["key", "typeAnnotation", "initializer"], + fields: Object.assign({}, namedTypeElementCommon, { + readonly: (0, _utils.validateOptional)(bool), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation"), + initializer: (0, _utils.validateOptionalType)("Expression"), + kind: { + validate: (0, _utils.assertOneOf)("get", "set") + } + }) + }); + (0, _utils.default)("TSMethodSignature", { + aliases: ["TSTypeElement"], + visitor: ["key", "typeParameters", "parameters", "typeAnnotation"], + fields: Object.assign({}, signatureDeclarationCommon, namedTypeElementCommon, { + kind: { + validate: (0, _utils.assertOneOf)("method", "get", "set") + } + }) + }); + (0, _utils.default)("TSIndexSignature", { + aliases: ["TSTypeElement"], + visitor: ["parameters", "typeAnnotation"], + fields: { + readonly: (0, _utils.validateOptional)(bool), + static: (0, _utils.validateOptional)(bool), + parameters: (0, _utils.validateArrayOfType)("Identifier"), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation") + } + }); + const tsKeywordTypes = ["TSAnyKeyword", "TSBooleanKeyword", "TSBigIntKeyword", "TSIntrinsicKeyword", "TSNeverKeyword", "TSNullKeyword", "TSNumberKeyword", "TSObjectKeyword", "TSStringKeyword", "TSSymbolKeyword", "TSUndefinedKeyword", "TSUnknownKeyword", "TSVoidKeyword"]; + + for (const type of tsKeywordTypes) { + (0, _utils.default)(type, { + aliases: ["TSType", "TSBaseType"], + visitor: [], + fields: {} + }); + } + + (0, _utils.default)("TSThisType", { + aliases: ["TSType", "TSBaseType"], + visitor: [], + fields: {} + }); + const fnOrCtrBase = { + aliases: ["TSType"], + visitor: ["typeParameters", "parameters", "typeAnnotation"] + }; + (0, _utils.default)("TSFunctionType", Object.assign({}, fnOrCtrBase, { + fields: signatureDeclarationCommon + })); + (0, _utils.default)("TSConstructorType", Object.assign({}, fnOrCtrBase, { + fields: Object.assign({}, signatureDeclarationCommon, { + abstract: (0, _utils.validateOptional)(bool) + }) + })); + (0, _utils.default)("TSTypeReference", { + aliases: ["TSType"], + visitor: ["typeName", "typeParameters"], + fields: { + typeName: (0, _utils.validateType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSTypePredicate", { + aliases: ["TSType"], + visitor: ["parameterName", "typeAnnotation"], + builder: ["parameterName", "typeAnnotation", "asserts"], + fields: { + parameterName: (0, _utils.validateType)(["Identifier", "TSThisType"]), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation"), + asserts: (0, _utils.validateOptional)(bool) + } + }); + (0, _utils.default)("TSTypeQuery", { + aliases: ["TSType"], + visitor: ["exprName"], + fields: { + exprName: (0, _utils.validateType)(["TSEntityName", "TSImportType"]) + } + }); + (0, _utils.default)("TSTypeLiteral", { + aliases: ["TSType"], + visitor: ["members"], + fields: { + members: (0, _utils.validateArrayOfType)("TSTypeElement") + } + }); + (0, _utils.default)("TSArrayType", { + aliases: ["TSType"], + visitor: ["elementType"], + fields: { + elementType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTupleType", { + aliases: ["TSType"], + visitor: ["elementTypes"], + fields: { + elementTypes: (0, _utils.validateArrayOfType)(["TSType", "TSNamedTupleMember"]) + } + }); + (0, _utils.default)("TSOptionalType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSRestType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSNamedTupleMember", { + visitor: ["label", "elementType"], + builder: ["label", "elementType", "optional"], + fields: { + label: (0, _utils.validateType)("Identifier"), + optional: { + validate: bool, + default: false + }, + elementType: (0, _utils.validateType)("TSType") + } + }); + const unionOrIntersection = { + aliases: ["TSType"], + visitor: ["types"], + fields: { + types: (0, _utils.validateArrayOfType)("TSType") + } + }; + (0, _utils.default)("TSUnionType", unionOrIntersection); + (0, _utils.default)("TSIntersectionType", unionOrIntersection); + (0, _utils.default)("TSConditionalType", { + aliases: ["TSType"], + visitor: ["checkType", "extendsType", "trueType", "falseType"], + fields: { + checkType: (0, _utils.validateType)("TSType"), + extendsType: (0, _utils.validateType)("TSType"), + trueType: (0, _utils.validateType)("TSType"), + falseType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSInferType", { + aliases: ["TSType"], + visitor: ["typeParameter"], + fields: { + typeParameter: (0, _utils.validateType)("TSTypeParameter") + } + }); + (0, _utils.default)("TSParenthesizedType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTypeOperator", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + operator: (0, _utils.validate)((0, _utils.assertValueType)("string")), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSIndexedAccessType", { + aliases: ["TSType"], + visitor: ["objectType", "indexType"], + fields: { + objectType: (0, _utils.validateType)("TSType"), + indexType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSMappedType", { + aliases: ["TSType"], + visitor: ["typeParameter", "typeAnnotation", "nameType"], + fields: { + readonly: (0, _utils.validateOptional)(bool), + typeParameter: (0, _utils.validateType)("TSTypeParameter"), + optional: (0, _utils.validateOptional)(bool), + typeAnnotation: (0, _utils.validateOptionalType)("TSType"), + nameType: (0, _utils.validateOptionalType)("TSType") + } + }); + (0, _utils.default)("TSLiteralType", { + aliases: ["TSType", "TSBaseType"], + visitor: ["literal"], + fields: { + literal: { + validate: function () { + const unaryExpression = (0, _utils.assertNodeType)("NumericLiteral", "BigIntLiteral"); + const unaryOperator = (0, _utils.assertOneOf)("-"); + const literal = (0, _utils.assertNodeType)("NumericLiteral", "StringLiteral", "BooleanLiteral", "BigIntLiteral"); + + function validator(parent, key, node) { + if ((0, _is.default)("UnaryExpression", node)) { + unaryOperator(node, "operator", node.operator); + unaryExpression(node, "argument", node.argument); + } else { + literal(parent, key, node); + } + } + + validator.oneOfNodeTypes = ["NumericLiteral", "StringLiteral", "BooleanLiteral", "BigIntLiteral", "UnaryExpression"]; + return validator; + }() + } + } + }); + (0, _utils.default)("TSExpressionWithTypeArguments", { + aliases: ["TSType"], + visitor: ["expression", "typeParameters"], + fields: { + expression: (0, _utils.validateType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSInterfaceDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "extends", "body"], + fields: { + declare: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("TSExpressionWithTypeArguments")), + body: (0, _utils.validateType)("TSInterfaceBody") + } + }); + (0, _utils.default)("TSInterfaceBody", { + visitor: ["body"], + fields: { + body: (0, _utils.validateArrayOfType)("TSTypeElement") + } + }); + (0, _utils.default)("TSTypeAliasDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "typeAnnotation"], + fields: { + declare: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSAsExpression", { + aliases: ["Expression"], + visitor: ["expression", "typeAnnotation"], + fields: { + expression: (0, _utils.validateType)("Expression"), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTypeAssertion", { + aliases: ["Expression"], + visitor: ["typeAnnotation", "expression"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType"), + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSEnumDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "members"], + fields: { + declare: (0, _utils.validateOptional)(bool), + const: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + members: (0, _utils.validateArrayOfType)("TSEnumMember"), + initializer: (0, _utils.validateOptionalType)("Expression") + } + }); + (0, _utils.default)("TSEnumMember", { + visitor: ["id", "initializer"], + fields: { + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + initializer: (0, _utils.validateOptionalType)("Expression") + } + }); + (0, _utils.default)("TSModuleDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "body"], + fields: { + declare: (0, _utils.validateOptional)(bool), + global: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + body: (0, _utils.validateType)(["TSModuleBlock", "TSModuleDeclaration"]) + } + }); + (0, _utils.default)("TSModuleBlock", { + aliases: ["Scopable", "Block", "BlockParent"], + visitor: ["body"], + fields: { + body: (0, _utils.validateArrayOfType)("Statement") + } + }); + (0, _utils.default)("TSImportType", { + aliases: ["TSType"], + visitor: ["argument", "qualifier", "typeParameters"], + fields: { + argument: (0, _utils.validateType)("StringLiteral"), + qualifier: (0, _utils.validateOptionalType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSImportEqualsDeclaration", { + aliases: ["Statement"], + visitor: ["id", "moduleReference"], + fields: { + isExport: (0, _utils.validate)(bool), + id: (0, _utils.validateType)("Identifier"), + moduleReference: (0, _utils.validateType)(["TSEntityName", "TSExternalModuleReference"]), + importKind: { + validate: (0, _utils.assertOneOf)("type", "value"), + optional: true + } + } + }); + (0, _utils.default)("TSExternalModuleReference", { + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("StringLiteral") + } + }); + (0, _utils.default)("TSNonNullExpression", { + aliases: ["Expression"], + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSExportAssignment", { + aliases: ["Statement"], + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSNamespaceExportDeclaration", { + aliases: ["Statement"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + (0, _utils.default)("TSTypeAnnotation", { + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TSType") + } + } + }); + (0, _utils.default)("TSTypeParameterInstantiation", { + visitor: ["params"], + fields: { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSType"))) + } + } + }); + (0, _utils.default)("TSTypeParameterDeclaration", { + visitor: ["params"], + fields: { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSTypeParameter"))) + } + } + }); + (0, _utils.default)("TSTypeParameter", { + builder: ["constraint", "default", "name"], + visitor: ["constraint", "default"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + }, + constraint: { + validate: (0, _utils.assertNodeType)("TSType"), + optional: true + }, + default: { + validate: (0, _utils.assertNodeType)("TSType"), + optional: true + } + } + }); + return typescript$4; + } + + var hasRequiredDefinitions$1; + + function requireDefinitions$1 () { + if (hasRequiredDefinitions$1) return definitions$1; + hasRequiredDefinitions$1 = 1; + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "VISITOR_KEYS", { + enumerable: true, + get: function () { + return _utils.VISITOR_KEYS; + } + }); + Object.defineProperty(exports, "ALIAS_KEYS", { + enumerable: true, + get: function () { + return _utils.ALIAS_KEYS; + } + }); + Object.defineProperty(exports, "FLIPPED_ALIAS_KEYS", { + enumerable: true, + get: function () { + return _utils.FLIPPED_ALIAS_KEYS; + } + }); + Object.defineProperty(exports, "NODE_FIELDS", { + enumerable: true, + get: function () { + return _utils.NODE_FIELDS; + } + }); + Object.defineProperty(exports, "BUILDER_KEYS", { + enumerable: true, + get: function () { + return _utils.BUILDER_KEYS; + } + }); + Object.defineProperty(exports, "DEPRECATED_KEYS", { + enumerable: true, + get: function () { + return _utils.DEPRECATED_KEYS; + } + }); + Object.defineProperty(exports, "NODE_PARENT_VALIDATIONS", { + enumerable: true, + get: function () { + return _utils.NODE_PARENT_VALIDATIONS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS_ALIAS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS_ALIAS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS_FLIPPED_ALIAS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS_FLIPPED_ALIAS; + } + }); + exports.TYPES = void 0; + + var _toFastProperties = toFastProperties; + + requireCore$1(); + + requireFlow$1(); + + requireJsx$1(); + + requireMisc$1(); + + requireExperimental$1(); + + requireTypescript$1(); + + var _utils = requireUtils$1(); + + var _placeholders = requirePlaceholders$1(); + + _toFastProperties(_utils.VISITOR_KEYS); + + _toFastProperties(_utils.ALIAS_KEYS); + + _toFastProperties(_utils.FLIPPED_ALIAS_KEYS); + + _toFastProperties(_utils.NODE_FIELDS); + + _toFastProperties(_utils.BUILDER_KEYS); + + _toFastProperties(_utils.DEPRECATED_KEYS); + + _toFastProperties(_placeholders.PLACEHOLDERS_ALIAS); + + _toFastProperties(_placeholders.PLACEHOLDERS_FLIPPED_ALIAS); + + const TYPES = Object.keys(_utils.VISITOR_KEYS).concat(Object.keys(_utils.FLIPPED_ALIAS_KEYS)).concat(Object.keys(_utils.DEPRECATED_KEYS)); + exports.TYPES = TYPES; + } (definitions$1)); + return definitions$1; + } + + Object.defineProperty(builder$3, "__esModule", { + value: true + }); + builder$3.default = builder$2; + + var _definitions$d = requireDefinitions$1(); + + var _validate$1 = requireValidate$1(); + + function builder$2(type, ...args) { + const keys = _definitions$d.BUILDER_KEYS[type]; + const countArgs = args.length; + + if (countArgs > keys.length) { + throw new Error(`${type}: Too many arguments passed. Received ${countArgs} but can receive no more than ${keys.length}`); + } + + const node = { + type + }; + let i = 0; + keys.forEach(key => { + const field = _definitions$d.NODE_FIELDS[type][key]; + let arg; + if (i < countArgs) arg = args[i]; + + if (arg === undefined) { + arg = Array.isArray(field.default) ? [] : field.default; + } + + node[key] = arg; + i++; + }); + + for (const key of Object.keys(node)) { + (0, _validate$1.default)(node, key, node[key]); + } + + return node; + } + + Object.defineProperty(generated$7, "__esModule", { + value: true + }); + generated$7.arrayExpression = arrayExpression; + generated$7.assignmentExpression = assignmentExpression; + generated$7.binaryExpression = binaryExpression; + generated$7.interpreterDirective = interpreterDirective; + generated$7.directive = directive; + generated$7.directiveLiteral = directiveLiteral; + generated$7.blockStatement = blockStatement; + generated$7.breakStatement = breakStatement; + generated$7.callExpression = callExpression; + generated$7.catchClause = catchClause; + generated$7.conditionalExpression = conditionalExpression; + generated$7.continueStatement = continueStatement; + generated$7.debuggerStatement = debuggerStatement; + generated$7.doWhileStatement = doWhileStatement; + generated$7.emptyStatement = emptyStatement; + generated$7.expressionStatement = expressionStatement; + generated$7.file = file; + generated$7.forInStatement = forInStatement; + generated$7.forStatement = forStatement; + generated$7.functionDeclaration = functionDeclaration; + generated$7.functionExpression = functionExpression; + generated$7.identifier = identifier$1; + generated$7.ifStatement = ifStatement; + generated$7.labeledStatement = labeledStatement; + generated$7.stringLiteral = stringLiteral; + generated$7.numericLiteral = numericLiteral; + generated$7.nullLiteral = nullLiteral; + generated$7.booleanLiteral = booleanLiteral; + generated$7.regExpLiteral = regExpLiteral; + generated$7.logicalExpression = logicalExpression; + generated$7.memberExpression = memberExpression; + generated$7.newExpression = newExpression; + generated$7.program = program; + generated$7.objectExpression = objectExpression; + generated$7.objectMethod = objectMethod; + generated$7.objectProperty = objectProperty; + generated$7.restElement = restElement; + generated$7.returnStatement = returnStatement; + generated$7.sequenceExpression = sequenceExpression; + generated$7.parenthesizedExpression = parenthesizedExpression; + generated$7.switchCase = switchCase; + generated$7.switchStatement = switchStatement; + generated$7.thisExpression = thisExpression; + generated$7.throwStatement = throwStatement; + generated$7.tryStatement = tryStatement; + generated$7.unaryExpression = unaryExpression; + generated$7.updateExpression = updateExpression; + generated$7.variableDeclaration = variableDeclaration; + generated$7.variableDeclarator = variableDeclarator; + generated$7.whileStatement = whileStatement; + generated$7.withStatement = withStatement; + generated$7.assignmentPattern = assignmentPattern; + generated$7.arrayPattern = arrayPattern; + generated$7.arrowFunctionExpression = arrowFunctionExpression; + generated$7.classBody = classBody; + generated$7.classExpression = classExpression; + generated$7.classDeclaration = classDeclaration; + generated$7.exportAllDeclaration = exportAllDeclaration; + generated$7.exportDefaultDeclaration = exportDefaultDeclaration; + generated$7.exportNamedDeclaration = exportNamedDeclaration; + generated$7.exportSpecifier = exportSpecifier; + generated$7.forOfStatement = forOfStatement; + generated$7.importDeclaration = importDeclaration; + generated$7.importDefaultSpecifier = importDefaultSpecifier; + generated$7.importNamespaceSpecifier = importNamespaceSpecifier; + generated$7.importSpecifier = importSpecifier; + generated$7.metaProperty = metaProperty; + generated$7.classMethod = classMethod; + generated$7.objectPattern = objectPattern; + generated$7.spreadElement = spreadElement; + generated$7.super = _super; + generated$7.taggedTemplateExpression = taggedTemplateExpression; + generated$7.templateElement = templateElement; + generated$7.templateLiteral = templateLiteral; + generated$7.yieldExpression = yieldExpression; + generated$7.awaitExpression = awaitExpression; + generated$7.import = _import; + generated$7.bigIntLiteral = bigIntLiteral; + generated$7.exportNamespaceSpecifier = exportNamespaceSpecifier; + generated$7.optionalMemberExpression = optionalMemberExpression; + generated$7.optionalCallExpression = optionalCallExpression; + generated$7.classProperty = classProperty; + generated$7.classPrivateProperty = classPrivateProperty; + generated$7.classPrivateMethod = classPrivateMethod; + generated$7.privateName = privateName; + generated$7.anyTypeAnnotation = anyTypeAnnotation; + generated$7.arrayTypeAnnotation = arrayTypeAnnotation; + generated$7.booleanTypeAnnotation = booleanTypeAnnotation; + generated$7.booleanLiteralTypeAnnotation = booleanLiteralTypeAnnotation; + generated$7.nullLiteralTypeAnnotation = nullLiteralTypeAnnotation; + generated$7.classImplements = classImplements; + generated$7.declareClass = declareClass; + generated$7.declareFunction = declareFunction; + generated$7.declareInterface = declareInterface; + generated$7.declareModule = declareModule; + generated$7.declareModuleExports = declareModuleExports; + generated$7.declareTypeAlias = declareTypeAlias; + generated$7.declareOpaqueType = declareOpaqueType; + generated$7.declareVariable = declareVariable; + generated$7.declareExportDeclaration = declareExportDeclaration; + generated$7.declareExportAllDeclaration = declareExportAllDeclaration; + generated$7.declaredPredicate = declaredPredicate; + generated$7.existsTypeAnnotation = existsTypeAnnotation; + generated$7.functionTypeAnnotation = functionTypeAnnotation; + generated$7.functionTypeParam = functionTypeParam; + generated$7.genericTypeAnnotation = genericTypeAnnotation; + generated$7.inferredPredicate = inferredPredicate; + generated$7.interfaceExtends = interfaceExtends; + generated$7.interfaceDeclaration = interfaceDeclaration; + generated$7.interfaceTypeAnnotation = interfaceTypeAnnotation; + generated$7.intersectionTypeAnnotation = intersectionTypeAnnotation; + generated$7.mixedTypeAnnotation = mixedTypeAnnotation; + generated$7.emptyTypeAnnotation = emptyTypeAnnotation; + generated$7.nullableTypeAnnotation = nullableTypeAnnotation; + generated$7.numberLiteralTypeAnnotation = numberLiteralTypeAnnotation; + generated$7.numberTypeAnnotation = numberTypeAnnotation; + generated$7.objectTypeAnnotation = objectTypeAnnotation; + generated$7.objectTypeInternalSlot = objectTypeInternalSlot; + generated$7.objectTypeCallProperty = objectTypeCallProperty; + generated$7.objectTypeIndexer = objectTypeIndexer; + generated$7.objectTypeProperty = objectTypeProperty; + generated$7.objectTypeSpreadProperty = objectTypeSpreadProperty; + generated$7.opaqueType = opaqueType; + generated$7.qualifiedTypeIdentifier = qualifiedTypeIdentifier; + generated$7.stringLiteralTypeAnnotation = stringLiteralTypeAnnotation; + generated$7.stringTypeAnnotation = stringTypeAnnotation; + generated$7.symbolTypeAnnotation = symbolTypeAnnotation; + generated$7.thisTypeAnnotation = thisTypeAnnotation; + generated$7.tupleTypeAnnotation = tupleTypeAnnotation; + generated$7.typeofTypeAnnotation = typeofTypeAnnotation; + generated$7.typeAlias = typeAlias; + generated$7.typeAnnotation = typeAnnotation; + generated$7.typeCastExpression = typeCastExpression; + generated$7.typeParameter = typeParameter; + generated$7.typeParameterDeclaration = typeParameterDeclaration; + generated$7.typeParameterInstantiation = typeParameterInstantiation; + generated$7.unionTypeAnnotation = unionTypeAnnotation; + generated$7.variance = variance; + generated$7.voidTypeAnnotation = voidTypeAnnotation; + generated$7.enumDeclaration = enumDeclaration; + generated$7.enumBooleanBody = enumBooleanBody; + generated$7.enumNumberBody = enumNumberBody; + generated$7.enumStringBody = enumStringBody; + generated$7.enumSymbolBody = enumSymbolBody; + generated$7.enumBooleanMember = enumBooleanMember; + generated$7.enumNumberMember = enumNumberMember; + generated$7.enumStringMember = enumStringMember; + generated$7.enumDefaultedMember = enumDefaultedMember; + generated$7.indexedAccessType = indexedAccessType; + generated$7.optionalIndexedAccessType = optionalIndexedAccessType; + generated$7.jSXAttribute = generated$7.jsxAttribute = jsxAttribute; + generated$7.jSXClosingElement = generated$7.jsxClosingElement = jsxClosingElement; + generated$7.jSXElement = generated$7.jsxElement = jsxElement; + generated$7.jSXEmptyExpression = generated$7.jsxEmptyExpression = jsxEmptyExpression; + generated$7.jSXExpressionContainer = generated$7.jsxExpressionContainer = jsxExpressionContainer; + generated$7.jSXSpreadChild = generated$7.jsxSpreadChild = jsxSpreadChild; + generated$7.jSXIdentifier = generated$7.jsxIdentifier = jsxIdentifier; + generated$7.jSXMemberExpression = generated$7.jsxMemberExpression = jsxMemberExpression; + generated$7.jSXNamespacedName = generated$7.jsxNamespacedName = jsxNamespacedName; + generated$7.jSXOpeningElement = generated$7.jsxOpeningElement = jsxOpeningElement; + generated$7.jSXSpreadAttribute = generated$7.jsxSpreadAttribute = jsxSpreadAttribute; + generated$7.jSXText = generated$7.jsxText = jsxText; + generated$7.jSXFragment = generated$7.jsxFragment = jsxFragment; + generated$7.jSXOpeningFragment = generated$7.jsxOpeningFragment = jsxOpeningFragment; + generated$7.jSXClosingFragment = generated$7.jsxClosingFragment = jsxClosingFragment; + generated$7.noop = noop$2; + generated$7.placeholder = placeholder; + generated$7.v8IntrinsicIdentifier = v8IntrinsicIdentifier; + generated$7.argumentPlaceholder = argumentPlaceholder; + generated$7.bindExpression = bindExpression; + generated$7.importAttribute = importAttribute; + generated$7.decorator = decorator; + generated$7.doExpression = doExpression; + generated$7.exportDefaultSpecifier = exportDefaultSpecifier; + generated$7.recordExpression = recordExpression; + generated$7.tupleExpression = tupleExpression; + generated$7.decimalLiteral = decimalLiteral; + generated$7.staticBlock = staticBlock; + generated$7.moduleExpression = moduleExpression; + generated$7.topicReference = topicReference; + generated$7.pipelineTopicExpression = pipelineTopicExpression; + generated$7.pipelineBareFunction = pipelineBareFunction; + generated$7.pipelinePrimaryTopicReference = pipelinePrimaryTopicReference; + generated$7.tSParameterProperty = generated$7.tsParameterProperty = tsParameterProperty; + generated$7.tSDeclareFunction = generated$7.tsDeclareFunction = tsDeclareFunction; + generated$7.tSDeclareMethod = generated$7.tsDeclareMethod = tsDeclareMethod; + generated$7.tSQualifiedName = generated$7.tsQualifiedName = tsQualifiedName; + generated$7.tSCallSignatureDeclaration = generated$7.tsCallSignatureDeclaration = tsCallSignatureDeclaration; + generated$7.tSConstructSignatureDeclaration = generated$7.tsConstructSignatureDeclaration = tsConstructSignatureDeclaration; + generated$7.tSPropertySignature = generated$7.tsPropertySignature = tsPropertySignature; + generated$7.tSMethodSignature = generated$7.tsMethodSignature = tsMethodSignature; + generated$7.tSIndexSignature = generated$7.tsIndexSignature = tsIndexSignature; + generated$7.tSAnyKeyword = generated$7.tsAnyKeyword = tsAnyKeyword; + generated$7.tSBooleanKeyword = generated$7.tsBooleanKeyword = tsBooleanKeyword; + generated$7.tSBigIntKeyword = generated$7.tsBigIntKeyword = tsBigIntKeyword; + generated$7.tSIntrinsicKeyword = generated$7.tsIntrinsicKeyword = tsIntrinsicKeyword; + generated$7.tSNeverKeyword = generated$7.tsNeverKeyword = tsNeverKeyword; + generated$7.tSNullKeyword = generated$7.tsNullKeyword = tsNullKeyword; + generated$7.tSNumberKeyword = generated$7.tsNumberKeyword = tsNumberKeyword; + generated$7.tSObjectKeyword = generated$7.tsObjectKeyword = tsObjectKeyword; + generated$7.tSStringKeyword = generated$7.tsStringKeyword = tsStringKeyword; + generated$7.tSSymbolKeyword = generated$7.tsSymbolKeyword = tsSymbolKeyword; + generated$7.tSUndefinedKeyword = generated$7.tsUndefinedKeyword = tsUndefinedKeyword; + generated$7.tSUnknownKeyword = generated$7.tsUnknownKeyword = tsUnknownKeyword; + generated$7.tSVoidKeyword = generated$7.tsVoidKeyword = tsVoidKeyword; + generated$7.tSThisType = generated$7.tsThisType = tsThisType; + generated$7.tSFunctionType = generated$7.tsFunctionType = tsFunctionType; + generated$7.tSConstructorType = generated$7.tsConstructorType = tsConstructorType; + generated$7.tSTypeReference = generated$7.tsTypeReference = tsTypeReference; + generated$7.tSTypePredicate = generated$7.tsTypePredicate = tsTypePredicate; + generated$7.tSTypeQuery = generated$7.tsTypeQuery = tsTypeQuery; + generated$7.tSTypeLiteral = generated$7.tsTypeLiteral = tsTypeLiteral; + generated$7.tSArrayType = generated$7.tsArrayType = tsArrayType; + generated$7.tSTupleType = generated$7.tsTupleType = tsTupleType; + generated$7.tSOptionalType = generated$7.tsOptionalType = tsOptionalType; + generated$7.tSRestType = generated$7.tsRestType = tsRestType; + generated$7.tSNamedTupleMember = generated$7.tsNamedTupleMember = tsNamedTupleMember; + generated$7.tSUnionType = generated$7.tsUnionType = tsUnionType; + generated$7.tSIntersectionType = generated$7.tsIntersectionType = tsIntersectionType; + generated$7.tSConditionalType = generated$7.tsConditionalType = tsConditionalType; + generated$7.tSInferType = generated$7.tsInferType = tsInferType; + generated$7.tSParenthesizedType = generated$7.tsParenthesizedType = tsParenthesizedType; + generated$7.tSTypeOperator = generated$7.tsTypeOperator = tsTypeOperator; + generated$7.tSIndexedAccessType = generated$7.tsIndexedAccessType = tsIndexedAccessType; + generated$7.tSMappedType = generated$7.tsMappedType = tsMappedType; + generated$7.tSLiteralType = generated$7.tsLiteralType = tsLiteralType; + generated$7.tSExpressionWithTypeArguments = generated$7.tsExpressionWithTypeArguments = tsExpressionWithTypeArguments; + generated$7.tSInterfaceDeclaration = generated$7.tsInterfaceDeclaration = tsInterfaceDeclaration; + generated$7.tSInterfaceBody = generated$7.tsInterfaceBody = tsInterfaceBody; + generated$7.tSTypeAliasDeclaration = generated$7.tsTypeAliasDeclaration = tsTypeAliasDeclaration; + generated$7.tSAsExpression = generated$7.tsAsExpression = tsAsExpression; + generated$7.tSTypeAssertion = generated$7.tsTypeAssertion = tsTypeAssertion; + generated$7.tSEnumDeclaration = generated$7.tsEnumDeclaration = tsEnumDeclaration; + generated$7.tSEnumMember = generated$7.tsEnumMember = tsEnumMember; + generated$7.tSModuleDeclaration = generated$7.tsModuleDeclaration = tsModuleDeclaration; + generated$7.tSModuleBlock = generated$7.tsModuleBlock = tsModuleBlock; + generated$7.tSImportType = generated$7.tsImportType = tsImportType; + generated$7.tSImportEqualsDeclaration = generated$7.tsImportEqualsDeclaration = tsImportEqualsDeclaration; + generated$7.tSExternalModuleReference = generated$7.tsExternalModuleReference = tsExternalModuleReference; + generated$7.tSNonNullExpression = generated$7.tsNonNullExpression = tsNonNullExpression; + generated$7.tSExportAssignment = generated$7.tsExportAssignment = tsExportAssignment; + generated$7.tSNamespaceExportDeclaration = generated$7.tsNamespaceExportDeclaration = tsNamespaceExportDeclaration; + generated$7.tSTypeAnnotation = generated$7.tsTypeAnnotation = tsTypeAnnotation; + generated$7.tSTypeParameterInstantiation = generated$7.tsTypeParameterInstantiation = tsTypeParameterInstantiation; + generated$7.tSTypeParameterDeclaration = generated$7.tsTypeParameterDeclaration = tsTypeParameterDeclaration; + generated$7.tSTypeParameter = generated$7.tsTypeParameter = tsTypeParameter; + generated$7.numberLiteral = NumberLiteral$1; + generated$7.regexLiteral = RegexLiteral$1; + generated$7.restProperty = RestProperty$1; + generated$7.spreadProperty = SpreadProperty$1; + + var _builder$1 = builder$3; + + function arrayExpression(elements) { + return (0, _builder$1.default)("ArrayExpression", ...arguments); + } + + function assignmentExpression(operator, left, right) { + return (0, _builder$1.default)("AssignmentExpression", ...arguments); + } + + function binaryExpression(operator, left, right) { + return (0, _builder$1.default)("BinaryExpression", ...arguments); + } + + function interpreterDirective(value) { + return (0, _builder$1.default)("InterpreterDirective", ...arguments); + } + + function directive(value) { + return (0, _builder$1.default)("Directive", ...arguments); + } + + function directiveLiteral(value) { + return (0, _builder$1.default)("DirectiveLiteral", ...arguments); + } + + function blockStatement(body, directives) { + return (0, _builder$1.default)("BlockStatement", ...arguments); + } + + function breakStatement(label) { + return (0, _builder$1.default)("BreakStatement", ...arguments); + } + + function callExpression(callee, _arguments) { + return (0, _builder$1.default)("CallExpression", ...arguments); + } + + function catchClause(param, body) { + return (0, _builder$1.default)("CatchClause", ...arguments); + } + + function conditionalExpression(test, consequent, alternate) { + return (0, _builder$1.default)("ConditionalExpression", ...arguments); + } + + function continueStatement(label) { + return (0, _builder$1.default)("ContinueStatement", ...arguments); + } + + function debuggerStatement() { + return (0, _builder$1.default)("DebuggerStatement", ...arguments); + } + + function doWhileStatement(test, body) { + return (0, _builder$1.default)("DoWhileStatement", ...arguments); + } + + function emptyStatement() { + return (0, _builder$1.default)("EmptyStatement", ...arguments); + } + + function expressionStatement(expression) { + return (0, _builder$1.default)("ExpressionStatement", ...arguments); + } + + function file(program, comments, tokens) { + return (0, _builder$1.default)("File", ...arguments); + } + + function forInStatement(left, right, body) { + return (0, _builder$1.default)("ForInStatement", ...arguments); + } + + function forStatement(init, test, update, body) { + return (0, _builder$1.default)("ForStatement", ...arguments); + } + + function functionDeclaration(id, params, body, generator, async) { + return (0, _builder$1.default)("FunctionDeclaration", ...arguments); + } + + function functionExpression(id, params, body, generator, async) { + return (0, _builder$1.default)("FunctionExpression", ...arguments); + } + + function identifier$1(name) { + return (0, _builder$1.default)("Identifier", ...arguments); + } + + function ifStatement(test, consequent, alternate) { + return (0, _builder$1.default)("IfStatement", ...arguments); + } + + function labeledStatement(label, body) { + return (0, _builder$1.default)("LabeledStatement", ...arguments); + } + + function stringLiteral(value) { + return (0, _builder$1.default)("StringLiteral", ...arguments); + } + + function numericLiteral(value) { + return (0, _builder$1.default)("NumericLiteral", ...arguments); + } + + function nullLiteral() { + return (0, _builder$1.default)("NullLiteral", ...arguments); + } + + function booleanLiteral(value) { + return (0, _builder$1.default)("BooleanLiteral", ...arguments); + } + + function regExpLiteral(pattern, flags) { + return (0, _builder$1.default)("RegExpLiteral", ...arguments); + } + + function logicalExpression(operator, left, right) { + return (0, _builder$1.default)("LogicalExpression", ...arguments); + } + + function memberExpression(object, property, computed, optional) { + return (0, _builder$1.default)("MemberExpression", ...arguments); + } + + function newExpression(callee, _arguments) { + return (0, _builder$1.default)("NewExpression", ...arguments); + } + + function program(body, directives, sourceType, interpreter) { + return (0, _builder$1.default)("Program", ...arguments); + } + + function objectExpression(properties) { + return (0, _builder$1.default)("ObjectExpression", ...arguments); + } + + function objectMethod(kind, key, params, body, computed, generator, async) { + return (0, _builder$1.default)("ObjectMethod", ...arguments); + } + + function objectProperty(key, value, computed, shorthand, decorators) { + return (0, _builder$1.default)("ObjectProperty", ...arguments); + } + + function restElement(argument) { + return (0, _builder$1.default)("RestElement", ...arguments); + } + + function returnStatement(argument) { + return (0, _builder$1.default)("ReturnStatement", ...arguments); + } + + function sequenceExpression(expressions) { + return (0, _builder$1.default)("SequenceExpression", ...arguments); + } + + function parenthesizedExpression(expression) { + return (0, _builder$1.default)("ParenthesizedExpression", ...arguments); + } + + function switchCase(test, consequent) { + return (0, _builder$1.default)("SwitchCase", ...arguments); + } + + function switchStatement(discriminant, cases) { + return (0, _builder$1.default)("SwitchStatement", ...arguments); + } + + function thisExpression() { + return (0, _builder$1.default)("ThisExpression", ...arguments); + } + + function throwStatement(argument) { + return (0, _builder$1.default)("ThrowStatement", ...arguments); + } + + function tryStatement(block, handler, finalizer) { + return (0, _builder$1.default)("TryStatement", ...arguments); + } + + function unaryExpression(operator, argument, prefix) { + return (0, _builder$1.default)("UnaryExpression", ...arguments); + } + + function updateExpression(operator, argument, prefix) { + return (0, _builder$1.default)("UpdateExpression", ...arguments); + } + + function variableDeclaration(kind, declarations) { + return (0, _builder$1.default)("VariableDeclaration", ...arguments); + } + + function variableDeclarator(id, init) { + return (0, _builder$1.default)("VariableDeclarator", ...arguments); + } + + function whileStatement(test, body) { + return (0, _builder$1.default)("WhileStatement", ...arguments); + } + + function withStatement(object, body) { + return (0, _builder$1.default)("WithStatement", ...arguments); + } + + function assignmentPattern(left, right) { + return (0, _builder$1.default)("AssignmentPattern", ...arguments); + } + + function arrayPattern(elements) { + return (0, _builder$1.default)("ArrayPattern", ...arguments); + } + + function arrowFunctionExpression(params, body, async) { + return (0, _builder$1.default)("ArrowFunctionExpression", ...arguments); + } + + function classBody(body) { + return (0, _builder$1.default)("ClassBody", ...arguments); + } + + function classExpression(id, superClass, body, decorators) { + return (0, _builder$1.default)("ClassExpression", ...arguments); + } + + function classDeclaration(id, superClass, body, decorators) { + return (0, _builder$1.default)("ClassDeclaration", ...arguments); + } + + function exportAllDeclaration(source) { + return (0, _builder$1.default)("ExportAllDeclaration", ...arguments); + } + + function exportDefaultDeclaration(declaration) { + return (0, _builder$1.default)("ExportDefaultDeclaration", ...arguments); + } + + function exportNamedDeclaration(declaration, specifiers, source) { + return (0, _builder$1.default)("ExportNamedDeclaration", ...arguments); + } + + function exportSpecifier(local, exported) { + return (0, _builder$1.default)("ExportSpecifier", ...arguments); + } + + function forOfStatement(left, right, body, _await) { + return (0, _builder$1.default)("ForOfStatement", ...arguments); + } + + function importDeclaration(specifiers, source) { + return (0, _builder$1.default)("ImportDeclaration", ...arguments); + } + + function importDefaultSpecifier(local) { + return (0, _builder$1.default)("ImportDefaultSpecifier", ...arguments); + } + + function importNamespaceSpecifier(local) { + return (0, _builder$1.default)("ImportNamespaceSpecifier", ...arguments); + } + + function importSpecifier(local, imported) { + return (0, _builder$1.default)("ImportSpecifier", ...arguments); + } + + function metaProperty(meta, property) { + return (0, _builder$1.default)("MetaProperty", ...arguments); + } + + function classMethod(kind, key, params, body, computed, _static, generator, async) { + return (0, _builder$1.default)("ClassMethod", ...arguments); + } + + function objectPattern(properties) { + return (0, _builder$1.default)("ObjectPattern", ...arguments); + } + + function spreadElement(argument) { + return (0, _builder$1.default)("SpreadElement", ...arguments); + } + + function _super() { + return (0, _builder$1.default)("Super", ...arguments); + } + + function taggedTemplateExpression(tag, quasi) { + return (0, _builder$1.default)("TaggedTemplateExpression", ...arguments); + } + + function templateElement(value, tail) { + return (0, _builder$1.default)("TemplateElement", ...arguments); + } + + function templateLiteral(quasis, expressions) { + return (0, _builder$1.default)("TemplateLiteral", ...arguments); + } + + function yieldExpression(argument, delegate) { + return (0, _builder$1.default)("YieldExpression", ...arguments); + } + + function awaitExpression(argument) { + return (0, _builder$1.default)("AwaitExpression", ...arguments); + } + + function _import() { + return (0, _builder$1.default)("Import", ...arguments); + } + + function bigIntLiteral(value) { + return (0, _builder$1.default)("BigIntLiteral", ...arguments); + } + + function exportNamespaceSpecifier(exported) { + return (0, _builder$1.default)("ExportNamespaceSpecifier", ...arguments); + } + + function optionalMemberExpression(object, property, computed, optional) { + return (0, _builder$1.default)("OptionalMemberExpression", ...arguments); + } + + function optionalCallExpression(callee, _arguments, optional) { + return (0, _builder$1.default)("OptionalCallExpression", ...arguments); + } + + function classProperty(key, value, typeAnnotation, decorators, computed, _static) { + return (0, _builder$1.default)("ClassProperty", ...arguments); + } + + function classPrivateProperty(key, value, decorators, _static) { + return (0, _builder$1.default)("ClassPrivateProperty", ...arguments); + } + + function classPrivateMethod(kind, key, params, body, _static) { + return (0, _builder$1.default)("ClassPrivateMethod", ...arguments); + } + + function privateName(id) { + return (0, _builder$1.default)("PrivateName", ...arguments); + } + + function anyTypeAnnotation() { + return (0, _builder$1.default)("AnyTypeAnnotation", ...arguments); + } + + function arrayTypeAnnotation(elementType) { + return (0, _builder$1.default)("ArrayTypeAnnotation", ...arguments); + } + + function booleanTypeAnnotation() { + return (0, _builder$1.default)("BooleanTypeAnnotation", ...arguments); + } + + function booleanLiteralTypeAnnotation(value) { + return (0, _builder$1.default)("BooleanLiteralTypeAnnotation", ...arguments); + } + + function nullLiteralTypeAnnotation() { + return (0, _builder$1.default)("NullLiteralTypeAnnotation", ...arguments); + } + + function classImplements(id, typeParameters) { + return (0, _builder$1.default)("ClassImplements", ...arguments); + } + + function declareClass(id, typeParameters, _extends, body) { + return (0, _builder$1.default)("DeclareClass", ...arguments); + } + + function declareFunction(id) { + return (0, _builder$1.default)("DeclareFunction", ...arguments); + } + + function declareInterface(id, typeParameters, _extends, body) { + return (0, _builder$1.default)("DeclareInterface", ...arguments); + } + + function declareModule(id, body, kind) { + return (0, _builder$1.default)("DeclareModule", ...arguments); + } + + function declareModuleExports(typeAnnotation) { + return (0, _builder$1.default)("DeclareModuleExports", ...arguments); + } + + function declareTypeAlias(id, typeParameters, right) { + return (0, _builder$1.default)("DeclareTypeAlias", ...arguments); + } + + function declareOpaqueType(id, typeParameters, supertype) { + return (0, _builder$1.default)("DeclareOpaqueType", ...arguments); + } + + function declareVariable(id) { + return (0, _builder$1.default)("DeclareVariable", ...arguments); + } + + function declareExportDeclaration(declaration, specifiers, source) { + return (0, _builder$1.default)("DeclareExportDeclaration", ...arguments); + } + + function declareExportAllDeclaration(source) { + return (0, _builder$1.default)("DeclareExportAllDeclaration", ...arguments); + } + + function declaredPredicate(value) { + return (0, _builder$1.default)("DeclaredPredicate", ...arguments); + } + + function existsTypeAnnotation() { + return (0, _builder$1.default)("ExistsTypeAnnotation", ...arguments); + } + + function functionTypeAnnotation(typeParameters, params, rest, returnType) { + return (0, _builder$1.default)("FunctionTypeAnnotation", ...arguments); + } + + function functionTypeParam(name, typeAnnotation) { + return (0, _builder$1.default)("FunctionTypeParam", ...arguments); + } + + function genericTypeAnnotation(id, typeParameters) { + return (0, _builder$1.default)("GenericTypeAnnotation", ...arguments); + } + + function inferredPredicate() { + return (0, _builder$1.default)("InferredPredicate", ...arguments); + } + + function interfaceExtends(id, typeParameters) { + return (0, _builder$1.default)("InterfaceExtends", ...arguments); + } + + function interfaceDeclaration(id, typeParameters, _extends, body) { + return (0, _builder$1.default)("InterfaceDeclaration", ...arguments); + } + + function interfaceTypeAnnotation(_extends, body) { + return (0, _builder$1.default)("InterfaceTypeAnnotation", ...arguments); + } + + function intersectionTypeAnnotation(types) { + return (0, _builder$1.default)("IntersectionTypeAnnotation", ...arguments); + } + + function mixedTypeAnnotation() { + return (0, _builder$1.default)("MixedTypeAnnotation", ...arguments); + } + + function emptyTypeAnnotation() { + return (0, _builder$1.default)("EmptyTypeAnnotation", ...arguments); + } + + function nullableTypeAnnotation(typeAnnotation) { + return (0, _builder$1.default)("NullableTypeAnnotation", ...arguments); + } + + function numberLiteralTypeAnnotation(value) { + return (0, _builder$1.default)("NumberLiteralTypeAnnotation", ...arguments); + } + + function numberTypeAnnotation() { + return (0, _builder$1.default)("NumberTypeAnnotation", ...arguments); + } + + function objectTypeAnnotation(properties, indexers, callProperties, internalSlots, exact) { + return (0, _builder$1.default)("ObjectTypeAnnotation", ...arguments); + } + + function objectTypeInternalSlot(id, value, optional, _static, method) { + return (0, _builder$1.default)("ObjectTypeInternalSlot", ...arguments); + } + + function objectTypeCallProperty(value) { + return (0, _builder$1.default)("ObjectTypeCallProperty", ...arguments); + } + + function objectTypeIndexer(id, key, value, variance) { + return (0, _builder$1.default)("ObjectTypeIndexer", ...arguments); + } + + function objectTypeProperty(key, value, variance) { + return (0, _builder$1.default)("ObjectTypeProperty", ...arguments); + } + + function objectTypeSpreadProperty(argument) { + return (0, _builder$1.default)("ObjectTypeSpreadProperty", ...arguments); + } + + function opaqueType(id, typeParameters, supertype, impltype) { + return (0, _builder$1.default)("OpaqueType", ...arguments); + } + + function qualifiedTypeIdentifier(id, qualification) { + return (0, _builder$1.default)("QualifiedTypeIdentifier", ...arguments); + } + + function stringLiteralTypeAnnotation(value) { + return (0, _builder$1.default)("StringLiteralTypeAnnotation", ...arguments); + } + + function stringTypeAnnotation() { + return (0, _builder$1.default)("StringTypeAnnotation", ...arguments); + } + + function symbolTypeAnnotation() { + return (0, _builder$1.default)("SymbolTypeAnnotation", ...arguments); + } + + function thisTypeAnnotation() { + return (0, _builder$1.default)("ThisTypeAnnotation", ...arguments); + } + + function tupleTypeAnnotation(types) { + return (0, _builder$1.default)("TupleTypeAnnotation", ...arguments); + } + + function typeofTypeAnnotation(argument) { + return (0, _builder$1.default)("TypeofTypeAnnotation", ...arguments); + } + + function typeAlias(id, typeParameters, right) { + return (0, _builder$1.default)("TypeAlias", ...arguments); + } + + function typeAnnotation(typeAnnotation) { + return (0, _builder$1.default)("TypeAnnotation", ...arguments); + } + + function typeCastExpression(expression, typeAnnotation) { + return (0, _builder$1.default)("TypeCastExpression", ...arguments); + } + + function typeParameter(bound, _default, variance) { + return (0, _builder$1.default)("TypeParameter", ...arguments); + } + + function typeParameterDeclaration(params) { + return (0, _builder$1.default)("TypeParameterDeclaration", ...arguments); + } + + function typeParameterInstantiation(params) { + return (0, _builder$1.default)("TypeParameterInstantiation", ...arguments); + } + + function unionTypeAnnotation(types) { + return (0, _builder$1.default)("UnionTypeAnnotation", ...arguments); + } + + function variance(kind) { + return (0, _builder$1.default)("Variance", ...arguments); + } + + function voidTypeAnnotation() { + return (0, _builder$1.default)("VoidTypeAnnotation", ...arguments); + } + + function enumDeclaration(id, body) { + return (0, _builder$1.default)("EnumDeclaration", ...arguments); + } + + function enumBooleanBody(members) { + return (0, _builder$1.default)("EnumBooleanBody", ...arguments); + } + + function enumNumberBody(members) { + return (0, _builder$1.default)("EnumNumberBody", ...arguments); + } + + function enumStringBody(members) { + return (0, _builder$1.default)("EnumStringBody", ...arguments); + } + + function enumSymbolBody(members) { + return (0, _builder$1.default)("EnumSymbolBody", ...arguments); + } + + function enumBooleanMember(id) { + return (0, _builder$1.default)("EnumBooleanMember", ...arguments); + } + + function enumNumberMember(id, init) { + return (0, _builder$1.default)("EnumNumberMember", ...arguments); + } + + function enumStringMember(id, init) { + return (0, _builder$1.default)("EnumStringMember", ...arguments); + } + + function enumDefaultedMember(id) { + return (0, _builder$1.default)("EnumDefaultedMember", ...arguments); + } + + function indexedAccessType(objectType, indexType) { + return (0, _builder$1.default)("IndexedAccessType", ...arguments); + } + + function optionalIndexedAccessType(objectType, indexType) { + return (0, _builder$1.default)("OptionalIndexedAccessType", ...arguments); + } + + function jsxAttribute(name, value) { + return (0, _builder$1.default)("JSXAttribute", ...arguments); + } + + function jsxClosingElement(name) { + return (0, _builder$1.default)("JSXClosingElement", ...arguments); + } + + function jsxElement(openingElement, closingElement, children, selfClosing) { + return (0, _builder$1.default)("JSXElement", ...arguments); + } + + function jsxEmptyExpression() { + return (0, _builder$1.default)("JSXEmptyExpression", ...arguments); + } + + function jsxExpressionContainer(expression) { + return (0, _builder$1.default)("JSXExpressionContainer", ...arguments); + } + + function jsxSpreadChild(expression) { + return (0, _builder$1.default)("JSXSpreadChild", ...arguments); + } + + function jsxIdentifier(name) { + return (0, _builder$1.default)("JSXIdentifier", ...arguments); + } + + function jsxMemberExpression(object, property) { + return (0, _builder$1.default)("JSXMemberExpression", ...arguments); + } + + function jsxNamespacedName(namespace, name) { + return (0, _builder$1.default)("JSXNamespacedName", ...arguments); + } + + function jsxOpeningElement(name, attributes, selfClosing) { + return (0, _builder$1.default)("JSXOpeningElement", ...arguments); + } + + function jsxSpreadAttribute(argument) { + return (0, _builder$1.default)("JSXSpreadAttribute", ...arguments); + } + + function jsxText(value) { + return (0, _builder$1.default)("JSXText", ...arguments); + } + + function jsxFragment(openingFragment, closingFragment, children) { + return (0, _builder$1.default)("JSXFragment", ...arguments); + } + + function jsxOpeningFragment() { + return (0, _builder$1.default)("JSXOpeningFragment", ...arguments); + } + + function jsxClosingFragment() { + return (0, _builder$1.default)("JSXClosingFragment", ...arguments); + } + + function noop$2() { + return (0, _builder$1.default)("Noop", ...arguments); + } + + function placeholder(expectedNode, name) { + return (0, _builder$1.default)("Placeholder", ...arguments); + } + + function v8IntrinsicIdentifier(name) { + return (0, _builder$1.default)("V8IntrinsicIdentifier", ...arguments); + } + + function argumentPlaceholder() { + return (0, _builder$1.default)("ArgumentPlaceholder", ...arguments); + } + + function bindExpression(object, callee) { + return (0, _builder$1.default)("BindExpression", ...arguments); + } + + function importAttribute(key, value) { + return (0, _builder$1.default)("ImportAttribute", ...arguments); + } + + function decorator(expression) { + return (0, _builder$1.default)("Decorator", ...arguments); + } + + function doExpression(body, async) { + return (0, _builder$1.default)("DoExpression", ...arguments); + } + + function exportDefaultSpecifier(exported) { + return (0, _builder$1.default)("ExportDefaultSpecifier", ...arguments); + } + + function recordExpression(properties) { + return (0, _builder$1.default)("RecordExpression", ...arguments); + } + + function tupleExpression(elements) { + return (0, _builder$1.default)("TupleExpression", ...arguments); + } + + function decimalLiteral(value) { + return (0, _builder$1.default)("DecimalLiteral", ...arguments); + } + + function staticBlock(body) { + return (0, _builder$1.default)("StaticBlock", ...arguments); + } + + function moduleExpression(body) { + return (0, _builder$1.default)("ModuleExpression", ...arguments); + } + + function topicReference() { + return (0, _builder$1.default)("TopicReference", ...arguments); + } + + function pipelineTopicExpression(expression) { + return (0, _builder$1.default)("PipelineTopicExpression", ...arguments); + } + + function pipelineBareFunction(callee) { + return (0, _builder$1.default)("PipelineBareFunction", ...arguments); + } + + function pipelinePrimaryTopicReference() { + return (0, _builder$1.default)("PipelinePrimaryTopicReference", ...arguments); + } + + function tsParameterProperty(parameter) { + return (0, _builder$1.default)("TSParameterProperty", ...arguments); + } + + function tsDeclareFunction(id, typeParameters, params, returnType) { + return (0, _builder$1.default)("TSDeclareFunction", ...arguments); + } + + function tsDeclareMethod(decorators, key, typeParameters, params, returnType) { + return (0, _builder$1.default)("TSDeclareMethod", ...arguments); + } + + function tsQualifiedName(left, right) { + return (0, _builder$1.default)("TSQualifiedName", ...arguments); + } + + function tsCallSignatureDeclaration(typeParameters, parameters, typeAnnotation) { + return (0, _builder$1.default)("TSCallSignatureDeclaration", ...arguments); + } + + function tsConstructSignatureDeclaration(typeParameters, parameters, typeAnnotation) { + return (0, _builder$1.default)("TSConstructSignatureDeclaration", ...arguments); + } + + function tsPropertySignature(key, typeAnnotation, initializer) { + return (0, _builder$1.default)("TSPropertySignature", ...arguments); + } + + function tsMethodSignature(key, typeParameters, parameters, typeAnnotation) { + return (0, _builder$1.default)("TSMethodSignature", ...arguments); + } + + function tsIndexSignature(parameters, typeAnnotation) { + return (0, _builder$1.default)("TSIndexSignature", ...arguments); + } + + function tsAnyKeyword() { + return (0, _builder$1.default)("TSAnyKeyword", ...arguments); + } + + function tsBooleanKeyword() { + return (0, _builder$1.default)("TSBooleanKeyword", ...arguments); + } + + function tsBigIntKeyword() { + return (0, _builder$1.default)("TSBigIntKeyword", ...arguments); + } + + function tsIntrinsicKeyword() { + return (0, _builder$1.default)("TSIntrinsicKeyword", ...arguments); + } + + function tsNeverKeyword() { + return (0, _builder$1.default)("TSNeverKeyword", ...arguments); + } + + function tsNullKeyword() { + return (0, _builder$1.default)("TSNullKeyword", ...arguments); + } + + function tsNumberKeyword() { + return (0, _builder$1.default)("TSNumberKeyword", ...arguments); + } + + function tsObjectKeyword() { + return (0, _builder$1.default)("TSObjectKeyword", ...arguments); + } + + function tsStringKeyword() { + return (0, _builder$1.default)("TSStringKeyword", ...arguments); + } + + function tsSymbolKeyword() { + return (0, _builder$1.default)("TSSymbolKeyword", ...arguments); + } + + function tsUndefinedKeyword() { + return (0, _builder$1.default)("TSUndefinedKeyword", ...arguments); + } + + function tsUnknownKeyword() { + return (0, _builder$1.default)("TSUnknownKeyword", ...arguments); + } + + function tsVoidKeyword() { + return (0, _builder$1.default)("TSVoidKeyword", ...arguments); + } + + function tsThisType() { + return (0, _builder$1.default)("TSThisType", ...arguments); + } + + function tsFunctionType(typeParameters, parameters, typeAnnotation) { + return (0, _builder$1.default)("TSFunctionType", ...arguments); + } + + function tsConstructorType(typeParameters, parameters, typeAnnotation) { + return (0, _builder$1.default)("TSConstructorType", ...arguments); + } + + function tsTypeReference(typeName, typeParameters) { + return (0, _builder$1.default)("TSTypeReference", ...arguments); + } + + function tsTypePredicate(parameterName, typeAnnotation, asserts) { + return (0, _builder$1.default)("TSTypePredicate", ...arguments); + } + + function tsTypeQuery(exprName) { + return (0, _builder$1.default)("TSTypeQuery", ...arguments); + } + + function tsTypeLiteral(members) { + return (0, _builder$1.default)("TSTypeLiteral", ...arguments); + } + + function tsArrayType(elementType) { + return (0, _builder$1.default)("TSArrayType", ...arguments); + } + + function tsTupleType(elementTypes) { + return (0, _builder$1.default)("TSTupleType", ...arguments); + } + + function tsOptionalType(typeAnnotation) { + return (0, _builder$1.default)("TSOptionalType", ...arguments); + } + + function tsRestType(typeAnnotation) { + return (0, _builder$1.default)("TSRestType", ...arguments); + } + + function tsNamedTupleMember(label, elementType, optional) { + return (0, _builder$1.default)("TSNamedTupleMember", ...arguments); + } + + function tsUnionType(types) { + return (0, _builder$1.default)("TSUnionType", ...arguments); + } + + function tsIntersectionType(types) { + return (0, _builder$1.default)("TSIntersectionType", ...arguments); + } + + function tsConditionalType(checkType, extendsType, trueType, falseType) { + return (0, _builder$1.default)("TSConditionalType", ...arguments); + } + + function tsInferType(typeParameter) { + return (0, _builder$1.default)("TSInferType", ...arguments); + } + + function tsParenthesizedType(typeAnnotation) { + return (0, _builder$1.default)("TSParenthesizedType", ...arguments); + } + + function tsTypeOperator(typeAnnotation) { + return (0, _builder$1.default)("TSTypeOperator", ...arguments); + } + + function tsIndexedAccessType(objectType, indexType) { + return (0, _builder$1.default)("TSIndexedAccessType", ...arguments); + } + + function tsMappedType(typeParameter, typeAnnotation, nameType) { + return (0, _builder$1.default)("TSMappedType", ...arguments); + } + + function tsLiteralType(literal) { + return (0, _builder$1.default)("TSLiteralType", ...arguments); + } + + function tsExpressionWithTypeArguments(expression, typeParameters) { + return (0, _builder$1.default)("TSExpressionWithTypeArguments", ...arguments); + } + + function tsInterfaceDeclaration(id, typeParameters, _extends, body) { + return (0, _builder$1.default)("TSInterfaceDeclaration", ...arguments); + } + + function tsInterfaceBody(body) { + return (0, _builder$1.default)("TSInterfaceBody", ...arguments); + } + + function tsTypeAliasDeclaration(id, typeParameters, typeAnnotation) { + return (0, _builder$1.default)("TSTypeAliasDeclaration", ...arguments); + } + + function tsAsExpression(expression, typeAnnotation) { + return (0, _builder$1.default)("TSAsExpression", ...arguments); + } + + function tsTypeAssertion(typeAnnotation, expression) { + return (0, _builder$1.default)("TSTypeAssertion", ...arguments); + } + + function tsEnumDeclaration(id, members) { + return (0, _builder$1.default)("TSEnumDeclaration", ...arguments); + } + + function tsEnumMember(id, initializer) { + return (0, _builder$1.default)("TSEnumMember", ...arguments); + } + + function tsModuleDeclaration(id, body) { + return (0, _builder$1.default)("TSModuleDeclaration", ...arguments); + } + + function tsModuleBlock(body) { + return (0, _builder$1.default)("TSModuleBlock", ...arguments); + } + + function tsImportType(argument, qualifier, typeParameters) { + return (0, _builder$1.default)("TSImportType", ...arguments); + } + + function tsImportEqualsDeclaration(id, moduleReference) { + return (0, _builder$1.default)("TSImportEqualsDeclaration", ...arguments); + } + + function tsExternalModuleReference(expression) { + return (0, _builder$1.default)("TSExternalModuleReference", ...arguments); + } + + function tsNonNullExpression(expression) { + return (0, _builder$1.default)("TSNonNullExpression", ...arguments); + } + + function tsExportAssignment(expression) { + return (0, _builder$1.default)("TSExportAssignment", ...arguments); + } + + function tsNamespaceExportDeclaration(id) { + return (0, _builder$1.default)("TSNamespaceExportDeclaration", ...arguments); + } + + function tsTypeAnnotation(typeAnnotation) { + return (0, _builder$1.default)("TSTypeAnnotation", ...arguments); + } + + function tsTypeParameterInstantiation(params) { + return (0, _builder$1.default)("TSTypeParameterInstantiation", ...arguments); + } + + function tsTypeParameterDeclaration(params) { + return (0, _builder$1.default)("TSTypeParameterDeclaration", ...arguments); + } + + function tsTypeParameter(constraint, _default, name) { + return (0, _builder$1.default)("TSTypeParameter", ...arguments); + } + + function NumberLiteral$1(...args) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + return (0, _builder$1.default)("NumberLiteral", ...args); + } + + function RegexLiteral$1(...args) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + return (0, _builder$1.default)("RegexLiteral", ...args); + } + + function RestProperty$1(...args) { + console.trace("The node type RestProperty has been renamed to RestElement"); + return (0, _builder$1.default)("RestProperty", ...args); + } + + function SpreadProperty$1(...args) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + return (0, _builder$1.default)("SpreadProperty", ...args); + } + + Object.defineProperty(cleanJSXElementLiteralChild$3, "__esModule", { + value: true + }); + cleanJSXElementLiteralChild$3.default = cleanJSXElementLiteralChild$2; + + var _generated$L = generated$7; + + function cleanJSXElementLiteralChild$2(child, args) { + const lines = child.value.split(/\r\n|\n|\r/); + let lastNonEmptyLine = 0; + + for (let i = 0; i < lines.length; i++) { + if (lines[i].match(/[^ \t]/)) { + lastNonEmptyLine = i; + } + } + + let str = ""; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const isFirstLine = i === 0; + const isLastLine = i === lines.length - 1; + const isLastNonEmptyLine = i === lastNonEmptyLine; + let trimmedLine = line.replace(/\t/g, " "); + + if (!isFirstLine) { + trimmedLine = trimmedLine.replace(/^[ ]+/, ""); + } + + if (!isLastLine) { + trimmedLine = trimmedLine.replace(/[ ]+$/, ""); + } + + if (trimmedLine) { + if (!isLastNonEmptyLine) { + trimmedLine += " "; + } + + str += trimmedLine; + } + } + + if (str) args.push((0, _generated$L.stringLiteral)(str)); + } + + Object.defineProperty(buildChildren$3, "__esModule", { + value: true + }); + buildChildren$3.default = buildChildren$2; + + var _generated$K = generated$8; + + var _cleanJSXElementLiteralChild$1 = cleanJSXElementLiteralChild$3; + + function buildChildren$2(node) { + const elements = []; + + for (let i = 0; i < node.children.length; i++) { + let child = node.children[i]; + + if ((0, _generated$K.isJSXText)(child)) { + (0, _cleanJSXElementLiteralChild$1.default)(child, elements); + continue; + } + + if ((0, _generated$K.isJSXExpressionContainer)(child)) child = child.expression; + if ((0, _generated$K.isJSXEmptyExpression)(child)) continue; + elements.push(child); + } + + return elements; + } + + var assertNode$3 = {}; + + var isNode$4 = {}; + + Object.defineProperty(isNode$4, "__esModule", { + value: true + }); + isNode$4.default = isNode$3; + + var _definitions$c = requireDefinitions$1(); + + function isNode$3(node) { + return !!(node && _definitions$c.VISITOR_KEYS[node.type]); + } + + Object.defineProperty(assertNode$3, "__esModule", { + value: true + }); + assertNode$3.default = assertNode$2; + + var _isNode$1 = isNode$4; + + function assertNode$2(node) { + if (!(0, _isNode$1.default)(node)) { + var _node$type; + + const type = (_node$type = node == null ? void 0 : node.type) != null ? _node$type : JSON.stringify(node); + throw new TypeError(`Not a valid node of type "${type}"`); + } + } + + var generated$6 = {}; + + Object.defineProperty(generated$6, "__esModule", { + value: true + }); + generated$6.assertArrayExpression = assertArrayExpression$1; + generated$6.assertAssignmentExpression = assertAssignmentExpression$1; + generated$6.assertBinaryExpression = assertBinaryExpression$1; + generated$6.assertInterpreterDirective = assertInterpreterDirective$1; + generated$6.assertDirective = assertDirective$1; + generated$6.assertDirectiveLiteral = assertDirectiveLiteral$1; + generated$6.assertBlockStatement = assertBlockStatement$1; + generated$6.assertBreakStatement = assertBreakStatement$1; + generated$6.assertCallExpression = assertCallExpression$1; + generated$6.assertCatchClause = assertCatchClause$1; + generated$6.assertConditionalExpression = assertConditionalExpression$1; + generated$6.assertContinueStatement = assertContinueStatement$1; + generated$6.assertDebuggerStatement = assertDebuggerStatement$1; + generated$6.assertDoWhileStatement = assertDoWhileStatement$1; + generated$6.assertEmptyStatement = assertEmptyStatement$1; + generated$6.assertExpressionStatement = assertExpressionStatement$1; + generated$6.assertFile = assertFile$1; + generated$6.assertForInStatement = assertForInStatement$1; + generated$6.assertForStatement = assertForStatement$1; + generated$6.assertFunctionDeclaration = assertFunctionDeclaration$1; + generated$6.assertFunctionExpression = assertFunctionExpression$1; + generated$6.assertIdentifier = assertIdentifier$1; + generated$6.assertIfStatement = assertIfStatement$1; + generated$6.assertLabeledStatement = assertLabeledStatement$1; + generated$6.assertStringLiteral = assertStringLiteral$1; + generated$6.assertNumericLiteral = assertNumericLiteral$1; + generated$6.assertNullLiteral = assertNullLiteral$1; + generated$6.assertBooleanLiteral = assertBooleanLiteral$1; + generated$6.assertRegExpLiteral = assertRegExpLiteral$1; + generated$6.assertLogicalExpression = assertLogicalExpression$1; + generated$6.assertMemberExpression = assertMemberExpression$1; + generated$6.assertNewExpression = assertNewExpression$1; + generated$6.assertProgram = assertProgram$1; + generated$6.assertObjectExpression = assertObjectExpression$1; + generated$6.assertObjectMethod = assertObjectMethod$1; + generated$6.assertObjectProperty = assertObjectProperty$1; + generated$6.assertRestElement = assertRestElement$1; + generated$6.assertReturnStatement = assertReturnStatement$1; + generated$6.assertSequenceExpression = assertSequenceExpression$1; + generated$6.assertParenthesizedExpression = assertParenthesizedExpression$1; + generated$6.assertSwitchCase = assertSwitchCase$1; + generated$6.assertSwitchStatement = assertSwitchStatement$1; + generated$6.assertThisExpression = assertThisExpression$1; + generated$6.assertThrowStatement = assertThrowStatement$1; + generated$6.assertTryStatement = assertTryStatement$1; + generated$6.assertUnaryExpression = assertUnaryExpression$1; + generated$6.assertUpdateExpression = assertUpdateExpression$1; + generated$6.assertVariableDeclaration = assertVariableDeclaration$1; + generated$6.assertVariableDeclarator = assertVariableDeclarator$1; + generated$6.assertWhileStatement = assertWhileStatement$1; + generated$6.assertWithStatement = assertWithStatement$1; + generated$6.assertAssignmentPattern = assertAssignmentPattern$1; + generated$6.assertArrayPattern = assertArrayPattern$1; + generated$6.assertArrowFunctionExpression = assertArrowFunctionExpression$1; + generated$6.assertClassBody = assertClassBody$1; + generated$6.assertClassExpression = assertClassExpression$1; + generated$6.assertClassDeclaration = assertClassDeclaration$1; + generated$6.assertExportAllDeclaration = assertExportAllDeclaration$1; + generated$6.assertExportDefaultDeclaration = assertExportDefaultDeclaration$1; + generated$6.assertExportNamedDeclaration = assertExportNamedDeclaration$1; + generated$6.assertExportSpecifier = assertExportSpecifier$1; + generated$6.assertForOfStatement = assertForOfStatement$1; + generated$6.assertImportDeclaration = assertImportDeclaration$1; + generated$6.assertImportDefaultSpecifier = assertImportDefaultSpecifier$1; + generated$6.assertImportNamespaceSpecifier = assertImportNamespaceSpecifier$1; + generated$6.assertImportSpecifier = assertImportSpecifier$1; + generated$6.assertMetaProperty = assertMetaProperty$1; + generated$6.assertClassMethod = assertClassMethod$1; + generated$6.assertObjectPattern = assertObjectPattern$1; + generated$6.assertSpreadElement = assertSpreadElement$1; + generated$6.assertSuper = assertSuper$1; + generated$6.assertTaggedTemplateExpression = assertTaggedTemplateExpression$1; + generated$6.assertTemplateElement = assertTemplateElement$1; + generated$6.assertTemplateLiteral = assertTemplateLiteral$1; + generated$6.assertYieldExpression = assertYieldExpression$1; + generated$6.assertAwaitExpression = assertAwaitExpression$1; + generated$6.assertImport = assertImport$1; + generated$6.assertBigIntLiteral = assertBigIntLiteral$1; + generated$6.assertExportNamespaceSpecifier = assertExportNamespaceSpecifier$1; + generated$6.assertOptionalMemberExpression = assertOptionalMemberExpression$1; + generated$6.assertOptionalCallExpression = assertOptionalCallExpression$1; + generated$6.assertClassProperty = assertClassProperty$1; + generated$6.assertClassPrivateProperty = assertClassPrivateProperty$1; + generated$6.assertClassPrivateMethod = assertClassPrivateMethod$1; + generated$6.assertPrivateName = assertPrivateName$1; + generated$6.assertAnyTypeAnnotation = assertAnyTypeAnnotation$1; + generated$6.assertArrayTypeAnnotation = assertArrayTypeAnnotation$1; + generated$6.assertBooleanTypeAnnotation = assertBooleanTypeAnnotation$1; + generated$6.assertBooleanLiteralTypeAnnotation = assertBooleanLiteralTypeAnnotation$1; + generated$6.assertNullLiteralTypeAnnotation = assertNullLiteralTypeAnnotation$1; + generated$6.assertClassImplements = assertClassImplements$1; + generated$6.assertDeclareClass = assertDeclareClass$1; + generated$6.assertDeclareFunction = assertDeclareFunction$1; + generated$6.assertDeclareInterface = assertDeclareInterface$1; + generated$6.assertDeclareModule = assertDeclareModule$1; + generated$6.assertDeclareModuleExports = assertDeclareModuleExports$1; + generated$6.assertDeclareTypeAlias = assertDeclareTypeAlias$1; + generated$6.assertDeclareOpaqueType = assertDeclareOpaqueType$1; + generated$6.assertDeclareVariable = assertDeclareVariable$1; + generated$6.assertDeclareExportDeclaration = assertDeclareExportDeclaration$1; + generated$6.assertDeclareExportAllDeclaration = assertDeclareExportAllDeclaration$1; + generated$6.assertDeclaredPredicate = assertDeclaredPredicate$1; + generated$6.assertExistsTypeAnnotation = assertExistsTypeAnnotation$1; + generated$6.assertFunctionTypeAnnotation = assertFunctionTypeAnnotation$1; + generated$6.assertFunctionTypeParam = assertFunctionTypeParam$1; + generated$6.assertGenericTypeAnnotation = assertGenericTypeAnnotation$1; + generated$6.assertInferredPredicate = assertInferredPredicate$1; + generated$6.assertInterfaceExtends = assertInterfaceExtends$1; + generated$6.assertInterfaceDeclaration = assertInterfaceDeclaration$1; + generated$6.assertInterfaceTypeAnnotation = assertInterfaceTypeAnnotation$1; + generated$6.assertIntersectionTypeAnnotation = assertIntersectionTypeAnnotation$1; + generated$6.assertMixedTypeAnnotation = assertMixedTypeAnnotation$1; + generated$6.assertEmptyTypeAnnotation = assertEmptyTypeAnnotation$1; + generated$6.assertNullableTypeAnnotation = assertNullableTypeAnnotation$1; + generated$6.assertNumberLiteralTypeAnnotation = assertNumberLiteralTypeAnnotation$1; + generated$6.assertNumberTypeAnnotation = assertNumberTypeAnnotation$1; + generated$6.assertObjectTypeAnnotation = assertObjectTypeAnnotation$1; + generated$6.assertObjectTypeInternalSlot = assertObjectTypeInternalSlot$1; + generated$6.assertObjectTypeCallProperty = assertObjectTypeCallProperty$1; + generated$6.assertObjectTypeIndexer = assertObjectTypeIndexer$1; + generated$6.assertObjectTypeProperty = assertObjectTypeProperty$1; + generated$6.assertObjectTypeSpreadProperty = assertObjectTypeSpreadProperty$1; + generated$6.assertOpaqueType = assertOpaqueType$1; + generated$6.assertQualifiedTypeIdentifier = assertQualifiedTypeIdentifier$1; + generated$6.assertStringLiteralTypeAnnotation = assertStringLiteralTypeAnnotation$1; + generated$6.assertStringTypeAnnotation = assertStringTypeAnnotation$1; + generated$6.assertSymbolTypeAnnotation = assertSymbolTypeAnnotation$1; + generated$6.assertThisTypeAnnotation = assertThisTypeAnnotation$1; + generated$6.assertTupleTypeAnnotation = assertTupleTypeAnnotation$1; + generated$6.assertTypeofTypeAnnotation = assertTypeofTypeAnnotation$1; + generated$6.assertTypeAlias = assertTypeAlias$1; + generated$6.assertTypeAnnotation = assertTypeAnnotation$1; + generated$6.assertTypeCastExpression = assertTypeCastExpression$1; + generated$6.assertTypeParameter = assertTypeParameter$1; + generated$6.assertTypeParameterDeclaration = assertTypeParameterDeclaration$1; + generated$6.assertTypeParameterInstantiation = assertTypeParameterInstantiation$1; + generated$6.assertUnionTypeAnnotation = assertUnionTypeAnnotation$1; + generated$6.assertVariance = assertVariance$1; + generated$6.assertVoidTypeAnnotation = assertVoidTypeAnnotation$1; + generated$6.assertEnumDeclaration = assertEnumDeclaration$1; + generated$6.assertEnumBooleanBody = assertEnumBooleanBody$1; + generated$6.assertEnumNumberBody = assertEnumNumberBody$1; + generated$6.assertEnumStringBody = assertEnumStringBody$1; + generated$6.assertEnumSymbolBody = assertEnumSymbolBody$1; + generated$6.assertEnumBooleanMember = assertEnumBooleanMember$1; + generated$6.assertEnumNumberMember = assertEnumNumberMember$1; + generated$6.assertEnumStringMember = assertEnumStringMember$1; + generated$6.assertEnumDefaultedMember = assertEnumDefaultedMember$1; + generated$6.assertIndexedAccessType = assertIndexedAccessType; + generated$6.assertOptionalIndexedAccessType = assertOptionalIndexedAccessType; + generated$6.assertJSXAttribute = assertJSXAttribute$1; + generated$6.assertJSXClosingElement = assertJSXClosingElement$1; + generated$6.assertJSXElement = assertJSXElement$1; + generated$6.assertJSXEmptyExpression = assertJSXEmptyExpression$1; + generated$6.assertJSXExpressionContainer = assertJSXExpressionContainer$1; + generated$6.assertJSXSpreadChild = assertJSXSpreadChild$1; + generated$6.assertJSXIdentifier = assertJSXIdentifier$1; + generated$6.assertJSXMemberExpression = assertJSXMemberExpression$1; + generated$6.assertJSXNamespacedName = assertJSXNamespacedName$1; + generated$6.assertJSXOpeningElement = assertJSXOpeningElement$1; + generated$6.assertJSXSpreadAttribute = assertJSXSpreadAttribute$1; + generated$6.assertJSXText = assertJSXText$1; + generated$6.assertJSXFragment = assertJSXFragment$1; + generated$6.assertJSXOpeningFragment = assertJSXOpeningFragment$1; + generated$6.assertJSXClosingFragment = assertJSXClosingFragment$1; + generated$6.assertNoop = assertNoop$1; + generated$6.assertPlaceholder = assertPlaceholder$1; + generated$6.assertV8IntrinsicIdentifier = assertV8IntrinsicIdentifier$1; + generated$6.assertArgumentPlaceholder = assertArgumentPlaceholder$1; + generated$6.assertBindExpression = assertBindExpression$1; + generated$6.assertImportAttribute = assertImportAttribute$1; + generated$6.assertDecorator = assertDecorator$1; + generated$6.assertDoExpression = assertDoExpression$1; + generated$6.assertExportDefaultSpecifier = assertExportDefaultSpecifier$1; + generated$6.assertRecordExpression = assertRecordExpression$1; + generated$6.assertTupleExpression = assertTupleExpression$1; + generated$6.assertDecimalLiteral = assertDecimalLiteral; + generated$6.assertStaticBlock = assertStaticBlock; + generated$6.assertModuleExpression = assertModuleExpression; + generated$6.assertTopicReference = assertTopicReference; + generated$6.assertPipelineTopicExpression = assertPipelineTopicExpression$1; + generated$6.assertPipelineBareFunction = assertPipelineBareFunction$1; + generated$6.assertPipelinePrimaryTopicReference = assertPipelinePrimaryTopicReference$1; + generated$6.assertTSParameterProperty = assertTSParameterProperty$1; + generated$6.assertTSDeclareFunction = assertTSDeclareFunction$1; + generated$6.assertTSDeclareMethod = assertTSDeclareMethod$1; + generated$6.assertTSQualifiedName = assertTSQualifiedName$1; + generated$6.assertTSCallSignatureDeclaration = assertTSCallSignatureDeclaration$1; + generated$6.assertTSConstructSignatureDeclaration = assertTSConstructSignatureDeclaration$1; + generated$6.assertTSPropertySignature = assertTSPropertySignature$1; + generated$6.assertTSMethodSignature = assertTSMethodSignature$1; + generated$6.assertTSIndexSignature = assertTSIndexSignature$1; + generated$6.assertTSAnyKeyword = assertTSAnyKeyword$1; + generated$6.assertTSBooleanKeyword = assertTSBooleanKeyword$1; + generated$6.assertTSBigIntKeyword = assertTSBigIntKeyword$1; + generated$6.assertTSIntrinsicKeyword = assertTSIntrinsicKeyword; + generated$6.assertTSNeverKeyword = assertTSNeverKeyword$1; + generated$6.assertTSNullKeyword = assertTSNullKeyword$1; + generated$6.assertTSNumberKeyword = assertTSNumberKeyword$1; + generated$6.assertTSObjectKeyword = assertTSObjectKeyword$1; + generated$6.assertTSStringKeyword = assertTSStringKeyword$1; + generated$6.assertTSSymbolKeyword = assertTSSymbolKeyword$1; + generated$6.assertTSUndefinedKeyword = assertTSUndefinedKeyword$1; + generated$6.assertTSUnknownKeyword = assertTSUnknownKeyword$1; + generated$6.assertTSVoidKeyword = assertTSVoidKeyword$1; + generated$6.assertTSThisType = assertTSThisType$1; + generated$6.assertTSFunctionType = assertTSFunctionType$1; + generated$6.assertTSConstructorType = assertTSConstructorType$1; + generated$6.assertTSTypeReference = assertTSTypeReference$1; + generated$6.assertTSTypePredicate = assertTSTypePredicate$1; + generated$6.assertTSTypeQuery = assertTSTypeQuery$1; + generated$6.assertTSTypeLiteral = assertTSTypeLiteral$1; + generated$6.assertTSArrayType = assertTSArrayType$1; + generated$6.assertTSTupleType = assertTSTupleType$1; + generated$6.assertTSOptionalType = assertTSOptionalType$1; + generated$6.assertTSRestType = assertTSRestType$1; + generated$6.assertTSNamedTupleMember = assertTSNamedTupleMember; + generated$6.assertTSUnionType = assertTSUnionType$1; + generated$6.assertTSIntersectionType = assertTSIntersectionType$1; + generated$6.assertTSConditionalType = assertTSConditionalType$1; + generated$6.assertTSInferType = assertTSInferType$1; + generated$6.assertTSParenthesizedType = assertTSParenthesizedType$1; + generated$6.assertTSTypeOperator = assertTSTypeOperator$1; + generated$6.assertTSIndexedAccessType = assertTSIndexedAccessType$1; + generated$6.assertTSMappedType = assertTSMappedType$1; + generated$6.assertTSLiteralType = assertTSLiteralType$1; + generated$6.assertTSExpressionWithTypeArguments = assertTSExpressionWithTypeArguments$1; + generated$6.assertTSInterfaceDeclaration = assertTSInterfaceDeclaration$1; + generated$6.assertTSInterfaceBody = assertTSInterfaceBody$1; + generated$6.assertTSTypeAliasDeclaration = assertTSTypeAliasDeclaration$1; + generated$6.assertTSAsExpression = assertTSAsExpression$1; + generated$6.assertTSTypeAssertion = assertTSTypeAssertion$1; + generated$6.assertTSEnumDeclaration = assertTSEnumDeclaration$1; + generated$6.assertTSEnumMember = assertTSEnumMember$1; + generated$6.assertTSModuleDeclaration = assertTSModuleDeclaration$1; + generated$6.assertTSModuleBlock = assertTSModuleBlock$1; + generated$6.assertTSImportType = assertTSImportType$1; + generated$6.assertTSImportEqualsDeclaration = assertTSImportEqualsDeclaration$1; + generated$6.assertTSExternalModuleReference = assertTSExternalModuleReference$1; + generated$6.assertTSNonNullExpression = assertTSNonNullExpression$1; + generated$6.assertTSExportAssignment = assertTSExportAssignment$1; + generated$6.assertTSNamespaceExportDeclaration = assertTSNamespaceExportDeclaration$1; + generated$6.assertTSTypeAnnotation = assertTSTypeAnnotation$1; + generated$6.assertTSTypeParameterInstantiation = assertTSTypeParameterInstantiation$1; + generated$6.assertTSTypeParameterDeclaration = assertTSTypeParameterDeclaration$1; + generated$6.assertTSTypeParameter = assertTSTypeParameter$1; + generated$6.assertExpression = assertExpression$1; + generated$6.assertBinary = assertBinary$1; + generated$6.assertScopable = assertScopable$1; + generated$6.assertBlockParent = assertBlockParent$1; + generated$6.assertBlock = assertBlock$1; + generated$6.assertStatement = assertStatement$1; + generated$6.assertTerminatorless = assertTerminatorless$1; + generated$6.assertCompletionStatement = assertCompletionStatement$1; + generated$6.assertConditional = assertConditional$1; + generated$6.assertLoop = assertLoop$1; + generated$6.assertWhile = assertWhile$1; + generated$6.assertExpressionWrapper = assertExpressionWrapper$1; + generated$6.assertFor = assertFor$1; + generated$6.assertForXStatement = assertForXStatement$1; + generated$6.assertFunction = assertFunction$1; + generated$6.assertFunctionParent = assertFunctionParent$1; + generated$6.assertPureish = assertPureish$1; + generated$6.assertDeclaration = assertDeclaration$1; + generated$6.assertPatternLike = assertPatternLike$1; + generated$6.assertLVal = assertLVal$1; + generated$6.assertTSEntityName = assertTSEntityName$1; + generated$6.assertLiteral = assertLiteral$1; + generated$6.assertImmutable = assertImmutable$1; + generated$6.assertUserWhitespacable = assertUserWhitespacable$1; + generated$6.assertMethod = assertMethod$1; + generated$6.assertObjectMember = assertObjectMember$1; + generated$6.assertProperty = assertProperty$1; + generated$6.assertUnaryLike = assertUnaryLike$1; + generated$6.assertPattern = assertPattern$1; + generated$6.assertClass = assertClass$1; + generated$6.assertModuleDeclaration = assertModuleDeclaration$1; + generated$6.assertExportDeclaration = assertExportDeclaration$1; + generated$6.assertModuleSpecifier = assertModuleSpecifier$1; + generated$6.assertPrivate = assertPrivate$1; + generated$6.assertFlow = assertFlow$1; + generated$6.assertFlowType = assertFlowType$1; + generated$6.assertFlowBaseAnnotation = assertFlowBaseAnnotation$1; + generated$6.assertFlowDeclaration = assertFlowDeclaration$1; + generated$6.assertFlowPredicate = assertFlowPredicate$1; + generated$6.assertEnumBody = assertEnumBody$1; + generated$6.assertEnumMember = assertEnumMember$1; + generated$6.assertJSX = assertJSX$1; + generated$6.assertTSTypeElement = assertTSTypeElement$1; + generated$6.assertTSType = assertTSType$1; + generated$6.assertTSBaseType = assertTSBaseType$1; + generated$6.assertNumberLiteral = assertNumberLiteral$1; + generated$6.assertRegexLiteral = assertRegexLiteral$1; + generated$6.assertRestProperty = assertRestProperty$1; + generated$6.assertSpreadProperty = assertSpreadProperty$1; + + var _is$1 = requireIs$1(); + + function assert$3(type, node, opts) { + if (!(0, _is$1.default)(type, node, opts)) { + throw new Error(`Expected type "${type}" with option ${JSON.stringify(opts)}, ` + `but instead got "${node.type}".`); + } + } + + function assertArrayExpression$1(node, opts) { + assert$3("ArrayExpression", node, opts); + } + + function assertAssignmentExpression$1(node, opts) { + assert$3("AssignmentExpression", node, opts); + } + + function assertBinaryExpression$1(node, opts) { + assert$3("BinaryExpression", node, opts); + } + + function assertInterpreterDirective$1(node, opts) { + assert$3("InterpreterDirective", node, opts); + } + + function assertDirective$1(node, opts) { + assert$3("Directive", node, opts); + } + + function assertDirectiveLiteral$1(node, opts) { + assert$3("DirectiveLiteral", node, opts); + } + + function assertBlockStatement$1(node, opts) { + assert$3("BlockStatement", node, opts); + } + + function assertBreakStatement$1(node, opts) { + assert$3("BreakStatement", node, opts); + } + + function assertCallExpression$1(node, opts) { + assert$3("CallExpression", node, opts); + } + + function assertCatchClause$1(node, opts) { + assert$3("CatchClause", node, opts); + } + + function assertConditionalExpression$1(node, opts) { + assert$3("ConditionalExpression", node, opts); + } + + function assertContinueStatement$1(node, opts) { + assert$3("ContinueStatement", node, opts); + } + + function assertDebuggerStatement$1(node, opts) { + assert$3("DebuggerStatement", node, opts); + } + + function assertDoWhileStatement$1(node, opts) { + assert$3("DoWhileStatement", node, opts); + } + + function assertEmptyStatement$1(node, opts) { + assert$3("EmptyStatement", node, opts); + } + + function assertExpressionStatement$1(node, opts) { + assert$3("ExpressionStatement", node, opts); + } + + function assertFile$1(node, opts) { + assert$3("File", node, opts); + } + + function assertForInStatement$1(node, opts) { + assert$3("ForInStatement", node, opts); + } + + function assertForStatement$1(node, opts) { + assert$3("ForStatement", node, opts); + } + + function assertFunctionDeclaration$1(node, opts) { + assert$3("FunctionDeclaration", node, opts); + } + + function assertFunctionExpression$1(node, opts) { + assert$3("FunctionExpression", node, opts); + } + + function assertIdentifier$1(node, opts) { + assert$3("Identifier", node, opts); + } + + function assertIfStatement$1(node, opts) { + assert$3("IfStatement", node, opts); + } + + function assertLabeledStatement$1(node, opts) { + assert$3("LabeledStatement", node, opts); + } + + function assertStringLiteral$1(node, opts) { + assert$3("StringLiteral", node, opts); + } + + function assertNumericLiteral$1(node, opts) { + assert$3("NumericLiteral", node, opts); + } + + function assertNullLiteral$1(node, opts) { + assert$3("NullLiteral", node, opts); + } + + function assertBooleanLiteral$1(node, opts) { + assert$3("BooleanLiteral", node, opts); + } + + function assertRegExpLiteral$1(node, opts) { + assert$3("RegExpLiteral", node, opts); + } + + function assertLogicalExpression$1(node, opts) { + assert$3("LogicalExpression", node, opts); + } + + function assertMemberExpression$1(node, opts) { + assert$3("MemberExpression", node, opts); + } + + function assertNewExpression$1(node, opts) { + assert$3("NewExpression", node, opts); + } + + function assertProgram$1(node, opts) { + assert$3("Program", node, opts); + } + + function assertObjectExpression$1(node, opts) { + assert$3("ObjectExpression", node, opts); + } + + function assertObjectMethod$1(node, opts) { + assert$3("ObjectMethod", node, opts); + } + + function assertObjectProperty$1(node, opts) { + assert$3("ObjectProperty", node, opts); + } + + function assertRestElement$1(node, opts) { + assert$3("RestElement", node, opts); + } + + function assertReturnStatement$1(node, opts) { + assert$3("ReturnStatement", node, opts); + } + + function assertSequenceExpression$1(node, opts) { + assert$3("SequenceExpression", node, opts); + } + + function assertParenthesizedExpression$1(node, opts) { + assert$3("ParenthesizedExpression", node, opts); + } + + function assertSwitchCase$1(node, opts) { + assert$3("SwitchCase", node, opts); + } + + function assertSwitchStatement$1(node, opts) { + assert$3("SwitchStatement", node, opts); + } + + function assertThisExpression$1(node, opts) { + assert$3("ThisExpression", node, opts); + } + + function assertThrowStatement$1(node, opts) { + assert$3("ThrowStatement", node, opts); + } + + function assertTryStatement$1(node, opts) { + assert$3("TryStatement", node, opts); + } + + function assertUnaryExpression$1(node, opts) { + assert$3("UnaryExpression", node, opts); + } + + function assertUpdateExpression$1(node, opts) { + assert$3("UpdateExpression", node, opts); + } + + function assertVariableDeclaration$1(node, opts) { + assert$3("VariableDeclaration", node, opts); + } + + function assertVariableDeclarator$1(node, opts) { + assert$3("VariableDeclarator", node, opts); + } + + function assertWhileStatement$1(node, opts) { + assert$3("WhileStatement", node, opts); + } + + function assertWithStatement$1(node, opts) { + assert$3("WithStatement", node, opts); + } + + function assertAssignmentPattern$1(node, opts) { + assert$3("AssignmentPattern", node, opts); + } + + function assertArrayPattern$1(node, opts) { + assert$3("ArrayPattern", node, opts); + } + + function assertArrowFunctionExpression$1(node, opts) { + assert$3("ArrowFunctionExpression", node, opts); + } + + function assertClassBody$1(node, opts) { + assert$3("ClassBody", node, opts); + } + + function assertClassExpression$1(node, opts) { + assert$3("ClassExpression", node, opts); + } + + function assertClassDeclaration$1(node, opts) { + assert$3("ClassDeclaration", node, opts); + } + + function assertExportAllDeclaration$1(node, opts) { + assert$3("ExportAllDeclaration", node, opts); + } + + function assertExportDefaultDeclaration$1(node, opts) { + assert$3("ExportDefaultDeclaration", node, opts); + } + + function assertExportNamedDeclaration$1(node, opts) { + assert$3("ExportNamedDeclaration", node, opts); + } + + function assertExportSpecifier$1(node, opts) { + assert$3("ExportSpecifier", node, opts); + } + + function assertForOfStatement$1(node, opts) { + assert$3("ForOfStatement", node, opts); + } + + function assertImportDeclaration$1(node, opts) { + assert$3("ImportDeclaration", node, opts); + } + + function assertImportDefaultSpecifier$1(node, opts) { + assert$3("ImportDefaultSpecifier", node, opts); + } + + function assertImportNamespaceSpecifier$1(node, opts) { + assert$3("ImportNamespaceSpecifier", node, opts); + } + + function assertImportSpecifier$1(node, opts) { + assert$3("ImportSpecifier", node, opts); + } + + function assertMetaProperty$1(node, opts) { + assert$3("MetaProperty", node, opts); + } + + function assertClassMethod$1(node, opts) { + assert$3("ClassMethod", node, opts); + } + + function assertObjectPattern$1(node, opts) { + assert$3("ObjectPattern", node, opts); + } + + function assertSpreadElement$1(node, opts) { + assert$3("SpreadElement", node, opts); + } + + function assertSuper$1(node, opts) { + assert$3("Super", node, opts); + } + + function assertTaggedTemplateExpression$1(node, opts) { + assert$3("TaggedTemplateExpression", node, opts); + } + + function assertTemplateElement$1(node, opts) { + assert$3("TemplateElement", node, opts); + } + + function assertTemplateLiteral$1(node, opts) { + assert$3("TemplateLiteral", node, opts); + } + + function assertYieldExpression$1(node, opts) { + assert$3("YieldExpression", node, opts); + } + + function assertAwaitExpression$1(node, opts) { + assert$3("AwaitExpression", node, opts); + } + + function assertImport$1(node, opts) { + assert$3("Import", node, opts); + } + + function assertBigIntLiteral$1(node, opts) { + assert$3("BigIntLiteral", node, opts); + } + + function assertExportNamespaceSpecifier$1(node, opts) { + assert$3("ExportNamespaceSpecifier", node, opts); + } + + function assertOptionalMemberExpression$1(node, opts) { + assert$3("OptionalMemberExpression", node, opts); + } + + function assertOptionalCallExpression$1(node, opts) { + assert$3("OptionalCallExpression", node, opts); + } + + function assertClassProperty$1(node, opts) { + assert$3("ClassProperty", node, opts); + } + + function assertClassPrivateProperty$1(node, opts) { + assert$3("ClassPrivateProperty", node, opts); + } + + function assertClassPrivateMethod$1(node, opts) { + assert$3("ClassPrivateMethod", node, opts); + } + + function assertPrivateName$1(node, opts) { + assert$3("PrivateName", node, opts); + } + + function assertAnyTypeAnnotation$1(node, opts) { + assert$3("AnyTypeAnnotation", node, opts); + } + + function assertArrayTypeAnnotation$1(node, opts) { + assert$3("ArrayTypeAnnotation", node, opts); + } + + function assertBooleanTypeAnnotation$1(node, opts) { + assert$3("BooleanTypeAnnotation", node, opts); + } + + function assertBooleanLiteralTypeAnnotation$1(node, opts) { + assert$3("BooleanLiteralTypeAnnotation", node, opts); + } + + function assertNullLiteralTypeAnnotation$1(node, opts) { + assert$3("NullLiteralTypeAnnotation", node, opts); + } + + function assertClassImplements$1(node, opts) { + assert$3("ClassImplements", node, opts); + } + + function assertDeclareClass$1(node, opts) { + assert$3("DeclareClass", node, opts); + } + + function assertDeclareFunction$1(node, opts) { + assert$3("DeclareFunction", node, opts); + } + + function assertDeclareInterface$1(node, opts) { + assert$3("DeclareInterface", node, opts); + } + + function assertDeclareModule$1(node, opts) { + assert$3("DeclareModule", node, opts); + } + + function assertDeclareModuleExports$1(node, opts) { + assert$3("DeclareModuleExports", node, opts); + } + + function assertDeclareTypeAlias$1(node, opts) { + assert$3("DeclareTypeAlias", node, opts); + } + + function assertDeclareOpaqueType$1(node, opts) { + assert$3("DeclareOpaqueType", node, opts); + } + + function assertDeclareVariable$1(node, opts) { + assert$3("DeclareVariable", node, opts); + } + + function assertDeclareExportDeclaration$1(node, opts) { + assert$3("DeclareExportDeclaration", node, opts); + } + + function assertDeclareExportAllDeclaration$1(node, opts) { + assert$3("DeclareExportAllDeclaration", node, opts); + } + + function assertDeclaredPredicate$1(node, opts) { + assert$3("DeclaredPredicate", node, opts); + } + + function assertExistsTypeAnnotation$1(node, opts) { + assert$3("ExistsTypeAnnotation", node, opts); + } + + function assertFunctionTypeAnnotation$1(node, opts) { + assert$3("FunctionTypeAnnotation", node, opts); + } + + function assertFunctionTypeParam$1(node, opts) { + assert$3("FunctionTypeParam", node, opts); + } + + function assertGenericTypeAnnotation$1(node, opts) { + assert$3("GenericTypeAnnotation", node, opts); + } + + function assertInferredPredicate$1(node, opts) { + assert$3("InferredPredicate", node, opts); + } + + function assertInterfaceExtends$1(node, opts) { + assert$3("InterfaceExtends", node, opts); + } + + function assertInterfaceDeclaration$1(node, opts) { + assert$3("InterfaceDeclaration", node, opts); + } + + function assertInterfaceTypeAnnotation$1(node, opts) { + assert$3("InterfaceTypeAnnotation", node, opts); + } + + function assertIntersectionTypeAnnotation$1(node, opts) { + assert$3("IntersectionTypeAnnotation", node, opts); + } + + function assertMixedTypeAnnotation$1(node, opts) { + assert$3("MixedTypeAnnotation", node, opts); + } + + function assertEmptyTypeAnnotation$1(node, opts) { + assert$3("EmptyTypeAnnotation", node, opts); + } + + function assertNullableTypeAnnotation$1(node, opts) { + assert$3("NullableTypeAnnotation", node, opts); + } + + function assertNumberLiteralTypeAnnotation$1(node, opts) { + assert$3("NumberLiteralTypeAnnotation", node, opts); + } + + function assertNumberTypeAnnotation$1(node, opts) { + assert$3("NumberTypeAnnotation", node, opts); + } + + function assertObjectTypeAnnotation$1(node, opts) { + assert$3("ObjectTypeAnnotation", node, opts); + } + + function assertObjectTypeInternalSlot$1(node, opts) { + assert$3("ObjectTypeInternalSlot", node, opts); + } + + function assertObjectTypeCallProperty$1(node, opts) { + assert$3("ObjectTypeCallProperty", node, opts); + } + + function assertObjectTypeIndexer$1(node, opts) { + assert$3("ObjectTypeIndexer", node, opts); + } + + function assertObjectTypeProperty$1(node, opts) { + assert$3("ObjectTypeProperty", node, opts); + } + + function assertObjectTypeSpreadProperty$1(node, opts) { + assert$3("ObjectTypeSpreadProperty", node, opts); + } + + function assertOpaqueType$1(node, opts) { + assert$3("OpaqueType", node, opts); + } + + function assertQualifiedTypeIdentifier$1(node, opts) { + assert$3("QualifiedTypeIdentifier", node, opts); + } + + function assertStringLiteralTypeAnnotation$1(node, opts) { + assert$3("StringLiteralTypeAnnotation", node, opts); + } + + function assertStringTypeAnnotation$1(node, opts) { + assert$3("StringTypeAnnotation", node, opts); + } + + function assertSymbolTypeAnnotation$1(node, opts) { + assert$3("SymbolTypeAnnotation", node, opts); + } + + function assertThisTypeAnnotation$1(node, opts) { + assert$3("ThisTypeAnnotation", node, opts); + } + + function assertTupleTypeAnnotation$1(node, opts) { + assert$3("TupleTypeAnnotation", node, opts); + } + + function assertTypeofTypeAnnotation$1(node, opts) { + assert$3("TypeofTypeAnnotation", node, opts); + } + + function assertTypeAlias$1(node, opts) { + assert$3("TypeAlias", node, opts); + } + + function assertTypeAnnotation$1(node, opts) { + assert$3("TypeAnnotation", node, opts); + } + + function assertTypeCastExpression$1(node, opts) { + assert$3("TypeCastExpression", node, opts); + } + + function assertTypeParameter$1(node, opts) { + assert$3("TypeParameter", node, opts); + } + + function assertTypeParameterDeclaration$1(node, opts) { + assert$3("TypeParameterDeclaration", node, opts); + } + + function assertTypeParameterInstantiation$1(node, opts) { + assert$3("TypeParameterInstantiation", node, opts); + } + + function assertUnionTypeAnnotation$1(node, opts) { + assert$3("UnionTypeAnnotation", node, opts); + } + + function assertVariance$1(node, opts) { + assert$3("Variance", node, opts); + } + + function assertVoidTypeAnnotation$1(node, opts) { + assert$3("VoidTypeAnnotation", node, opts); + } + + function assertEnumDeclaration$1(node, opts) { + assert$3("EnumDeclaration", node, opts); + } + + function assertEnumBooleanBody$1(node, opts) { + assert$3("EnumBooleanBody", node, opts); + } + + function assertEnumNumberBody$1(node, opts) { + assert$3("EnumNumberBody", node, opts); + } + + function assertEnumStringBody$1(node, opts) { + assert$3("EnumStringBody", node, opts); + } + + function assertEnumSymbolBody$1(node, opts) { + assert$3("EnumSymbolBody", node, opts); + } + + function assertEnumBooleanMember$1(node, opts) { + assert$3("EnumBooleanMember", node, opts); + } + + function assertEnumNumberMember$1(node, opts) { + assert$3("EnumNumberMember", node, opts); + } + + function assertEnumStringMember$1(node, opts) { + assert$3("EnumStringMember", node, opts); + } + + function assertEnumDefaultedMember$1(node, opts) { + assert$3("EnumDefaultedMember", node, opts); + } + + function assertIndexedAccessType(node, opts) { + assert$3("IndexedAccessType", node, opts); + } + + function assertOptionalIndexedAccessType(node, opts) { + assert$3("OptionalIndexedAccessType", node, opts); + } + + function assertJSXAttribute$1(node, opts) { + assert$3("JSXAttribute", node, opts); + } + + function assertJSXClosingElement$1(node, opts) { + assert$3("JSXClosingElement", node, opts); + } + + function assertJSXElement$1(node, opts) { + assert$3("JSXElement", node, opts); + } + + function assertJSXEmptyExpression$1(node, opts) { + assert$3("JSXEmptyExpression", node, opts); + } + + function assertJSXExpressionContainer$1(node, opts) { + assert$3("JSXExpressionContainer", node, opts); + } + + function assertJSXSpreadChild$1(node, opts) { + assert$3("JSXSpreadChild", node, opts); + } + + function assertJSXIdentifier$1(node, opts) { + assert$3("JSXIdentifier", node, opts); + } + + function assertJSXMemberExpression$1(node, opts) { + assert$3("JSXMemberExpression", node, opts); + } + + function assertJSXNamespacedName$1(node, opts) { + assert$3("JSXNamespacedName", node, opts); + } + + function assertJSXOpeningElement$1(node, opts) { + assert$3("JSXOpeningElement", node, opts); + } + + function assertJSXSpreadAttribute$1(node, opts) { + assert$3("JSXSpreadAttribute", node, opts); + } + + function assertJSXText$1(node, opts) { + assert$3("JSXText", node, opts); + } + + function assertJSXFragment$1(node, opts) { + assert$3("JSXFragment", node, opts); + } + + function assertJSXOpeningFragment$1(node, opts) { + assert$3("JSXOpeningFragment", node, opts); + } + + function assertJSXClosingFragment$1(node, opts) { + assert$3("JSXClosingFragment", node, opts); + } + + function assertNoop$1(node, opts) { + assert$3("Noop", node, opts); + } + + function assertPlaceholder$1(node, opts) { + assert$3("Placeholder", node, opts); + } + + function assertV8IntrinsicIdentifier$1(node, opts) { + assert$3("V8IntrinsicIdentifier", node, opts); + } + + function assertArgumentPlaceholder$1(node, opts) { + assert$3("ArgumentPlaceholder", node, opts); + } + + function assertBindExpression$1(node, opts) { + assert$3("BindExpression", node, opts); + } + + function assertImportAttribute$1(node, opts) { + assert$3("ImportAttribute", node, opts); + } + + function assertDecorator$1(node, opts) { + assert$3("Decorator", node, opts); + } + + function assertDoExpression$1(node, opts) { + assert$3("DoExpression", node, opts); + } + + function assertExportDefaultSpecifier$1(node, opts) { + assert$3("ExportDefaultSpecifier", node, opts); + } + + function assertRecordExpression$1(node, opts) { + assert$3("RecordExpression", node, opts); + } + + function assertTupleExpression$1(node, opts) { + assert$3("TupleExpression", node, opts); + } + + function assertDecimalLiteral(node, opts) { + assert$3("DecimalLiteral", node, opts); + } + + function assertStaticBlock(node, opts) { + assert$3("StaticBlock", node, opts); + } + + function assertModuleExpression(node, opts) { + assert$3("ModuleExpression", node, opts); + } + + function assertTopicReference(node, opts) { + assert$3("TopicReference", node, opts); + } + + function assertPipelineTopicExpression$1(node, opts) { + assert$3("PipelineTopicExpression", node, opts); + } + + function assertPipelineBareFunction$1(node, opts) { + assert$3("PipelineBareFunction", node, opts); + } + + function assertPipelinePrimaryTopicReference$1(node, opts) { + assert$3("PipelinePrimaryTopicReference", node, opts); + } + + function assertTSParameterProperty$1(node, opts) { + assert$3("TSParameterProperty", node, opts); + } + + function assertTSDeclareFunction$1(node, opts) { + assert$3("TSDeclareFunction", node, opts); + } + + function assertTSDeclareMethod$1(node, opts) { + assert$3("TSDeclareMethod", node, opts); + } + + function assertTSQualifiedName$1(node, opts) { + assert$3("TSQualifiedName", node, opts); + } + + function assertTSCallSignatureDeclaration$1(node, opts) { + assert$3("TSCallSignatureDeclaration", node, opts); + } + + function assertTSConstructSignatureDeclaration$1(node, opts) { + assert$3("TSConstructSignatureDeclaration", node, opts); + } + + function assertTSPropertySignature$1(node, opts) { + assert$3("TSPropertySignature", node, opts); + } + + function assertTSMethodSignature$1(node, opts) { + assert$3("TSMethodSignature", node, opts); + } + + function assertTSIndexSignature$1(node, opts) { + assert$3("TSIndexSignature", node, opts); + } + + function assertTSAnyKeyword$1(node, opts) { + assert$3("TSAnyKeyword", node, opts); + } + + function assertTSBooleanKeyword$1(node, opts) { + assert$3("TSBooleanKeyword", node, opts); + } + + function assertTSBigIntKeyword$1(node, opts) { + assert$3("TSBigIntKeyword", node, opts); + } + + function assertTSIntrinsicKeyword(node, opts) { + assert$3("TSIntrinsicKeyword", node, opts); + } + + function assertTSNeverKeyword$1(node, opts) { + assert$3("TSNeverKeyword", node, opts); + } + + function assertTSNullKeyword$1(node, opts) { + assert$3("TSNullKeyword", node, opts); + } + + function assertTSNumberKeyword$1(node, opts) { + assert$3("TSNumberKeyword", node, opts); + } + + function assertTSObjectKeyword$1(node, opts) { + assert$3("TSObjectKeyword", node, opts); + } + + function assertTSStringKeyword$1(node, opts) { + assert$3("TSStringKeyword", node, opts); + } + + function assertTSSymbolKeyword$1(node, opts) { + assert$3("TSSymbolKeyword", node, opts); + } + + function assertTSUndefinedKeyword$1(node, opts) { + assert$3("TSUndefinedKeyword", node, opts); + } + + function assertTSUnknownKeyword$1(node, opts) { + assert$3("TSUnknownKeyword", node, opts); + } + + function assertTSVoidKeyword$1(node, opts) { + assert$3("TSVoidKeyword", node, opts); + } + + function assertTSThisType$1(node, opts) { + assert$3("TSThisType", node, opts); + } + + function assertTSFunctionType$1(node, opts) { + assert$3("TSFunctionType", node, opts); + } + + function assertTSConstructorType$1(node, opts) { + assert$3("TSConstructorType", node, opts); + } + + function assertTSTypeReference$1(node, opts) { + assert$3("TSTypeReference", node, opts); + } + + function assertTSTypePredicate$1(node, opts) { + assert$3("TSTypePredicate", node, opts); + } + + function assertTSTypeQuery$1(node, opts) { + assert$3("TSTypeQuery", node, opts); + } + + function assertTSTypeLiteral$1(node, opts) { + assert$3("TSTypeLiteral", node, opts); + } + + function assertTSArrayType$1(node, opts) { + assert$3("TSArrayType", node, opts); + } + + function assertTSTupleType$1(node, opts) { + assert$3("TSTupleType", node, opts); + } + + function assertTSOptionalType$1(node, opts) { + assert$3("TSOptionalType", node, opts); + } + + function assertTSRestType$1(node, opts) { + assert$3("TSRestType", node, opts); + } + + function assertTSNamedTupleMember(node, opts) { + assert$3("TSNamedTupleMember", node, opts); + } + + function assertTSUnionType$1(node, opts) { + assert$3("TSUnionType", node, opts); + } + + function assertTSIntersectionType$1(node, opts) { + assert$3("TSIntersectionType", node, opts); + } + + function assertTSConditionalType$1(node, opts) { + assert$3("TSConditionalType", node, opts); + } + + function assertTSInferType$1(node, opts) { + assert$3("TSInferType", node, opts); + } + + function assertTSParenthesizedType$1(node, opts) { + assert$3("TSParenthesizedType", node, opts); + } + + function assertTSTypeOperator$1(node, opts) { + assert$3("TSTypeOperator", node, opts); + } + + function assertTSIndexedAccessType$1(node, opts) { + assert$3("TSIndexedAccessType", node, opts); + } + + function assertTSMappedType$1(node, opts) { + assert$3("TSMappedType", node, opts); + } + + function assertTSLiteralType$1(node, opts) { + assert$3("TSLiteralType", node, opts); + } + + function assertTSExpressionWithTypeArguments$1(node, opts) { + assert$3("TSExpressionWithTypeArguments", node, opts); + } + + function assertTSInterfaceDeclaration$1(node, opts) { + assert$3("TSInterfaceDeclaration", node, opts); + } + + function assertTSInterfaceBody$1(node, opts) { + assert$3("TSInterfaceBody", node, opts); + } + + function assertTSTypeAliasDeclaration$1(node, opts) { + assert$3("TSTypeAliasDeclaration", node, opts); + } + + function assertTSAsExpression$1(node, opts) { + assert$3("TSAsExpression", node, opts); + } + + function assertTSTypeAssertion$1(node, opts) { + assert$3("TSTypeAssertion", node, opts); + } + + function assertTSEnumDeclaration$1(node, opts) { + assert$3("TSEnumDeclaration", node, opts); + } + + function assertTSEnumMember$1(node, opts) { + assert$3("TSEnumMember", node, opts); + } + + function assertTSModuleDeclaration$1(node, opts) { + assert$3("TSModuleDeclaration", node, opts); + } + + function assertTSModuleBlock$1(node, opts) { + assert$3("TSModuleBlock", node, opts); + } + + function assertTSImportType$1(node, opts) { + assert$3("TSImportType", node, opts); + } + + function assertTSImportEqualsDeclaration$1(node, opts) { + assert$3("TSImportEqualsDeclaration", node, opts); + } + + function assertTSExternalModuleReference$1(node, opts) { + assert$3("TSExternalModuleReference", node, opts); + } + + function assertTSNonNullExpression$1(node, opts) { + assert$3("TSNonNullExpression", node, opts); + } + + function assertTSExportAssignment$1(node, opts) { + assert$3("TSExportAssignment", node, opts); + } + + function assertTSNamespaceExportDeclaration$1(node, opts) { + assert$3("TSNamespaceExportDeclaration", node, opts); + } + + function assertTSTypeAnnotation$1(node, opts) { + assert$3("TSTypeAnnotation", node, opts); + } + + function assertTSTypeParameterInstantiation$1(node, opts) { + assert$3("TSTypeParameterInstantiation", node, opts); + } + + function assertTSTypeParameterDeclaration$1(node, opts) { + assert$3("TSTypeParameterDeclaration", node, opts); + } + + function assertTSTypeParameter$1(node, opts) { + assert$3("TSTypeParameter", node, opts); + } + + function assertExpression$1(node, opts) { + assert$3("Expression", node, opts); + } + + function assertBinary$1(node, opts) { + assert$3("Binary", node, opts); + } + + function assertScopable$1(node, opts) { + assert$3("Scopable", node, opts); + } + + function assertBlockParent$1(node, opts) { + assert$3("BlockParent", node, opts); + } + + function assertBlock$1(node, opts) { + assert$3("Block", node, opts); + } + + function assertStatement$1(node, opts) { + assert$3("Statement", node, opts); + } + + function assertTerminatorless$1(node, opts) { + assert$3("Terminatorless", node, opts); + } + + function assertCompletionStatement$1(node, opts) { + assert$3("CompletionStatement", node, opts); + } + + function assertConditional$1(node, opts) { + assert$3("Conditional", node, opts); + } + + function assertLoop$1(node, opts) { + assert$3("Loop", node, opts); + } + + function assertWhile$1(node, opts) { + assert$3("While", node, opts); + } + + function assertExpressionWrapper$1(node, opts) { + assert$3("ExpressionWrapper", node, opts); + } + + function assertFor$1(node, opts) { + assert$3("For", node, opts); + } + + function assertForXStatement$1(node, opts) { + assert$3("ForXStatement", node, opts); + } + + function assertFunction$1(node, opts) { + assert$3("Function", node, opts); + } + + function assertFunctionParent$1(node, opts) { + assert$3("FunctionParent", node, opts); + } + + function assertPureish$1(node, opts) { + assert$3("Pureish", node, opts); + } + + function assertDeclaration$1(node, opts) { + assert$3("Declaration", node, opts); + } + + function assertPatternLike$1(node, opts) { + assert$3("PatternLike", node, opts); + } + + function assertLVal$1(node, opts) { + assert$3("LVal", node, opts); + } + + function assertTSEntityName$1(node, opts) { + assert$3("TSEntityName", node, opts); + } + + function assertLiteral$1(node, opts) { + assert$3("Literal", node, opts); + } + + function assertImmutable$1(node, opts) { + assert$3("Immutable", node, opts); + } + + function assertUserWhitespacable$1(node, opts) { + assert$3("UserWhitespacable", node, opts); + } + + function assertMethod$1(node, opts) { + assert$3("Method", node, opts); + } + + function assertObjectMember$1(node, opts) { + assert$3("ObjectMember", node, opts); + } + + function assertProperty$1(node, opts) { + assert$3("Property", node, opts); + } + + function assertUnaryLike$1(node, opts) { + assert$3("UnaryLike", node, opts); + } + + function assertPattern$1(node, opts) { + assert$3("Pattern", node, opts); + } + + function assertClass$1(node, opts) { + assert$3("Class", node, opts); + } + + function assertModuleDeclaration$1(node, opts) { + assert$3("ModuleDeclaration", node, opts); + } + + function assertExportDeclaration$1(node, opts) { + assert$3("ExportDeclaration", node, opts); + } + + function assertModuleSpecifier$1(node, opts) { + assert$3("ModuleSpecifier", node, opts); + } + + function assertPrivate$1(node, opts) { + assert$3("Private", node, opts); + } + + function assertFlow$1(node, opts) { + assert$3("Flow", node, opts); + } + + function assertFlowType$1(node, opts) { + assert$3("FlowType", node, opts); + } + + function assertFlowBaseAnnotation$1(node, opts) { + assert$3("FlowBaseAnnotation", node, opts); + } + + function assertFlowDeclaration$1(node, opts) { + assert$3("FlowDeclaration", node, opts); + } + + function assertFlowPredicate$1(node, opts) { + assert$3("FlowPredicate", node, opts); + } + + function assertEnumBody$1(node, opts) { + assert$3("EnumBody", node, opts); + } + + function assertEnumMember$1(node, opts) { + assert$3("EnumMember", node, opts); + } + + function assertJSX$1(node, opts) { + assert$3("JSX", node, opts); + } + + function assertTSTypeElement$1(node, opts) { + assert$3("TSTypeElement", node, opts); + } + + function assertTSType$1(node, opts) { + assert$3("TSType", node, opts); + } + + function assertTSBaseType$1(node, opts) { + assert$3("TSBaseType", node, opts); + } + + function assertNumberLiteral$1(node, opts) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + assert$3("NumberLiteral", node, opts); + } + + function assertRegexLiteral$1(node, opts) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + assert$3("RegexLiteral", node, opts); + } + + function assertRestProperty$1(node, opts) { + console.trace("The node type RestProperty has been renamed to RestElement"); + assert$3("RestProperty", node, opts); + } + + function assertSpreadProperty$1(node, opts) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + assert$3("SpreadProperty", node, opts); + } + + var createTypeAnnotationBasedOnTypeof$3 = {}; + + Object.defineProperty(createTypeAnnotationBasedOnTypeof$3, "__esModule", { + value: true + }); + createTypeAnnotationBasedOnTypeof$3.default = createTypeAnnotationBasedOnTypeof$2; + + var _generated$J = generated$7; + + function createTypeAnnotationBasedOnTypeof$2(type) { + if (type === "string") { + return (0, _generated$J.stringTypeAnnotation)(); + } else if (type === "number") { + return (0, _generated$J.numberTypeAnnotation)(); + } else if (type === "undefined") { + return (0, _generated$J.voidTypeAnnotation)(); + } else if (type === "boolean") { + return (0, _generated$J.booleanTypeAnnotation)(); + } else if (type === "function") { + return (0, _generated$J.genericTypeAnnotation)((0, _generated$J.identifier)("Function")); + } else if (type === "object") { + return (0, _generated$J.genericTypeAnnotation)((0, _generated$J.identifier)("Object")); + } else if (type === "symbol") { + return (0, _generated$J.genericTypeAnnotation)((0, _generated$J.identifier)("Symbol")); + } else if (type === "bigint") { + return (0, _generated$J.anyTypeAnnotation)(); + } else { + throw new Error("Invalid typeof value: " + type); + } + } + + var createFlowUnionType$3 = {}; + + var removeTypeDuplicates$7 = {}; + + Object.defineProperty(removeTypeDuplicates$7, "__esModule", { + value: true + }); + removeTypeDuplicates$7.default = removeTypeDuplicates$6; + + var _generated$I = generated$8; + + function getQualifiedName(node) { + return (0, _generated$I.isIdentifier)(node) ? node.name : `${node.id.name}.${getQualifiedName(node.qualification)}`; + } + + function removeTypeDuplicates$6(nodes) { + const generics = {}; + const bases = {}; + const typeGroups = new Set(); + const types = []; + + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (!node) continue; + + if (types.indexOf(node) >= 0) { + continue; + } + + if ((0, _generated$I.isAnyTypeAnnotation)(node)) { + return [node]; + } + + if ((0, _generated$I.isFlowBaseAnnotation)(node)) { + bases[node.type] = node; + continue; + } + + if ((0, _generated$I.isUnionTypeAnnotation)(node)) { + if (!typeGroups.has(node.types)) { + nodes = nodes.concat(node.types); + typeGroups.add(node.types); + } + + continue; + } + + if ((0, _generated$I.isGenericTypeAnnotation)(node)) { + const name = getQualifiedName(node.id); + + if (generics[name]) { + let existing = generics[name]; + + if (existing.typeParameters) { + if (node.typeParameters) { + existing.typeParameters.params = removeTypeDuplicates$6(existing.typeParameters.params.concat(node.typeParameters.params)); + } + } else { + existing = node.typeParameters; + } + } else { + generics[name] = node; + } + + continue; + } + + types.push(node); + } + + for (const type of Object.keys(bases)) { + types.push(bases[type]); + } + + for (const name of Object.keys(generics)) { + types.push(generics[name]); + } + + return types; + } + + Object.defineProperty(createFlowUnionType$3, "__esModule", { + value: true + }); + createFlowUnionType$3.default = createFlowUnionType$2; + + var _generated$H = generated$7; + + var _removeTypeDuplicates$3 = removeTypeDuplicates$7; + + function createFlowUnionType$2(types) { + const flattened = (0, _removeTypeDuplicates$3.default)(types); + + if (flattened.length === 1) { + return flattened[0]; + } else { + return (0, _generated$H.unionTypeAnnotation)(flattened); + } + } + + var createTSUnionType$3 = {}; + + var removeTypeDuplicates$5 = {}; + + Object.defineProperty(removeTypeDuplicates$5, "__esModule", { + value: true + }); + removeTypeDuplicates$5.default = removeTypeDuplicates$4; + + var _generated$G = generated$8; + + function removeTypeDuplicates$4(nodes) { + const generics = {}; + const bases = {}; + const typeGroups = new Set(); + const types = []; + + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (!node) continue; + + if (types.indexOf(node) >= 0) { + continue; + } + + if ((0, _generated$G.isTSAnyKeyword)(node)) { + return [node]; + } + + if ((0, _generated$G.isTSBaseType)(node)) { + bases[node.type] = node; + continue; + } + + if ((0, _generated$G.isTSUnionType)(node)) { + if (!typeGroups.has(node.types)) { + nodes.push(...node.types); + typeGroups.add(node.types); + } + + continue; + } + + types.push(node); + } + + for (const type of Object.keys(bases)) { + types.push(bases[type]); + } + + for (const name of Object.keys(generics)) { + types.push(generics[name]); + } + + return types; + } + + Object.defineProperty(createTSUnionType$3, "__esModule", { + value: true + }); + createTSUnionType$3.default = createTSUnionType$2; + + var _generated$F = generated$7; + + var _removeTypeDuplicates$2 = removeTypeDuplicates$5; + + function createTSUnionType$2(typeAnnotations) { + const types = typeAnnotations.map(type => type.typeAnnotation); + const flattened = (0, _removeTypeDuplicates$2.default)(types); + + if (flattened.length === 1) { + return flattened[0]; + } else { + return (0, _generated$F.tsUnionType)(flattened); + } + } + + var uppercase = {}; + + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "ArrayExpression", { + enumerable: true, + get: function () { + return _index.arrayExpression; + } + }); + Object.defineProperty(exports, "AssignmentExpression", { + enumerable: true, + get: function () { + return _index.assignmentExpression; + } + }); + Object.defineProperty(exports, "BinaryExpression", { + enumerable: true, + get: function () { + return _index.binaryExpression; + } + }); + Object.defineProperty(exports, "InterpreterDirective", { + enumerable: true, + get: function () { + return _index.interpreterDirective; + } + }); + Object.defineProperty(exports, "Directive", { + enumerable: true, + get: function () { + return _index.directive; + } + }); + Object.defineProperty(exports, "DirectiveLiteral", { + enumerable: true, + get: function () { + return _index.directiveLiteral; + } + }); + Object.defineProperty(exports, "BlockStatement", { + enumerable: true, + get: function () { + return _index.blockStatement; + } + }); + Object.defineProperty(exports, "BreakStatement", { + enumerable: true, + get: function () { + return _index.breakStatement; + } + }); + Object.defineProperty(exports, "CallExpression", { + enumerable: true, + get: function () { + return _index.callExpression; + } + }); + Object.defineProperty(exports, "CatchClause", { + enumerable: true, + get: function () { + return _index.catchClause; + } + }); + Object.defineProperty(exports, "ConditionalExpression", { + enumerable: true, + get: function () { + return _index.conditionalExpression; + } + }); + Object.defineProperty(exports, "ContinueStatement", { + enumerable: true, + get: function () { + return _index.continueStatement; + } + }); + Object.defineProperty(exports, "DebuggerStatement", { + enumerable: true, + get: function () { + return _index.debuggerStatement; + } + }); + Object.defineProperty(exports, "DoWhileStatement", { + enumerable: true, + get: function () { + return _index.doWhileStatement; + } + }); + Object.defineProperty(exports, "EmptyStatement", { + enumerable: true, + get: function () { + return _index.emptyStatement; + } + }); + Object.defineProperty(exports, "ExpressionStatement", { + enumerable: true, + get: function () { + return _index.expressionStatement; + } + }); + Object.defineProperty(exports, "File", { + enumerable: true, + get: function () { + return _index.file; + } + }); + Object.defineProperty(exports, "ForInStatement", { + enumerable: true, + get: function () { + return _index.forInStatement; + } + }); + Object.defineProperty(exports, "ForStatement", { + enumerable: true, + get: function () { + return _index.forStatement; + } + }); + Object.defineProperty(exports, "FunctionDeclaration", { + enumerable: true, + get: function () { + return _index.functionDeclaration; + } + }); + Object.defineProperty(exports, "FunctionExpression", { + enumerable: true, + get: function () { + return _index.functionExpression; + } + }); + Object.defineProperty(exports, "Identifier", { + enumerable: true, + get: function () { + return _index.identifier; + } + }); + Object.defineProperty(exports, "IfStatement", { + enumerable: true, + get: function () { + return _index.ifStatement; + } + }); + Object.defineProperty(exports, "LabeledStatement", { + enumerable: true, + get: function () { + return _index.labeledStatement; + } + }); + Object.defineProperty(exports, "StringLiteral", { + enumerable: true, + get: function () { + return _index.stringLiteral; + } + }); + Object.defineProperty(exports, "NumericLiteral", { + enumerable: true, + get: function () { + return _index.numericLiteral; + } + }); + Object.defineProperty(exports, "NullLiteral", { + enumerable: true, + get: function () { + return _index.nullLiteral; + } + }); + Object.defineProperty(exports, "BooleanLiteral", { + enumerable: true, + get: function () { + return _index.booleanLiteral; + } + }); + Object.defineProperty(exports, "RegExpLiteral", { + enumerable: true, + get: function () { + return _index.regExpLiteral; + } + }); + Object.defineProperty(exports, "LogicalExpression", { + enumerable: true, + get: function () { + return _index.logicalExpression; + } + }); + Object.defineProperty(exports, "MemberExpression", { + enumerable: true, + get: function () { + return _index.memberExpression; + } + }); + Object.defineProperty(exports, "NewExpression", { + enumerable: true, + get: function () { + return _index.newExpression; + } + }); + Object.defineProperty(exports, "Program", { + enumerable: true, + get: function () { + return _index.program; + } + }); + Object.defineProperty(exports, "ObjectExpression", { + enumerable: true, + get: function () { + return _index.objectExpression; + } + }); + Object.defineProperty(exports, "ObjectMethod", { + enumerable: true, + get: function () { + return _index.objectMethod; + } + }); + Object.defineProperty(exports, "ObjectProperty", { + enumerable: true, + get: function () { + return _index.objectProperty; + } + }); + Object.defineProperty(exports, "RestElement", { + enumerable: true, + get: function () { + return _index.restElement; + } + }); + Object.defineProperty(exports, "ReturnStatement", { + enumerable: true, + get: function () { + return _index.returnStatement; + } + }); + Object.defineProperty(exports, "SequenceExpression", { + enumerable: true, + get: function () { + return _index.sequenceExpression; + } + }); + Object.defineProperty(exports, "ParenthesizedExpression", { + enumerable: true, + get: function () { + return _index.parenthesizedExpression; + } + }); + Object.defineProperty(exports, "SwitchCase", { + enumerable: true, + get: function () { + return _index.switchCase; + } + }); + Object.defineProperty(exports, "SwitchStatement", { + enumerable: true, + get: function () { + return _index.switchStatement; + } + }); + Object.defineProperty(exports, "ThisExpression", { + enumerable: true, + get: function () { + return _index.thisExpression; + } + }); + Object.defineProperty(exports, "ThrowStatement", { + enumerable: true, + get: function () { + return _index.throwStatement; + } + }); + Object.defineProperty(exports, "TryStatement", { + enumerable: true, + get: function () { + return _index.tryStatement; + } + }); + Object.defineProperty(exports, "UnaryExpression", { + enumerable: true, + get: function () { + return _index.unaryExpression; + } + }); + Object.defineProperty(exports, "UpdateExpression", { + enumerable: true, + get: function () { + return _index.updateExpression; + } + }); + Object.defineProperty(exports, "VariableDeclaration", { + enumerable: true, + get: function () { + return _index.variableDeclaration; + } + }); + Object.defineProperty(exports, "VariableDeclarator", { + enumerable: true, + get: function () { + return _index.variableDeclarator; + } + }); + Object.defineProperty(exports, "WhileStatement", { + enumerable: true, + get: function () { + return _index.whileStatement; + } + }); + Object.defineProperty(exports, "WithStatement", { + enumerable: true, + get: function () { + return _index.withStatement; + } + }); + Object.defineProperty(exports, "AssignmentPattern", { + enumerable: true, + get: function () { + return _index.assignmentPattern; + } + }); + Object.defineProperty(exports, "ArrayPattern", { + enumerable: true, + get: function () { + return _index.arrayPattern; + } + }); + Object.defineProperty(exports, "ArrowFunctionExpression", { + enumerable: true, + get: function () { + return _index.arrowFunctionExpression; + } + }); + Object.defineProperty(exports, "ClassBody", { + enumerable: true, + get: function () { + return _index.classBody; + } + }); + Object.defineProperty(exports, "ClassExpression", { + enumerable: true, + get: function () { + return _index.classExpression; + } + }); + Object.defineProperty(exports, "ClassDeclaration", { + enumerable: true, + get: function () { + return _index.classDeclaration; + } + }); + Object.defineProperty(exports, "ExportAllDeclaration", { + enumerable: true, + get: function () { + return _index.exportAllDeclaration; + } + }); + Object.defineProperty(exports, "ExportDefaultDeclaration", { + enumerable: true, + get: function () { + return _index.exportDefaultDeclaration; + } + }); + Object.defineProperty(exports, "ExportNamedDeclaration", { + enumerable: true, + get: function () { + return _index.exportNamedDeclaration; + } + }); + Object.defineProperty(exports, "ExportSpecifier", { + enumerable: true, + get: function () { + return _index.exportSpecifier; + } + }); + Object.defineProperty(exports, "ForOfStatement", { + enumerable: true, + get: function () { + return _index.forOfStatement; + } + }); + Object.defineProperty(exports, "ImportDeclaration", { + enumerable: true, + get: function () { + return _index.importDeclaration; + } + }); + Object.defineProperty(exports, "ImportDefaultSpecifier", { + enumerable: true, + get: function () { + return _index.importDefaultSpecifier; + } + }); + Object.defineProperty(exports, "ImportNamespaceSpecifier", { + enumerable: true, + get: function () { + return _index.importNamespaceSpecifier; + } + }); + Object.defineProperty(exports, "ImportSpecifier", { + enumerable: true, + get: function () { + return _index.importSpecifier; + } + }); + Object.defineProperty(exports, "MetaProperty", { + enumerable: true, + get: function () { + return _index.metaProperty; + } + }); + Object.defineProperty(exports, "ClassMethod", { + enumerable: true, + get: function () { + return _index.classMethod; + } + }); + Object.defineProperty(exports, "ObjectPattern", { + enumerable: true, + get: function () { + return _index.objectPattern; + } + }); + Object.defineProperty(exports, "SpreadElement", { + enumerable: true, + get: function () { + return _index.spreadElement; + } + }); + Object.defineProperty(exports, "Super", { + enumerable: true, + get: function () { + return _index.super; + } + }); + Object.defineProperty(exports, "TaggedTemplateExpression", { + enumerable: true, + get: function () { + return _index.taggedTemplateExpression; + } + }); + Object.defineProperty(exports, "TemplateElement", { + enumerable: true, + get: function () { + return _index.templateElement; + } + }); + Object.defineProperty(exports, "TemplateLiteral", { + enumerable: true, + get: function () { + return _index.templateLiteral; + } + }); + Object.defineProperty(exports, "YieldExpression", { + enumerable: true, + get: function () { + return _index.yieldExpression; + } + }); + Object.defineProperty(exports, "AwaitExpression", { + enumerable: true, + get: function () { + return _index.awaitExpression; + } + }); + Object.defineProperty(exports, "Import", { + enumerable: true, + get: function () { + return _index.import; + } + }); + Object.defineProperty(exports, "BigIntLiteral", { + enumerable: true, + get: function () { + return _index.bigIntLiteral; + } + }); + Object.defineProperty(exports, "ExportNamespaceSpecifier", { + enumerable: true, + get: function () { + return _index.exportNamespaceSpecifier; + } + }); + Object.defineProperty(exports, "OptionalMemberExpression", { + enumerable: true, + get: function () { + return _index.optionalMemberExpression; + } + }); + Object.defineProperty(exports, "OptionalCallExpression", { + enumerable: true, + get: function () { + return _index.optionalCallExpression; + } + }); + Object.defineProperty(exports, "ClassProperty", { + enumerable: true, + get: function () { + return _index.classProperty; + } + }); + Object.defineProperty(exports, "ClassPrivateProperty", { + enumerable: true, + get: function () { + return _index.classPrivateProperty; + } + }); + Object.defineProperty(exports, "ClassPrivateMethod", { + enumerable: true, + get: function () { + return _index.classPrivateMethod; + } + }); + Object.defineProperty(exports, "PrivateName", { + enumerable: true, + get: function () { + return _index.privateName; + } + }); + Object.defineProperty(exports, "AnyTypeAnnotation", { + enumerable: true, + get: function () { + return _index.anyTypeAnnotation; + } + }); + Object.defineProperty(exports, "ArrayTypeAnnotation", { + enumerable: true, + get: function () { + return _index.arrayTypeAnnotation; + } + }); + Object.defineProperty(exports, "BooleanTypeAnnotation", { + enumerable: true, + get: function () { + return _index.booleanTypeAnnotation; + } + }); + Object.defineProperty(exports, "BooleanLiteralTypeAnnotation", { + enumerable: true, + get: function () { + return _index.booleanLiteralTypeAnnotation; + } + }); + Object.defineProperty(exports, "NullLiteralTypeAnnotation", { + enumerable: true, + get: function () { + return _index.nullLiteralTypeAnnotation; + } + }); + Object.defineProperty(exports, "ClassImplements", { + enumerable: true, + get: function () { + return _index.classImplements; + } + }); + Object.defineProperty(exports, "DeclareClass", { + enumerable: true, + get: function () { + return _index.declareClass; + } + }); + Object.defineProperty(exports, "DeclareFunction", { + enumerable: true, + get: function () { + return _index.declareFunction; + } + }); + Object.defineProperty(exports, "DeclareInterface", { + enumerable: true, + get: function () { + return _index.declareInterface; + } + }); + Object.defineProperty(exports, "DeclareModule", { + enumerable: true, + get: function () { + return _index.declareModule; + } + }); + Object.defineProperty(exports, "DeclareModuleExports", { + enumerable: true, + get: function () { + return _index.declareModuleExports; + } + }); + Object.defineProperty(exports, "DeclareTypeAlias", { + enumerable: true, + get: function () { + return _index.declareTypeAlias; + } + }); + Object.defineProperty(exports, "DeclareOpaqueType", { + enumerable: true, + get: function () { + return _index.declareOpaqueType; + } + }); + Object.defineProperty(exports, "DeclareVariable", { + enumerable: true, + get: function () { + return _index.declareVariable; + } + }); + Object.defineProperty(exports, "DeclareExportDeclaration", { + enumerable: true, + get: function () { + return _index.declareExportDeclaration; + } + }); + Object.defineProperty(exports, "DeclareExportAllDeclaration", { + enumerable: true, + get: function () { + return _index.declareExportAllDeclaration; + } + }); + Object.defineProperty(exports, "DeclaredPredicate", { + enumerable: true, + get: function () { + return _index.declaredPredicate; + } + }); + Object.defineProperty(exports, "ExistsTypeAnnotation", { + enumerable: true, + get: function () { + return _index.existsTypeAnnotation; + } + }); + Object.defineProperty(exports, "FunctionTypeAnnotation", { + enumerable: true, + get: function () { + return _index.functionTypeAnnotation; + } + }); + Object.defineProperty(exports, "FunctionTypeParam", { + enumerable: true, + get: function () { + return _index.functionTypeParam; + } + }); + Object.defineProperty(exports, "GenericTypeAnnotation", { + enumerable: true, + get: function () { + return _index.genericTypeAnnotation; + } + }); + Object.defineProperty(exports, "InferredPredicate", { + enumerable: true, + get: function () { + return _index.inferredPredicate; + } + }); + Object.defineProperty(exports, "InterfaceExtends", { + enumerable: true, + get: function () { + return _index.interfaceExtends; + } + }); + Object.defineProperty(exports, "InterfaceDeclaration", { + enumerable: true, + get: function () { + return _index.interfaceDeclaration; + } + }); + Object.defineProperty(exports, "InterfaceTypeAnnotation", { + enumerable: true, + get: function () { + return _index.interfaceTypeAnnotation; + } + }); + Object.defineProperty(exports, "IntersectionTypeAnnotation", { + enumerable: true, + get: function () { + return _index.intersectionTypeAnnotation; + } + }); + Object.defineProperty(exports, "MixedTypeAnnotation", { + enumerable: true, + get: function () { + return _index.mixedTypeAnnotation; + } + }); + Object.defineProperty(exports, "EmptyTypeAnnotation", { + enumerable: true, + get: function () { + return _index.emptyTypeAnnotation; + } + }); + Object.defineProperty(exports, "NullableTypeAnnotation", { + enumerable: true, + get: function () { + return _index.nullableTypeAnnotation; + } + }); + Object.defineProperty(exports, "NumberLiteralTypeAnnotation", { + enumerable: true, + get: function () { + return _index.numberLiteralTypeAnnotation; + } + }); + Object.defineProperty(exports, "NumberTypeAnnotation", { + enumerable: true, + get: function () { + return _index.numberTypeAnnotation; + } + }); + Object.defineProperty(exports, "ObjectTypeAnnotation", { + enumerable: true, + get: function () { + return _index.objectTypeAnnotation; + } + }); + Object.defineProperty(exports, "ObjectTypeInternalSlot", { + enumerable: true, + get: function () { + return _index.objectTypeInternalSlot; + } + }); + Object.defineProperty(exports, "ObjectTypeCallProperty", { + enumerable: true, + get: function () { + return _index.objectTypeCallProperty; + } + }); + Object.defineProperty(exports, "ObjectTypeIndexer", { + enumerable: true, + get: function () { + return _index.objectTypeIndexer; + } + }); + Object.defineProperty(exports, "ObjectTypeProperty", { + enumerable: true, + get: function () { + return _index.objectTypeProperty; + } + }); + Object.defineProperty(exports, "ObjectTypeSpreadProperty", { + enumerable: true, + get: function () { + return _index.objectTypeSpreadProperty; + } + }); + Object.defineProperty(exports, "OpaqueType", { + enumerable: true, + get: function () { + return _index.opaqueType; + } + }); + Object.defineProperty(exports, "QualifiedTypeIdentifier", { + enumerable: true, + get: function () { + return _index.qualifiedTypeIdentifier; + } + }); + Object.defineProperty(exports, "StringLiteralTypeAnnotation", { + enumerable: true, + get: function () { + return _index.stringLiteralTypeAnnotation; + } + }); + Object.defineProperty(exports, "StringTypeAnnotation", { + enumerable: true, + get: function () { + return _index.stringTypeAnnotation; + } + }); + Object.defineProperty(exports, "SymbolTypeAnnotation", { + enumerable: true, + get: function () { + return _index.symbolTypeAnnotation; + } + }); + Object.defineProperty(exports, "ThisTypeAnnotation", { + enumerable: true, + get: function () { + return _index.thisTypeAnnotation; + } + }); + Object.defineProperty(exports, "TupleTypeAnnotation", { + enumerable: true, + get: function () { + return _index.tupleTypeAnnotation; + } + }); + Object.defineProperty(exports, "TypeofTypeAnnotation", { + enumerable: true, + get: function () { + return _index.typeofTypeAnnotation; + } + }); + Object.defineProperty(exports, "TypeAlias", { + enumerable: true, + get: function () { + return _index.typeAlias; + } + }); + Object.defineProperty(exports, "TypeAnnotation", { + enumerable: true, + get: function () { + return _index.typeAnnotation; + } + }); + Object.defineProperty(exports, "TypeCastExpression", { + enumerable: true, + get: function () { + return _index.typeCastExpression; + } + }); + Object.defineProperty(exports, "TypeParameter", { + enumerable: true, + get: function () { + return _index.typeParameter; + } + }); + Object.defineProperty(exports, "TypeParameterDeclaration", { + enumerable: true, + get: function () { + return _index.typeParameterDeclaration; + } + }); + Object.defineProperty(exports, "TypeParameterInstantiation", { + enumerable: true, + get: function () { + return _index.typeParameterInstantiation; + } + }); + Object.defineProperty(exports, "UnionTypeAnnotation", { + enumerable: true, + get: function () { + return _index.unionTypeAnnotation; + } + }); + Object.defineProperty(exports, "Variance", { + enumerable: true, + get: function () { + return _index.variance; + } + }); + Object.defineProperty(exports, "VoidTypeAnnotation", { + enumerable: true, + get: function () { + return _index.voidTypeAnnotation; + } + }); + Object.defineProperty(exports, "EnumDeclaration", { + enumerable: true, + get: function () { + return _index.enumDeclaration; + } + }); + Object.defineProperty(exports, "EnumBooleanBody", { + enumerable: true, + get: function () { + return _index.enumBooleanBody; + } + }); + Object.defineProperty(exports, "EnumNumberBody", { + enumerable: true, + get: function () { + return _index.enumNumberBody; + } + }); + Object.defineProperty(exports, "EnumStringBody", { + enumerable: true, + get: function () { + return _index.enumStringBody; + } + }); + Object.defineProperty(exports, "EnumSymbolBody", { + enumerable: true, + get: function () { + return _index.enumSymbolBody; + } + }); + Object.defineProperty(exports, "EnumBooleanMember", { + enumerable: true, + get: function () { + return _index.enumBooleanMember; + } + }); + Object.defineProperty(exports, "EnumNumberMember", { + enumerable: true, + get: function () { + return _index.enumNumberMember; + } + }); + Object.defineProperty(exports, "EnumStringMember", { + enumerable: true, + get: function () { + return _index.enumStringMember; + } + }); + Object.defineProperty(exports, "EnumDefaultedMember", { + enumerable: true, + get: function () { + return _index.enumDefaultedMember; + } + }); + Object.defineProperty(exports, "IndexedAccessType", { + enumerable: true, + get: function () { + return _index.indexedAccessType; + } + }); + Object.defineProperty(exports, "OptionalIndexedAccessType", { + enumerable: true, + get: function () { + return _index.optionalIndexedAccessType; + } + }); + Object.defineProperty(exports, "JSXAttribute", { + enumerable: true, + get: function () { + return _index.jsxAttribute; + } + }); + Object.defineProperty(exports, "JSXClosingElement", { + enumerable: true, + get: function () { + return _index.jsxClosingElement; + } + }); + Object.defineProperty(exports, "JSXElement", { + enumerable: true, + get: function () { + return _index.jsxElement; + } + }); + Object.defineProperty(exports, "JSXEmptyExpression", { + enumerable: true, + get: function () { + return _index.jsxEmptyExpression; + } + }); + Object.defineProperty(exports, "JSXExpressionContainer", { + enumerable: true, + get: function () { + return _index.jsxExpressionContainer; + } + }); + Object.defineProperty(exports, "JSXSpreadChild", { + enumerable: true, + get: function () { + return _index.jsxSpreadChild; + } + }); + Object.defineProperty(exports, "JSXIdentifier", { + enumerable: true, + get: function () { + return _index.jsxIdentifier; + } + }); + Object.defineProperty(exports, "JSXMemberExpression", { + enumerable: true, + get: function () { + return _index.jsxMemberExpression; + } + }); + Object.defineProperty(exports, "JSXNamespacedName", { + enumerable: true, + get: function () { + return _index.jsxNamespacedName; + } + }); + Object.defineProperty(exports, "JSXOpeningElement", { + enumerable: true, + get: function () { + return _index.jsxOpeningElement; + } + }); + Object.defineProperty(exports, "JSXSpreadAttribute", { + enumerable: true, + get: function () { + return _index.jsxSpreadAttribute; + } + }); + Object.defineProperty(exports, "JSXText", { + enumerable: true, + get: function () { + return _index.jsxText; + } + }); + Object.defineProperty(exports, "JSXFragment", { + enumerable: true, + get: function () { + return _index.jsxFragment; + } + }); + Object.defineProperty(exports, "JSXOpeningFragment", { + enumerable: true, + get: function () { + return _index.jsxOpeningFragment; + } + }); + Object.defineProperty(exports, "JSXClosingFragment", { + enumerable: true, + get: function () { + return _index.jsxClosingFragment; + } + }); + Object.defineProperty(exports, "Noop", { + enumerable: true, + get: function () { + return _index.noop; + } + }); + Object.defineProperty(exports, "Placeholder", { + enumerable: true, + get: function () { + return _index.placeholder; + } + }); + Object.defineProperty(exports, "V8IntrinsicIdentifier", { + enumerable: true, + get: function () { + return _index.v8IntrinsicIdentifier; + } + }); + Object.defineProperty(exports, "ArgumentPlaceholder", { + enumerable: true, + get: function () { + return _index.argumentPlaceholder; + } + }); + Object.defineProperty(exports, "BindExpression", { + enumerable: true, + get: function () { + return _index.bindExpression; + } + }); + Object.defineProperty(exports, "ImportAttribute", { + enumerable: true, + get: function () { + return _index.importAttribute; + } + }); + Object.defineProperty(exports, "Decorator", { + enumerable: true, + get: function () { + return _index.decorator; + } + }); + Object.defineProperty(exports, "DoExpression", { + enumerable: true, + get: function () { + return _index.doExpression; + } + }); + Object.defineProperty(exports, "ExportDefaultSpecifier", { + enumerable: true, + get: function () { + return _index.exportDefaultSpecifier; + } + }); + Object.defineProperty(exports, "RecordExpression", { + enumerable: true, + get: function () { + return _index.recordExpression; + } + }); + Object.defineProperty(exports, "TupleExpression", { + enumerable: true, + get: function () { + return _index.tupleExpression; + } + }); + Object.defineProperty(exports, "DecimalLiteral", { + enumerable: true, + get: function () { + return _index.decimalLiteral; + } + }); + Object.defineProperty(exports, "StaticBlock", { + enumerable: true, + get: function () { + return _index.staticBlock; + } + }); + Object.defineProperty(exports, "ModuleExpression", { + enumerable: true, + get: function () { + return _index.moduleExpression; + } + }); + Object.defineProperty(exports, "TopicReference", { + enumerable: true, + get: function () { + return _index.topicReference; + } + }); + Object.defineProperty(exports, "PipelineTopicExpression", { + enumerable: true, + get: function () { + return _index.pipelineTopicExpression; + } + }); + Object.defineProperty(exports, "PipelineBareFunction", { + enumerable: true, + get: function () { + return _index.pipelineBareFunction; + } + }); + Object.defineProperty(exports, "PipelinePrimaryTopicReference", { + enumerable: true, + get: function () { + return _index.pipelinePrimaryTopicReference; + } + }); + Object.defineProperty(exports, "TSParameterProperty", { + enumerable: true, + get: function () { + return _index.tsParameterProperty; + } + }); + Object.defineProperty(exports, "TSDeclareFunction", { + enumerable: true, + get: function () { + return _index.tsDeclareFunction; + } + }); + Object.defineProperty(exports, "TSDeclareMethod", { + enumerable: true, + get: function () { + return _index.tsDeclareMethod; + } + }); + Object.defineProperty(exports, "TSQualifiedName", { + enumerable: true, + get: function () { + return _index.tsQualifiedName; + } + }); + Object.defineProperty(exports, "TSCallSignatureDeclaration", { + enumerable: true, + get: function () { + return _index.tsCallSignatureDeclaration; + } + }); + Object.defineProperty(exports, "TSConstructSignatureDeclaration", { + enumerable: true, + get: function () { + return _index.tsConstructSignatureDeclaration; + } + }); + Object.defineProperty(exports, "TSPropertySignature", { + enumerable: true, + get: function () { + return _index.tsPropertySignature; + } + }); + Object.defineProperty(exports, "TSMethodSignature", { + enumerable: true, + get: function () { + return _index.tsMethodSignature; + } + }); + Object.defineProperty(exports, "TSIndexSignature", { + enumerable: true, + get: function () { + return _index.tsIndexSignature; + } + }); + Object.defineProperty(exports, "TSAnyKeyword", { + enumerable: true, + get: function () { + return _index.tsAnyKeyword; + } + }); + Object.defineProperty(exports, "TSBooleanKeyword", { + enumerable: true, + get: function () { + return _index.tsBooleanKeyword; + } + }); + Object.defineProperty(exports, "TSBigIntKeyword", { + enumerable: true, + get: function () { + return _index.tsBigIntKeyword; + } + }); + Object.defineProperty(exports, "TSIntrinsicKeyword", { + enumerable: true, + get: function () { + return _index.tsIntrinsicKeyword; + } + }); + Object.defineProperty(exports, "TSNeverKeyword", { + enumerable: true, + get: function () { + return _index.tsNeverKeyword; + } + }); + Object.defineProperty(exports, "TSNullKeyword", { + enumerable: true, + get: function () { + return _index.tsNullKeyword; + } + }); + Object.defineProperty(exports, "TSNumberKeyword", { + enumerable: true, + get: function () { + return _index.tsNumberKeyword; + } + }); + Object.defineProperty(exports, "TSObjectKeyword", { + enumerable: true, + get: function () { + return _index.tsObjectKeyword; + } + }); + Object.defineProperty(exports, "TSStringKeyword", { + enumerable: true, + get: function () { + return _index.tsStringKeyword; + } + }); + Object.defineProperty(exports, "TSSymbolKeyword", { + enumerable: true, + get: function () { + return _index.tsSymbolKeyword; + } + }); + Object.defineProperty(exports, "TSUndefinedKeyword", { + enumerable: true, + get: function () { + return _index.tsUndefinedKeyword; + } + }); + Object.defineProperty(exports, "TSUnknownKeyword", { + enumerable: true, + get: function () { + return _index.tsUnknownKeyword; + } + }); + Object.defineProperty(exports, "TSVoidKeyword", { + enumerable: true, + get: function () { + return _index.tsVoidKeyword; + } + }); + Object.defineProperty(exports, "TSThisType", { + enumerable: true, + get: function () { + return _index.tsThisType; + } + }); + Object.defineProperty(exports, "TSFunctionType", { + enumerable: true, + get: function () { + return _index.tsFunctionType; + } + }); + Object.defineProperty(exports, "TSConstructorType", { + enumerable: true, + get: function () { + return _index.tsConstructorType; + } + }); + Object.defineProperty(exports, "TSTypeReference", { + enumerable: true, + get: function () { + return _index.tsTypeReference; + } + }); + Object.defineProperty(exports, "TSTypePredicate", { + enumerable: true, + get: function () { + return _index.tsTypePredicate; + } + }); + Object.defineProperty(exports, "TSTypeQuery", { + enumerable: true, + get: function () { + return _index.tsTypeQuery; + } + }); + Object.defineProperty(exports, "TSTypeLiteral", { + enumerable: true, + get: function () { + return _index.tsTypeLiteral; + } + }); + Object.defineProperty(exports, "TSArrayType", { + enumerable: true, + get: function () { + return _index.tsArrayType; + } + }); + Object.defineProperty(exports, "TSTupleType", { + enumerable: true, + get: function () { + return _index.tsTupleType; + } + }); + Object.defineProperty(exports, "TSOptionalType", { + enumerable: true, + get: function () { + return _index.tsOptionalType; + } + }); + Object.defineProperty(exports, "TSRestType", { + enumerable: true, + get: function () { + return _index.tsRestType; + } + }); + Object.defineProperty(exports, "TSNamedTupleMember", { + enumerable: true, + get: function () { + return _index.tsNamedTupleMember; + } + }); + Object.defineProperty(exports, "TSUnionType", { + enumerable: true, + get: function () { + return _index.tsUnionType; + } + }); + Object.defineProperty(exports, "TSIntersectionType", { + enumerable: true, + get: function () { + return _index.tsIntersectionType; + } + }); + Object.defineProperty(exports, "TSConditionalType", { + enumerable: true, + get: function () { + return _index.tsConditionalType; + } + }); + Object.defineProperty(exports, "TSInferType", { + enumerable: true, + get: function () { + return _index.tsInferType; + } + }); + Object.defineProperty(exports, "TSParenthesizedType", { + enumerable: true, + get: function () { + return _index.tsParenthesizedType; + } + }); + Object.defineProperty(exports, "TSTypeOperator", { + enumerable: true, + get: function () { + return _index.tsTypeOperator; + } + }); + Object.defineProperty(exports, "TSIndexedAccessType", { + enumerable: true, + get: function () { + return _index.tsIndexedAccessType; + } + }); + Object.defineProperty(exports, "TSMappedType", { + enumerable: true, + get: function () { + return _index.tsMappedType; + } + }); + Object.defineProperty(exports, "TSLiteralType", { + enumerable: true, + get: function () { + return _index.tsLiteralType; + } + }); + Object.defineProperty(exports, "TSExpressionWithTypeArguments", { + enumerable: true, + get: function () { + return _index.tsExpressionWithTypeArguments; + } + }); + Object.defineProperty(exports, "TSInterfaceDeclaration", { + enumerable: true, + get: function () { + return _index.tsInterfaceDeclaration; + } + }); + Object.defineProperty(exports, "TSInterfaceBody", { + enumerable: true, + get: function () { + return _index.tsInterfaceBody; + } + }); + Object.defineProperty(exports, "TSTypeAliasDeclaration", { + enumerable: true, + get: function () { + return _index.tsTypeAliasDeclaration; + } + }); + Object.defineProperty(exports, "TSAsExpression", { + enumerable: true, + get: function () { + return _index.tsAsExpression; + } + }); + Object.defineProperty(exports, "TSTypeAssertion", { + enumerable: true, + get: function () { + return _index.tsTypeAssertion; + } + }); + Object.defineProperty(exports, "TSEnumDeclaration", { + enumerable: true, + get: function () { + return _index.tsEnumDeclaration; + } + }); + Object.defineProperty(exports, "TSEnumMember", { + enumerable: true, + get: function () { + return _index.tsEnumMember; + } + }); + Object.defineProperty(exports, "TSModuleDeclaration", { + enumerable: true, + get: function () { + return _index.tsModuleDeclaration; + } + }); + Object.defineProperty(exports, "TSModuleBlock", { + enumerable: true, + get: function () { + return _index.tsModuleBlock; + } + }); + Object.defineProperty(exports, "TSImportType", { + enumerable: true, + get: function () { + return _index.tsImportType; + } + }); + Object.defineProperty(exports, "TSImportEqualsDeclaration", { + enumerable: true, + get: function () { + return _index.tsImportEqualsDeclaration; + } + }); + Object.defineProperty(exports, "TSExternalModuleReference", { + enumerable: true, + get: function () { + return _index.tsExternalModuleReference; + } + }); + Object.defineProperty(exports, "TSNonNullExpression", { + enumerable: true, + get: function () { + return _index.tsNonNullExpression; + } + }); + Object.defineProperty(exports, "TSExportAssignment", { + enumerable: true, + get: function () { + return _index.tsExportAssignment; + } + }); + Object.defineProperty(exports, "TSNamespaceExportDeclaration", { + enumerable: true, + get: function () { + return _index.tsNamespaceExportDeclaration; + } + }); + Object.defineProperty(exports, "TSTypeAnnotation", { + enumerable: true, + get: function () { + return _index.tsTypeAnnotation; + } + }); + Object.defineProperty(exports, "TSTypeParameterInstantiation", { + enumerable: true, + get: function () { + return _index.tsTypeParameterInstantiation; + } + }); + Object.defineProperty(exports, "TSTypeParameterDeclaration", { + enumerable: true, + get: function () { + return _index.tsTypeParameterDeclaration; + } + }); + Object.defineProperty(exports, "TSTypeParameter", { + enumerable: true, + get: function () { + return _index.tsTypeParameter; + } + }); + Object.defineProperty(exports, "NumberLiteral", { + enumerable: true, + get: function () { + return _index.numberLiteral; + } + }); + Object.defineProperty(exports, "RegexLiteral", { + enumerable: true, + get: function () { + return _index.regexLiteral; + } + }); + Object.defineProperty(exports, "RestProperty", { + enumerable: true, + get: function () { + return _index.restProperty; + } + }); + Object.defineProperty(exports, "SpreadProperty", { + enumerable: true, + get: function () { + return _index.spreadProperty; + } + }); + + var _index = generated$7; + } (uppercase)); + + var cloneNode$3 = {}; + + Object.defineProperty(cloneNode$3, "__esModule", { + value: true + }); + cloneNode$3.default = cloneNode$2; + + var _definitions$b = requireDefinitions$1(); + + var _generated$E = generated$8; + + const has$2 = Function.call.bind(Object.prototype.hasOwnProperty); + + function cloneIfNode$1(obj, deep, withoutLoc) { + if (obj && typeof obj.type === "string") { + return cloneNode$2(obj, deep, withoutLoc); + } + + return obj; + } + + function cloneIfNodeOrArray$1(obj, deep, withoutLoc) { + if (Array.isArray(obj)) { + return obj.map(node => cloneIfNode$1(node, deep, withoutLoc)); + } + + return cloneIfNode$1(obj, deep, withoutLoc); + } + + function cloneNode$2(node, deep = true, withoutLoc = false) { + if (!node) return node; + const { + type + } = node; + const newNode = { + type: node.type + }; + + if ((0, _generated$E.isIdentifier)(node)) { + newNode.name = node.name; + + if (has$2(node, "optional") && typeof node.optional === "boolean") { + newNode.optional = node.optional; + } + + if (has$2(node, "typeAnnotation")) { + newNode.typeAnnotation = deep ? cloneIfNodeOrArray$1(node.typeAnnotation, true, withoutLoc) : node.typeAnnotation; + } + } else if (!has$2(_definitions$b.NODE_FIELDS, type)) { + throw new Error(`Unknown node type: "${type}"`); + } else { + for (const field of Object.keys(_definitions$b.NODE_FIELDS[type])) { + if (has$2(node, field)) { + if (deep) { + newNode[field] = (0, _generated$E.isFile)(node) && field === "comments" ? maybeCloneComments$1(node.comments, deep, withoutLoc) : cloneIfNodeOrArray$1(node[field], true, withoutLoc); + } else { + newNode[field] = node[field]; + } + } + } + } + + if (has$2(node, "loc")) { + if (withoutLoc) { + newNode.loc = null; + } else { + newNode.loc = node.loc; + } + } + + if (has$2(node, "leadingComments")) { + newNode.leadingComments = maybeCloneComments$1(node.leadingComments, deep, withoutLoc); + } + + if (has$2(node, "innerComments")) { + newNode.innerComments = maybeCloneComments$1(node.innerComments, deep, withoutLoc); + } + + if (has$2(node, "trailingComments")) { + newNode.trailingComments = maybeCloneComments$1(node.trailingComments, deep, withoutLoc); + } + + if (has$2(node, "extra")) { + newNode.extra = Object.assign({}, node.extra); + } + + return newNode; + } + + function maybeCloneComments$1(comments, deep, withoutLoc) { + if (!comments || !deep) { + return comments; + } + + return comments.map(({ + type, + value, + loc + }) => { + if (withoutLoc) { + return { + type, + value, + loc: null + }; + } + + return { + type, + value, + loc + }; + }); + } + + var clone$4 = {}; + + Object.defineProperty(clone$4, "__esModule", { + value: true + }); + clone$4.default = clone$3; + + var _cloneNode$b = cloneNode$3; + + function clone$3(node) { + return (0, _cloneNode$b.default)(node, false); + } + + var cloneDeep$3 = {}; + + Object.defineProperty(cloneDeep$3, "__esModule", { + value: true + }); + cloneDeep$3.default = cloneDeep$2; + + var _cloneNode$a = cloneNode$3; + + function cloneDeep$2(node) { + return (0, _cloneNode$a.default)(node); + } + + var cloneDeepWithoutLoc$3 = {}; + + Object.defineProperty(cloneDeepWithoutLoc$3, "__esModule", { + value: true + }); + cloneDeepWithoutLoc$3.default = cloneDeepWithoutLoc$2; + + var _cloneNode$9 = cloneNode$3; + + function cloneDeepWithoutLoc$2(node) { + return (0, _cloneNode$9.default)(node, true, true); + } + + var cloneWithoutLoc$3 = {}; + + Object.defineProperty(cloneWithoutLoc$3, "__esModule", { + value: true + }); + cloneWithoutLoc$3.default = cloneWithoutLoc$2; + + var _cloneNode$8 = cloneNode$3; + + function cloneWithoutLoc$2(node) { + return (0, _cloneNode$8.default)(node, false, true); + } + + var addComment$3 = {}; + + var addComments$3 = {}; + + Object.defineProperty(addComments$3, "__esModule", { + value: true + }); + addComments$3.default = addComments$2; + + function addComments$2(node, type, comments) { + if (!comments || !node) return node; + const key = `${type}Comments`; + + if (node[key]) { + if (type === "leading") { + node[key] = comments.concat(node[key]); + } else { + node[key].push(...comments); + } + } else { + node[key] = comments; + } + + return node; + } + + Object.defineProperty(addComment$3, "__esModule", { + value: true + }); + addComment$3.default = addComment$2; + + var _addComments$1 = addComments$3; + + function addComment$2(node, type, content, line) { + return (0, _addComments$1.default)(node, type, [{ + type: line ? "CommentLine" : "CommentBlock", + value: content + }]); + } + + var inheritInnerComments$3 = {}; + + var inherit$3 = {}; + + Object.defineProperty(inherit$3, "__esModule", { + value: true + }); + inherit$3.default = inherit$2; + + function inherit$2(key, child, parent) { + if (child && parent) { + child[key] = Array.from(new Set([].concat(child[key], parent[key]).filter(Boolean))); + } + } + + Object.defineProperty(inheritInnerComments$3, "__esModule", { + value: true + }); + inheritInnerComments$3.default = inheritInnerComments$2; + + var _inherit$5 = inherit$3; + + function inheritInnerComments$2(child, parent) { + (0, _inherit$5.default)("innerComments", child, parent); + } + + var inheritLeadingComments$3 = {}; + + Object.defineProperty(inheritLeadingComments$3, "__esModule", { + value: true + }); + inheritLeadingComments$3.default = inheritLeadingComments$2; + + var _inherit$4 = inherit$3; + + function inheritLeadingComments$2(child, parent) { + (0, _inherit$4.default)("leadingComments", child, parent); + } + + var inheritsComments$3 = {}; + + var inheritTrailingComments$3 = {}; + + Object.defineProperty(inheritTrailingComments$3, "__esModule", { + value: true + }); + inheritTrailingComments$3.default = inheritTrailingComments$2; + + var _inherit$3 = inherit$3; + + function inheritTrailingComments$2(child, parent) { + (0, _inherit$3.default)("trailingComments", child, parent); + } + + Object.defineProperty(inheritsComments$3, "__esModule", { + value: true + }); + inheritsComments$3.default = inheritsComments$2; + + var _inheritTrailingComments$1 = inheritTrailingComments$3; + + var _inheritLeadingComments$1 = inheritLeadingComments$3; + + var _inheritInnerComments$1 = inheritInnerComments$3; + + function inheritsComments$2(child, parent) { + (0, _inheritTrailingComments$1.default)(child, parent); + (0, _inheritLeadingComments$1.default)(child, parent); + (0, _inheritInnerComments$1.default)(child, parent); + return child; + } + + var removeComments$3 = {}; + + Object.defineProperty(removeComments$3, "__esModule", { + value: true + }); + removeComments$3.default = removeComments$2; + + var _constants$9 = constants$1; + + function removeComments$2(node) { + _constants$9.COMMENT_KEYS.forEach(key => { + node[key] = null; + }); + + return node; + } + + var generated$5 = {}; + + Object.defineProperty(generated$5, "__esModule", { + value: true + }); + generated$5.TSBASETYPE_TYPES = generated$5.TSTYPE_TYPES = generated$5.TSTYPEELEMENT_TYPES = generated$5.JSX_TYPES = generated$5.ENUMMEMBER_TYPES = generated$5.ENUMBODY_TYPES = generated$5.FLOWPREDICATE_TYPES = generated$5.FLOWDECLARATION_TYPES = generated$5.FLOWBASEANNOTATION_TYPES = generated$5.FLOWTYPE_TYPES = generated$5.FLOW_TYPES = generated$5.PRIVATE_TYPES = generated$5.MODULESPECIFIER_TYPES = generated$5.EXPORTDECLARATION_TYPES = generated$5.MODULEDECLARATION_TYPES = generated$5.CLASS_TYPES = generated$5.PATTERN_TYPES = generated$5.UNARYLIKE_TYPES = generated$5.PROPERTY_TYPES = generated$5.OBJECTMEMBER_TYPES = generated$5.METHOD_TYPES = generated$5.USERWHITESPACABLE_TYPES = generated$5.IMMUTABLE_TYPES = generated$5.LITERAL_TYPES = generated$5.TSENTITYNAME_TYPES = generated$5.LVAL_TYPES = generated$5.PATTERNLIKE_TYPES = generated$5.DECLARATION_TYPES = generated$5.PUREISH_TYPES = generated$5.FUNCTIONPARENT_TYPES = generated$5.FUNCTION_TYPES = generated$5.FORXSTATEMENT_TYPES = generated$5.FOR_TYPES = generated$5.EXPRESSIONWRAPPER_TYPES = generated$5.WHILE_TYPES = generated$5.LOOP_TYPES = generated$5.CONDITIONAL_TYPES = generated$5.COMPLETIONSTATEMENT_TYPES = generated$5.TERMINATORLESS_TYPES = generated$5.STATEMENT_TYPES = generated$5.BLOCK_TYPES = generated$5.BLOCKPARENT_TYPES = generated$5.SCOPABLE_TYPES = generated$5.BINARY_TYPES = generated$5.EXPRESSION_TYPES = void 0; + + var _definitions$a = requireDefinitions$1(); + + const EXPRESSION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Expression"]; + generated$5.EXPRESSION_TYPES = EXPRESSION_TYPES$1; + const BINARY_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Binary"]; + generated$5.BINARY_TYPES = BINARY_TYPES$1; + const SCOPABLE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Scopable"]; + generated$5.SCOPABLE_TYPES = SCOPABLE_TYPES$1; + const BLOCKPARENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["BlockParent"]; + generated$5.BLOCKPARENT_TYPES = BLOCKPARENT_TYPES$1; + const BLOCK_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Block"]; + generated$5.BLOCK_TYPES = BLOCK_TYPES$1; + const STATEMENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Statement"]; + generated$5.STATEMENT_TYPES = STATEMENT_TYPES$1; + const TERMINATORLESS_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Terminatorless"]; + generated$5.TERMINATORLESS_TYPES = TERMINATORLESS_TYPES$1; + const COMPLETIONSTATEMENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["CompletionStatement"]; + generated$5.COMPLETIONSTATEMENT_TYPES = COMPLETIONSTATEMENT_TYPES$1; + const CONDITIONAL_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Conditional"]; + generated$5.CONDITIONAL_TYPES = CONDITIONAL_TYPES$1; + const LOOP_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Loop"]; + generated$5.LOOP_TYPES = LOOP_TYPES$1; + const WHILE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["While"]; + generated$5.WHILE_TYPES = WHILE_TYPES$1; + const EXPRESSIONWRAPPER_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ExpressionWrapper"]; + generated$5.EXPRESSIONWRAPPER_TYPES = EXPRESSIONWRAPPER_TYPES$1; + const FOR_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["For"]; + generated$5.FOR_TYPES = FOR_TYPES$1; + const FORXSTATEMENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ForXStatement"]; + generated$5.FORXSTATEMENT_TYPES = FORXSTATEMENT_TYPES$1; + const FUNCTION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Function"]; + generated$5.FUNCTION_TYPES = FUNCTION_TYPES$1; + const FUNCTIONPARENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["FunctionParent"]; + generated$5.FUNCTIONPARENT_TYPES = FUNCTIONPARENT_TYPES$1; + const PUREISH_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Pureish"]; + generated$5.PUREISH_TYPES = PUREISH_TYPES$1; + const DECLARATION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Declaration"]; + generated$5.DECLARATION_TYPES = DECLARATION_TYPES$1; + const PATTERNLIKE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["PatternLike"]; + generated$5.PATTERNLIKE_TYPES = PATTERNLIKE_TYPES$1; + const LVAL_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["LVal"]; + generated$5.LVAL_TYPES = LVAL_TYPES$1; + const TSENTITYNAME_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["TSEntityName"]; + generated$5.TSENTITYNAME_TYPES = TSENTITYNAME_TYPES$1; + const LITERAL_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Literal"]; + generated$5.LITERAL_TYPES = LITERAL_TYPES$1; + const IMMUTABLE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Immutable"]; + generated$5.IMMUTABLE_TYPES = IMMUTABLE_TYPES$1; + const USERWHITESPACABLE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["UserWhitespacable"]; + generated$5.USERWHITESPACABLE_TYPES = USERWHITESPACABLE_TYPES$1; + const METHOD_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Method"]; + generated$5.METHOD_TYPES = METHOD_TYPES$1; + const OBJECTMEMBER_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ObjectMember"]; + generated$5.OBJECTMEMBER_TYPES = OBJECTMEMBER_TYPES$1; + const PROPERTY_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Property"]; + generated$5.PROPERTY_TYPES = PROPERTY_TYPES$1; + const UNARYLIKE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["UnaryLike"]; + generated$5.UNARYLIKE_TYPES = UNARYLIKE_TYPES$1; + const PATTERN_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Pattern"]; + generated$5.PATTERN_TYPES = PATTERN_TYPES$1; + const CLASS_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Class"]; + generated$5.CLASS_TYPES = CLASS_TYPES$1; + const MODULEDECLARATION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ModuleDeclaration"]; + generated$5.MODULEDECLARATION_TYPES = MODULEDECLARATION_TYPES$1; + const EXPORTDECLARATION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ExportDeclaration"]; + generated$5.EXPORTDECLARATION_TYPES = EXPORTDECLARATION_TYPES$1; + const MODULESPECIFIER_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["ModuleSpecifier"]; + generated$5.MODULESPECIFIER_TYPES = MODULESPECIFIER_TYPES$1; + const PRIVATE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Private"]; + generated$5.PRIVATE_TYPES = PRIVATE_TYPES$1; + const FLOW_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["Flow"]; + generated$5.FLOW_TYPES = FLOW_TYPES$1; + const FLOWTYPE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["FlowType"]; + generated$5.FLOWTYPE_TYPES = FLOWTYPE_TYPES$1; + const FLOWBASEANNOTATION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["FlowBaseAnnotation"]; + generated$5.FLOWBASEANNOTATION_TYPES = FLOWBASEANNOTATION_TYPES$1; + const FLOWDECLARATION_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["FlowDeclaration"]; + generated$5.FLOWDECLARATION_TYPES = FLOWDECLARATION_TYPES$1; + const FLOWPREDICATE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["FlowPredicate"]; + generated$5.FLOWPREDICATE_TYPES = FLOWPREDICATE_TYPES$1; + const ENUMBODY_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["EnumBody"]; + generated$5.ENUMBODY_TYPES = ENUMBODY_TYPES$1; + const ENUMMEMBER_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["EnumMember"]; + generated$5.ENUMMEMBER_TYPES = ENUMMEMBER_TYPES$1; + const JSX_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["JSX"]; + generated$5.JSX_TYPES = JSX_TYPES$1; + const TSTYPEELEMENT_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["TSTypeElement"]; + generated$5.TSTYPEELEMENT_TYPES = TSTYPEELEMENT_TYPES$1; + const TSTYPE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["TSType"]; + generated$5.TSTYPE_TYPES = TSTYPE_TYPES$1; + const TSBASETYPE_TYPES$1 = _definitions$a.FLIPPED_ALIAS_KEYS["TSBaseType"]; + generated$5.TSBASETYPE_TYPES = TSBASETYPE_TYPES$1; + + var ensureBlock$3 = {}; + + var toBlock$3 = {}; + + Object.defineProperty(toBlock$3, "__esModule", { + value: true + }); + toBlock$3.default = toBlock$2; + + var _generated$D = generated$8; + + var _generated2$7 = generated$7; + + function toBlock$2(node, parent) { + if ((0, _generated$D.isBlockStatement)(node)) { + return node; + } + + let blockNodes = []; + + if ((0, _generated$D.isEmptyStatement)(node)) { + blockNodes = []; + } else { + if (!(0, _generated$D.isStatement)(node)) { + if ((0, _generated$D.isFunction)(parent)) { + node = (0, _generated2$7.returnStatement)(node); + } else { + node = (0, _generated2$7.expressionStatement)(node); + } + } + + blockNodes = [node]; + } + + return (0, _generated2$7.blockStatement)(blockNodes); + } + + Object.defineProperty(ensureBlock$3, "__esModule", { + value: true + }); + ensureBlock$3.default = ensureBlock$2; + + var _toBlock$1 = toBlock$3; + + function ensureBlock$2(node, key = "body") { + return node[key] = (0, _toBlock$1.default)(node[key], node); + } + + var toBindingIdentifierName$3 = {}; + + var toIdentifier$3 = {}; + + Object.defineProperty(toIdentifier$3, "__esModule", { + value: true + }); + toIdentifier$3.default = toIdentifier$2; + + var _isValidIdentifier$5 = isValidIdentifier$3; + + var _helperValidatorIdentifier$1 = lib$5; + + function toIdentifier$2(input) { + input = input + ""; + let name = ""; + + for (const c of input) { + name += (0, _helperValidatorIdentifier$1.isIdentifierChar)(c.codePointAt(0)) ? c : "-"; + } + + name = name.replace(/^[-0-9]+/, ""); + name = name.replace(/[-\s]+(.)?/g, function (match, c) { + return c ? c.toUpperCase() : ""; + }); + + if (!(0, _isValidIdentifier$5.default)(name)) { + name = `_${name}`; + } + + return name || "_"; + } + + Object.defineProperty(toBindingIdentifierName$3, "__esModule", { + value: true + }); + toBindingIdentifierName$3.default = toBindingIdentifierName$2; + + var _toIdentifier$1 = toIdentifier$3; + + function toBindingIdentifierName$2(name) { + name = (0, _toIdentifier$1.default)(name); + if (name === "eval" || name === "arguments") name = "_" + name; + return name; + } + + var toComputedKey$3 = {}; + + Object.defineProperty(toComputedKey$3, "__esModule", { + value: true + }); + toComputedKey$3.default = toComputedKey$2; + + var _generated$C = generated$8; + + var _generated2$6 = generated$7; + + function toComputedKey$2(node, key = node.key || node.property) { + if (!node.computed && (0, _generated$C.isIdentifier)(key)) key = (0, _generated2$6.stringLiteral)(key.name); + return key; + } + + var toExpression$3 = {}; + + Object.defineProperty(toExpression$3, "__esModule", { + value: true + }); + toExpression$3.default = void 0; + + var _generated$B = generated$8; + + var _default$7 = toExpression$2; + toExpression$3.default = _default$7; + + function toExpression$2(node) { + if ((0, _generated$B.isExpressionStatement)(node)) { + node = node.expression; + } + + if ((0, _generated$B.isExpression)(node)) { + return node; + } + + if ((0, _generated$B.isClass)(node)) { + node.type = "ClassExpression"; + } else if ((0, _generated$B.isFunction)(node)) { + node.type = "FunctionExpression"; + } + + if (!(0, _generated$B.isExpression)(node)) { + throw new Error(`cannot turn ${node.type} to an expression`); + } + + return node; + } + + var toKeyAlias$3 = {}; + + var removePropertiesDeep$3 = {}; + + var traverseFast$3 = {}; + + Object.defineProperty(traverseFast$3, "__esModule", { + value: true + }); + traverseFast$3.default = traverseFast$2; + + var _definitions$9 = requireDefinitions$1(); + + function traverseFast$2(node, enter, opts) { + if (!node) return; + const keys = _definitions$9.VISITOR_KEYS[node.type]; + if (!keys) return; + opts = opts || {}; + enter(node, opts); + + for (const key of keys) { + const subNode = node[key]; + + if (Array.isArray(subNode)) { + for (const node of subNode) { + traverseFast$2(node, enter, opts); + } + } else { + traverseFast$2(subNode, enter, opts); + } + } + } + + var removeProperties$3 = {}; + + Object.defineProperty(removeProperties$3, "__esModule", { + value: true + }); + removeProperties$3.default = removeProperties$2; + + var _constants$8 = constants$1; + + const CLEAR_KEYS$1 = ["tokens", "start", "end", "loc", "raw", "rawValue"]; + + const CLEAR_KEYS_PLUS_COMMENTS$1 = _constants$8.COMMENT_KEYS.concat(["comments"]).concat(CLEAR_KEYS$1); + + function removeProperties$2(node, opts = {}) { + const map = opts.preserveComments ? CLEAR_KEYS$1 : CLEAR_KEYS_PLUS_COMMENTS$1; + + for (const key of map) { + if (node[key] != null) node[key] = undefined; + } + + for (const key of Object.keys(node)) { + if (key[0] === "_" && node[key] != null) node[key] = undefined; + } + + const symbols = Object.getOwnPropertySymbols(node); + + for (const sym of symbols) { + node[sym] = null; + } + } + + Object.defineProperty(removePropertiesDeep$3, "__esModule", { + value: true + }); + removePropertiesDeep$3.default = removePropertiesDeep$2; + + var _traverseFast$1 = traverseFast$3; + + var _removeProperties$1 = removeProperties$3; + + function removePropertiesDeep$2(tree, opts) { + (0, _traverseFast$1.default)(tree, _removeProperties$1.default, opts); + return tree; + } + + Object.defineProperty(toKeyAlias$3, "__esModule", { + value: true + }); + toKeyAlias$3.default = toKeyAlias$2; + + var _generated$A = generated$8; + + var _cloneNode$7 = cloneNode$3; + + var _removePropertiesDeep$1 = removePropertiesDeep$3; + + function toKeyAlias$2(node, key = node.key) { + let alias; + + if (node.kind === "method") { + return toKeyAlias$2.increment() + ""; + } else if ((0, _generated$A.isIdentifier)(key)) { + alias = key.name; + } else if ((0, _generated$A.isStringLiteral)(key)) { + alias = JSON.stringify(key.value); + } else { + alias = JSON.stringify((0, _removePropertiesDeep$1.default)((0, _cloneNode$7.default)(key))); + } + + if (node.computed) { + alias = `[${alias}]`; + } + + if (node.static) { + alias = `static:${alias}`; + } + + return alias; + } + + toKeyAlias$2.uid = 0; + + toKeyAlias$2.increment = function () { + if (toKeyAlias$2.uid >= Number.MAX_SAFE_INTEGER) { + return toKeyAlias$2.uid = 0; + } else { + return toKeyAlias$2.uid++; + } + }; + + var toSequenceExpression$3 = {}; + + var gatherSequenceExpressions$3 = {}; + + var getBindingIdentifiers$3 = {}; + + Object.defineProperty(getBindingIdentifiers$3, "__esModule", { + value: true + }); + getBindingIdentifiers$3.default = getBindingIdentifiers$2; + + var _generated$z = generated$8; + + function getBindingIdentifiers$2(node, duplicates, outerOnly) { + let search = [].concat(node); + const ids = Object.create(null); + + while (search.length) { + const id = search.shift(); + if (!id) continue; + const keys = getBindingIdentifiers$2.keys[id.type]; + + if ((0, _generated$z.isIdentifier)(id)) { + if (duplicates) { + const _ids = ids[id.name] = ids[id.name] || []; + + _ids.push(id); + } else { + ids[id.name] = id; + } + + continue; + } + + if ((0, _generated$z.isExportDeclaration)(id) && !(0, _generated$z.isExportAllDeclaration)(id)) { + if ((0, _generated$z.isDeclaration)(id.declaration)) { + search.push(id.declaration); + } + + continue; + } + + if (outerOnly) { + if ((0, _generated$z.isFunctionDeclaration)(id)) { + search.push(id.id); + continue; + } + + if ((0, _generated$z.isFunctionExpression)(id)) { + continue; + } + } + + if (keys) { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if (id[key]) { + search = search.concat(id[key]); + } + } + } + } + + return ids; + } + + getBindingIdentifiers$2.keys = { + DeclareClass: ["id"], + DeclareFunction: ["id"], + DeclareModule: ["id"], + DeclareVariable: ["id"], + DeclareInterface: ["id"], + DeclareTypeAlias: ["id"], + DeclareOpaqueType: ["id"], + InterfaceDeclaration: ["id"], + TypeAlias: ["id"], + OpaqueType: ["id"], + CatchClause: ["param"], + LabeledStatement: ["label"], + UnaryExpression: ["argument"], + AssignmentExpression: ["left"], + ImportSpecifier: ["local"], + ImportNamespaceSpecifier: ["local"], + ImportDefaultSpecifier: ["local"], + ImportDeclaration: ["specifiers"], + ExportSpecifier: ["exported"], + ExportNamespaceSpecifier: ["exported"], + ExportDefaultSpecifier: ["exported"], + FunctionDeclaration: ["id", "params"], + FunctionExpression: ["id", "params"], + ArrowFunctionExpression: ["params"], + ObjectMethod: ["params"], + ClassMethod: ["params"], + ClassPrivateMethod: ["params"], + ForInStatement: ["left"], + ForOfStatement: ["left"], + ClassDeclaration: ["id"], + ClassExpression: ["id"], + RestElement: ["argument"], + UpdateExpression: ["argument"], + ObjectProperty: ["value"], + AssignmentPattern: ["left"], + ArrayPattern: ["elements"], + ObjectPattern: ["properties"], + VariableDeclaration: ["declarations"], + VariableDeclarator: ["id"] + }; + + Object.defineProperty(gatherSequenceExpressions$3, "__esModule", { + value: true + }); + gatherSequenceExpressions$3.default = gatherSequenceExpressions$2; + + var _getBindingIdentifiers$5 = getBindingIdentifiers$3; + + var _generated$y = generated$8; + + var _generated2$5 = generated$7; + + var _cloneNode$6 = cloneNode$3; + + function gatherSequenceExpressions$2(nodes, scope, declars) { + const exprs = []; + let ensureLastUndefined = true; + + for (const node of nodes) { + if (!(0, _generated$y.isEmptyStatement)(node)) { + ensureLastUndefined = false; + } + + if ((0, _generated$y.isExpression)(node)) { + exprs.push(node); + } else if ((0, _generated$y.isExpressionStatement)(node)) { + exprs.push(node.expression); + } else if ((0, _generated$y.isVariableDeclaration)(node)) { + if (node.kind !== "var") return; + + for (const declar of node.declarations) { + const bindings = (0, _getBindingIdentifiers$5.default)(declar); + + for (const key of Object.keys(bindings)) { + declars.push({ + kind: node.kind, + id: (0, _cloneNode$6.default)(bindings[key]) + }); + } + + if (declar.init) { + exprs.push((0, _generated2$5.assignmentExpression)("=", declar.id, declar.init)); + } + } + + ensureLastUndefined = true; + } else if ((0, _generated$y.isIfStatement)(node)) { + const consequent = node.consequent ? gatherSequenceExpressions$2([node.consequent], scope, declars) : scope.buildUndefinedNode(); + const alternate = node.alternate ? gatherSequenceExpressions$2([node.alternate], scope, declars) : scope.buildUndefinedNode(); + if (!consequent || !alternate) return; + exprs.push((0, _generated2$5.conditionalExpression)(node.test, consequent, alternate)); + } else if ((0, _generated$y.isBlockStatement)(node)) { + const body = gatherSequenceExpressions$2(node.body, scope, declars); + if (!body) return; + exprs.push(body); + } else if ((0, _generated$y.isEmptyStatement)(node)) { + if (nodes.indexOf(node) === 0) { + ensureLastUndefined = true; + } + } else { + return; + } + } + + if (ensureLastUndefined) { + exprs.push(scope.buildUndefinedNode()); + } + + if (exprs.length === 1) { + return exprs[0]; + } else { + return (0, _generated2$5.sequenceExpression)(exprs); + } + } + + Object.defineProperty(toSequenceExpression$3, "__esModule", { + value: true + }); + toSequenceExpression$3.default = toSequenceExpression$2; + + var _gatherSequenceExpressions$1 = gatherSequenceExpressions$3; + + function toSequenceExpression$2(nodes, scope) { + if (!(nodes != null && nodes.length)) return; + const declars = []; + const result = (0, _gatherSequenceExpressions$1.default)(nodes, scope, declars); + if (!result) return; + + for (const declar of declars) { + scope.push(declar); + } + + return result; + } + + var toStatement$3 = {}; + + Object.defineProperty(toStatement$3, "__esModule", { + value: true + }); + toStatement$3.default = void 0; + + var _generated$x = generated$8; + + var _generated2$4 = generated$7; + + var _default$6 = toStatement$2; + toStatement$3.default = _default$6; + + function toStatement$2(node, ignore) { + if ((0, _generated$x.isStatement)(node)) { + return node; + } + + let mustHaveId = false; + let newType; + + if ((0, _generated$x.isClass)(node)) { + mustHaveId = true; + newType = "ClassDeclaration"; + } else if ((0, _generated$x.isFunction)(node)) { + mustHaveId = true; + newType = "FunctionDeclaration"; + } else if ((0, _generated$x.isAssignmentExpression)(node)) { + return (0, _generated2$4.expressionStatement)(node); + } + + if (mustHaveId && !node.id) { + newType = false; + } + + if (!newType) { + if (ignore) { + return false; + } else { + throw new Error(`cannot turn ${node.type} to a statement`); + } + } + + node.type = newType; + return node; + } + + var valueToNode$3 = {}; + + Object.defineProperty(valueToNode$3, "__esModule", { + value: true + }); + valueToNode$3.default = void 0; + + var _isValidIdentifier$4 = isValidIdentifier$3; + + var _generated$w = generated$7; + + var _default$5 = valueToNode$2; + valueToNode$3.default = _default$5; + const objectToString$2 = Function.call.bind(Object.prototype.toString); + + function isRegExp$1(value) { + return objectToString$2(value) === "[object RegExp]"; + } + + function isPlainObject$1(value) { + if (typeof value !== "object" || value === null || Object.prototype.toString.call(value) !== "[object Object]") { + return false; + } + + const proto = Object.getPrototypeOf(value); + return proto === null || Object.getPrototypeOf(proto) === null; + } + + function valueToNode$2(value) { + if (value === undefined) { + return (0, _generated$w.identifier)("undefined"); + } + + if (value === true || value === false) { + return (0, _generated$w.booleanLiteral)(value); + } + + if (value === null) { + return (0, _generated$w.nullLiteral)(); + } + + if (typeof value === "string") { + return (0, _generated$w.stringLiteral)(value); + } + + if (typeof value === "number") { + let result; + + if (Number.isFinite(value)) { + result = (0, _generated$w.numericLiteral)(Math.abs(value)); + } else { + let numerator; + + if (Number.isNaN(value)) { + numerator = (0, _generated$w.numericLiteral)(0); + } else { + numerator = (0, _generated$w.numericLiteral)(1); + } + + result = (0, _generated$w.binaryExpression)("/", numerator, (0, _generated$w.numericLiteral)(0)); + } + + if (value < 0 || Object.is(value, -0)) { + result = (0, _generated$w.unaryExpression)("-", result); + } + + return result; + } + + if (isRegExp$1(value)) { + const pattern = value.source; + const flags = value.toString().match(/\/([a-z]+|)$/)[1]; + return (0, _generated$w.regExpLiteral)(pattern, flags); + } + + if (Array.isArray(value)) { + return (0, _generated$w.arrayExpression)(value.map(valueToNode$2)); + } + + if (isPlainObject$1(value)) { + const props = []; + + for (const key of Object.keys(value)) { + let nodeKey; + + if ((0, _isValidIdentifier$4.default)(key)) { + nodeKey = (0, _generated$w.identifier)(key); + } else { + nodeKey = (0, _generated$w.stringLiteral)(key); + } + + props.push((0, _generated$w.objectProperty)(nodeKey, valueToNode$2(value[key]))); + } + + return (0, _generated$w.objectExpression)(props); + } + + throw new Error("don't know how to turn this value into a node"); + } + + var appendToMemberExpression$3 = {}; + + Object.defineProperty(appendToMemberExpression$3, "__esModule", { + value: true + }); + appendToMemberExpression$3.default = appendToMemberExpression$2; + + var _generated$v = generated$7; + + function appendToMemberExpression$2(member, append, computed = false) { + member.object = (0, _generated$v.memberExpression)(member.object, member.property, member.computed); + member.property = append; + member.computed = !!computed; + return member; + } + + var inherits$3 = {}; + + Object.defineProperty(inherits$3, "__esModule", { + value: true + }); + inherits$3.default = inherits$2; + + var _constants$7 = constants$1; + + var _inheritsComments$1 = inheritsComments$3; + + function inherits$2(child, parent) { + if (!child || !parent) return child; + + for (const key of _constants$7.INHERIT_KEYS.optional) { + if (child[key] == null) { + child[key] = parent[key]; + } + } + + for (const key of Object.keys(parent)) { + if (key[0] === "_" && key !== "__clone") child[key] = parent[key]; + } + + for (const key of _constants$7.INHERIT_KEYS.force) { + child[key] = parent[key]; + } + + (0, _inheritsComments$1.default)(child, parent); + return child; + } + + var prependToMemberExpression$3 = {}; + + Object.defineProperty(prependToMemberExpression$3, "__esModule", { + value: true + }); + prependToMemberExpression$3.default = prependToMemberExpression$2; + + var _generated$u = generated$7; + + function prependToMemberExpression$2(member, prepend) { + member.object = (0, _generated$u.memberExpression)(prepend, member.object); + return member; + } + + var getOuterBindingIdentifiers$3 = {}; + + Object.defineProperty(getOuterBindingIdentifiers$3, "__esModule", { + value: true + }); + getOuterBindingIdentifiers$3.default = void 0; + + var _getBindingIdentifiers$4 = getBindingIdentifiers$3; + + var _default$4 = getOuterBindingIdentifiers$2; + getOuterBindingIdentifiers$3.default = _default$4; + + function getOuterBindingIdentifiers$2(node, duplicates) { + return (0, _getBindingIdentifiers$4.default)(node, duplicates, true); + } + + var traverse$3 = {}; + + Object.defineProperty(traverse$3, "__esModule", { + value: true + }); + traverse$3.default = traverse$2; + + var _definitions$8 = requireDefinitions$1(); + + function traverse$2(node, handlers, state) { + if (typeof handlers === "function") { + handlers = { + enter: handlers + }; + } + + const { + enter, + exit + } = handlers; + traverseSimpleImpl$1(node, enter, exit, state, []); + } + + function traverseSimpleImpl$1(node, enter, exit, state, ancestors) { + const keys = _definitions$8.VISITOR_KEYS[node.type]; + if (!keys) return; + if (enter) enter(node, ancestors, state); + + for (const key of keys) { + const subNode = node[key]; + + if (Array.isArray(subNode)) { + for (let i = 0; i < subNode.length; i++) { + const child = subNode[i]; + if (!child) continue; + ancestors.push({ + node, + key, + index: i + }); + traverseSimpleImpl$1(child, enter, exit, state, ancestors); + ancestors.pop(); + } + } else if (subNode) { + ancestors.push({ + node, + key + }); + traverseSimpleImpl$1(subNode, enter, exit, state, ancestors); + ancestors.pop(); + } + } + + if (exit) exit(node, ancestors, state); + } + + var isBinding$3 = {}; + + Object.defineProperty(isBinding$3, "__esModule", { + value: true + }); + isBinding$3.default = isBinding$2; + + var _getBindingIdentifiers$3 = getBindingIdentifiers$3; + + function isBinding$2(node, parent, grandparent) { + if (grandparent && node.type === "Identifier" && parent.type === "ObjectProperty" && grandparent.type === "ObjectExpression") { + return false; + } + + const keys = _getBindingIdentifiers$3.default.keys[parent.type]; + + if (keys) { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = parent[key]; + + if (Array.isArray(val)) { + if (val.indexOf(node) >= 0) return true; + } else { + if (val === node) return true; + } + } + } + + return false; + } + + var isBlockScoped$3 = {}; + + var isLet$3 = {}; + + Object.defineProperty(isLet$3, "__esModule", { + value: true + }); + isLet$3.default = isLet$2; + + var _generated$t = generated$8; + + var _constants$6 = constants$1; + + function isLet$2(node) { + return (0, _generated$t.isVariableDeclaration)(node) && (node.kind !== "var" || node[_constants$6.BLOCK_SCOPED_SYMBOL]); + } + + Object.defineProperty(isBlockScoped$3, "__esModule", { + value: true + }); + isBlockScoped$3.default = isBlockScoped$2; + + var _generated$s = generated$8; + + var _isLet$1 = isLet$3; + + function isBlockScoped$2(node) { + return (0, _generated$s.isFunctionDeclaration)(node) || (0, _generated$s.isClassDeclaration)(node) || (0, _isLet$1.default)(node); + } + + var isImmutable$4 = {}; + + Object.defineProperty(isImmutable$4, "__esModule", { + value: true + }); + isImmutable$4.default = isImmutable$3; + + var _isType$1 = requireIsType$1(); + + var _generated$r = generated$8; + + function isImmutable$3(node) { + if ((0, _isType$1.default)(node.type, "Immutable")) return true; + + if ((0, _generated$r.isIdentifier)(node)) { + if (node.name === "undefined") { + return true; + } else { + return false; + } + } + + return false; + } + + var isNodesEquivalent$3 = {}; + + Object.defineProperty(isNodesEquivalent$3, "__esModule", { + value: true + }); + isNodesEquivalent$3.default = isNodesEquivalent$2; + + var _definitions$7 = requireDefinitions$1(); + + function isNodesEquivalent$2(a, b) { + if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) { + return a === b; + } + + if (a.type !== b.type) { + return false; + } + + const fields = Object.keys(_definitions$7.NODE_FIELDS[a.type] || a.type); + const visitorKeys = _definitions$7.VISITOR_KEYS[a.type]; + + for (const field of fields) { + if (typeof a[field] !== typeof b[field]) { + return false; + } + + if (a[field] == null && b[field] == null) { + continue; + } else if (a[field] == null || b[field] == null) { + return false; + } + + if (Array.isArray(a[field])) { + if (!Array.isArray(b[field])) { + return false; + } + + if (a[field].length !== b[field].length) { + return false; + } + + for (let i = 0; i < a[field].length; i++) { + if (!isNodesEquivalent$2(a[field][i], b[field][i])) { + return false; + } + } + + continue; + } + + if (typeof a[field] === "object" && !(visitorKeys != null && visitorKeys.includes(field))) { + for (const key of Object.keys(a[field])) { + if (a[field][key] !== b[field][key]) { + return false; + } + } + + continue; + } + + if (!isNodesEquivalent$2(a[field], b[field])) { + return false; + } + } + + return true; + } + + var isReferenced$3 = {}; + + Object.defineProperty(isReferenced$3, "__esModule", { + value: true + }); + isReferenced$3.default = isReferenced$2; + + function isReferenced$2(node, parent, grandparent) { + switch (parent.type) { + case "MemberExpression": + case "OptionalMemberExpression": + if (parent.property === node) { + return !!parent.computed; + } + + return parent.object === node; + + case "JSXMemberExpression": + return parent.object === node; + + case "VariableDeclarator": + return parent.init === node; + + case "ArrowFunctionExpression": + return parent.body === node; + + case "PrivateName": + return false; + + case "ClassMethod": + case "ClassPrivateMethod": + case "ObjectMethod": + if (parent.key === node) { + return !!parent.computed; + } + + return false; + + case "ObjectProperty": + if (parent.key === node) { + return !!parent.computed; + } + + return !grandparent || grandparent.type !== "ObjectPattern"; + + case "ClassProperty": + if (parent.key === node) { + return !!parent.computed; + } + + return true; + + case "ClassPrivateProperty": + return parent.key !== node; + + case "ClassDeclaration": + case "ClassExpression": + return parent.superClass === node; + + case "AssignmentExpression": + return parent.right === node; + + case "AssignmentPattern": + return parent.right === node; + + case "LabeledStatement": + return false; + + case "CatchClause": + return false; + + case "RestElement": + return false; + + case "BreakStatement": + case "ContinueStatement": + return false; + + case "FunctionDeclaration": + case "FunctionExpression": + return false; + + case "ExportNamespaceSpecifier": + case "ExportDefaultSpecifier": + return false; + + case "ExportSpecifier": + if (grandparent != null && grandparent.source) { + return false; + } + + return parent.local === node; + + case "ImportDefaultSpecifier": + case "ImportNamespaceSpecifier": + case "ImportSpecifier": + return false; + + case "ImportAttribute": + return false; + + case "JSXAttribute": + return false; + + case "ObjectPattern": + case "ArrayPattern": + return false; + + case "MetaProperty": + return false; + + case "ObjectTypeProperty": + return parent.key !== node; + + case "TSEnumMember": + return parent.id !== node; + + case "TSPropertySignature": + if (parent.key === node) { + return !!parent.computed; + } + + return true; + } + + return true; + } + + var isScope$3 = {}; + + Object.defineProperty(isScope$3, "__esModule", { + value: true + }); + isScope$3.default = isScope$2; + + var _generated$q = generated$8; + + function isScope$2(node, parent) { + if ((0, _generated$q.isBlockStatement)(node) && ((0, _generated$q.isFunction)(parent) || (0, _generated$q.isCatchClause)(parent))) { + return false; + } + + if ((0, _generated$q.isPattern)(node) && ((0, _generated$q.isFunction)(parent) || (0, _generated$q.isCatchClause)(parent))) { + return true; + } + + return (0, _generated$q.isScopable)(node); + } + + var isSpecifierDefault$3 = {}; + + Object.defineProperty(isSpecifierDefault$3, "__esModule", { + value: true + }); + isSpecifierDefault$3.default = isSpecifierDefault$2; + + var _generated$p = generated$8; + + function isSpecifierDefault$2(specifier) { + return (0, _generated$p.isImportDefaultSpecifier)(specifier) || (0, _generated$p.isIdentifier)(specifier.imported || specifier.exported, { + name: "default" + }); + } + + var isValidES3Identifier$3 = {}; + + Object.defineProperty(isValidES3Identifier$3, "__esModule", { + value: true + }); + isValidES3Identifier$3.default = isValidES3Identifier$2; + + var _isValidIdentifier$3 = isValidIdentifier$3; + + const RESERVED_WORDS_ES3_ONLY$1 = new Set(["abstract", "boolean", "byte", "char", "double", "enum", "final", "float", "goto", "implements", "int", "interface", "long", "native", "package", "private", "protected", "public", "short", "static", "synchronized", "throws", "transient", "volatile"]); + + function isValidES3Identifier$2(name) { + return (0, _isValidIdentifier$3.default)(name) && !RESERVED_WORDS_ES3_ONLY$1.has(name); + } + + var isVar$3 = {}; + + Object.defineProperty(isVar$3, "__esModule", { + value: true + }); + isVar$3.default = isVar$2; + + var _generated$o = generated$8; + + var _constants$5 = constants$1; + + function isVar$2(node) { + return (0, _generated$o.isVariableDeclaration)(node, { + kind: "var" + }) && !node[_constants$5.BLOCK_SCOPED_SYMBOL]; + } + + var generated$4 = {}; + + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + var _exportNames = { + react: true, + assertNode: true, + createTypeAnnotationBasedOnTypeof: true, + createUnionTypeAnnotation: true, + createFlowUnionType: true, + createTSUnionType: true, + cloneNode: true, + clone: true, + cloneDeep: true, + cloneDeepWithoutLoc: true, + cloneWithoutLoc: true, + addComment: true, + addComments: true, + inheritInnerComments: true, + inheritLeadingComments: true, + inheritsComments: true, + inheritTrailingComments: true, + removeComments: true, + ensureBlock: true, + toBindingIdentifierName: true, + toBlock: true, + toComputedKey: true, + toExpression: true, + toIdentifier: true, + toKeyAlias: true, + toSequenceExpression: true, + toStatement: true, + valueToNode: true, + appendToMemberExpression: true, + inherits: true, + prependToMemberExpression: true, + removeProperties: true, + removePropertiesDeep: true, + removeTypeDuplicates: true, + getBindingIdentifiers: true, + getOuterBindingIdentifiers: true, + traverse: true, + traverseFast: true, + shallowEqual: true, + is: true, + isBinding: true, + isBlockScoped: true, + isImmutable: true, + isLet: true, + isNode: true, + isNodesEquivalent: true, + isPlaceholderType: true, + isReferenced: true, + isScope: true, + isSpecifierDefault: true, + isType: true, + isValidES3Identifier: true, + isValidIdentifier: true, + isVar: true, + matchesPattern: true, + validate: true, + buildMatchMemberExpression: true + }; + Object.defineProperty(exports, "assertNode", { + enumerable: true, + get: function () { + return _assertNode.default; + } + }); + Object.defineProperty(exports, "createTypeAnnotationBasedOnTypeof", { + enumerable: true, + get: function () { + return _createTypeAnnotationBasedOnTypeof.default; + } + }); + Object.defineProperty(exports, "createUnionTypeAnnotation", { + enumerable: true, + get: function () { + return _createFlowUnionType.default; + } + }); + Object.defineProperty(exports, "createFlowUnionType", { + enumerable: true, + get: function () { + return _createFlowUnionType.default; + } + }); + Object.defineProperty(exports, "createTSUnionType", { + enumerable: true, + get: function () { + return _createTSUnionType.default; + } + }); + Object.defineProperty(exports, "cloneNode", { + enumerable: true, + get: function () { + return _cloneNode.default; + } + }); + Object.defineProperty(exports, "clone", { + enumerable: true, + get: function () { + return _clone.default; + } + }); + Object.defineProperty(exports, "cloneDeep", { + enumerable: true, + get: function () { + return _cloneDeep.default; + } + }); + Object.defineProperty(exports, "cloneDeepWithoutLoc", { + enumerable: true, + get: function () { + return _cloneDeepWithoutLoc.default; + } + }); + Object.defineProperty(exports, "cloneWithoutLoc", { + enumerable: true, + get: function () { + return _cloneWithoutLoc.default; + } + }); + Object.defineProperty(exports, "addComment", { + enumerable: true, + get: function () { + return _addComment.default; + } + }); + Object.defineProperty(exports, "addComments", { + enumerable: true, + get: function () { + return _addComments.default; + } + }); + Object.defineProperty(exports, "inheritInnerComments", { + enumerable: true, + get: function () { + return _inheritInnerComments.default; + } + }); + Object.defineProperty(exports, "inheritLeadingComments", { + enumerable: true, + get: function () { + return _inheritLeadingComments.default; + } + }); + Object.defineProperty(exports, "inheritsComments", { + enumerable: true, + get: function () { + return _inheritsComments.default; + } + }); + Object.defineProperty(exports, "inheritTrailingComments", { + enumerable: true, + get: function () { + return _inheritTrailingComments.default; + } + }); + Object.defineProperty(exports, "removeComments", { + enumerable: true, + get: function () { + return _removeComments.default; + } + }); + Object.defineProperty(exports, "ensureBlock", { + enumerable: true, + get: function () { + return _ensureBlock.default; + } + }); + Object.defineProperty(exports, "toBindingIdentifierName", { + enumerable: true, + get: function () { + return _toBindingIdentifierName.default; + } + }); + Object.defineProperty(exports, "toBlock", { + enumerable: true, + get: function () { + return _toBlock.default; + } + }); + Object.defineProperty(exports, "toComputedKey", { + enumerable: true, + get: function () { + return _toComputedKey.default; + } + }); + Object.defineProperty(exports, "toExpression", { + enumerable: true, + get: function () { + return _toExpression.default; + } + }); + Object.defineProperty(exports, "toIdentifier", { + enumerable: true, + get: function () { + return _toIdentifier.default; + } + }); + Object.defineProperty(exports, "toKeyAlias", { + enumerable: true, + get: function () { + return _toKeyAlias.default; + } + }); + Object.defineProperty(exports, "toSequenceExpression", { + enumerable: true, + get: function () { + return _toSequenceExpression.default; + } + }); + Object.defineProperty(exports, "toStatement", { + enumerable: true, + get: function () { + return _toStatement.default; + } + }); + Object.defineProperty(exports, "valueToNode", { + enumerable: true, + get: function () { + return _valueToNode.default; + } + }); + Object.defineProperty(exports, "appendToMemberExpression", { + enumerable: true, + get: function () { + return _appendToMemberExpression.default; + } + }); + Object.defineProperty(exports, "inherits", { + enumerable: true, + get: function () { + return _inherits.default; + } + }); + Object.defineProperty(exports, "prependToMemberExpression", { + enumerable: true, + get: function () { + return _prependToMemberExpression.default; + } + }); + Object.defineProperty(exports, "removeProperties", { + enumerable: true, + get: function () { + return _removeProperties.default; + } + }); + Object.defineProperty(exports, "removePropertiesDeep", { + enumerable: true, + get: function () { + return _removePropertiesDeep.default; + } + }); + Object.defineProperty(exports, "removeTypeDuplicates", { + enumerable: true, + get: function () { + return _removeTypeDuplicates.default; + } + }); + Object.defineProperty(exports, "getBindingIdentifiers", { + enumerable: true, + get: function () { + return _getBindingIdentifiers.default; + } + }); + Object.defineProperty(exports, "getOuterBindingIdentifiers", { + enumerable: true, + get: function () { + return _getOuterBindingIdentifiers.default; + } + }); + Object.defineProperty(exports, "traverse", { + enumerable: true, + get: function () { + return _traverse.default; + } + }); + Object.defineProperty(exports, "traverseFast", { + enumerable: true, + get: function () { + return _traverseFast.default; + } + }); + Object.defineProperty(exports, "shallowEqual", { + enumerable: true, + get: function () { + return _shallowEqual.default; + } + }); + Object.defineProperty(exports, "is", { + enumerable: true, + get: function () { + return _is.default; + } + }); + Object.defineProperty(exports, "isBinding", { + enumerable: true, + get: function () { + return _isBinding.default; + } + }); + Object.defineProperty(exports, "isBlockScoped", { + enumerable: true, + get: function () { + return _isBlockScoped.default; + } + }); + Object.defineProperty(exports, "isImmutable", { + enumerable: true, + get: function () { + return _isImmutable.default; + } + }); + Object.defineProperty(exports, "isLet", { + enumerable: true, + get: function () { + return _isLet.default; + } + }); + Object.defineProperty(exports, "isNode", { + enumerable: true, + get: function () { + return _isNode.default; + } + }); + Object.defineProperty(exports, "isNodesEquivalent", { + enumerable: true, + get: function () { + return _isNodesEquivalent.default; + } + }); + Object.defineProperty(exports, "isPlaceholderType", { + enumerable: true, + get: function () { + return _isPlaceholderType.default; + } + }); + Object.defineProperty(exports, "isReferenced", { + enumerable: true, + get: function () { + return _isReferenced.default; + } + }); + Object.defineProperty(exports, "isScope", { + enumerable: true, + get: function () { + return _isScope.default; + } + }); + Object.defineProperty(exports, "isSpecifierDefault", { + enumerable: true, + get: function () { + return _isSpecifierDefault.default; + } + }); + Object.defineProperty(exports, "isType", { + enumerable: true, + get: function () { + return _isType.default; + } + }); + Object.defineProperty(exports, "isValidES3Identifier", { + enumerable: true, + get: function () { + return _isValidES3Identifier.default; + } + }); + Object.defineProperty(exports, "isValidIdentifier", { + enumerable: true, + get: function () { + return _isValidIdentifier.default; + } + }); + Object.defineProperty(exports, "isVar", { + enumerable: true, + get: function () { + return _isVar.default; + } + }); + Object.defineProperty(exports, "matchesPattern", { + enumerable: true, + get: function () { + return _matchesPattern.default; + } + }); + Object.defineProperty(exports, "validate", { + enumerable: true, + get: function () { + return _validate.default; + } + }); + Object.defineProperty(exports, "buildMatchMemberExpression", { + enumerable: true, + get: function () { + return _buildMatchMemberExpression.default; + } + }); + exports.react = void 0; + + var _isReactComponent = isReactComponent$4; + + var _isCompatTag = isCompatTag$3; + + var _buildChildren = buildChildren$3; + + var _assertNode = assertNode$3; + + var _generated = generated$6; + + Object.keys(_generated).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _generated[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated[key]; + } + }); + }); + + var _createTypeAnnotationBasedOnTypeof = createTypeAnnotationBasedOnTypeof$3; + + var _createFlowUnionType = createFlowUnionType$3; + + var _createTSUnionType = createTSUnionType$3; + + var _generated2 = generated$7; + + Object.keys(_generated2).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _generated2[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated2[key]; + } + }); + }); + + var _uppercase = uppercase; + + Object.keys(_uppercase).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _uppercase[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _uppercase[key]; + } + }); + }); + + var _cloneNode = cloneNode$3; + + var _clone = clone$4; + + var _cloneDeep = cloneDeep$3; + + var _cloneDeepWithoutLoc = cloneDeepWithoutLoc$3; + + var _cloneWithoutLoc = cloneWithoutLoc$3; + + var _addComment = addComment$3; + + var _addComments = addComments$3; + + var _inheritInnerComments = inheritInnerComments$3; + + var _inheritLeadingComments = inheritLeadingComments$3; + + var _inheritsComments = inheritsComments$3; + + var _inheritTrailingComments = inheritTrailingComments$3; + + var _removeComments = removeComments$3; + + var _generated3 = generated$5; + + Object.keys(_generated3).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _generated3[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated3[key]; + } + }); + }); + + var _constants = constants$1; + + Object.keys(_constants).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _constants[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _constants[key]; + } + }); + }); + + var _ensureBlock = ensureBlock$3; + + var _toBindingIdentifierName = toBindingIdentifierName$3; + + var _toBlock = toBlock$3; + + var _toComputedKey = toComputedKey$3; + + var _toExpression = toExpression$3; + + var _toIdentifier = toIdentifier$3; + + var _toKeyAlias = toKeyAlias$3; + + var _toSequenceExpression = toSequenceExpression$3; + + var _toStatement = toStatement$3; + + var _valueToNode = valueToNode$3; + + var _definitions = requireDefinitions$1(); + + Object.keys(_definitions).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _definitions[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _definitions[key]; + } + }); + }); + + var _appendToMemberExpression = appendToMemberExpression$3; + + var _inherits = inherits$3; + + var _prependToMemberExpression = prependToMemberExpression$3; + + var _removeProperties = removeProperties$3; + + var _removePropertiesDeep = removePropertiesDeep$3; + + var _removeTypeDuplicates = removeTypeDuplicates$7; + + var _getBindingIdentifiers = getBindingIdentifiers$3; + + var _getOuterBindingIdentifiers = getOuterBindingIdentifiers$3; + + var _traverse = traverse$3; + + Object.keys(_traverse).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _traverse[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _traverse[key]; + } + }); + }); + + var _traverseFast = traverseFast$3; + + var _shallowEqual = shallowEqual$3; + + var _is = requireIs$1(); + + var _isBinding = isBinding$3; + + var _isBlockScoped = isBlockScoped$3; + + var _isImmutable = isImmutable$4; + + var _isLet = isLet$3; + + var _isNode = isNode$4; + + var _isNodesEquivalent = isNodesEquivalent$3; + + var _isPlaceholderType = requireIsPlaceholderType$1(); + + var _isReferenced = isReferenced$3; + + var _isScope = isScope$3; + + var _isSpecifierDefault = isSpecifierDefault$3; + + var _isType = requireIsType$1(); + + var _isValidES3Identifier = isValidES3Identifier$3; + + var _isValidIdentifier = isValidIdentifier$3; + + var _isVar = isVar$3; + + var _matchesPattern = matchesPattern$3; + + var _validate = requireValidate$1(); + + var _buildMatchMemberExpression = buildMatchMemberExpression$3; + + var _generated4 = generated$8; + + Object.keys(_generated4).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _generated4[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated4[key]; + } + }); + }); + + var _generated5 = generated$4; + + Object.keys(_generated5).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _generated5[key]) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated5[key]; + } + }); + }); + const react = { + isReactComponent: _isReactComponent.default, + isCompatTag: _isCompatTag.default, + buildChildren: _buildChildren.default + }; + exports.react = react; + } (lib$6)); + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + + function createSimplePath(ancestors) { + if (ancestors.length === 0) { + return null; + } + + // Slice the array because babel-types traverse may continue mutating + // the ancestors array in later traversal logic. + return new SimplePath(ancestors.slice()); + } + + /** + * Mimics @babel/traverse's NodePath API in a simpler fashion that isn't as + * heavy, but still allows the ease of passing paths around to process nested + * AST structures. + */ + class SimplePath { + _index; + _ancestors; + _ancestor; + + _parentPath; + + constructor(ancestors, index = ancestors.length - 1) { + if (index < 0 || index >= ancestors.length) { + console.error(ancestors); + throw new Error("Created invalid path"); + } + + this._ancestors = ancestors; + this._ancestor = ancestors[index]; + this._index = index; + } + + get parentPath() { + let path = this._parentPath; + if (path === undefined) { + if (this._index === 0) { + path = null; + } else { + path = new SimplePath(this._ancestors, this._index - 1); + } + this._parentPath = path; + } + + return path; + } + + get parent() { + return this._ancestor.node; + } + + get node() { + const { node, key, index } = this._ancestor; + + if (typeof index === "number") { + return node[key][index]; + } + + return node[key]; + } + + get key() { + return this._ancestor.key; + } + + set node(replacement) { + if (this.type !== "Identifier") { + throw new Error( + "Replacing anything other than leaf nodes is undefined behavior " + + "in t.traverse()" + ); + } + + const { node, key, index } = this._ancestor; + if (typeof index === "number") { + node[key][index] = replacement; + } else { + node[key] = replacement; + } + } + + get type() { + return this.node.type; + } + + get inList() { + return typeof this._ancestor.index === "number"; + } + + get containerIndex() { + const { index } = this._ancestor; + + if (typeof index !== "number") { + throw new Error("Cannot get index of non-array node"); + } + + return index; + } + + get depth() { + return this._index; + } + + replace(node) { + this.node = node; + } + + find(predicate) { + for (let path = this; path; path = path.parentPath) { + if (predicate(path)) { + return path; + } + } + return null; + } + + findParent(predicate) { + if (!this.parentPath) { + throw new Error("Cannot use findParent on root path"); + } + + return this.parentPath.find(predicate); + } + + getSibling(offset) { + const { node, key, index } = this._ancestor; + + if (typeof index !== "number") { + throw new Error("Non-array nodes do not have siblings"); + } + + const container = node[key]; + + const siblingIndex = index + offset; + if (siblingIndex < 0 || siblingIndex >= container.length) { + return null; + } + + return new SimplePath( + this._ancestors.slice(0, -1).concat([{ node, key, index: siblingIndex }]) + ); + } + } + + var dist = {}; + + var lib$4 = {}; + + var isReactComponent$2 = {}; + + var buildMatchMemberExpression$1 = {}; + + var matchesPattern$1 = {}; + + var generated$3 = {}; + + var shallowEqual$1 = {}; + + Object.defineProperty(shallowEqual$1, "__esModule", { + value: true + }); + shallowEqual$1.default = shallowEqual; + + function shallowEqual(actual, expected) { + const keys = Object.keys(expected); + + for (const key of keys) { + if (actual[key] !== expected[key]) { + return false; + } + } + + return true; + } + + Object.defineProperty(generated$3, "__esModule", { + value: true + }); + generated$3.isArrayExpression = isArrayExpression$1; + generated$3.isAssignmentExpression = isAssignmentExpression$2; + generated$3.isBinaryExpression = isBinaryExpression$1; + generated$3.isInterpreterDirective = isInterpreterDirective; + generated$3.isDirective = isDirective; + generated$3.isDirectiveLiteral = isDirectiveLiteral; + generated$3.isBlockStatement = isBlockStatement$1; + generated$3.isBreakStatement = isBreakStatement; + generated$3.isCallExpression = isCallExpression$4; + generated$3.isCatchClause = isCatchClause; + generated$3.isConditionalExpression = isConditionalExpression$1; + generated$3.isContinueStatement = isContinueStatement; + generated$3.isDebuggerStatement = isDebuggerStatement; + generated$3.isDoWhileStatement = isDoWhileStatement; + generated$3.isEmptyStatement = isEmptyStatement$1; + generated$3.isExpressionStatement = isExpressionStatement$2; + generated$3.isFile = isFile$1; + generated$3.isForInStatement = isForInStatement$1; + generated$3.isForStatement = isForStatement$2; + generated$3.isFunctionDeclaration = isFunctionDeclaration; + generated$3.isFunctionExpression = isFunctionExpression; + generated$3.isIdentifier = isIdentifier$3; + generated$3.isIfStatement = isIfStatement$2; + generated$3.isLabeledStatement = isLabeledStatement; + generated$3.isStringLiteral = isStringLiteral$1; + generated$3.isNumericLiteral = isNumericLiteral; + generated$3.isNullLiteral = isNullLiteral; + generated$3.isBooleanLiteral = isBooleanLiteral; + generated$3.isRegExpLiteral = isRegExpLiteral; + generated$3.isLogicalExpression = isLogicalExpression$1; + generated$3.isMemberExpression = isMemberExpression$4; + generated$3.isNewExpression = isNewExpression$3; + generated$3.isProgram = isProgram$1; + generated$3.isObjectExpression = isObjectExpression$1; + generated$3.isObjectMethod = isObjectMethod; + generated$3.isObjectProperty = isObjectProperty; + generated$3.isRestElement = isRestElement; + generated$3.isReturnStatement = isReturnStatement$1; + generated$3.isSequenceExpression = isSequenceExpression$1; + generated$3.isParenthesizedExpression = isParenthesizedExpression; + generated$3.isSwitchCase = isSwitchCase; + generated$3.isSwitchStatement = isSwitchStatement$1; + generated$3.isThisExpression = isThisExpression; + generated$3.isThrowStatement = isThrowStatement$1; + generated$3.isTryStatement = isTryStatement; + generated$3.isUnaryExpression = isUnaryExpression; + generated$3.isUpdateExpression = isUpdateExpression; + generated$3.isVariableDeclaration = isVariableDeclaration; + generated$3.isVariableDeclarator = isVariableDeclarator$1; + generated$3.isWhileStatement = isWhileStatement$1; + generated$3.isWithStatement = isWithStatement; + generated$3.isAssignmentPattern = isAssignmentPattern$1; + generated$3.isArrayPattern = isArrayPattern; + generated$3.isArrowFunctionExpression = isArrowFunctionExpression$1; + generated$3.isClassBody = isClassBody; + generated$3.isClassExpression = isClassExpression$1; + generated$3.isClassDeclaration = isClassDeclaration$2; + generated$3.isExportAllDeclaration = isExportAllDeclaration; + generated$3.isExportDefaultDeclaration = isExportDefaultDeclaration$2; + generated$3.isExportNamedDeclaration = isExportNamedDeclaration$1; + generated$3.isExportSpecifier = isExportSpecifier; + generated$3.isForOfStatement = isForOfStatement$1; + generated$3.isImportDeclaration = isImportDeclaration; + generated$3.isImportDefaultSpecifier = isImportDefaultSpecifier$1; + generated$3.isImportNamespaceSpecifier = isImportNamespaceSpecifier$1; + generated$3.isImportSpecifier = isImportSpecifier; + generated$3.isMetaProperty = isMetaProperty; + generated$3.isClassMethod = isClassMethod; + generated$3.isObjectPattern = isObjectPattern$1; + generated$3.isSpreadElement = isSpreadElement; + generated$3.isSuper = isSuper; + generated$3.isTaggedTemplateExpression = isTaggedTemplateExpression$1; + generated$3.isTemplateElement = isTemplateElement; + generated$3.isTemplateLiteral = isTemplateLiteral; + generated$3.isYieldExpression = isYieldExpression$1; + generated$3.isAnyTypeAnnotation = isAnyTypeAnnotation; + generated$3.isArrayTypeAnnotation = isArrayTypeAnnotation$1; + generated$3.isBooleanTypeAnnotation = isBooleanTypeAnnotation; + generated$3.isBooleanLiteralTypeAnnotation = isBooleanLiteralTypeAnnotation; + generated$3.isNullLiteralTypeAnnotation = isNullLiteralTypeAnnotation; + generated$3.isClassImplements = isClassImplements; + generated$3.isDeclareClass = isDeclareClass; + generated$3.isDeclareFunction = isDeclareFunction; + generated$3.isDeclareInterface = isDeclareInterface; + generated$3.isDeclareModule = isDeclareModule; + generated$3.isDeclareModuleExports = isDeclareModuleExports; + generated$3.isDeclareTypeAlias = isDeclareTypeAlias; + generated$3.isDeclareOpaqueType = isDeclareOpaqueType; + generated$3.isDeclareVariable = isDeclareVariable; + generated$3.isDeclareExportDeclaration = isDeclareExportDeclaration; + generated$3.isDeclareExportAllDeclaration = isDeclareExportAllDeclaration; + generated$3.isDeclaredPredicate = isDeclaredPredicate; + generated$3.isExistsTypeAnnotation = isExistsTypeAnnotation; + generated$3.isFunctionTypeAnnotation = isFunctionTypeAnnotation; + generated$3.isFunctionTypeParam = isFunctionTypeParam; + generated$3.isGenericTypeAnnotation = isGenericTypeAnnotation; + generated$3.isInferredPredicate = isInferredPredicate; + generated$3.isInterfaceExtends = isInterfaceExtends; + generated$3.isInterfaceDeclaration = isInterfaceDeclaration; + generated$3.isInterfaceTypeAnnotation = isInterfaceTypeAnnotation; + generated$3.isIntersectionTypeAnnotation = isIntersectionTypeAnnotation$1; + generated$3.isMixedTypeAnnotation = isMixedTypeAnnotation; + generated$3.isEmptyTypeAnnotation = isEmptyTypeAnnotation; + generated$3.isNullableTypeAnnotation = isNullableTypeAnnotation$1; + generated$3.isNumberLiteralTypeAnnotation = isNumberLiteralTypeAnnotation; + generated$3.isNumberTypeAnnotation = isNumberTypeAnnotation; + generated$3.isObjectTypeAnnotation = isObjectTypeAnnotation; + generated$3.isObjectTypeInternalSlot = isObjectTypeInternalSlot; + generated$3.isObjectTypeCallProperty = isObjectTypeCallProperty; + generated$3.isObjectTypeIndexer = isObjectTypeIndexer; + generated$3.isObjectTypeProperty = isObjectTypeProperty; + generated$3.isObjectTypeSpreadProperty = isObjectTypeSpreadProperty; + generated$3.isOpaqueType = isOpaqueType; + generated$3.isQualifiedTypeIdentifier = isQualifiedTypeIdentifier; + generated$3.isStringLiteralTypeAnnotation = isStringLiteralTypeAnnotation; + generated$3.isStringTypeAnnotation = isStringTypeAnnotation; + generated$3.isSymbolTypeAnnotation = isSymbolTypeAnnotation; + generated$3.isThisTypeAnnotation = isThisTypeAnnotation; + generated$3.isTupleTypeAnnotation = isTupleTypeAnnotation; + generated$3.isTypeofTypeAnnotation = isTypeofTypeAnnotation; + generated$3.isTypeAlias = isTypeAlias; + generated$3.isTypeAnnotation = isTypeAnnotation$1; + generated$3.isTypeCastExpression = isTypeCastExpression; + generated$3.isTypeParameter = isTypeParameter; + generated$3.isTypeParameterDeclaration = isTypeParameterDeclaration; + generated$3.isTypeParameterInstantiation = isTypeParameterInstantiation; + generated$3.isUnionTypeAnnotation = isUnionTypeAnnotation$1; + generated$3.isVariance = isVariance; + generated$3.isVoidTypeAnnotation = isVoidTypeAnnotation; + generated$3.isEnumDeclaration = isEnumDeclaration; + generated$3.isEnumBooleanBody = isEnumBooleanBody; + generated$3.isEnumNumberBody = isEnumNumberBody; + generated$3.isEnumStringBody = isEnumStringBody; + generated$3.isEnumSymbolBody = isEnumSymbolBody; + generated$3.isEnumBooleanMember = isEnumBooleanMember; + generated$3.isEnumNumberMember = isEnumNumberMember; + generated$3.isEnumStringMember = isEnumStringMember; + generated$3.isEnumDefaultedMember = isEnumDefaultedMember; + generated$3.isJSXAttribute = isJSXAttribute; + generated$3.isJSXClosingElement = isJSXClosingElement; + generated$3.isJSXElement = isJSXElement; + generated$3.isJSXEmptyExpression = isJSXEmptyExpression; + generated$3.isJSXExpressionContainer = isJSXExpressionContainer; + generated$3.isJSXSpreadChild = isJSXSpreadChild; + generated$3.isJSXIdentifier = isJSXIdentifier; + generated$3.isJSXMemberExpression = isJSXMemberExpression; + generated$3.isJSXNamespacedName = isJSXNamespacedName; + generated$3.isJSXOpeningElement = isJSXOpeningElement; + generated$3.isJSXSpreadAttribute = isJSXSpreadAttribute; + generated$3.isJSXText = isJSXText; + generated$3.isJSXFragment = isJSXFragment; + generated$3.isJSXOpeningFragment = isJSXOpeningFragment; + generated$3.isJSXClosingFragment = isJSXClosingFragment; + generated$3.isNoop = isNoop; + generated$3.isPlaceholder = isPlaceholder; + generated$3.isV8IntrinsicIdentifier = isV8IntrinsicIdentifier; + generated$3.isArgumentPlaceholder = isArgumentPlaceholder; + generated$3.isAwaitExpression = isAwaitExpression$1; + generated$3.isBindExpression = isBindExpression; + generated$3.isClassProperty = isClassProperty; + generated$3.isOptionalMemberExpression = isOptionalMemberExpression$2; + generated$3.isPipelineTopicExpression = isPipelineTopicExpression; + generated$3.isPipelineBareFunction = isPipelineBareFunction; + generated$3.isPipelinePrimaryTopicReference = isPipelinePrimaryTopicReference; + generated$3.isOptionalCallExpression = isOptionalCallExpression$2; + generated$3.isClassPrivateProperty = isClassPrivateProperty; + generated$3.isClassPrivateMethod = isClassPrivateMethod; + generated$3.isImport = isImport; + generated$3.isImportAttribute = isImportAttribute; + generated$3.isDecorator = isDecorator; + generated$3.isDoExpression = isDoExpression; + generated$3.isExportDefaultSpecifier = isExportDefaultSpecifier$1; + generated$3.isExportNamespaceSpecifier = isExportNamespaceSpecifier$1; + generated$3.isPrivateName = isPrivateName; + generated$3.isBigIntLiteral = isBigIntLiteral; + generated$3.isRecordExpression = isRecordExpression; + generated$3.isTupleExpression = isTupleExpression; + generated$3.isTSParameterProperty = isTSParameterProperty; + generated$3.isTSDeclareFunction = isTSDeclareFunction; + generated$3.isTSDeclareMethod = isTSDeclareMethod; + generated$3.isTSQualifiedName = isTSQualifiedName; + generated$3.isTSCallSignatureDeclaration = isTSCallSignatureDeclaration; + generated$3.isTSConstructSignatureDeclaration = isTSConstructSignatureDeclaration; + generated$3.isTSPropertySignature = isTSPropertySignature; + generated$3.isTSMethodSignature = isTSMethodSignature; + generated$3.isTSIndexSignature = isTSIndexSignature; + generated$3.isTSAnyKeyword = isTSAnyKeyword; + generated$3.isTSBooleanKeyword = isTSBooleanKeyword; + generated$3.isTSBigIntKeyword = isTSBigIntKeyword; + generated$3.isTSNeverKeyword = isTSNeverKeyword; + generated$3.isTSNullKeyword = isTSNullKeyword; + generated$3.isTSNumberKeyword = isTSNumberKeyword; + generated$3.isTSObjectKeyword = isTSObjectKeyword; + generated$3.isTSStringKeyword = isTSStringKeyword; + generated$3.isTSSymbolKeyword = isTSSymbolKeyword; + generated$3.isTSUndefinedKeyword = isTSUndefinedKeyword; + generated$3.isTSUnknownKeyword = isTSUnknownKeyword; + generated$3.isTSVoidKeyword = isTSVoidKeyword; + generated$3.isTSThisType = isTSThisType; + generated$3.isTSFunctionType = isTSFunctionType; + generated$3.isTSConstructorType = isTSConstructorType; + generated$3.isTSTypeReference = isTSTypeReference; + generated$3.isTSTypePredicate = isTSTypePredicate; + generated$3.isTSTypeQuery = isTSTypeQuery; + generated$3.isTSTypeLiteral = isTSTypeLiteral; + generated$3.isTSArrayType = isTSArrayType$1; + generated$3.isTSTupleType = isTSTupleType; + generated$3.isTSOptionalType = isTSOptionalType$1; + generated$3.isTSRestType = isTSRestType$1; + generated$3.isTSUnionType = isTSUnionType$1; + generated$3.isTSIntersectionType = isTSIntersectionType$1; + generated$3.isTSConditionalType = isTSConditionalType; + generated$3.isTSInferType = isTSInferType; + generated$3.isTSParenthesizedType = isTSParenthesizedType; + generated$3.isTSTypeOperator = isTSTypeOperator; + generated$3.isTSIndexedAccessType = isTSIndexedAccessType; + generated$3.isTSMappedType = isTSMappedType; + generated$3.isTSLiteralType = isTSLiteralType; + generated$3.isTSExpressionWithTypeArguments = isTSExpressionWithTypeArguments; + generated$3.isTSInterfaceDeclaration = isTSInterfaceDeclaration; + generated$3.isTSInterfaceBody = isTSInterfaceBody; + generated$3.isTSTypeAliasDeclaration = isTSTypeAliasDeclaration; + generated$3.isTSAsExpression = isTSAsExpression$1; + generated$3.isTSTypeAssertion = isTSTypeAssertion$1; + generated$3.isTSEnumDeclaration = isTSEnumDeclaration; + generated$3.isTSEnumMember = isTSEnumMember; + generated$3.isTSModuleDeclaration = isTSModuleDeclaration; + generated$3.isTSModuleBlock = isTSModuleBlock; + generated$3.isTSImportType = isTSImportType; + generated$3.isTSImportEqualsDeclaration = isTSImportEqualsDeclaration; + generated$3.isTSExternalModuleReference = isTSExternalModuleReference; + generated$3.isTSNonNullExpression = isTSNonNullExpression$1; + generated$3.isTSExportAssignment = isTSExportAssignment; + generated$3.isTSNamespaceExportDeclaration = isTSNamespaceExportDeclaration; + generated$3.isTSTypeAnnotation = isTSTypeAnnotation; + generated$3.isTSTypeParameterInstantiation = isTSTypeParameterInstantiation; + generated$3.isTSTypeParameterDeclaration = isTSTypeParameterDeclaration; + generated$3.isTSTypeParameter = isTSTypeParameter; + generated$3.isExpression = isExpression; + generated$3.isBinary = isBinary$2; + generated$3.isScopable = isScopable; + generated$3.isBlockParent = isBlockParent; + generated$3.isBlock = isBlock; + generated$3.isStatement = isStatement$2; + generated$3.isTerminatorless = isTerminatorless; + generated$3.isCompletionStatement = isCompletionStatement; + generated$3.isConditional = isConditional$1; + generated$3.isLoop = isLoop$2; + generated$3.isWhile = isWhile; + generated$3.isExpressionWrapper = isExpressionWrapper; + generated$3.isFor = isFor$2; + generated$3.isForXStatement = isForXStatement; + generated$3.isFunction = isFunction$6; + generated$3.isFunctionParent = isFunctionParent; + generated$3.isPureish = isPureish; + generated$3.isDeclaration = isDeclaration; + generated$3.isPatternLike = isPatternLike; + generated$3.isLVal = isLVal; + generated$3.isTSEntityName = isTSEntityName; + generated$3.isLiteral = isLiteral$2; + generated$3.isImmutable = isImmutable$2; + generated$3.isUserWhitespacable = isUserWhitespacable; + generated$3.isMethod = isMethod; + generated$3.isObjectMember = isObjectMember; + generated$3.isProperty = isProperty; + generated$3.isUnaryLike = isUnaryLike$1; + generated$3.isPattern = isPattern; + generated$3.isClass = isClass; + generated$3.isModuleDeclaration = isModuleDeclaration; + generated$3.isExportDeclaration = isExportDeclaration$1; + generated$3.isModuleSpecifier = isModuleSpecifier; + generated$3.isFlow = isFlow; + generated$3.isFlowType = isFlowType; + generated$3.isFlowBaseAnnotation = isFlowBaseAnnotation; + generated$3.isFlowDeclaration = isFlowDeclaration; + generated$3.isFlowPredicate = isFlowPredicate; + generated$3.isEnumBody = isEnumBody; + generated$3.isEnumMember = isEnumMember; + generated$3.isJSX = isJSX; + generated$3.isPrivate = isPrivate; + generated$3.isTSTypeElement = isTSTypeElement; + generated$3.isTSType = isTSType; + generated$3.isTSBaseType = isTSBaseType; + generated$3.isNumberLiteral = isNumberLiteral; + generated$3.isRegexLiteral = isRegexLiteral; + generated$3.isRestProperty = isRestProperty; + generated$3.isSpreadProperty = isSpreadProperty; + + var _shallowEqual = _interopRequireDefault$y(shallowEqual$1); + + function _interopRequireDefault$y(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function isArrayExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isAssignmentExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AssignmentExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBinaryExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BinaryExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isInterpreterDirective(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterpreterDirective") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDirective(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Directive") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDirectiveLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DirectiveLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBlockStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BlockStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBreakStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BreakStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isCallExpression$4(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "CallExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isCatchClause(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "CatchClause") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isConditionalExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ConditionalExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isContinueStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ContinueStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDebuggerStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DebuggerStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDoWhileStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DoWhileStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEmptyStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EmptyStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExpressionStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExpressionStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFile$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "File") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isForInStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForInStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isForStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunctionDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunctionExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isIdentifier$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Identifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isIfStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "IfStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isLabeledStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "LabeledStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isStringLiteral$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNumericLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumericLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNullLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBooleanLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isRegExpLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RegExpLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isLogicalExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "LogicalExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isMemberExpression$4(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNewExpression$3(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NewExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isProgram$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Program") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectMethod(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isRestElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RestElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isReturnStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ReturnStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSequenceExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SequenceExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isParenthesizedExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ParenthesizedExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSwitchCase(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SwitchCase") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSwitchStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SwitchStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isThisExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThisExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isThrowStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThrowStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTryStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TryStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isUnaryExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UnaryExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isUpdateExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UpdateExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isVariableDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VariableDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isVariableDeclarator$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VariableDeclarator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isWhileStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "WhileStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isWithStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "WithStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isAssignmentPattern$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AssignmentPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isArrayPattern(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isArrowFunctionExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrowFunctionExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassDeclaration$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportAllDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportAllDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportDefaultDeclaration$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportDefaultDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportNamedDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportNamedDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportSpecifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isForOfStatement$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForOfStatement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImportDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImportDefaultSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportDefaultSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImportNamespaceSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportNamespaceSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImportSpecifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isMetaProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MetaProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassMethod(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectPattern$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectPattern") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSpreadElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SpreadElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSuper(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Super") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTaggedTemplateExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TaggedTemplateExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTemplateElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TemplateElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTemplateLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TemplateLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isYieldExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "YieldExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isAnyTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AnyTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isArrayTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArrayTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBooleanTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBooleanLiteralTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BooleanLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNullLiteralTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassImplements(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassImplements") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareClass(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareClass") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareFunction(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareInterface(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareInterface") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareModule(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareModule") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareModuleExports(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareModuleExports") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareTypeAlias(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareTypeAlias") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareOpaqueType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareOpaqueType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareVariable(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareVariable") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareExportDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareExportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclareExportAllDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclareExportAllDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclaredPredicate(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DeclaredPredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExistsTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExistsTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunctionTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunctionTypeParam(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionTypeParam") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isGenericTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "GenericTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isInferredPredicate(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InferredPredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isInterfaceExtends(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceExtends") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isInterfaceDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isInterfaceTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "InterfaceTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isIntersectionTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "IntersectionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isMixedTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "MixedTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEmptyTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EmptyTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNullableTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NullableTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNumberLiteralTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNumberTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeInternalSlot(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeInternalSlot") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeCallProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeCallProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeIndexer(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeIndexer") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectTypeSpreadProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectTypeSpreadProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isOpaqueType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OpaqueType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isQualifiedTypeIdentifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "QualifiedTypeIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isStringLiteralTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringLiteralTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isStringTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "StringTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSymbolTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SymbolTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isThisTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ThisTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTupleTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TupleTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeofTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeofTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeAlias(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeAlias") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeCastExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeCastExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeParameter(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameter") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeParameterDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameterDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTypeParameterInstantiation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TypeParameterInstantiation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isUnionTypeAnnotation$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UnionTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isVariance(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Variance") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isVoidTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "VoidTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumBooleanBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumBooleanBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumNumberBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumNumberBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumStringBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumStringBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumSymbolBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumSymbolBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumBooleanMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumBooleanMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumNumberMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumNumberMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumStringMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumStringMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumDefaultedMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumDefaultedMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXAttribute(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXClosingElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXClosingElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXEmptyExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXEmptyExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXExpressionContainer(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXExpressionContainer") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXSpreadChild(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXSpreadChild") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXIdentifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXMemberExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXMemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXNamespacedName(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXNamespacedName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXOpeningElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXOpeningElement") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXSpreadAttribute(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXSpreadAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXText(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXText") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXFragment(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXOpeningFragment(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXOpeningFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSXClosingFragment(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSXClosingFragment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNoop(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Noop") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPlaceholder(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Placeholder") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isV8IntrinsicIdentifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "V8IntrinsicIdentifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isArgumentPlaceholder(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ArgumentPlaceholder") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isAwaitExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "AwaitExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBindExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BindExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isOptionalMemberExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OptionalMemberExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPipelineTopicExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelineTopicExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPipelineBareFunction(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelineBareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPipelinePrimaryTopicReference(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PipelinePrimaryTopicReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isOptionalCallExpression$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "OptionalCallExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassPrivateProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassPrivateProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClassPrivateMethod(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ClassPrivateMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImport(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Import") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImportAttribute(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ImportAttribute") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDecorator(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Decorator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDoExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "DoExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportDefaultSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportDefaultSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportNamespaceSpecifier$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportNamespaceSpecifier") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPrivateName(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PrivateName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBigIntLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BigIntLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isRecordExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RecordExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTupleExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TupleExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSParameterProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSParameterProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSDeclareFunction(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSDeclareFunction") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSDeclareMethod(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSDeclareMethod") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSQualifiedName(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSQualifiedName") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSCallSignatureDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSCallSignatureDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSConstructSignatureDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConstructSignatureDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSPropertySignature(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSPropertySignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSMethodSignature(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSMethodSignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSIndexSignature(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIndexSignature") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSAnyKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSAnyKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSBooleanKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSBooleanKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSBigIntKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSBigIntKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSNeverKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNeverKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSNullKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNullKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSNumberKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNumberKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSObjectKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSObjectKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSStringKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSStringKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSSymbolKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSSymbolKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSUndefinedKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUndefinedKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSUnknownKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUnknownKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSVoidKeyword(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSVoidKeyword") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSThisType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSThisType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSFunctionType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSFunctionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSConstructorType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConstructorType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeReference(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypePredicate(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypePredicate") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeQuery(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeQuery") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeLiteral(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSArrayType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSArrayType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTupleType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTupleType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSOptionalType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSOptionalType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSRestType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSRestType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSUnionType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSUnionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSIntersectionType$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIntersectionType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSConditionalType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSConditionalType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSInferType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInferType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSParenthesizedType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSParenthesizedType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeOperator(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeOperator") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSIndexedAccessType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSIndexedAccessType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSMappedType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSMappedType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSLiteralType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSLiteralType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSExpressionWithTypeArguments(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExpressionWithTypeArguments") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSInterfaceDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInterfaceDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSInterfaceBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSInterfaceBody") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAliasDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAliasDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSAsExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSAsExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAssertion$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAssertion") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSEnumDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSEnumDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSEnumMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSEnumMember") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSModuleDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSModuleDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSModuleBlock(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSModuleBlock") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSImportType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSImportType") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSImportEqualsDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSImportEqualsDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSExternalModuleReference(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExternalModuleReference") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSNonNullExpression$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNonNullExpression") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSExportAssignment(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSExportAssignment") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSNamespaceExportDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSNamespaceExportDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeAnnotation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameterInstantiation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameterInstantiation") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameterDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameterDeclaration") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeParameter(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeParameter") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExpression(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Expression" || "ArrayExpression" === nodeType || "AssignmentExpression" === nodeType || "BinaryExpression" === nodeType || "CallExpression" === nodeType || "ConditionalExpression" === nodeType || "FunctionExpression" === nodeType || "Identifier" === nodeType || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "LogicalExpression" === nodeType || "MemberExpression" === nodeType || "NewExpression" === nodeType || "ObjectExpression" === nodeType || "SequenceExpression" === nodeType || "ParenthesizedExpression" === nodeType || "ThisExpression" === nodeType || "UnaryExpression" === nodeType || "UpdateExpression" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassExpression" === nodeType || "MetaProperty" === nodeType || "Super" === nodeType || "TaggedTemplateExpression" === nodeType || "TemplateLiteral" === nodeType || "YieldExpression" === nodeType || "TypeCastExpression" === nodeType || "JSXElement" === nodeType || "JSXFragment" === nodeType || "AwaitExpression" === nodeType || "BindExpression" === nodeType || "OptionalMemberExpression" === nodeType || "PipelinePrimaryTopicReference" === nodeType || "OptionalCallExpression" === nodeType || "Import" === nodeType || "DoExpression" === nodeType || "BigIntLiteral" === nodeType || "RecordExpression" === nodeType || "TupleExpression" === nodeType || "TSAsExpression" === nodeType || "TSTypeAssertion" === nodeType || "TSNonNullExpression" === nodeType || nodeType === "Placeholder" && ("Expression" === node.expectedNode || "Identifier" === node.expectedNode || "StringLiteral" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBinary$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Binary" || "BinaryExpression" === nodeType || "LogicalExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isScopable(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Scopable" || "BlockStatement" === nodeType || "CatchClause" === nodeType || "DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "Program" === nodeType || "ObjectMethod" === nodeType || "SwitchStatement" === nodeType || "WhileStatement" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassExpression" === nodeType || "ClassDeclaration" === nodeType || "ForOfStatement" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBlockParent(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "BlockParent" || "BlockStatement" === nodeType || "CatchClause" === nodeType || "DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "Program" === nodeType || "ObjectMethod" === nodeType || "SwitchStatement" === nodeType || "WhileStatement" === nodeType || "ArrowFunctionExpression" === nodeType || "ForOfStatement" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isBlock(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Block" || "BlockStatement" === nodeType || "Program" === nodeType || "TSModuleBlock" === nodeType || nodeType === "Placeholder" && "BlockStatement" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isStatement$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Statement" || "BlockStatement" === nodeType || "BreakStatement" === nodeType || "ContinueStatement" === nodeType || "DebuggerStatement" === nodeType || "DoWhileStatement" === nodeType || "EmptyStatement" === nodeType || "ExpressionStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "FunctionDeclaration" === nodeType || "IfStatement" === nodeType || "LabeledStatement" === nodeType || "ReturnStatement" === nodeType || "SwitchStatement" === nodeType || "ThrowStatement" === nodeType || "TryStatement" === nodeType || "VariableDeclaration" === nodeType || "WhileStatement" === nodeType || "WithStatement" === nodeType || "ClassDeclaration" === nodeType || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ForOfStatement" === nodeType || "ImportDeclaration" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType || "EnumDeclaration" === nodeType || "TSDeclareFunction" === nodeType || "TSInterfaceDeclaration" === nodeType || "TSTypeAliasDeclaration" === nodeType || "TSEnumDeclaration" === nodeType || "TSModuleDeclaration" === nodeType || "TSImportEqualsDeclaration" === nodeType || "TSExportAssignment" === nodeType || "TSNamespaceExportDeclaration" === nodeType || nodeType === "Placeholder" && ("Statement" === node.expectedNode || "Declaration" === node.expectedNode || "BlockStatement" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTerminatorless(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Terminatorless" || "BreakStatement" === nodeType || "ContinueStatement" === nodeType || "ReturnStatement" === nodeType || "ThrowStatement" === nodeType || "YieldExpression" === nodeType || "AwaitExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isCompletionStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "CompletionStatement" || "BreakStatement" === nodeType || "ContinueStatement" === nodeType || "ReturnStatement" === nodeType || "ThrowStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isConditional$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Conditional" || "ConditionalExpression" === nodeType || "IfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isLoop$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Loop" || "DoWhileStatement" === nodeType || "ForInStatement" === nodeType || "ForStatement" === nodeType || "WhileStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isWhile(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "While" || "DoWhileStatement" === nodeType || "WhileStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExpressionWrapper(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExpressionWrapper" || "ExpressionStatement" === nodeType || "ParenthesizedExpression" === nodeType || "TypeCastExpression" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFor$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "For" || "ForInStatement" === nodeType || "ForStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isForXStatement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ForXStatement" || "ForInStatement" === nodeType || "ForOfStatement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunction$6(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Function" || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "ObjectMethod" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFunctionParent(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FunctionParent" || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "ObjectMethod" === nodeType || "ArrowFunctionExpression" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPureish(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Pureish" || "FunctionDeclaration" === nodeType || "FunctionExpression" === nodeType || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "ArrowFunctionExpression" === nodeType || "BigIntLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Declaration" || "FunctionDeclaration" === nodeType || "VariableDeclaration" === nodeType || "ClassDeclaration" === nodeType || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ImportDeclaration" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType || "EnumDeclaration" === nodeType || "TSDeclareFunction" === nodeType || "TSInterfaceDeclaration" === nodeType || "TSTypeAliasDeclaration" === nodeType || "TSEnumDeclaration" === nodeType || "TSModuleDeclaration" === nodeType || nodeType === "Placeholder" && "Declaration" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPatternLike(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "PatternLike" || "Identifier" === nodeType || "RestElement" === nodeType || "AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || nodeType === "Placeholder" && ("Pattern" === node.expectedNode || "Identifier" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isLVal(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "LVal" || "Identifier" === nodeType || "MemberExpression" === nodeType || "RestElement" === nodeType || "AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || "TSParameterProperty" === nodeType || nodeType === "Placeholder" && ("Pattern" === node.expectedNode || "Identifier" === node.expectedNode)) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSEntityName(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSEntityName" || "Identifier" === nodeType || "TSQualifiedName" === nodeType || nodeType === "Placeholder" && "Identifier" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isLiteral$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Literal" || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "RegExpLiteral" === nodeType || "TemplateLiteral" === nodeType || "BigIntLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isImmutable$2(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Immutable" || "StringLiteral" === nodeType || "NumericLiteral" === nodeType || "NullLiteral" === nodeType || "BooleanLiteral" === nodeType || "JSXAttribute" === nodeType || "JSXClosingElement" === nodeType || "JSXElement" === nodeType || "JSXExpressionContainer" === nodeType || "JSXSpreadChild" === nodeType || "JSXOpeningElement" === nodeType || "JSXText" === nodeType || "JSXFragment" === nodeType || "JSXOpeningFragment" === nodeType || "JSXClosingFragment" === nodeType || "BigIntLiteral" === nodeType || nodeType === "Placeholder" && "StringLiteral" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isUserWhitespacable(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UserWhitespacable" || "ObjectMethod" === nodeType || "ObjectProperty" === nodeType || "ObjectTypeInternalSlot" === nodeType || "ObjectTypeCallProperty" === nodeType || "ObjectTypeIndexer" === nodeType || "ObjectTypeProperty" === nodeType || "ObjectTypeSpreadProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isMethod(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Method" || "ObjectMethod" === nodeType || "ClassMethod" === nodeType || "ClassPrivateMethod" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isObjectMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ObjectMember" || "ObjectMethod" === nodeType || "ObjectProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isProperty(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Property" || "ObjectProperty" === nodeType || "ClassProperty" === nodeType || "ClassPrivateProperty" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isUnaryLike$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "UnaryLike" || "UnaryExpression" === nodeType || "SpreadElement" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPattern(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Pattern" || "AssignmentPattern" === nodeType || "ArrayPattern" === nodeType || "ObjectPattern" === nodeType || nodeType === "Placeholder" && "Pattern" === node.expectedNode) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isClass(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Class" || "ClassExpression" === nodeType || "ClassDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isModuleDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ModuleDeclaration" || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType || "ImportDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isExportDeclaration$1(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ExportDeclaration" || "ExportAllDeclaration" === nodeType || "ExportDefaultDeclaration" === nodeType || "ExportNamedDeclaration" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isModuleSpecifier(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "ModuleSpecifier" || "ExportSpecifier" === nodeType || "ImportDefaultSpecifier" === nodeType || "ImportNamespaceSpecifier" === nodeType || "ImportSpecifier" === nodeType || "ExportDefaultSpecifier" === nodeType || "ExportNamespaceSpecifier" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFlow(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Flow" || "AnyTypeAnnotation" === nodeType || "ArrayTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "BooleanLiteralTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "ClassImplements" === nodeType || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "DeclaredPredicate" === nodeType || "ExistsTypeAnnotation" === nodeType || "FunctionTypeAnnotation" === nodeType || "FunctionTypeParam" === nodeType || "GenericTypeAnnotation" === nodeType || "InferredPredicate" === nodeType || "InterfaceExtends" === nodeType || "InterfaceDeclaration" === nodeType || "InterfaceTypeAnnotation" === nodeType || "IntersectionTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NullableTypeAnnotation" === nodeType || "NumberLiteralTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "ObjectTypeAnnotation" === nodeType || "ObjectTypeInternalSlot" === nodeType || "ObjectTypeCallProperty" === nodeType || "ObjectTypeIndexer" === nodeType || "ObjectTypeProperty" === nodeType || "ObjectTypeSpreadProperty" === nodeType || "OpaqueType" === nodeType || "QualifiedTypeIdentifier" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || "TypeAlias" === nodeType || "TypeAnnotation" === nodeType || "TypeCastExpression" === nodeType || "TypeParameter" === nodeType || "TypeParameterDeclaration" === nodeType || "TypeParameterInstantiation" === nodeType || "UnionTypeAnnotation" === nodeType || "Variance" === nodeType || "VoidTypeAnnotation" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFlowType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FlowType" || "AnyTypeAnnotation" === nodeType || "ArrayTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "BooleanLiteralTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "ExistsTypeAnnotation" === nodeType || "FunctionTypeAnnotation" === nodeType || "GenericTypeAnnotation" === nodeType || "InterfaceTypeAnnotation" === nodeType || "IntersectionTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NullableTypeAnnotation" === nodeType || "NumberLiteralTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "ObjectTypeAnnotation" === nodeType || "StringLiteralTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "TupleTypeAnnotation" === nodeType || "TypeofTypeAnnotation" === nodeType || "UnionTypeAnnotation" === nodeType || "VoidTypeAnnotation" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFlowBaseAnnotation(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FlowBaseAnnotation" || "AnyTypeAnnotation" === nodeType || "BooleanTypeAnnotation" === nodeType || "NullLiteralTypeAnnotation" === nodeType || "MixedTypeAnnotation" === nodeType || "EmptyTypeAnnotation" === nodeType || "NumberTypeAnnotation" === nodeType || "StringTypeAnnotation" === nodeType || "SymbolTypeAnnotation" === nodeType || "ThisTypeAnnotation" === nodeType || "VoidTypeAnnotation" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFlowDeclaration(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FlowDeclaration" || "DeclareClass" === nodeType || "DeclareFunction" === nodeType || "DeclareInterface" === nodeType || "DeclareModule" === nodeType || "DeclareModuleExports" === nodeType || "DeclareTypeAlias" === nodeType || "DeclareOpaqueType" === nodeType || "DeclareVariable" === nodeType || "DeclareExportDeclaration" === nodeType || "DeclareExportAllDeclaration" === nodeType || "InterfaceDeclaration" === nodeType || "OpaqueType" === nodeType || "TypeAlias" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isFlowPredicate(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "FlowPredicate" || "DeclaredPredicate" === nodeType || "InferredPredicate" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumBody(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumBody" || "EnumBooleanBody" === nodeType || "EnumNumberBody" === nodeType || "EnumStringBody" === nodeType || "EnumSymbolBody" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isEnumMember(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "EnumMember" || "EnumBooleanMember" === nodeType || "EnumNumberMember" === nodeType || "EnumStringMember" === nodeType || "EnumDefaultedMember" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isJSX(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "JSX" || "JSXAttribute" === nodeType || "JSXClosingElement" === nodeType || "JSXElement" === nodeType || "JSXEmptyExpression" === nodeType || "JSXExpressionContainer" === nodeType || "JSXSpreadChild" === nodeType || "JSXIdentifier" === nodeType || "JSXMemberExpression" === nodeType || "JSXNamespacedName" === nodeType || "JSXOpeningElement" === nodeType || "JSXSpreadAttribute" === nodeType || "JSXText" === nodeType || "JSXFragment" === nodeType || "JSXOpeningFragment" === nodeType || "JSXClosingFragment" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isPrivate(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "Private" || "ClassPrivateProperty" === nodeType || "ClassPrivateMethod" === nodeType || "PrivateName" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSTypeElement(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSTypeElement" || "TSCallSignatureDeclaration" === nodeType || "TSConstructSignatureDeclaration" === nodeType || "TSPropertySignature" === nodeType || "TSMethodSignature" === nodeType || "TSIndexSignature" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSType" || "TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || "TSObjectKeyword" === nodeType || "TSStringKeyword" === nodeType || "TSSymbolKeyword" === nodeType || "TSUndefinedKeyword" === nodeType || "TSUnknownKeyword" === nodeType || "TSVoidKeyword" === nodeType || "TSThisType" === nodeType || "TSFunctionType" === nodeType || "TSConstructorType" === nodeType || "TSTypeReference" === nodeType || "TSTypePredicate" === nodeType || "TSTypeQuery" === nodeType || "TSTypeLiteral" === nodeType || "TSArrayType" === nodeType || "TSTupleType" === nodeType || "TSOptionalType" === nodeType || "TSRestType" === nodeType || "TSUnionType" === nodeType || "TSIntersectionType" === nodeType || "TSConditionalType" === nodeType || "TSInferType" === nodeType || "TSParenthesizedType" === nodeType || "TSTypeOperator" === nodeType || "TSIndexedAccessType" === nodeType || "TSMappedType" === nodeType || "TSLiteralType" === nodeType || "TSExpressionWithTypeArguments" === nodeType || "TSImportType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isTSBaseType(node, opts) { + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "TSBaseType" || "TSAnyKeyword" === nodeType || "TSBooleanKeyword" === nodeType || "TSBigIntKeyword" === nodeType || "TSNeverKeyword" === nodeType || "TSNullKeyword" === nodeType || "TSNumberKeyword" === nodeType || "TSObjectKeyword" === nodeType || "TSStringKeyword" === nodeType || "TSSymbolKeyword" === nodeType || "TSUndefinedKeyword" === nodeType || "TSUnknownKeyword" === nodeType || "TSVoidKeyword" === nodeType || "TSThisType" === nodeType || "TSLiteralType" === nodeType) { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isNumberLiteral(node, opts) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "NumberLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isRegexLiteral(node, opts) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RegexLiteral") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isRestProperty(node, opts) { + console.trace("The node type RestProperty has been renamed to RestElement"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "RestProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + function isSpreadProperty(node, opts) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + if (!node) return false; + const nodeType = node.type; + + if (nodeType === "SpreadProperty") { + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + + return false; + } + + Object.defineProperty(matchesPattern$1, "__esModule", { + value: true + }); + matchesPattern$1.default = matchesPattern; + + var _generated$n = generated$3; + + function matchesPattern(member, match, allowPartial) { + if (!(0, _generated$n.isMemberExpression)(member)) return false; + const parts = Array.isArray(match) ? match : match.split("."); + const nodes = []; + let node; + + for (node = member; (0, _generated$n.isMemberExpression)(node); node = node.object) { + nodes.push(node.property); + } + + nodes.push(node); + if (nodes.length < parts.length) return false; + if (!allowPartial && nodes.length > parts.length) return false; + + for (let i = 0, j = nodes.length - 1; i < parts.length; i++, j--) { + const node = nodes[j]; + let value; + + if ((0, _generated$n.isIdentifier)(node)) { + value = node.name; + } else if ((0, _generated$n.isStringLiteral)(node)) { + value = node.value; + } else { + return false; + } + + if (parts[i] !== value) return false; + } + + return true; + } + + Object.defineProperty(buildMatchMemberExpression$1, "__esModule", { + value: true + }); + buildMatchMemberExpression$1.default = buildMatchMemberExpression; + + var _matchesPattern = _interopRequireDefault$x(matchesPattern$1); + + function _interopRequireDefault$x(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function buildMatchMemberExpression(match, allowPartial) { + const parts = match.split("."); + return member => (0, _matchesPattern.default)(member, parts, allowPartial); + } + + Object.defineProperty(isReactComponent$2, "__esModule", { + value: true + }); + isReactComponent$2.default = void 0; + + var _buildMatchMemberExpression = _interopRequireDefault$w(buildMatchMemberExpression$1); + + function _interopRequireDefault$w(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + const isReactComponent$1 = (0, _buildMatchMemberExpression.default)("React.Component"); + var _default$3 = isReactComponent$1; + isReactComponent$2.default = _default$3; + + var isCompatTag$1 = {}; + + Object.defineProperty(isCompatTag$1, "__esModule", { + value: true + }); + isCompatTag$1.default = isCompatTag; + + function isCompatTag(tagName) { + return !!tagName && /^[a-z]/.test(tagName); + } + + var buildChildren$1 = {}; + + var cleanJSXElementLiteralChild$1 = {}; + + var generated$2 = {}; + + var builder$1 = {}; + + function listCacheClear$1() { + this.__data__ = []; + this.size = 0; + } + + var _listCacheClear = listCacheClear$1; + + function eq$2(value, other) { + return value === other || (value !== value && other !== other); + } + + var eq_1 = eq$2; + + var eq$1 = eq_1; + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf$4(array, key) { + var length = array.length; + while (length--) { + if (eq$1(array[length][0], key)) { + return length; + } + } + return -1; + } + + var _assocIndexOf = assocIndexOf$4; + + var assocIndexOf$3 = _assocIndexOf; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete$1(key) { + var data = this.__data__, + index = assocIndexOf$3(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + var _listCacheDelete = listCacheDelete$1; + + var assocIndexOf$2 = _assocIndexOf; + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet$1(key) { + var data = this.__data__, + index = assocIndexOf$2(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + var _listCacheGet = listCacheGet$1; + + var assocIndexOf$1 = _assocIndexOf; + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas$1(key) { + return assocIndexOf$1(this.__data__, key) > -1; + } + + var _listCacheHas = listCacheHas$1; + + var assocIndexOf = _assocIndexOf; + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet$1(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + var _listCacheSet = listCacheSet$1; + + var listCacheClear = _listCacheClear, + listCacheDelete = _listCacheDelete, + listCacheGet = _listCacheGet, + listCacheHas = _listCacheHas, + listCacheSet = _listCacheSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache$4(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache$4.prototype.clear = listCacheClear; + ListCache$4.prototype['delete'] = listCacheDelete; + ListCache$4.prototype.get = listCacheGet; + ListCache$4.prototype.has = listCacheHas; + ListCache$4.prototype.set = listCacheSet; + + var _ListCache = ListCache$4; + + var ListCache$3 = _ListCache; + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear$1() { + this.__data__ = new ListCache$3; + this.size = 0; + } + + var _stackClear = stackClear$1; + + function stackDelete$1(key) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + var _stackDelete = stackDelete$1; + + function stackGet$1(key) { + return this.__data__.get(key); + } + + var _stackGet = stackGet$1; + + function stackHas$1(key) { + return this.__data__.has(key); + } + + var _stackHas = stackHas$1; + + var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + var _freeGlobal = freeGlobal$1; + + var freeGlobal = _freeGlobal; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root$8 = freeGlobal || freeSelf || Function('return this')(); + + var _root = root$8; + + var root$7 = _root; + + /** Built-in value references. */ + var Symbol$4 = root$7.Symbol; + + var _Symbol = Symbol$4; + + var Symbol$3 = _Symbol; + + /** Used for built-in method references. */ + var objectProto$d = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$b = objectProto$d.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$d.toString; + + /** Built-in value references. */ + var symToStringTag$1 = Symbol$3 ? Symbol$3.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag$1(value) { + var isOwn = hasOwnProperty$b.call(value, symToStringTag$1), + tag = value[symToStringTag$1]; + + try { + value[symToStringTag$1] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString$1.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag$1] = tag; + } else { + delete value[symToStringTag$1]; + } + } + return result; + } + + var _getRawTag = getRawTag$1; + + var objectProto$c = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto$c.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString$1(value) { + return nativeObjectToString.call(value); + } + + var _objectToString = objectToString$1; + + var Symbol$2 = _Symbol, + getRawTag = _getRawTag, + objectToString = _objectToString; + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag$6(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); + } + + var _baseGetTag = baseGetTag$6; + + function isObject$6(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + var isObject_1 = isObject$6; + + var baseGetTag$5 = _baseGetTag, + isObject$5 = isObject_1; + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag$2 = '[object Function]', + genTag$1 = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction$5(value) { + if (!isObject$5(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag$5(value); + return tag == funcTag$2 || tag == genTag$1 || tag == asyncTag || tag == proxyTag; + } + + var isFunction_1 = isFunction$5; + + var root$6 = _root; + + /** Used to detect overreaching core-js shims. */ + var coreJsData$1 = root$6['__core-js_shared__']; + + var _coreJsData = coreJsData$1; + + var coreJsData = _coreJsData; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked$1(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + var _isMasked = isMasked$1; + + var funcProto$2 = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$2 = funcProto$2.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource$2(func) { + if (func != null) { + try { + return funcToString$2.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + var _toSource = toSource$2; + + var isFunction$4 = isFunction_1, + isMasked = _isMasked, + isObject$4 = isObject_1, + toSource$1 = _toSource; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype, + objectProto$b = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$a = objectProto$b.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString$1.call(hasOwnProperty$a).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative$1(value) { + if (!isObject$4(value) || isMasked(value)) { + return false; + } + var pattern = isFunction$4(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource$1(value)); + } + + var _baseIsNative = baseIsNative$1; + + function getValue$1(object, key) { + return object == null ? undefined : object[key]; + } + + var _getValue = getValue$1; + + var baseIsNative = _baseIsNative, + getValue = _getValue; + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative$7(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; + } + + var _getNative = getNative$7; + + var getNative$6 = _getNative, + root$5 = _root; + + /* Built-in method references that are verified to be native. */ + var Map$4 = getNative$6(root$5, 'Map'); + + var _Map = Map$4; + + var getNative$5 = _getNative; + + /* Built-in method references that are verified to be native. */ + var nativeCreate$4 = getNative$5(Object, 'create'); + + var _nativeCreate = nativeCreate$4; + + var nativeCreate$3 = _nativeCreate; + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear$1() { + this.__data__ = nativeCreate$3 ? nativeCreate$3(null) : {}; + this.size = 0; + } + + var _hashClear = hashClear$1; + + function hashDelete$1(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + var _hashDelete = hashDelete$1; + + var nativeCreate$2 = _nativeCreate; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$2 = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$a = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$9 = objectProto$a.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet$1(key) { + var data = this.__data__; + if (nativeCreate$2) { + var result = data[key]; + return result === HASH_UNDEFINED$2 ? undefined : result; + } + return hasOwnProperty$9.call(data, key) ? data[key] : undefined; + } + + var _hashGet = hashGet$1; + + var nativeCreate$1 = _nativeCreate; + + /** Used for built-in method references. */ + var objectProto$9 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$8 = objectProto$9.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas$1(key) { + var data = this.__data__; + return nativeCreate$1 ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key); + } + + var _hashHas = hashHas$1; + + var nativeCreate = _nativeCreate; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet$1(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value; + return this; + } + + var _hashSet = hashSet$1; + + var hashClear = _hashClear, + hashDelete = _hashDelete, + hashGet = _hashGet, + hashHas = _hashHas, + hashSet = _hashSet; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash$1(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash$1.prototype.clear = hashClear; + Hash$1.prototype['delete'] = hashDelete; + Hash$1.prototype.get = hashGet; + Hash$1.prototype.has = hashHas; + Hash$1.prototype.set = hashSet; + + var _Hash = Hash$1; + + var Hash = _Hash, + ListCache$2 = _ListCache, + Map$3 = _Map; + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear$1() { + this.size = 0; + this.__data__ = { + 'hash': new Hash, + 'map': new (Map$3 || ListCache$2), + 'string': new Hash + }; + } + + var _mapCacheClear = mapCacheClear$1; + + function isKeyable$1(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + var _isKeyable = isKeyable$1; + + var isKeyable = _isKeyable; + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData$4(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + var _getMapData = getMapData$4; + + var getMapData$3 = _getMapData; + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete$1(key) { + var result = getMapData$3(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + var _mapCacheDelete = mapCacheDelete$1; + + var getMapData$2 = _getMapData; + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet$1(key) { + return getMapData$2(this, key).get(key); + } + + var _mapCacheGet = mapCacheGet$1; + + var getMapData$1 = _getMapData; + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas$1(key) { + return getMapData$1(this, key).has(key); + } + + var _mapCacheHas = mapCacheHas$1; + + var getMapData = _getMapData; + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet$1(key, value) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + var _mapCacheSet = mapCacheSet$1; + + var mapCacheClear = _mapCacheClear, + mapCacheDelete = _mapCacheDelete, + mapCacheGet = _mapCacheGet, + mapCacheHas = _mapCacheHas, + mapCacheSet = _mapCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache$2(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache$2.prototype.clear = mapCacheClear; + MapCache$2.prototype['delete'] = mapCacheDelete; + MapCache$2.prototype.get = mapCacheGet; + MapCache$2.prototype.has = mapCacheHas; + MapCache$2.prototype.set = mapCacheSet; + + var _MapCache = MapCache$2; + + var ListCache$1 = _ListCache, + Map$2 = _Map, + MapCache$1 = _MapCache; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE$1 = 200; + + /** + * Sets the stack `key` to `value`. + * + * @private + * @name set + * @memberOf Stack + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the stack cache instance. + */ + function stackSet$1(key, value) { + var data = this.__data__; + if (data instanceof ListCache$1) { + var pairs = data.__data__; + if (!Map$2 || (pairs.length < LARGE_ARRAY_SIZE$1 - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache$1(pairs); + } + data.set(key, value); + this.size = data.size; + return this; + } + + var _stackSet = stackSet$1; + + var ListCache = _ListCache, + stackClear = _stackClear, + stackDelete = _stackDelete, + stackGet = _stackGet, + stackHas = _stackHas, + stackSet = _stackSet; + + /** + * Creates a stack cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Stack$1(entries) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + // Add methods to `Stack`. + Stack$1.prototype.clear = stackClear; + Stack$1.prototype['delete'] = stackDelete; + Stack$1.prototype.get = stackGet; + Stack$1.prototype.has = stackHas; + Stack$1.prototype.set = stackSet; + + var _Stack = Stack$1; + + function arrayEach$1(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } + + var _arrayEach = arrayEach$1; + + var getNative$4 = _getNative; + + var defineProperty$1 = (function() { + try { + var func = getNative$4(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + var _defineProperty = defineProperty$1; + + var defineProperty = _defineProperty; + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue$2(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + var _baseAssignValue = baseAssignValue$2; + + var baseAssignValue$1 = _baseAssignValue, + eq = eq_1; + + /** Used for built-in method references. */ + var objectProto$8 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$7 = objectProto$8.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue$2(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty$7.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + baseAssignValue$1(object, key, value); + } + } + + var _assignValue = assignValue$2; + + var assignValue$1 = _assignValue, + baseAssignValue = _baseAssignValue; + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject$4(source, props, object, customizer) { + var isNew = !object; + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : undefined; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue$1(object, key, newValue); + } + } + return object; + } + + var _copyObject = copyObject$4; + + function baseTimes$1(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + var _baseTimes = baseTimes$1; + + function isObjectLike$7(value) { + return value != null && typeof value == 'object'; + } + + var isObjectLike_1 = isObjectLike$7; + + var baseGetTag$4 = _baseGetTag, + isObjectLike$6 = isObjectLike_1; + + /** `Object#toString` result references. */ + var argsTag$2 = '[object Arguments]'; + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments$1(value) { + return isObjectLike$6(value) && baseGetTag$4(value) == argsTag$2; + } + + var _baseIsArguments = baseIsArguments$1; + + var baseIsArguments = _baseIsArguments, + isObjectLike$5 = isObjectLike_1; + + /** Used for built-in method references. */ + var objectProto$7 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$6 = objectProto$7.hasOwnProperty; + + /** Built-in value references. */ + var propertyIsEnumerable$1 = objectProto$7.propertyIsEnumerable; + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + var isArguments$1 = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike$5(value) && hasOwnProperty$6.call(value, 'callee') && + !propertyIsEnumerable$1.call(value, 'callee'); + }; + + var isArguments_1 = isArguments$1; + + var isArray$5 = Array.isArray; + + var isArray_1 = isArray$5; + + var isBufferExports = {}; + var isBuffer$4 = { + get exports(){ return isBufferExports; }, + set exports(v){ isBufferExports = v; }, + }; + + function stubFalse() { + return false; + } + + var stubFalse_1 = stubFalse; + + (function (module, exports) { + var root = _root, + stubFalse = stubFalse_1; + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; + + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; + + module.exports = isBuffer; + } (isBuffer$4, isBufferExports)); + + var MAX_SAFE_INTEGER$1 = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex$1(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER$1 : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + var _isIndex = isIndex$1; + + var MAX_SAFE_INTEGER = 9007199254740991; + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength$2(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + var isLength_1 = isLength$2; + + var baseGetTag$3 = _baseGetTag, + isLength$1 = isLength_1, + isObjectLike$4 = isObjectLike_1; + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]', + arrayTag$1 = '[object Array]', + boolTag$2 = '[object Boolean]', + dateTag$2 = '[object Date]', + errorTag$1 = '[object Error]', + funcTag$1 = '[object Function]', + mapTag$4 = '[object Map]', + numberTag$2 = '[object Number]', + objectTag$3 = '[object Object]', + regexpTag$3 = '[object RegExp]', + setTag$4 = '[object Set]', + stringTag$2 = '[object String]', + weakMapTag$2 = '[object WeakMap]'; + + var arrayBufferTag$2 = '[object ArrayBuffer]', + dataViewTag$3 = '[object DataView]', + float32Tag$2 = '[object Float32Array]', + float64Tag$2 = '[object Float64Array]', + int8Tag$2 = '[object Int8Array]', + int16Tag$2 = '[object Int16Array]', + int32Tag$2 = '[object Int32Array]', + uint8Tag$2 = '[object Uint8Array]', + uint8ClampedTag$2 = '[object Uint8ClampedArray]', + uint16Tag$2 = '[object Uint16Array]', + uint32Tag$2 = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag$2] = typedArrayTags[float64Tag$2] = + typedArrayTags[int8Tag$2] = typedArrayTags[int16Tag$2] = + typedArrayTags[int32Tag$2] = typedArrayTags[uint8Tag$2] = + typedArrayTags[uint8ClampedTag$2] = typedArrayTags[uint16Tag$2] = + typedArrayTags[uint32Tag$2] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag$1] = + typedArrayTags[arrayBufferTag$2] = typedArrayTags[boolTag$2] = + typedArrayTags[dataViewTag$3] = typedArrayTags[dateTag$2] = + typedArrayTags[errorTag$1] = typedArrayTags[funcTag$1] = + typedArrayTags[mapTag$4] = typedArrayTags[numberTag$2] = + typedArrayTags[objectTag$3] = typedArrayTags[regexpTag$3] = + typedArrayTags[setTag$4] = typedArrayTags[stringTag$2] = + typedArrayTags[weakMapTag$2] = false; + + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray$1(value) { + return isObjectLike$4(value) && + isLength$1(value.length) && !!typedArrayTags[baseGetTag$3(value)]; + } + + var _baseIsTypedArray = baseIsTypedArray$1; + + function baseUnary$4(func) { + return function(value) { + return func(value); + }; + } + + var _baseUnary = baseUnary$4; + + var _nodeUtilExports = {}; + var _nodeUtil = { + get exports(){ return _nodeUtilExports; }, + set exports(v){ _nodeUtilExports = v; }, + }; + + (function (module, exports) { + var freeGlobal = _freeGlobal; + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports && freeGlobal.process; + + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); + + module.exports = nodeUtil; + } (_nodeUtil, _nodeUtilExports)); + + var baseIsTypedArray = _baseIsTypedArray, + baseUnary$3 = _baseUnary, + nodeUtil$3 = _nodeUtilExports; + + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil$3 && nodeUtil$3.isTypedArray; + + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray$1 = nodeIsTypedArray ? baseUnary$3(nodeIsTypedArray) : baseIsTypedArray; + + var isTypedArray_1 = isTypedArray$1; + + var baseTimes = _baseTimes, + isArguments = isArguments_1, + isArray$4 = isArray_1, + isBuffer$3 = isBufferExports, + isIndex = _isIndex, + isTypedArray = isTypedArray_1; + + /** Used for built-in method references. */ + var objectProto$6 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$5 = objectProto$6.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys$2(value, inherited) { + var isArr = isArray$4(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer$3(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$5.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + var _arrayLikeKeys = arrayLikeKeys$2; + + var objectProto$5 = Object.prototype; + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype$3(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; + + return value === proto; + } + + var _isPrototype = isPrototype$3; + + function overArg$2(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + + var _overArg = overArg$2; + + var overArg$1 = _overArg; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys$1 = overArg$1(Object.keys, Object); + + var _nativeKeys = nativeKeys$1; + + var isPrototype$2 = _isPrototype, + nativeKeys = _nativeKeys; + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$4.hasOwnProperty; + + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys$1(object) { + if (!isPrototype$2(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$4.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + var _baseKeys = baseKeys$1; + + var isFunction$3 = isFunction_1, + isLength = isLength_1; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike$2(value) { + return value != null && isLength(value.length) && !isFunction$3(value); + } + + var isArrayLike_1 = isArrayLike$2; + + var arrayLikeKeys$1 = _arrayLikeKeys, + baseKeys = _baseKeys, + isArrayLike$1 = isArrayLike_1; + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys$3(object) { + return isArrayLike$1(object) ? arrayLikeKeys$1(object) : baseKeys(object); + } + + var keys_1 = keys$3; + + var copyObject$3 = _copyObject, + keys$2 = keys_1; + + /** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssign$1(object, source) { + return object && copyObject$3(source, keys$2(source), object); + } + + var _baseAssign = baseAssign$1; + + function nativeKeysIn$1(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + var _nativeKeysIn = nativeKeysIn$1; + + var isObject$3 = isObject_1, + isPrototype$1 = _isPrototype, + nativeKeysIn = _nativeKeysIn; + + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$3.hasOwnProperty; + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn$1(object) { + if (!isObject$3(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype$1(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty$3.call(object, key)))) { + result.push(key); + } + } + return result; + } + + var _baseKeysIn = baseKeysIn$1; + + var arrayLikeKeys = _arrayLikeKeys, + baseKeysIn = _baseKeysIn, + isArrayLike = isArrayLike_1; + + /** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ + function keysIn$3(object) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + var keysIn_1 = keysIn$3; + + var copyObject$2 = _copyObject, + keysIn$2 = keysIn_1; + + /** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + function baseAssignIn$1(object, source) { + return object && copyObject$2(source, keysIn$2(source), object); + } + + var _baseAssignIn = baseAssignIn$1; + + var _cloneBufferExports = {}; + var _cloneBuffer = { + get exports(){ return _cloneBufferExports; }, + set exports(v){ _cloneBufferExports = v; }, + }; + + (function (module, exports) { + var root = _root; + + /** Detect free variable `exports`. */ + var freeExports = exports && !exports.nodeType && exports; + + /** Detect free variable `module`. */ + var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; + + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined; + + /** + * Creates a clone of `buffer`. + * + * @private + * @param {Buffer} buffer The buffer to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Buffer} Returns the cloned buffer. + */ + function cloneBuffer(buffer, isDeep) { + if (isDeep) { + return buffer.slice(); + } + var length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length); + + buffer.copy(result); + return result; + } + + module.exports = cloneBuffer; + } (_cloneBuffer, _cloneBufferExports)); + + function copyArray$1(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + var _copyArray = copyArray$1; + + function arrayFilter$1(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; + } + + var _arrayFilter = arrayFilter$1; + + function stubArray$2() { + return []; + } + + var stubArray_1 = stubArray$2; + + var arrayFilter = _arrayFilter, + stubArray$1 = stubArray_1; + + /** Used for built-in method references. */ + var objectProto$2 = Object.prototype; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$2.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols$1 = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols$4 = !nativeGetSymbols$1 ? stubArray$1 : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols$1(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + var _getSymbols = getSymbols$4; + + var copyObject$1 = _copyObject, + getSymbols$3 = _getSymbols; + + /** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbols$1(source, object) { + return copyObject$1(source, getSymbols$3(source), object); + } + + var _copySymbols = copySymbols$1; + + function arrayPush$2(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; + } + + var _arrayPush = arrayPush$2; + + var overArg = _overArg; + + /** Built-in value references. */ + var getPrototype$3 = overArg(Object.getPrototypeOf, Object); + + var _getPrototype = getPrototype$3; + + var arrayPush$1 = _arrayPush, + getPrototype$2 = _getPrototype, + getSymbols$2 = _getSymbols, + stubArray = stubArray_1; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetSymbols = Object.getOwnPropertySymbols; + + /** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbolsIn$2 = !nativeGetSymbols ? stubArray : function(object) { + var result = []; + while (object) { + arrayPush$1(result, getSymbols$2(object)); + object = getPrototype$2(object); + } + return result; + }; + + var _getSymbolsIn = getSymbolsIn$2; + + var copyObject = _copyObject, + getSymbolsIn$1 = _getSymbolsIn; + + /** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ + function copySymbolsIn$1(source, object) { + return copyObject(source, getSymbolsIn$1(source), object); + } + + var _copySymbolsIn = copySymbolsIn$1; + + var arrayPush = _arrayPush, + isArray$3 = isArray_1; + + /** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ + function baseGetAllKeys$2(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return isArray$3(object) ? result : arrayPush(result, symbolsFunc(object)); + } + + var _baseGetAllKeys = baseGetAllKeys$2; + + var baseGetAllKeys$1 = _baseGetAllKeys, + getSymbols$1 = _getSymbols, + keys$1 = keys_1; + + /** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeys$1(object) { + return baseGetAllKeys$1(object, keys$1, getSymbols$1); + } + + var _getAllKeys = getAllKeys$1; + + var baseGetAllKeys = _baseGetAllKeys, + getSymbolsIn = _getSymbolsIn, + keysIn$1 = keysIn_1; + + /** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ + function getAllKeysIn$1(object) { + return baseGetAllKeys(object, keysIn$1, getSymbolsIn); + } + + var _getAllKeysIn = getAllKeysIn$1; + + var getNative$3 = _getNative, + root$4 = _root; + + /* Built-in method references that are verified to be native. */ + var DataView$1 = getNative$3(root$4, 'DataView'); + + var _DataView = DataView$1; + + var getNative$2 = _getNative, + root$3 = _root; + + /* Built-in method references that are verified to be native. */ + var Promise$2 = getNative$2(root$3, 'Promise'); + + var _Promise = Promise$2; + + var getNative$1 = _getNative, + root$2 = _root; + + /* Built-in method references that are verified to be native. */ + var Set$3 = getNative$1(root$2, 'Set'); + + var _Set = Set$3; + + var getNative = _getNative, + root$1 = _root; + + /* Built-in method references that are verified to be native. */ + var WeakMap$2 = getNative(root$1, 'WeakMap'); + + var _WeakMap = WeakMap$2; + + var DataView = _DataView, + Map$1 = _Map, + Promise$1 = _Promise, + Set$2 = _Set, + WeakMap$1 = _WeakMap, + baseGetTag$2 = _baseGetTag, + toSource = _toSource; + + /** `Object#toString` result references. */ + var mapTag$3 = '[object Map]', + objectTag$2 = '[object Object]', + promiseTag = '[object Promise]', + setTag$3 = '[object Set]', + weakMapTag$1 = '[object WeakMap]'; + + var dataViewTag$2 = '[object DataView]'; + + /** Used to detect maps, sets, and weakmaps. */ + var dataViewCtorString = toSource(DataView), + mapCtorString = toSource(Map$1), + promiseCtorString = toSource(Promise$1), + setCtorString = toSource(Set$2), + weakMapCtorString = toSource(WeakMap$1); + + /** + * Gets the `toStringTag` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + var getTag$3 = baseGetTag$2; + + // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. + if ((DataView && getTag$3(new DataView(new ArrayBuffer(1))) != dataViewTag$2) || + (Map$1 && getTag$3(new Map$1) != mapTag$3) || + (Promise$1 && getTag$3(Promise$1.resolve()) != promiseTag) || + (Set$2 && getTag$3(new Set$2) != setTag$3) || + (WeakMap$1 && getTag$3(new WeakMap$1) != weakMapTag$1)) { + getTag$3 = function(value) { + var result = baseGetTag$2(value), + Ctor = result == objectTag$2 ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: return dataViewTag$2; + case mapCtorString: return mapTag$3; + case promiseCtorString: return promiseTag; + case setCtorString: return setTag$3; + case weakMapCtorString: return weakMapTag$1; + } + } + return result; + }; + } + + var _getTag = getTag$3; + + var objectProto$1 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$1.hasOwnProperty; + + /** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ + function initCloneArray$1(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && hasOwnProperty$2.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; + } + + var _initCloneArray = initCloneArray$1; + + var root = _root; + + /** Built-in value references. */ + var Uint8Array$2 = root.Uint8Array; + + var _Uint8Array = Uint8Array$2; + + var Uint8Array$1 = _Uint8Array; + + /** + * Creates a clone of `arrayBuffer`. + * + * @private + * @param {ArrayBuffer} arrayBuffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function cloneArrayBuffer$3(arrayBuffer) { + var result = new arrayBuffer.constructor(arrayBuffer.byteLength); + new Uint8Array$1(result).set(new Uint8Array$1(arrayBuffer)); + return result; + } + + var _cloneArrayBuffer = cloneArrayBuffer$3; + + var cloneArrayBuffer$2 = _cloneArrayBuffer; + + /** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ + function cloneDataView$1(dataView, isDeep) { + var buffer = isDeep ? cloneArrayBuffer$2(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); + } + + var _cloneDataView = cloneDataView$1; + + var reFlags = /\w*$/; + + /** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ + function cloneRegExp$1(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; + } + + var _cloneRegExp = cloneRegExp$1; + + var Symbol$1 = _Symbol; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + + /** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ + function cloneSymbol$1(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; + } + + var _cloneSymbol = cloneSymbol$1; + + var cloneArrayBuffer$1 = _cloneArrayBuffer; + + /** + * Creates a clone of `typedArray`. + * + * @private + * @param {Object} typedArray The typed array to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned typed array. + */ + function cloneTypedArray$1(typedArray, isDeep) { + var buffer = isDeep ? cloneArrayBuffer$1(typedArray.buffer) : typedArray.buffer; + return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); + } + + var _cloneTypedArray = cloneTypedArray$1; + + var cloneArrayBuffer = _cloneArrayBuffer, + cloneDataView = _cloneDataView, + cloneRegExp = _cloneRegExp, + cloneSymbol = _cloneSymbol, + cloneTypedArray = _cloneTypedArray; + + /** `Object#toString` result references. */ + var boolTag$1 = '[object Boolean]', + dateTag$1 = '[object Date]', + mapTag$2 = '[object Map]', + numberTag$1 = '[object Number]', + regexpTag$2 = '[object RegExp]', + setTag$2 = '[object Set]', + stringTag$1 = '[object String]', + symbolTag$1 = '[object Symbol]'; + + var arrayBufferTag$1 = '[object ArrayBuffer]', + dataViewTag$1 = '[object DataView]', + float32Tag$1 = '[object Float32Array]', + float64Tag$1 = '[object Float64Array]', + int8Tag$1 = '[object Int8Array]', + int16Tag$1 = '[object Int16Array]', + int32Tag$1 = '[object Int32Array]', + uint8Tag$1 = '[object Uint8Array]', + uint8ClampedTag$1 = '[object Uint8ClampedArray]', + uint16Tag$1 = '[object Uint16Array]', + uint32Tag$1 = '[object Uint32Array]'; + + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag$1(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag$1: + return cloneArrayBuffer(object); + + case boolTag$1: + case dateTag$1: + return new Ctor(+object); + + case dataViewTag$1: + return cloneDataView(object, isDeep); + + case float32Tag$1: case float64Tag$1: + case int8Tag$1: case int16Tag$1: case int32Tag$1: + case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1: + return cloneTypedArray(object, isDeep); + + case mapTag$2: + return new Ctor; + + case numberTag$1: + case stringTag$1: + return new Ctor(object); + + case regexpTag$2: + return cloneRegExp(object); + + case setTag$2: + return new Ctor; + + case symbolTag$1: + return cloneSymbol(object); + } + } + + var _initCloneByTag = initCloneByTag$1; + + var isObject$2 = isObject_1; + + /** Built-in value references. */ + var objectCreate = Object.create; + + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate$1 = (function() { + function object() {} + return function(proto) { + if (!isObject$2(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + var _baseCreate = baseCreate$1; + + var baseCreate = _baseCreate, + getPrototype$1 = _getPrototype, + isPrototype = _isPrototype; + + /** + * Initializes an object clone. + * + * @private + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneObject$1(object) { + return (typeof object.constructor == 'function' && !isPrototype(object)) + ? baseCreate(getPrototype$1(object)) + : {}; + } + + var _initCloneObject = initCloneObject$1; + + var getTag$2 = _getTag, + isObjectLike$3 = isObjectLike_1; + + /** `Object#toString` result references. */ + var mapTag$1 = '[object Map]'; + + /** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ + function baseIsMap$1(value) { + return isObjectLike$3(value) && getTag$2(value) == mapTag$1; + } + + var _baseIsMap = baseIsMap$1; + + var baseIsMap = _baseIsMap, + baseUnary$2 = _baseUnary, + nodeUtil$2 = _nodeUtilExports; + + /* Node.js helper references. */ + var nodeIsMap = nodeUtil$2 && nodeUtil$2.isMap; + + /** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ + var isMap$2 = nodeIsMap ? baseUnary$2(nodeIsMap) : baseIsMap; + + var isMap_1 = isMap$2; + + var getTag$1 = _getTag, + isObjectLike$2 = isObjectLike_1; + + /** `Object#toString` result references. */ + var setTag$1 = '[object Set]'; + + /** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ + function baseIsSet$1(value) { + return isObjectLike$2(value) && getTag$1(value) == setTag$1; + } + + var _baseIsSet = baseIsSet$1; + + var baseIsSet = _baseIsSet, + baseUnary$1 = _baseUnary, + nodeUtil$1 = _nodeUtilExports; + + /* Node.js helper references. */ + var nodeIsSet = nodeUtil$1 && nodeUtil$1.isSet; + + /** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ + var isSet$2 = nodeIsSet ? baseUnary$1(nodeIsSet) : baseIsSet; + + var isSet_1 = isSet$2; + + var Stack = _Stack, + arrayEach = _arrayEach, + assignValue = _assignValue, + baseAssign = _baseAssign, + baseAssignIn = _baseAssignIn, + cloneBuffer = _cloneBufferExports, + copyArray = _copyArray, + copySymbols = _copySymbols, + copySymbolsIn = _copySymbolsIn, + getAllKeys = _getAllKeys, + getAllKeysIn = _getAllKeysIn, + getTag = _getTag, + initCloneArray = _initCloneArray, + initCloneByTag = _initCloneByTag, + initCloneObject = _initCloneObject, + isArray$2 = isArray_1, + isBuffer$2 = isBufferExports, + isMap$1 = isMap_1, + isObject$1 = isObject_1, + isSet$1 = isSet_1, + keys = keys_1; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG$1 = 4; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag$1 = '[object Object]', + regexpTag$1 = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = + cloneableTags[boolTag] = cloneableTags[dateTag] = + cloneableTags[float32Tag] = cloneableTags[float64Tag] = + cloneableTags[int8Tag] = cloneableTags[int16Tag] = + cloneableTags[int32Tag] = cloneableTags[mapTag] = + cloneableTags[numberTag] = cloneableTags[objectTag$1] = + cloneableTags[regexpTag$1] = cloneableTags[setTag] = + cloneableTags[stringTag] = cloneableTags[symbolTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[weakMapTag] = false; + + /** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone$1(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG$1; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject$1(value)) { + return value; + } + var isArr = isArray$2(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return copyArray(value, result); + } + } else { + var tag = getTag(value), + isFunc = tag == funcTag || tag == genTag; + + if (isBuffer$2(value)) { + return cloneBuffer(value, isDeep); + } + if (tag == objectTag$1 || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new Stack); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (isSet$1(value)) { + value.forEach(function(subValue) { + result.add(baseClone$1(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap$1(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone$1(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(value); + arrayEach(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + assignValue(result, key, baseClone$1(subValue, bitmask, customizer, key, value, stack)); + }); + return result; + } + + var _baseClone = baseClone$1; + + var baseClone = _baseClone; + + /** Used to compose bitmasks for cloning. */ + var CLONE_SYMBOLS_FLAG = 4; + + /** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ + function clone$2(value) { + return baseClone(value, CLONE_SYMBOLS_FLAG); + } + + var clone_1 = clone$2; + + var definitions = {}; + + var core = {}; + + var is = {}; + + var isType$1 = {}; + + var hasRequiredIsType; + + function requireIsType () { + if (hasRequiredIsType) return isType$1; + hasRequiredIsType = 1; + + Object.defineProperty(isType$1, "__esModule", { + value: true + }); + isType$1.default = isType; + + var _definitions = requireDefinitions(); + + function isType(nodeType, targetType) { + if (nodeType === targetType) return true; + if (_definitions.ALIAS_KEYS[targetType]) return false; + const aliases = _definitions.FLIPPED_ALIAS_KEYS[targetType]; + + if (aliases) { + if (aliases[0] === nodeType) return true; + + for (const alias of aliases) { + if (nodeType === alias) return true; + } + } + + return false; + } + return isType$1; + } + + var isPlaceholderType = {}; + + var hasRequiredIsPlaceholderType; + + function requireIsPlaceholderType () { + if (hasRequiredIsPlaceholderType) return isPlaceholderType; + hasRequiredIsPlaceholderType = 1; + + Object.defineProperty(isPlaceholderType, "__esModule", { + value: true + }); + isPlaceholderType.default = isPlaceholderType$1; + + var _definitions = requireDefinitions(); + + function isPlaceholderType$1(placeholderType, targetType) { + if (placeholderType === targetType) return true; + const aliases = _definitions.PLACEHOLDERS_ALIAS[placeholderType]; + + if (aliases) { + for (const alias of aliases) { + if (targetType === alias) return true; + } + } + + return false; + } + return isPlaceholderType; + } + + var hasRequiredIs; + + function requireIs () { + if (hasRequiredIs) return is; + hasRequiredIs = 1; + + Object.defineProperty(is, "__esModule", { + value: true + }); + is.default = is$1; + + var _shallowEqual = _interopRequireDefault(shallowEqual$1); + + var _isType = _interopRequireDefault(requireIsType()); + + var _isPlaceholderType = _interopRequireDefault(requireIsPlaceholderType()); + + var _definitions = requireDefinitions(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function is$1(type, node, opts) { + if (!node) return false; + const matches = (0, _isType.default)(node.type, type); + + if (!matches) { + if (!opts && node.type === "Placeholder" && type in _definitions.FLIPPED_ALIAS_KEYS) { + return (0, _isPlaceholderType.default)(node.expectedNode, type); + } + + return false; + } + + if (typeof opts === "undefined") { + return true; + } else { + return (0, _shallowEqual.default)(node, opts); + } + } + return is; + } + + var isValidIdentifier$1 = {}; + + var lib$3 = {}; + + var identifier = {}; + + Object.defineProperty(identifier, "__esModule", { + value: true + }); + identifier.isIdentifierStart = isIdentifierStart$2; + identifier.isIdentifierChar = isIdentifierChar$2; + identifier.isIdentifierName = isIdentifierName; + let nonASCIIidentifierStartChars$2 = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + let nonASCIIidentifierChars$2 = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + const nonASCIIidentifierStart$2 = new RegExp("[" + nonASCIIidentifierStartChars$2 + "]"); + const nonASCIIidentifier$2 = new RegExp("[" + nonASCIIidentifierStartChars$2 + nonASCIIidentifierChars$2 + "]"); + nonASCIIidentifierStartChars$2 = nonASCIIidentifierChars$2 = null; + const astralIdentifierStartCodes$2 = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; + const astralIdentifierCodes$2 = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + function isInAstralSet$2(code, set) { + let pos = 0x10000; + + for (let i = 0, length = set.length; i < length; i += 2) { + pos += set[i]; + if (pos > code) return false; + pos += set[i + 1]; + if (pos >= code) return true; + } + + return false; + } + + function isIdentifierStart$2(code) { + if (code < 65) return code === 36; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart$2.test(String.fromCharCode(code)); + } + + return isInAstralSet$2(code, astralIdentifierStartCodes$2); + } + + function isIdentifierChar$2(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier$2.test(String.fromCharCode(code)); + } + + return isInAstralSet$2(code, astralIdentifierStartCodes$2) || isInAstralSet$2(code, astralIdentifierCodes$2); + } + + function isIdentifierName(name) { + let isFirst = true; + + for (let _i = 0, _Array$from = Array.from(name); _i < _Array$from.length; _i++) { + const char = _Array$from[_i]; + const cp = char.codePointAt(0); + + if (isFirst) { + if (!isIdentifierStart$2(cp)) { + return false; + } + + isFirst = false; + } else if (!isIdentifierChar$2(cp)) { + return false; + } + } + + return !isFirst; + } + + var keyword = {}; + + Object.defineProperty(keyword, "__esModule", { + value: true + }); + keyword.isReservedWord = isReservedWord$2; + keyword.isStrictReservedWord = isStrictReservedWord$2; + keyword.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord$2; + keyword.isStrictBindReservedWord = isStrictBindReservedWord$2; + keyword.isKeyword = isKeyword$2; + const reservedWords$2 = { + keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], + strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], + strictBind: ["eval", "arguments"] + }; + const keywords$3 = new Set(reservedWords$2.keyword); + const reservedWordsStrictSet$2 = new Set(reservedWords$2.strict); + const reservedWordsStrictBindSet$2 = new Set(reservedWords$2.strictBind); + + function isReservedWord$2(word, inModule) { + return inModule && word === "await" || word === "enum"; + } + + function isStrictReservedWord$2(word, inModule) { + return isReservedWord$2(word, inModule) || reservedWordsStrictSet$2.has(word); + } + + function isStrictBindOnlyReservedWord$2(word) { + return reservedWordsStrictBindSet$2.has(word); + } + + function isStrictBindReservedWord$2(word, inModule) { + return isStrictReservedWord$2(word, inModule) || isStrictBindOnlyReservedWord$2(word); + } + + function isKeyword$2(word) { + return keywords$3.has(word); + } + + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "isIdentifierName", { + enumerable: true, + get: function () { + return _identifier.isIdentifierName; + } + }); + Object.defineProperty(exports, "isIdentifierChar", { + enumerable: true, + get: function () { + return _identifier.isIdentifierChar; + } + }); + Object.defineProperty(exports, "isIdentifierStart", { + enumerable: true, + get: function () { + return _identifier.isIdentifierStart; + } + }); + Object.defineProperty(exports, "isReservedWord", { + enumerable: true, + get: function () { + return _keyword.isReservedWord; + } + }); + Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindOnlyReservedWord; + } + }); + Object.defineProperty(exports, "isStrictBindReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictBindReservedWord; + } + }); + Object.defineProperty(exports, "isStrictReservedWord", { + enumerable: true, + get: function () { + return _keyword.isStrictReservedWord; + } + }); + Object.defineProperty(exports, "isKeyword", { + enumerable: true, + get: function () { + return _keyword.isKeyword; + } + }); + + var _identifier = identifier; + + var _keyword = keyword; + } (lib$3)); + + Object.defineProperty(isValidIdentifier$1, "__esModule", { + value: true + }); + isValidIdentifier$1.default = isValidIdentifier; + + var _helperValidatorIdentifier = lib$3; + + function isValidIdentifier(name, reserved = true) { + if (typeof name !== "string") return false; + + if (reserved) { + if ((0, _helperValidatorIdentifier.isKeyword)(name) || (0, _helperValidatorIdentifier.isStrictReservedWord)(name)) { + return false; + } else if (name === "await") { + return false; + } + } + + return (0, _helperValidatorIdentifier.isIdentifierName)(name); + } + + var constants = {}; + + Object.defineProperty(constants, "__esModule", { + value: true + }); + constants.NOT_LOCAL_BINDING = constants.BLOCK_SCOPED_SYMBOL = constants.INHERIT_KEYS = constants.UNARY_OPERATORS = constants.STRING_UNARY_OPERATORS = constants.NUMBER_UNARY_OPERATORS = constants.BOOLEAN_UNARY_OPERATORS = constants.ASSIGNMENT_OPERATORS = constants.BINARY_OPERATORS = constants.NUMBER_BINARY_OPERATORS = constants.BOOLEAN_BINARY_OPERATORS = constants.COMPARISON_BINARY_OPERATORS = constants.EQUALITY_BINARY_OPERATORS = constants.BOOLEAN_NUMBER_BINARY_OPERATORS = constants.UPDATE_OPERATORS = constants.LOGICAL_OPERATORS = constants.COMMENT_KEYS = constants.FOR_INIT_KEYS = constants.FLATTENABLE_KEYS = constants.STATEMENT_OR_BLOCK_KEYS = void 0; + const STATEMENT_OR_BLOCK_KEYS = ["consequent", "body", "alternate"]; + constants.STATEMENT_OR_BLOCK_KEYS = STATEMENT_OR_BLOCK_KEYS; + const FLATTENABLE_KEYS = ["body", "expressions"]; + constants.FLATTENABLE_KEYS = FLATTENABLE_KEYS; + const FOR_INIT_KEYS = ["left", "init"]; + constants.FOR_INIT_KEYS = FOR_INIT_KEYS; + const COMMENT_KEYS = ["leadingComments", "trailingComments", "innerComments"]; + constants.COMMENT_KEYS = COMMENT_KEYS; + const LOGICAL_OPERATORS = ["||", "&&", "??"]; + constants.LOGICAL_OPERATORS = LOGICAL_OPERATORS; + const UPDATE_OPERATORS = ["++", "--"]; + constants.UPDATE_OPERATORS = UPDATE_OPERATORS; + const BOOLEAN_NUMBER_BINARY_OPERATORS = [">", "<", ">=", "<="]; + constants.BOOLEAN_NUMBER_BINARY_OPERATORS = BOOLEAN_NUMBER_BINARY_OPERATORS; + const EQUALITY_BINARY_OPERATORS = ["==", "===", "!=", "!=="]; + constants.EQUALITY_BINARY_OPERATORS = EQUALITY_BINARY_OPERATORS; + const COMPARISON_BINARY_OPERATORS = [...EQUALITY_BINARY_OPERATORS, "in", "instanceof"]; + constants.COMPARISON_BINARY_OPERATORS = COMPARISON_BINARY_OPERATORS; + const BOOLEAN_BINARY_OPERATORS = [...COMPARISON_BINARY_OPERATORS, ...BOOLEAN_NUMBER_BINARY_OPERATORS]; + constants.BOOLEAN_BINARY_OPERATORS = BOOLEAN_BINARY_OPERATORS; + const NUMBER_BINARY_OPERATORS = ["-", "/", "%", "*", "**", "&", "|", ">>", ">>>", "<<", "^"]; + constants.NUMBER_BINARY_OPERATORS = NUMBER_BINARY_OPERATORS; + const BINARY_OPERATORS = ["+", ...NUMBER_BINARY_OPERATORS, ...BOOLEAN_BINARY_OPERATORS]; + constants.BINARY_OPERATORS = BINARY_OPERATORS; + const ASSIGNMENT_OPERATORS = ["=", "+=", ...NUMBER_BINARY_OPERATORS.map(op => op + "="), ...LOGICAL_OPERATORS.map(op => op + "=")]; + constants.ASSIGNMENT_OPERATORS = ASSIGNMENT_OPERATORS; + const BOOLEAN_UNARY_OPERATORS = ["delete", "!"]; + constants.BOOLEAN_UNARY_OPERATORS = BOOLEAN_UNARY_OPERATORS; + const NUMBER_UNARY_OPERATORS = ["+", "-", "~"]; + constants.NUMBER_UNARY_OPERATORS = NUMBER_UNARY_OPERATORS; + const STRING_UNARY_OPERATORS = ["typeof"]; + constants.STRING_UNARY_OPERATORS = STRING_UNARY_OPERATORS; + const UNARY_OPERATORS = ["void", "throw", ...BOOLEAN_UNARY_OPERATORS, ...NUMBER_UNARY_OPERATORS, ...STRING_UNARY_OPERATORS]; + constants.UNARY_OPERATORS = UNARY_OPERATORS; + const INHERIT_KEYS = { + optional: ["typeAnnotation", "typeParameters", "returnType"], + force: ["start", "loc", "end"] + }; + constants.INHERIT_KEYS = INHERIT_KEYS; + const BLOCK_SCOPED_SYMBOL = Symbol.for("var used to be block scoped"); + constants.BLOCK_SCOPED_SYMBOL = BLOCK_SCOPED_SYMBOL; + const NOT_LOCAL_BINDING = Symbol.for("should not be considered a local binding"); + constants.NOT_LOCAL_BINDING = NOT_LOCAL_BINDING; + + var utils = {}; + + var validate = {}; + + var hasRequiredValidate; + + function requireValidate () { + if (hasRequiredValidate) return validate; + hasRequiredValidate = 1; + + Object.defineProperty(validate, "__esModule", { + value: true + }); + validate.default = validate$1; + validate.validateField = validateField; + validate.validateChild = validateChild; + + var _definitions = requireDefinitions(); + + function validate$1(node, key, val) { + if (!node) return; + const fields = _definitions.NODE_FIELDS[node.type]; + if (!fields) return; + const field = fields[key]; + validateField(node, key, val, field); + validateChild(node, key, val); + } + + function validateField(node, key, val, field) { + if (!(field == null ? void 0 : field.validate)) return; + if (field.optional && val == null) return; + field.validate(node, key, val); + } + + function validateChild(node, key, val) { + if (val == null) return; + const validate = _definitions.NODE_PARENT_VALIDATIONS[val.type]; + if (!validate) return; + validate(node, key, val); + } + return validate; + } + + var hasRequiredUtils; + + function requireUtils () { + if (hasRequiredUtils) return utils; + hasRequiredUtils = 1; + + Object.defineProperty(utils, "__esModule", { + value: true + }); + utils.validate = validate; + utils.typeIs = typeIs; + utils.validateType = validateType; + utils.validateOptional = validateOptional; + utils.validateOptionalType = validateOptionalType; + utils.arrayOf = arrayOf; + utils.arrayOfType = arrayOfType; + utils.validateArrayOfType = validateArrayOfType; + utils.assertEach = assertEach; + utils.assertOneOf = assertOneOf; + utils.assertNodeType = assertNodeType; + utils.assertNodeOrValueType = assertNodeOrValueType; + utils.assertValueType = assertValueType; + utils.assertShape = assertShape; + utils.assertOptionalChainStart = assertOptionalChainStart; + utils.chain = chain; + utils.default = defineType; + utils.NODE_PARENT_VALIDATIONS = utils.DEPRECATED_KEYS = utils.BUILDER_KEYS = utils.NODE_FIELDS = utils.FLIPPED_ALIAS_KEYS = utils.ALIAS_KEYS = utils.VISITOR_KEYS = void 0; + + var _is = _interopRequireDefault(requireIs()); + + var _validate = requireValidate(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + const VISITOR_KEYS = {}; + utils.VISITOR_KEYS = VISITOR_KEYS; + const ALIAS_KEYS = {}; + utils.ALIAS_KEYS = ALIAS_KEYS; + const FLIPPED_ALIAS_KEYS = {}; + utils.FLIPPED_ALIAS_KEYS = FLIPPED_ALIAS_KEYS; + const NODE_FIELDS = {}; + utils.NODE_FIELDS = NODE_FIELDS; + const BUILDER_KEYS = {}; + utils.BUILDER_KEYS = BUILDER_KEYS; + const DEPRECATED_KEYS = {}; + utils.DEPRECATED_KEYS = DEPRECATED_KEYS; + const NODE_PARENT_VALIDATIONS = {}; + utils.NODE_PARENT_VALIDATIONS = NODE_PARENT_VALIDATIONS; + + function getType(val) { + if (Array.isArray(val)) { + return "array"; + } else if (val === null) { + return "null"; + } else { + return typeof val; + } + } + + function validate(validate) { + return { + validate + }; + } + + function typeIs(typeName) { + return typeof typeName === "string" ? assertNodeType(typeName) : assertNodeType(...typeName); + } + + function validateType(typeName) { + return validate(typeIs(typeName)); + } + + function validateOptional(validate) { + return { + validate, + optional: true + }; + } + + function validateOptionalType(typeName) { + return { + validate: typeIs(typeName), + optional: true + }; + } + + function arrayOf(elementType) { + return chain(assertValueType("array"), assertEach(elementType)); + } + + function arrayOfType(typeName) { + return arrayOf(typeIs(typeName)); + } + + function validateArrayOfType(typeName) { + return validate(arrayOfType(typeName)); + } + + function assertEach(callback) { + function validator(node, key, val) { + if (!Array.isArray(val)) return; + + for (let i = 0; i < val.length; i++) { + const subkey = `${key}[${i}]`; + const v = val[i]; + callback(node, subkey, v); + if (process$1.env.BABEL_TYPES_8_BREAKING) (0, _validate.validateChild)(node, subkey, v); + } + } + + validator.each = callback; + return validator; + } + + function assertOneOf(...values) { + function validate(node, key, val) { + if (values.indexOf(val) < 0) { + throw new TypeError(`Property ${key} expected value to be one of ${JSON.stringify(values)} but got ${JSON.stringify(val)}`); + } + } + + validate.oneOf = values; + return validate; + } + + function assertNodeType(...types) { + function validate(node, key, val) { + for (const type of types) { + if ((0, _is.default)(type, val)) { + (0, _validate.validateChild)(node, key, val); + return; + } + } + + throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); + } + + validate.oneOfNodeTypes = types; + return validate; + } + + function assertNodeOrValueType(...types) { + function validate(node, key, val) { + for (const type of types) { + if (getType(val) === type || (0, _is.default)(type, val)) { + (0, _validate.validateChild)(node, key, val); + return; + } + } + + throw new TypeError(`Property ${key} of ${node.type} expected node to be of a type ${JSON.stringify(types)} but instead got ${JSON.stringify(val == null ? void 0 : val.type)}`); + } + + validate.oneOfNodeOrValueTypes = types; + return validate; + } + + function assertValueType(type) { + function validate(node, key, val) { + const valid = getType(val) === type; + + if (!valid) { + throw new TypeError(`Property ${key} expected type of ${type} but got ${getType(val)}`); + } + } + + validate.type = type; + return validate; + } + + function assertShape(shape) { + function validate(node, key, val) { + const errors = []; + + for (const property of Object.keys(shape)) { + try { + (0, _validate.validateField)(node, property, val[property], shape[property]); + } catch (error) { + if (error instanceof TypeError) { + errors.push(error.message); + continue; + } + + throw error; + } + } + + if (errors.length) { + throw new TypeError(`Property ${key} of ${node.type} expected to have the following:\n${errors.join("\n")}`); + } + } + + validate.shapeOf = shape; + return validate; + } + + function assertOptionalChainStart() { + function validate(node) { + var _current; + + let current = node; + + while (node) { + const { + type + } = current; + + if (type === "OptionalCallExpression") { + if (current.optional) return; + current = current.callee; + continue; + } + + if (type === "OptionalMemberExpression") { + if (current.optional) return; + current = current.object; + continue; + } + + break; + } + + throw new TypeError(`Non-optional ${node.type} must chain from an optional OptionalMemberExpression or OptionalCallExpression. Found chain from ${(_current = current) == null ? void 0 : _current.type}`); + } + + return validate; + } + + function chain(...fns) { + function validate(...args) { + for (const fn of fns) { + fn(...args); + } + } + + validate.chainOf = fns; + return validate; + } + + const validTypeOpts = ["aliases", "builder", "deprecatedAlias", "fields", "inherits", "visitor", "validate"]; + const validFieldKeys = ["default", "optional", "validate"]; + + function defineType(type, opts = {}) { + const inherits = opts.inherits && store[opts.inherits] || {}; + let fields = opts.fields; + + if (!fields) { + fields = {}; + + if (inherits.fields) { + const keys = Object.getOwnPropertyNames(inherits.fields); + + for (const key of keys) { + const field = inherits.fields[key]; + fields[key] = { + default: field.default, + optional: field.optional, + validate: field.validate + }; + } + } + } + + const visitor = opts.visitor || inherits.visitor || []; + const aliases = opts.aliases || inherits.aliases || []; + const builder = opts.builder || inherits.builder || opts.visitor || []; + + for (const k of Object.keys(opts)) { + if (validTypeOpts.indexOf(k) === -1) { + throw new Error(`Unknown type option "${k}" on ${type}`); + } + } + + if (opts.deprecatedAlias) { + DEPRECATED_KEYS[opts.deprecatedAlias] = type; + } + + for (const key of visitor.concat(builder)) { + fields[key] = fields[key] || {}; + } + + for (const key of Object.keys(fields)) { + const field = fields[key]; + + if (field.default !== undefined && builder.indexOf(key) === -1) { + field.optional = true; + } + + if (field.default === undefined) { + field.default = null; + } else if (!field.validate && field.default != null) { + field.validate = assertValueType(getType(field.default)); + } + + for (const k of Object.keys(field)) { + if (validFieldKeys.indexOf(k) === -1) { + throw new Error(`Unknown field key "${k}" on ${type}.${key}`); + } + } + } + + VISITOR_KEYS[type] = opts.visitor = visitor; + BUILDER_KEYS[type] = opts.builder = builder; + NODE_FIELDS[type] = opts.fields = fields; + ALIAS_KEYS[type] = opts.aliases = aliases; + aliases.forEach(alias => { + FLIPPED_ALIAS_KEYS[alias] = FLIPPED_ALIAS_KEYS[alias] || []; + FLIPPED_ALIAS_KEYS[alias].push(type); + }); + + if (opts.validate) { + NODE_PARENT_VALIDATIONS[type] = opts.validate; + } + + store[type] = opts; + } + + const store = {}; + return utils; + } + + var hasRequiredCore; + + function requireCore () { + if (hasRequiredCore) return core; + hasRequiredCore = 1; + + Object.defineProperty(core, "__esModule", { + value: true + }); + core.patternLikeCommon = core.functionDeclarationCommon = core.functionTypeAnnotationCommon = core.functionCommon = void 0; + + var _is = _interopRequireDefault(requireIs()); + + var _isValidIdentifier = _interopRequireDefault(isValidIdentifier$1); + + var _helperValidatorIdentifier = lib$3; + + var _constants = constants; + + var _utils = _interopRequireWildcard(requireUtils()); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + (0, _utils.default)("ArrayExpression", { + fields: { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeOrValueType)("null", "Expression", "SpreadElement"))), + default: !process$1.env.BABEL_TYPES_8_BREAKING ? [] : undefined + } + }, + visitor: ["elements"], + aliases: ["Expression"] + }); + (0, _utils.default)("AssignmentExpression", { + fields: { + operator: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertValueType)("string"); + } + + const identifier = (0, _utils.assertOneOf)(..._constants.ASSIGNMENT_OPERATORS); + const pattern = (0, _utils.assertOneOf)("="); + return function (node, key, val) { + const validator = (0, _is.default)("Pattern", node.left) ? pattern : identifier; + validator(node, key, val); + }; + }() + }, + left: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("LVal") : (0, _utils.assertNodeType)("Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + builder: ["operator", "left", "right"], + visitor: ["left", "right"], + aliases: ["Expression"] + }); + (0, _utils.default)("BinaryExpression", { + builder: ["operator", "left", "right"], + fields: { + operator: { + validate: (0, _utils.assertOneOf)(..._constants.BINARY_OPERATORS) + }, + left: { + validate: function () { + const expression = (0, _utils.assertNodeType)("Expression"); + const inOp = (0, _utils.assertNodeType)("Expression", "PrivateName"); + + const validator = function (node, key, val) { + const validator = node.operator === "in" ? inOp : expression; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "PrivateName"]; + return validator; + }() + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + visitor: ["left", "right"], + aliases: ["Binary", "Expression"] + }); + (0, _utils.default)("InterpreterDirective", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("Directive", { + visitor: ["value"], + fields: { + value: { + validate: (0, _utils.assertNodeType)("DirectiveLiteral") + } + } + }); + (0, _utils.default)("DirectiveLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("BlockStatement", { + builder: ["body", "directives"], + visitor: ["directives", "body"], + fields: { + directives: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Directive"))), + default: [] + }, + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + }, + aliases: ["Scopable", "BlockParent", "Block", "Statement"] + }); + (0, _utils.default)("BreakStatement", { + visitor: ["label"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }, + aliases: ["Statement", "Terminatorless", "CompletionStatement"] + }); + (0, _utils.default)("CallExpression", { + visitor: ["callee", "arguments", "typeParameters", "typeArguments"], + builder: ["callee", "arguments"], + aliases: ["Expression"], + fields: Object.assign({ + callee: { + validate: (0, _utils.assertNodeType)("Expression", "V8IntrinsicIdentifier") + }, + arguments: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement", "JSXNamespacedName", "ArgumentPlaceholder"))) + } + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + optional: { + validate: (0, _utils.assertOneOf)(true, false), + optional: true + } + } : {}, { + typeArguments: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterInstantiation"), + optional: true + } + }) + }); + (0, _utils.default)("CatchClause", { + visitor: ["param", "body"], + fields: { + param: { + validate: (0, _utils.assertNodeType)("Identifier", "ArrayPattern", "ObjectPattern"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }, + aliases: ["Scopable", "BlockParent"] + }); + (0, _utils.default)("ConditionalExpression", { + visitor: ["test", "consequent", "alternate"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + consequent: { + validate: (0, _utils.assertNodeType)("Expression") + }, + alternate: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Expression", "Conditional"] + }); + (0, _utils.default)("ContinueStatement", { + visitor: ["label"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }, + aliases: ["Statement", "Terminatorless", "CompletionStatement"] + }); + (0, _utils.default)("DebuggerStatement", { + aliases: ["Statement"] + }); + (0, _utils.default)("DoWhileStatement", { + visitor: ["test", "body"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + }, + aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"] + }); + (0, _utils.default)("EmptyStatement", { + aliases: ["Statement"] + }); + (0, _utils.default)("ExpressionStatement", { + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + }, + aliases: ["Statement", "ExpressionWrapper"] + }); + (0, _utils.default)("File", { + builder: ["program", "comments", "tokens"], + visitor: ["program"], + fields: { + program: { + validate: (0, _utils.assertNodeType)("Program") + }, + comments: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? Object.assign(() => {}, { + each: { + oneOfNodeTypes: ["CommentBlock", "CommentLine"] + } + }) : (0, _utils.assertEach)((0, _utils.assertNodeType)("CommentBlock", "CommentLine")), + optional: true + }, + tokens: { + validate: (0, _utils.assertEach)(Object.assign(() => {}, { + type: "any" + })), + optional: true + } + } + }); + (0, _utils.default)("ForInStatement", { + visitor: ["left", "right", "body"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"], + fields: { + left: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("VariableDeclaration", "LVal") : (0, _utils.assertNodeType)("VariableDeclaration", "Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("ForStatement", { + visitor: ["init", "test", "update", "body"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop"], + fields: { + init: { + validate: (0, _utils.assertNodeType)("VariableDeclaration", "Expression"), + optional: true + }, + test: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + update: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + const functionCommon = { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Identifier", "Pattern", "RestElement", "TSParameterProperty"))) + }, + generator: { + default: false + }, + async: { + default: false + } + }; + core.functionCommon = functionCommon; + const functionTypeAnnotationCommon = { + returnType: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + } + }; + core.functionTypeAnnotationCommon = functionTypeAnnotationCommon; + const functionDeclarationCommon = Object.assign({}, functionCommon, { + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + } + }); + core.functionDeclarationCommon = functionDeclarationCommon; + (0, _utils.default)("FunctionDeclaration", { + builder: ["id", "params", "body", "generator", "async"], + visitor: ["id", "params", "body", "returnType", "typeParameters"], + fields: Object.assign({}, functionDeclarationCommon, functionTypeAnnotationCommon, { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }), + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Statement", "Pureish", "Declaration"], + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return () => {}; + const identifier = (0, _utils.assertNodeType)("Identifier"); + return function (parent, key, node) { + if (!(0, _is.default)("ExportDefaultDeclaration", parent)) { + identifier(node, "id", node.id); + } + }; + }() + }); + (0, _utils.default)("FunctionExpression", { + inherits: "FunctionDeclaration", + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"], + fields: Object.assign({}, functionCommon, functionTypeAnnotationCommon, { + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + const patternLikeCommon = { + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))) + } + }; + core.patternLikeCommon = patternLikeCommon; + (0, _utils.default)("Identifier", { + builder: ["name"], + visitor: ["typeAnnotation", "decorators"], + aliases: ["Expression", "PatternLike", "LVal", "TSEntityName"], + fields: Object.assign({}, patternLikeCommon, { + name: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!(0, _isValidIdentifier.default)(val, false)) { + throw new TypeError(`"${val}" is not a valid identifier name`); + } + }, { + type: "string" + })) + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }), + + validate(parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const match = /\.(\w+)$/.exec(key); + if (!match) return; + const [, parentKey] = match; + const nonComp = { + computed: false + }; + + if (parentKey === "property") { + if ((0, _is.default)("MemberExpression", parent, nonComp)) return; + if ((0, _is.default)("OptionalMemberExpression", parent, nonComp)) return; + } else if (parentKey === "key") { + if ((0, _is.default)("Property", parent, nonComp)) return; + if ((0, _is.default)("Method", parent, nonComp)) return; + } else if (parentKey === "exported") { + if ((0, _is.default)("ExportSpecifier", parent)) return; + } else if (parentKey === "imported") { + if ((0, _is.default)("ImportSpecifier", parent, { + imported: node + })) return; + } else if (parentKey === "meta") { + if ((0, _is.default)("MetaProperty", parent, { + meta: node + })) return; + } + + if (((0, _helperValidatorIdentifier.isKeyword)(node.name) || (0, _helperValidatorIdentifier.isReservedWord)(node.name)) && node.name !== "this") { + throw new TypeError(`"${node.name}" is not a valid identifier`); + } + } + + }); + (0, _utils.default)("IfStatement", { + visitor: ["test", "consequent", "alternate"], + aliases: ["Statement", "Conditional"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + consequent: { + validate: (0, _utils.assertNodeType)("Statement") + }, + alternate: { + optional: true, + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("LabeledStatement", { + visitor: ["label", "body"], + aliases: ["Statement"], + fields: { + label: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("StringLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("NumericLiteral", { + builder: ["value"], + deprecatedAlias: "NumberLiteral", + fields: { + value: { + validate: (0, _utils.assertValueType)("number") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("NullLiteral", { + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("BooleanLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("boolean") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("RegExpLiteral", { + builder: ["pattern", "flags"], + deprecatedAlias: "RegexLiteral", + aliases: ["Expression", "Pureish", "Literal"], + fields: { + pattern: { + validate: (0, _utils.assertValueType)("string") + }, + flags: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const invalid = /[^gimsuy]/.exec(val); + + if (invalid) { + throw new TypeError(`"${invalid[0]}" is not a valid RegExp flag`); + } + }, { + type: "string" + })), + default: "" + } + } + }); + (0, _utils.default)("LogicalExpression", { + builder: ["operator", "left", "right"], + visitor: ["left", "right"], + aliases: ["Binary", "Expression"], + fields: { + operator: { + validate: (0, _utils.assertOneOf)(..._constants.LOGICAL_OPERATORS) + }, + left: { + validate: (0, _utils.assertNodeType)("Expression") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("MemberExpression", { + builder: ["object", "property", "computed", "optional"], + visitor: ["object", "property"], + aliases: ["Expression", "LVal"], + fields: Object.assign({ + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + property: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "PrivateName"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "PrivateName"]; + return validator; + }() + }, + computed: { + default: false + } + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + optional: { + validate: (0, _utils.assertOneOf)(true, false), + optional: true + } + } : {}) + }); + (0, _utils.default)("NewExpression", { + inherits: "CallExpression" + }); + (0, _utils.default)("Program", { + visitor: ["directives", "body"], + builder: ["body", "directives", "sourceType", "interpreter"], + fields: { + sourceFile: { + validate: (0, _utils.assertValueType)("string") + }, + sourceType: { + validate: (0, _utils.assertOneOf)("script", "module"), + default: "script" + }, + interpreter: { + validate: (0, _utils.assertNodeType)("InterpreterDirective"), + default: null, + optional: true + }, + directives: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Directive"))), + default: [] + }, + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + }, + aliases: ["Scopable", "BlockParent", "Block"] + }); + (0, _utils.default)("ObjectExpression", { + visitor: ["properties"], + aliases: ["Expression"], + fields: { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ObjectMethod", "ObjectProperty", "SpreadElement"))) + } + } + }); + (0, _utils.default)("ObjectMethod", { + builder: ["kind", "key", "params", "body", "computed", "generator", "async"], + fields: Object.assign({}, functionCommon, functionTypeAnnotationCommon, { + kind: Object.assign({ + validate: (0, _utils.assertOneOf)("method", "get", "set") + }, !process$1.env.BABEL_TYPES_8_BREAKING ? { + default: "method" + } : {}), + computed: { + default: false + }, + key: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "StringLiteral", "NumericLiteral"]; + return validator; + }() + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }), + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + aliases: ["UserWhitespacable", "Function", "Scopable", "BlockParent", "FunctionParent", "Method", "ObjectMember"] + }); + (0, _utils.default)("ObjectProperty", { + builder: ["key", "value", "computed", "shorthand", ...(!process$1.env.BABEL_TYPES_8_BREAKING ? ["decorators"] : [])], + fields: { + computed: { + default: false + }, + key: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier", "StringLiteral", "NumericLiteral"]; + return validator; + }() + }, + value: { + validate: (0, _utils.assertNodeType)("Expression", "PatternLike") + }, + shorthand: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("boolean"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.computed) { + throw new TypeError("Property shorthand of ObjectProperty cannot be true if computed is true"); + } + }, { + type: "boolean" + }), function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && !(0, _is.default)("Identifier", node.key)) { + throw new TypeError("Property shorthand of ObjectProperty cannot be true if key is not an Identifier"); + } + }), + default: false + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }, + visitor: ["key", "value", "decorators"], + aliases: ["UserWhitespacable", "Property", "ObjectMember"], + validate: function () { + const pattern = (0, _utils.assertNodeType)("Identifier", "Pattern"); + const expression = (0, _utils.assertNodeType)("Expression"); + return function (parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const validator = (0, _is.default)("ObjectPattern", parent) ? pattern : expression; + validator(node, "value", node.value); + }; + }() + }); + (0, _utils.default)("RestElement", { + visitor: ["argument", "typeAnnotation"], + builder: ["argument"], + aliases: ["LVal", "PatternLike"], + deprecatedAlias: "RestProperty", + fields: Object.assign({}, patternLikeCommon, { + argument: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("LVal") : (0, _utils.assertNodeType)("Identifier", "Pattern", "MemberExpression") + } + }), + + validate(parent, key) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + const match = /(\w+)\[(\d+)\]/.exec(key); + if (!match) throw new Error("Internal Babel error: malformed key."); + const [, listKey, index] = match; + + if (parent[listKey].length > index + 1) { + throw new TypeError(`RestElement must be last element of ${listKey}`); + } + } + + }); + (0, _utils.default)("ReturnStatement", { + visitor: ["argument"], + aliases: ["Statement", "Terminatorless", "CompletionStatement"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + } + } + }); + (0, _utils.default)("SequenceExpression", { + visitor: ["expressions"], + fields: { + expressions: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression"))) + } + }, + aliases: ["Expression"] + }); + (0, _utils.default)("ParenthesizedExpression", { + visitor: ["expression"], + aliases: ["Expression", "ExpressionWrapper"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("SwitchCase", { + visitor: ["test", "consequent"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + consequent: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Statement"))) + } + } + }); + (0, _utils.default)("SwitchStatement", { + visitor: ["discriminant", "cases"], + aliases: ["Statement", "BlockParent", "Scopable"], + fields: { + discriminant: { + validate: (0, _utils.assertNodeType)("Expression") + }, + cases: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("SwitchCase"))) + } + } + }); + (0, _utils.default)("ThisExpression", { + aliases: ["Expression"] + }); + (0, _utils.default)("ThrowStatement", { + visitor: ["argument"], + aliases: ["Statement", "Terminatorless", "CompletionStatement"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("TryStatement", { + visitor: ["block", "handler", "finalizer"], + aliases: ["Statement"], + fields: { + block: { + validate: (0, _utils.chain)((0, _utils.assertNodeType)("BlockStatement"), Object.assign(function (node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!node.handler && !node.finalizer) { + throw new TypeError("TryStatement expects either a handler or finalizer, or both"); + } + }, { + oneOfNodeTypes: ["BlockStatement"] + })) + }, + handler: { + optional: true, + validate: (0, _utils.assertNodeType)("CatchClause") + }, + finalizer: { + optional: true, + validate: (0, _utils.assertNodeType)("BlockStatement") + } + } + }); + (0, _utils.default)("UnaryExpression", { + builder: ["operator", "argument", "prefix"], + fields: { + prefix: { + default: true + }, + argument: { + validate: (0, _utils.assertNodeType)("Expression") + }, + operator: { + validate: (0, _utils.assertOneOf)(..._constants.UNARY_OPERATORS) + } + }, + visitor: ["argument"], + aliases: ["UnaryLike", "Expression"] + }); + (0, _utils.default)("UpdateExpression", { + builder: ["operator", "argument", "prefix"], + fields: { + prefix: { + default: false + }, + argument: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertNodeType)("Expression") : (0, _utils.assertNodeType)("Identifier", "MemberExpression") + }, + operator: { + validate: (0, _utils.assertOneOf)(..._constants.UPDATE_OPERATORS) + } + }, + visitor: ["argument"], + aliases: ["Expression"] + }); + (0, _utils.default)("VariableDeclaration", { + builder: ["kind", "declarations"], + visitor: ["declarations"], + aliases: ["Statement", "Declaration"], + fields: { + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + kind: { + validate: (0, _utils.assertOneOf)("var", "let", "const") + }, + declarations: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("VariableDeclarator"))) + } + }, + + validate(parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + if (!(0, _is.default)("ForXStatement", parent, { + left: node + })) return; + + if (node.declarations.length !== 1) { + throw new TypeError(`Exactly one VariableDeclarator is required in the VariableDeclaration of a ${parent.type}`); + } + } + + }); + (0, _utils.default)("VariableDeclarator", { + visitor: ["id", "init"], + fields: { + id: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertNodeType)("LVal"); + } + + const normal = (0, _utils.assertNodeType)("Identifier", "ArrayPattern", "ObjectPattern"); + const without = (0, _utils.assertNodeType)("Identifier"); + return function (node, key, val) { + const validator = node.init ? normal : without; + validator(node, key, val); + }; + }() + }, + definite: { + optional: true, + validate: (0, _utils.assertValueType)("boolean") + }, + init: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("WhileStatement", { + visitor: ["test", "body"], + aliases: ["Statement", "BlockParent", "Loop", "While", "Scopable"], + fields: { + test: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + (0, _utils.default)("WithStatement", { + visitor: ["object", "body"], + aliases: ["Statement"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + } + } + }); + return core; + } + + var es2015 = {}; + + var hasRequiredEs2015; + + function requireEs2015 () { + if (hasRequiredEs2015) return es2015; + hasRequiredEs2015 = 1; + + Object.defineProperty(es2015, "__esModule", { + value: true + }); + es2015.classMethodOrDeclareMethodCommon = es2015.classMethodOrPropertyCommon = void 0; + + var _utils = _interopRequireWildcard(requireUtils()); + + var _core = requireCore(); + + var _is = _interopRequireDefault(requireIs()); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + (0, _utils.default)("AssignmentPattern", { + visitor: ["left", "right", "decorators"], + builder: ["left", "right"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, _core.patternLikeCommon, { + left: { + validate: (0, _utils.assertNodeType)("Identifier", "ObjectPattern", "ArrayPattern", "MemberExpression") + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }) + }); + (0, _utils.default)("ArrayPattern", { + visitor: ["elements", "typeAnnotation"], + builder: ["elements"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, _core.patternLikeCommon, { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeOrValueType)("null", "PatternLike"))) + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }) + }); + (0, _utils.default)("ArrowFunctionExpression", { + builder: ["params", "body", "async"], + visitor: ["params", "body", "returnType", "typeParameters"], + aliases: ["Scopable", "Function", "BlockParent", "FunctionParent", "Expression", "Pureish"], + fields: Object.assign({}, _core.functionCommon, _core.functionTypeAnnotationCommon, { + expression: { + validate: (0, _utils.assertValueType)("boolean") + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement", "Expression") + } + }) + }); + (0, _utils.default)("ClassBody", { + visitor: ["body"], + fields: { + body: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ClassMethod", "ClassPrivateMethod", "ClassProperty", "ClassPrivateProperty", "TSDeclareMethod", "TSIndexSignature"))) + } + } + }); + (0, _utils.default)("ClassExpression", { + builder: ["id", "superClass", "body", "decorators"], + visitor: ["id", "body", "superClass", "mixins", "typeParameters", "superTypeParameters", "implements", "decorators"], + aliases: ["Scopable", "Class", "Expression"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("ClassBody") + }, + superClass: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + }, + superTypeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + }, + implements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSExpressionWithTypeArguments", "ClassImplements"))), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + mixins: { + validate: (0, _utils.assertNodeType)("InterfaceExtends"), + optional: true + } + } + }); + (0, _utils.default)("ClassDeclaration", { + inherits: "ClassExpression", + aliases: ["Scopable", "Class", "Statement", "Declaration"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterDeclaration", "TSTypeParameterDeclaration", "Noop"), + optional: true + }, + body: { + validate: (0, _utils.assertNodeType)("ClassBody") + }, + superClass: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + }, + superTypeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + }, + implements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSExpressionWithTypeArguments", "ClassImplements"))), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + mixins: { + validate: (0, _utils.assertNodeType)("InterfaceExtends"), + optional: true + }, + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + abstract: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }, + validate: function () { + const identifier = (0, _utils.assertNodeType)("Identifier"); + return function (parent, key, node) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (!(0, _is.default)("ExportDefaultDeclaration", parent)) { + identifier(node, "id", node.id); + } + }; + }() + }); + (0, _utils.default)("ExportAllDeclaration", { + visitor: ["source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + source: { + validate: (0, _utils.assertNodeType)("StringLiteral") + } + } + }); + (0, _utils.default)("ExportDefaultDeclaration", { + visitor: ["declaration"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + declaration: { + validate: (0, _utils.assertNodeType)("FunctionDeclaration", "TSDeclareFunction", "ClassDeclaration", "Expression") + } + } + }); + (0, _utils.default)("ExportNamedDeclaration", { + visitor: ["declaration", "specifiers", "source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration", "ExportDeclaration"], + fields: { + declaration: { + optional: true, + validate: (0, _utils.chain)((0, _utils.assertNodeType)("Declaration"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.specifiers.length) { + throw new TypeError("Only declaration or specifiers is allowed on ExportNamedDeclaration"); + } + }, { + oneOfNodeTypes: ["Declaration"] + }), function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && node.source) { + throw new TypeError("Cannot export a declaration from a source"); + } + }) + }, + specifiers: { + default: [], + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)(function () { + const sourced = (0, _utils.assertNodeType)("ExportSpecifier", "ExportDefaultSpecifier", "ExportNamespaceSpecifier"); + const sourceless = (0, _utils.assertNodeType)("ExportSpecifier"); + if (!process$1.env.BABEL_TYPES_8_BREAKING) return sourced; + return function (node, key, val) { + const validator = node.source ? sourced : sourceless; + validator(node, key, val); + }; + }())) + }, + source: { + validate: (0, _utils.assertNodeType)("StringLiteral"), + optional: true + }, + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("type", "value")) + } + }); + (0, _utils.default)("ExportSpecifier", { + visitor: ["local", "exported"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + exported: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ForOfStatement", { + visitor: ["left", "right", "body"], + builder: ["left", "right", "body", "await"], + aliases: ["Scopable", "Statement", "For", "BlockParent", "Loop", "ForXStatement"], + fields: { + left: { + validate: function () { + if (!process$1.env.BABEL_TYPES_8_BREAKING) { + return (0, _utils.assertNodeType)("VariableDeclaration", "LVal"); + } + + const declaration = (0, _utils.assertNodeType)("VariableDeclaration"); + const lval = (0, _utils.assertNodeType)("Identifier", "MemberExpression", "ArrayPattern", "ObjectPattern"); + return function (node, key, val) { + if ((0, _is.default)("VariableDeclaration", val)) { + declaration(node, key, val); + } else { + lval(node, key, val); + } + }; + }() + }, + right: { + validate: (0, _utils.assertNodeType)("Expression") + }, + body: { + validate: (0, _utils.assertNodeType)("Statement") + }, + await: { + default: false + } + } + }); + (0, _utils.default)("ImportDeclaration", { + visitor: ["specifiers", "source"], + aliases: ["Statement", "Declaration", "ModuleDeclaration"], + fields: { + specifiers: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ImportSpecifier", "ImportDefaultSpecifier", "ImportNamespaceSpecifier"))) + }, + source: { + validate: (0, _utils.assertNodeType)("StringLiteral") + }, + importKind: { + validate: (0, _utils.assertOneOf)("type", "typeof", "value"), + optional: true + } + } + }); + (0, _utils.default)("ImportDefaultSpecifier", { + visitor: ["local"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ImportNamespaceSpecifier", { + visitor: ["local"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ImportSpecifier", { + visitor: ["local", "imported"], + aliases: ["ModuleSpecifier"], + fields: { + local: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + imported: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + importKind: { + validate: (0, _utils.assertOneOf)("type", "typeof"), + optional: true + } + } + }); + (0, _utils.default)("MetaProperty", { + visitor: ["meta", "property"], + aliases: ["Expression"], + fields: { + meta: { + validate: (0, _utils.chain)((0, _utils.assertNodeType)("Identifier"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + let property; + + switch (val.name) { + case "function": + property = "sent"; + break; + + case "new": + property = "target"; + break; + + case "import": + property = "meta"; + break; + } + + if (!(0, _is.default)("Identifier", node.property, { + name: property + })) { + throw new TypeError("Unrecognised MetaProperty"); + } + }, { + oneOfNodeTypes: ["Identifier"] + })) + }, + property: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + const classMethodOrPropertyCommon = { + abstract: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + accessibility: { + validate: (0, _utils.assertOneOf)("public", "private", "protected"), + optional: true + }, + static: { + default: false + }, + computed: { + default: false + }, + optional: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + key: { + validate: (0, _utils.chain)(function () { + const normal = (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral"); + const computed = (0, _utils.assertNodeType)("Expression"); + return function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + }(), (0, _utils.assertNodeType)("Identifier", "StringLiteral", "NumericLiteral", "Expression")) + } + }; + es2015.classMethodOrPropertyCommon = classMethodOrPropertyCommon; + const classMethodOrDeclareMethodCommon = Object.assign({}, _core.functionCommon, classMethodOrPropertyCommon, { + kind: { + validate: (0, _utils.assertOneOf)("get", "set", "method", "constructor"), + default: "method" + }, + access: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("string"), (0, _utils.assertOneOf)("public", "private", "protected")), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + }); + es2015.classMethodOrDeclareMethodCommon = classMethodOrDeclareMethodCommon; + (0, _utils.default)("ClassMethod", { + aliases: ["Function", "Scopable", "BlockParent", "FunctionParent", "Method"], + builder: ["kind", "key", "params", "body", "computed", "static", "generator", "async"], + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + fields: Object.assign({}, classMethodOrDeclareMethodCommon, _core.functionTypeAnnotationCommon, { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + (0, _utils.default)("ObjectPattern", { + visitor: ["properties", "typeAnnotation", "decorators"], + builder: ["properties"], + aliases: ["Pattern", "PatternLike", "LVal"], + fields: Object.assign({}, _core.patternLikeCommon, { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("RestElement", "ObjectProperty"))) + } + }) + }); + (0, _utils.default)("SpreadElement", { + visitor: ["argument"], + aliases: ["UnaryLike"], + deprecatedAlias: "SpreadProperty", + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("Super", { + aliases: ["Expression"] + }); + (0, _utils.default)("TaggedTemplateExpression", { + visitor: ["tag", "quasi"], + aliases: ["Expression"], + fields: { + tag: { + validate: (0, _utils.assertNodeType)("Expression") + }, + quasi: { + validate: (0, _utils.assertNodeType)("TemplateLiteral") + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("TemplateElement", { + builder: ["value", "tail"], + fields: { + value: { + validate: (0, _utils.assertShape)({ + raw: { + validate: (0, _utils.assertValueType)("string") + }, + cooked: { + validate: (0, _utils.assertValueType)("string"), + optional: true + } + }) + }, + tail: { + default: false + } + } + }); + (0, _utils.default)("TemplateLiteral", { + visitor: ["quasis", "expressions"], + aliases: ["Expression", "Literal"], + fields: { + quasis: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TemplateElement"))) + }, + expressions: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression")), function (node, key, val) { + if (node.quasis.length !== val.length + 1) { + throw new TypeError(`Number of ${node.type} quasis should be exactly one more than the number of expressions.\nExpected ${val.length + 1} quasis but got ${node.quasis.length}`); + } + }) + } + } + }); + (0, _utils.default)("YieldExpression", { + builder: ["argument", "delegate"], + visitor: ["argument"], + aliases: ["Expression", "Terminatorless"], + fields: { + delegate: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("boolean"), Object.assign(function (node, key, val) { + if (!process$1.env.BABEL_TYPES_8_BREAKING) return; + + if (val && !node.argument) { + throw new TypeError("Property delegate of YieldExpression cannot be true if there is no argument"); + } + }, { + type: "boolean" + })), + default: false + }, + argument: { + optional: true, + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + return es2015; + } + + var flow$3 = {}; + + var hasRequiredFlow; + + function requireFlow () { + if (hasRequiredFlow) return flow$3; + hasRequiredFlow = 1; + + var _utils = _interopRequireWildcard(requireUtils()); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + const defineInterfaceishType = (name, typeParameterType = "TypeParameterDeclaration") => { + (0, _utils.default)(name, { + builder: ["id", "typeParameters", "extends", "body"], + visitor: ["id", "typeParameters", "extends", "mixins", "implements", "body"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)(typeParameterType), + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + mixins: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + implements: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ClassImplements")), + body: (0, _utils.validateType)("ObjectTypeAnnotation") + } + }); + }; + + (0, _utils.default)("AnyTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ArrayTypeAnnotation", { + visitor: ["elementType"], + aliases: ["Flow", "FlowType"], + fields: { + elementType: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("BooleanTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("BooleanLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("NullLiteralTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ClassImplements", { + visitor: ["id", "typeParameters"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + defineInterfaceishType("DeclareClass"); + (0, _utils.default)("DeclareFunction", { + visitor: ["id"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + predicate: (0, _utils.validateOptionalType)("DeclaredPredicate") + } + }); + defineInterfaceishType("DeclareInterface"); + (0, _utils.default)("DeclareModule", { + builder: ["id", "body", "kind"], + visitor: ["id", "body"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + body: (0, _utils.validateType)("BlockStatement"), + kind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("CommonJS", "ES")) + } + }); + (0, _utils.default)("DeclareModuleExports", { + visitor: ["typeAnnotation"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + typeAnnotation: (0, _utils.validateType)("TypeAnnotation") + } + }); + (0, _utils.default)("DeclareTypeAlias", { + visitor: ["id", "typeParameters", "right"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + right: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("DeclareOpaqueType", { + visitor: ["id", "typeParameters", "supertype"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + supertype: (0, _utils.validateOptionalType)("FlowType") + } + }); + (0, _utils.default)("DeclareVariable", { + visitor: ["id"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + (0, _utils.default)("DeclareExportDeclaration", { + visitor: ["declaration", "specifiers", "source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + declaration: (0, _utils.validateOptionalType)("Flow"), + specifiers: (0, _utils.validateOptional)((0, _utils.arrayOfType)(["ExportSpecifier", "ExportNamespaceSpecifier"])), + source: (0, _utils.validateOptionalType)("StringLiteral"), + default: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("DeclareExportAllDeclaration", { + visitor: ["source"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + source: (0, _utils.validateType)("StringLiteral"), + exportKind: (0, _utils.validateOptional)((0, _utils.assertOneOf)("type", "value")) + } + }); + (0, _utils.default)("DeclaredPredicate", { + visitor: ["value"], + aliases: ["Flow", "FlowPredicate"], + fields: { + value: (0, _utils.validateType)("Flow") + } + }); + (0, _utils.default)("ExistsTypeAnnotation", { + aliases: ["Flow", "FlowType"] + }); + (0, _utils.default)("FunctionTypeAnnotation", { + visitor: ["typeParameters", "params", "rest", "returnType"], + aliases: ["Flow", "FlowType"], + fields: { + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + params: (0, _utils.validate)((0, _utils.arrayOfType)("FunctionTypeParam")), + rest: (0, _utils.validateOptionalType)("FunctionTypeParam"), + returnType: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("FunctionTypeParam", { + visitor: ["name", "typeAnnotation"], + aliases: ["Flow"], + fields: { + name: (0, _utils.validateOptionalType)("Identifier"), + typeAnnotation: (0, _utils.validateType)("FlowType"), + optional: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("GenericTypeAnnotation", { + visitor: ["id", "typeParameters"], + aliases: ["Flow", "FlowType"], + fields: { + id: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + (0, _utils.default)("InferredPredicate", { + aliases: ["Flow", "FlowPredicate"] + }); + (0, _utils.default)("InterfaceExtends", { + visitor: ["id", "typeParameters"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterInstantiation") + } + }); + defineInterfaceishType("InterfaceDeclaration"); + (0, _utils.default)("InterfaceTypeAnnotation", { + visitor: ["extends", "body"], + aliases: ["Flow", "FlowType"], + fields: { + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("InterfaceExtends")), + body: (0, _utils.validateType)("ObjectTypeAnnotation") + } + }); + (0, _utils.default)("IntersectionTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("MixedTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("EmptyTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("NullableTypeAnnotation", { + visitor: ["typeAnnotation"], + aliases: ["Flow", "FlowType"], + fields: { + typeAnnotation: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("NumberLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("number")) + } + }); + (0, _utils.default)("NumberTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ObjectTypeAnnotation", { + visitor: ["properties", "indexers", "callProperties", "internalSlots"], + aliases: ["Flow", "FlowType"], + builder: ["properties", "indexers", "callProperties", "internalSlots", "exact"], + fields: { + properties: (0, _utils.validate)((0, _utils.arrayOfType)(["ObjectTypeProperty", "ObjectTypeSpreadProperty"])), + indexers: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeIndexer")), + callProperties: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeCallProperty")), + internalSlots: (0, _utils.validateOptional)((0, _utils.arrayOfType)("ObjectTypeInternalSlot")), + exact: { + validate: (0, _utils.assertValueType)("boolean"), + default: false + }, + inexact: (0, _utils.validateOptional)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeInternalSlot", { + visitor: ["id", "value", "optional", "static", "method"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + id: (0, _utils.validateType)("Identifier"), + value: (0, _utils.validateType)("FlowType"), + optional: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + method: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeCallProperty", { + visitor: ["value"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + value: (0, _utils.validateType)("FlowType"), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")) + } + }); + (0, _utils.default)("ObjectTypeIndexer", { + visitor: ["id", "key", "value", "variance"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + id: (0, _utils.validateOptionalType)("Identifier"), + key: (0, _utils.validateType)("FlowType"), + value: (0, _utils.validateType)("FlowType"), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + variance: (0, _utils.validateOptionalType)("Variance") + } + }); + (0, _utils.default)("ObjectTypeProperty", { + visitor: ["key", "value", "variance"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + key: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + value: (0, _utils.validateType)("FlowType"), + kind: (0, _utils.validate)((0, _utils.assertOneOf)("init", "get", "set")), + static: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + proto: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + optional: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + variance: (0, _utils.validateOptionalType)("Variance") + } + }); + (0, _utils.default)("ObjectTypeSpreadProperty", { + visitor: ["argument"], + aliases: ["Flow", "UserWhitespacable"], + fields: { + argument: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("OpaqueType", { + visitor: ["id", "typeParameters", "supertype", "impltype"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + supertype: (0, _utils.validateOptionalType)("FlowType"), + impltype: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("QualifiedTypeIdentifier", { + visitor: ["id", "qualification"], + aliases: ["Flow"], + fields: { + id: (0, _utils.validateType)("Identifier"), + qualification: (0, _utils.validateType)(["Identifier", "QualifiedTypeIdentifier"]) + } + }); + (0, _utils.default)("StringLiteralTypeAnnotation", { + builder: ["value"], + aliases: ["Flow", "FlowType"], + fields: { + value: (0, _utils.validate)((0, _utils.assertValueType)("string")) + } + }); + (0, _utils.default)("StringTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("SymbolTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("ThisTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("TupleTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("TypeofTypeAnnotation", { + visitor: ["argument"], + aliases: ["Flow", "FlowType"], + fields: { + argument: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeAlias", { + visitor: ["id", "typeParameters", "right"], + aliases: ["Flow", "FlowDeclaration", "Statement", "Declaration"], + fields: { + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TypeParameterDeclaration"), + right: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeAnnotation", { + aliases: ["Flow"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("FlowType") + } + }); + (0, _utils.default)("TypeCastExpression", { + visitor: ["expression", "typeAnnotation"], + aliases: ["Flow", "ExpressionWrapper", "Expression"], + fields: { + expression: (0, _utils.validateType)("Expression"), + typeAnnotation: (0, _utils.validateType)("TypeAnnotation") + } + }); + (0, _utils.default)("TypeParameter", { + aliases: ["Flow"], + visitor: ["bound", "default", "variance"], + fields: { + name: (0, _utils.validate)((0, _utils.assertValueType)("string")), + bound: (0, _utils.validateOptionalType)("TypeAnnotation"), + default: (0, _utils.validateOptionalType)("FlowType"), + variance: (0, _utils.validateOptionalType)("Variance") + } + }); + (0, _utils.default)("TypeParameterDeclaration", { + aliases: ["Flow"], + visitor: ["params"], + fields: { + params: (0, _utils.validate)((0, _utils.arrayOfType)("TypeParameter")) + } + }); + (0, _utils.default)("TypeParameterInstantiation", { + aliases: ["Flow"], + visitor: ["params"], + fields: { + params: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("UnionTypeAnnotation", { + visitor: ["types"], + aliases: ["Flow", "FlowType"], + fields: { + types: (0, _utils.validate)((0, _utils.arrayOfType)("FlowType")) + } + }); + (0, _utils.default)("Variance", { + aliases: ["Flow"], + builder: ["kind"], + fields: { + kind: (0, _utils.validate)((0, _utils.assertOneOf)("minus", "plus")) + } + }); + (0, _utils.default)("VoidTypeAnnotation", { + aliases: ["Flow", "FlowType", "FlowBaseAnnotation"] + }); + (0, _utils.default)("EnumDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "body"], + fields: { + id: (0, _utils.validateType)("Identifier"), + body: (0, _utils.validateType)(["EnumBooleanBody", "EnumNumberBody", "EnumStringBody", "EnumSymbolBody"]) + } + }); + (0, _utils.default)("EnumBooleanBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicit: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)("EnumBooleanMember") + } + }); + (0, _utils.default)("EnumNumberBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicit: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)("EnumNumberMember") + } + }); + (0, _utils.default)("EnumStringBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + explicit: (0, _utils.validate)((0, _utils.assertValueType)("boolean")), + members: (0, _utils.validateArrayOfType)(["EnumStringMember", "EnumDefaultedMember"]) + } + }); + (0, _utils.default)("EnumSymbolBody", { + aliases: ["EnumBody"], + visitor: ["members"], + fields: { + members: (0, _utils.validateArrayOfType)("EnumDefaultedMember") + } + }); + (0, _utils.default)("EnumBooleanMember", { + aliases: ["EnumMember"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("BooleanLiteral") + } + }); + (0, _utils.default)("EnumNumberMember", { + aliases: ["EnumMember"], + visitor: ["id", "init"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("NumericLiteral") + } + }); + (0, _utils.default)("EnumStringMember", { + aliases: ["EnumMember"], + visitor: ["id", "init"], + fields: { + id: (0, _utils.validateType)("Identifier"), + init: (0, _utils.validateType)("StringLiteral") + } + }); + (0, _utils.default)("EnumDefaultedMember", { + aliases: ["EnumMember"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + return flow$3; + } + + var jsx$3 = {}; + + var hasRequiredJsx; + + function requireJsx () { + if (hasRequiredJsx) return jsx$3; + hasRequiredJsx = 1; + + var _utils = _interopRequireWildcard(requireUtils()); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + (0, _utils.default)("JSXAttribute", { + visitor: ["name", "value"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXNamespacedName") + }, + value: { + optional: true, + validate: (0, _utils.assertNodeType)("JSXElement", "JSXFragment", "StringLiteral", "JSXExpressionContainer") + } + } + }); + (0, _utils.default)("JSXClosingElement", { + visitor: ["name"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXMemberExpression", "JSXNamespacedName") + } + } + }); + (0, _utils.default)("JSXElement", { + builder: ["openingElement", "closingElement", "children", "selfClosing"], + visitor: ["openingElement", "children", "closingElement"], + aliases: ["JSX", "Immutable", "Expression"], + fields: { + openingElement: { + validate: (0, _utils.assertNodeType)("JSXOpeningElement") + }, + closingElement: { + optional: true, + validate: (0, _utils.assertNodeType)("JSXClosingElement") + }, + children: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXText", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement", "JSXFragment"))) + }, + selfClosing: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + } + }); + (0, _utils.default)("JSXEmptyExpression", { + aliases: ["JSX"] + }); + (0, _utils.default)("JSXExpressionContainer", { + visitor: ["expression"], + aliases: ["JSX", "Immutable"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression", "JSXEmptyExpression") + } + } + }); + (0, _utils.default)("JSXSpreadChild", { + visitor: ["expression"], + aliases: ["JSX", "Immutable"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("JSXIdentifier", { + builder: ["name"], + aliases: ["JSX"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("JSXMemberExpression", { + visitor: ["object", "property"], + aliases: ["JSX"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("JSXMemberExpression", "JSXIdentifier") + }, + property: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + } + } + }); + (0, _utils.default)("JSXNamespacedName", { + visitor: ["namespace", "name"], + aliases: ["JSX"], + fields: { + namespace: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + }, + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier") + } + } + }); + (0, _utils.default)("JSXOpeningElement", { + builder: ["name", "attributes", "selfClosing"], + visitor: ["name", "attributes"], + aliases: ["JSX", "Immutable"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("JSXIdentifier", "JSXMemberExpression", "JSXNamespacedName") + }, + selfClosing: { + default: false + }, + attributes: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXAttribute", "JSXSpreadAttribute"))) + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation", "TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("JSXSpreadAttribute", { + visitor: ["argument"], + aliases: ["JSX"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("JSXText", { + aliases: ["JSX", "Immutable"], + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + (0, _utils.default)("JSXFragment", { + builder: ["openingFragment", "closingFragment", "children"], + visitor: ["openingFragment", "children", "closingFragment"], + aliases: ["JSX", "Immutable", "Expression"], + fields: { + openingFragment: { + validate: (0, _utils.assertNodeType)("JSXOpeningFragment") + }, + closingFragment: { + validate: (0, _utils.assertNodeType)("JSXClosingFragment") + }, + children: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("JSXText", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement", "JSXFragment"))) + } + } + }); + (0, _utils.default)("JSXOpeningFragment", { + aliases: ["JSX", "Immutable"] + }); + (0, _utils.default)("JSXClosingFragment", { + aliases: ["JSX", "Immutable"] + }); + return jsx$3; + } + + var misc = {}; + + var placeholders$2 = {}; + + var hasRequiredPlaceholders; + + function requirePlaceholders () { + if (hasRequiredPlaceholders) return placeholders$2; + hasRequiredPlaceholders = 1; + + Object.defineProperty(placeholders$2, "__esModule", { + value: true + }); + placeholders$2.PLACEHOLDERS_FLIPPED_ALIAS = placeholders$2.PLACEHOLDERS_ALIAS = placeholders$2.PLACEHOLDERS = void 0; + + var _utils = requireUtils(); + + const PLACEHOLDERS = ["Identifier", "StringLiteral", "Expression", "Statement", "Declaration", "BlockStatement", "ClassBody", "Pattern"]; + placeholders$2.PLACEHOLDERS = PLACEHOLDERS; + const PLACEHOLDERS_ALIAS = { + Declaration: ["Statement"], + Pattern: ["PatternLike", "LVal"] + }; + placeholders$2.PLACEHOLDERS_ALIAS = PLACEHOLDERS_ALIAS; + + for (const type of PLACEHOLDERS) { + const alias = _utils.ALIAS_KEYS[type]; + if (alias == null ? void 0 : alias.length) PLACEHOLDERS_ALIAS[type] = alias; + } + + const PLACEHOLDERS_FLIPPED_ALIAS = {}; + placeholders$2.PLACEHOLDERS_FLIPPED_ALIAS = PLACEHOLDERS_FLIPPED_ALIAS; + Object.keys(PLACEHOLDERS_ALIAS).forEach(type => { + PLACEHOLDERS_ALIAS[type].forEach(alias => { + if (!Object.hasOwnProperty.call(PLACEHOLDERS_FLIPPED_ALIAS, alias)) { + PLACEHOLDERS_FLIPPED_ALIAS[alias] = []; + } + + PLACEHOLDERS_FLIPPED_ALIAS[alias].push(type); + }); + }); + return placeholders$2; + } + + var hasRequiredMisc; + + function requireMisc () { + if (hasRequiredMisc) return misc; + hasRequiredMisc = 1; + + var _utils = _interopRequireWildcard(requireUtils()); + + var _placeholders = requirePlaceholders(); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + (0, _utils.default)("Noop", { + visitor: [] + }); + (0, _utils.default)("Placeholder", { + visitor: [], + builder: ["expectedNode", "name"], + fields: { + name: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + expectedNode: { + validate: (0, _utils.assertOneOf)(..._placeholders.PLACEHOLDERS) + } + } + }); + (0, _utils.default)("V8IntrinsicIdentifier", { + builder: ["name"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + } + } + }); + return misc; + } + + var experimental = {}; + + var hasRequiredExperimental; + + function requireExperimental () { + if (hasRequiredExperimental) return experimental; + hasRequiredExperimental = 1; + + var _utils = _interopRequireWildcard(requireUtils()); + + var _es = requireEs2015(); + + var _core = requireCore(); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + (0, _utils.default)("ArgumentPlaceholder", {}); + (0, _utils.default)("AwaitExpression", { + builder: ["argument"], + visitor: ["argument"], + aliases: ["Expression", "Terminatorless"], + fields: { + argument: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("BindExpression", { + visitor: ["object", "callee"], + aliases: ["Expression"], + fields: !process$1.env.BABEL_TYPES_8_BREAKING ? { + object: { + validate: Object.assign(() => {}, { + oneOfNodeTypes: ["Expression"] + }) + }, + callee: { + validate: Object.assign(() => {}, { + oneOfNodeTypes: ["Expression"] + }) + } + } : { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + callee: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("ClassProperty", { + visitor: ["key", "value", "typeAnnotation", "decorators"], + builder: ["key", "value", "typeAnnotation", "decorators", "computed", "static"], + aliases: ["Property"], + fields: Object.assign({}, _es.classMethodOrPropertyCommon, { + value: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + definite: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TypeAnnotation", "TSTypeAnnotation", "Noop"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + }, + readonly: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + declare: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + } + }) + }); + (0, _utils.default)("OptionalMemberExpression", { + builder: ["object", "property", "computed", "optional"], + visitor: ["object", "property"], + aliases: ["Expression"], + fields: { + object: { + validate: (0, _utils.assertNodeType)("Expression") + }, + property: { + validate: function () { + const normal = (0, _utils.assertNodeType)("Identifier"); + const computed = (0, _utils.assertNodeType)("Expression"); + + const validator = function (node, key, val) { + const validator = node.computed ? computed : normal; + validator(node, key, val); + }; + + validator.oneOfNodeTypes = ["Expression", "Identifier"]; + return validator; + }() + }, + computed: { + default: false + }, + optional: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertValueType)("boolean") : (0, _utils.chain)((0, _utils.assertValueType)("boolean"), (0, _utils.assertOptionalChainStart)()) + } + } + }); + (0, _utils.default)("PipelineTopicExpression", { + builder: ["expression"], + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("PipelineBareFunction", { + builder: ["callee"], + visitor: ["callee"], + fields: { + callee: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("PipelinePrimaryTopicReference", { + aliases: ["Expression"] + }); + (0, _utils.default)("OptionalCallExpression", { + visitor: ["callee", "arguments", "typeParameters", "typeArguments"], + builder: ["callee", "arguments", "optional"], + aliases: ["Expression"], + fields: { + callee: { + validate: (0, _utils.assertNodeType)("Expression") + }, + arguments: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement", "JSXNamespacedName"))) + }, + optional: { + validate: !process$1.env.BABEL_TYPES_8_BREAKING ? (0, _utils.assertValueType)("boolean") : (0, _utils.chain)((0, _utils.assertValueType)("boolean"), (0, _utils.assertOptionalChainStart)()) + }, + typeArguments: { + validate: (0, _utils.assertNodeType)("TypeParameterInstantiation"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterInstantiation"), + optional: true + } + } + }); + (0, _utils.default)("ClassPrivateProperty", { + visitor: ["key", "value", "decorators"], + builder: ["key", "value", "decorators"], + aliases: ["Property", "Private"], + fields: { + key: { + validate: (0, _utils.assertNodeType)("PrivateName") + }, + value: { + validate: (0, _utils.assertNodeType)("Expression"), + optional: true + }, + decorators: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Decorator"))), + optional: true + } + } + }); + (0, _utils.default)("ClassPrivateMethod", { + builder: ["kind", "key", "params", "body", "static"], + visitor: ["key", "params", "body", "decorators", "returnType", "typeParameters"], + aliases: ["Function", "Scopable", "BlockParent", "FunctionParent", "Method", "Private"], + fields: Object.assign({}, _es.classMethodOrDeclareMethodCommon, _core.functionTypeAnnotationCommon, { + key: { + validate: (0, _utils.assertNodeType)("PrivateName") + }, + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + }) + }); + (0, _utils.default)("Import", { + aliases: ["Expression"] + }); + (0, _utils.default)("ImportAttribute", { + visitor: ["key", "value"], + fields: { + key: { + validate: (0, _utils.assertNodeType)("Identifier") + }, + value: { + validate: (0, _utils.assertNodeType)("StringLiteral") + } + } + }); + (0, _utils.default)("Decorator", { + visitor: ["expression"], + fields: { + expression: { + validate: (0, _utils.assertNodeType)("Expression") + } + } + }); + (0, _utils.default)("DoExpression", { + visitor: ["body"], + aliases: ["Expression"], + fields: { + body: { + validate: (0, _utils.assertNodeType)("BlockStatement") + } + } + }); + (0, _utils.default)("ExportDefaultSpecifier", { + visitor: ["exported"], + aliases: ["ModuleSpecifier"], + fields: { + exported: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("ExportNamespaceSpecifier", { + visitor: ["exported"], + aliases: ["ModuleSpecifier"], + fields: { + exported: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("PrivateName", { + visitor: ["id"], + aliases: ["Private"], + fields: { + id: { + validate: (0, _utils.assertNodeType)("Identifier") + } + } + }); + (0, _utils.default)("BigIntLiteral", { + builder: ["value"], + fields: { + value: { + validate: (0, _utils.assertValueType)("string") + } + }, + aliases: ["Expression", "Pureish", "Literal", "Immutable"] + }); + (0, _utils.default)("RecordExpression", { + visitor: ["properties"], + aliases: ["Expression"], + fields: { + properties: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("ObjectProperty", "SpreadElement"))) + } + } + }); + (0, _utils.default)("TupleExpression", { + fields: { + elements: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("Expression", "SpreadElement"))), + default: [] + } + }, + visitor: ["elements"], + aliases: ["Expression"] + }); + return experimental; + } + + var typescript$3 = {}; + + var hasRequiredTypescript; + + function requireTypescript () { + if (hasRequiredTypescript) return typescript$3; + hasRequiredTypescript = 1; + + var _utils = _interopRequireWildcard(requireUtils()); + + var _core = requireCore(); + + var _es = requireEs2015(); + + function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + + const bool = (0, _utils.assertValueType)("boolean"); + const tSFunctionTypeAnnotationCommon = { + returnType: { + validate: (0, _utils.assertNodeType)("TSTypeAnnotation", "Noop"), + optional: true + }, + typeParameters: { + validate: (0, _utils.assertNodeType)("TSTypeParameterDeclaration", "Noop"), + optional: true + } + }; + (0, _utils.default)("TSParameterProperty", { + aliases: ["LVal"], + visitor: ["parameter"], + fields: { + accessibility: { + validate: (0, _utils.assertOneOf)("public", "private", "protected"), + optional: true + }, + readonly: { + validate: (0, _utils.assertValueType)("boolean"), + optional: true + }, + parameter: { + validate: (0, _utils.assertNodeType)("Identifier", "AssignmentPattern") + } + } + }); + (0, _utils.default)("TSDeclareFunction", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "params", "returnType"], + fields: Object.assign({}, _core.functionDeclarationCommon, tSFunctionTypeAnnotationCommon) + }); + (0, _utils.default)("TSDeclareMethod", { + visitor: ["decorators", "key", "typeParameters", "params", "returnType"], + fields: Object.assign({}, _es.classMethodOrDeclareMethodCommon, tSFunctionTypeAnnotationCommon) + }); + (0, _utils.default)("TSQualifiedName", { + aliases: ["TSEntityName"], + visitor: ["left", "right"], + fields: { + left: (0, _utils.validateType)("TSEntityName"), + right: (0, _utils.validateType)("Identifier") + } + }); + const signatureDeclarationCommon = { + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + parameters: (0, _utils.validateArrayOfType)(["Identifier", "RestElement"]), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation") + }; + const callConstructSignatureDeclaration = { + aliases: ["TSTypeElement"], + visitor: ["typeParameters", "parameters", "typeAnnotation"], + fields: signatureDeclarationCommon + }; + (0, _utils.default)("TSCallSignatureDeclaration", callConstructSignatureDeclaration); + (0, _utils.default)("TSConstructSignatureDeclaration", callConstructSignatureDeclaration); + const namedTypeElementCommon = { + key: (0, _utils.validateType)("Expression"), + computed: (0, _utils.validate)(bool), + optional: (0, _utils.validateOptional)(bool) + }; + (0, _utils.default)("TSPropertySignature", { + aliases: ["TSTypeElement"], + visitor: ["key", "typeAnnotation", "initializer"], + fields: Object.assign({}, namedTypeElementCommon, { + readonly: (0, _utils.validateOptional)(bool), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation"), + initializer: (0, _utils.validateOptionalType)("Expression") + }) + }); + (0, _utils.default)("TSMethodSignature", { + aliases: ["TSTypeElement"], + visitor: ["key", "typeParameters", "parameters", "typeAnnotation"], + fields: Object.assign({}, signatureDeclarationCommon, namedTypeElementCommon) + }); + (0, _utils.default)("TSIndexSignature", { + aliases: ["TSTypeElement"], + visitor: ["parameters", "typeAnnotation"], + fields: { + readonly: (0, _utils.validateOptional)(bool), + parameters: (0, _utils.validateArrayOfType)("Identifier"), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation") + } + }); + const tsKeywordTypes = ["TSAnyKeyword", "TSBooleanKeyword", "TSBigIntKeyword", "TSNeverKeyword", "TSNullKeyword", "TSNumberKeyword", "TSObjectKeyword", "TSStringKeyword", "TSSymbolKeyword", "TSUndefinedKeyword", "TSUnknownKeyword", "TSVoidKeyword"]; + + for (const type of tsKeywordTypes) { + (0, _utils.default)(type, { + aliases: ["TSType", "TSBaseType"], + visitor: [], + fields: {} + }); + } + + (0, _utils.default)("TSThisType", { + aliases: ["TSType", "TSBaseType"], + visitor: [], + fields: {} + }); + const fnOrCtr = { + aliases: ["TSType"], + visitor: ["typeParameters", "parameters", "typeAnnotation"], + fields: signatureDeclarationCommon + }; + (0, _utils.default)("TSFunctionType", fnOrCtr); + (0, _utils.default)("TSConstructorType", fnOrCtr); + (0, _utils.default)("TSTypeReference", { + aliases: ["TSType"], + visitor: ["typeName", "typeParameters"], + fields: { + typeName: (0, _utils.validateType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSTypePredicate", { + aliases: ["TSType"], + visitor: ["parameterName", "typeAnnotation"], + builder: ["parameterName", "typeAnnotation", "asserts"], + fields: { + parameterName: (0, _utils.validateType)(["Identifier", "TSThisType"]), + typeAnnotation: (0, _utils.validateOptionalType)("TSTypeAnnotation"), + asserts: (0, _utils.validateOptional)(bool) + } + }); + (0, _utils.default)("TSTypeQuery", { + aliases: ["TSType"], + visitor: ["exprName"], + fields: { + exprName: (0, _utils.validateType)(["TSEntityName", "TSImportType"]) + } + }); + (0, _utils.default)("TSTypeLiteral", { + aliases: ["TSType"], + visitor: ["members"], + fields: { + members: (0, _utils.validateArrayOfType)("TSTypeElement") + } + }); + (0, _utils.default)("TSArrayType", { + aliases: ["TSType"], + visitor: ["elementType"], + fields: { + elementType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTupleType", { + aliases: ["TSType"], + visitor: ["elementTypes"], + fields: { + elementTypes: (0, _utils.validateArrayOfType)("TSType") + } + }); + (0, _utils.default)("TSOptionalType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSRestType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + const unionOrIntersection = { + aliases: ["TSType"], + visitor: ["types"], + fields: { + types: (0, _utils.validateArrayOfType)("TSType") + } + }; + (0, _utils.default)("TSUnionType", unionOrIntersection); + (0, _utils.default)("TSIntersectionType", unionOrIntersection); + (0, _utils.default)("TSConditionalType", { + aliases: ["TSType"], + visitor: ["checkType", "extendsType", "trueType", "falseType"], + fields: { + checkType: (0, _utils.validateType)("TSType"), + extendsType: (0, _utils.validateType)("TSType"), + trueType: (0, _utils.validateType)("TSType"), + falseType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSInferType", { + aliases: ["TSType"], + visitor: ["typeParameter"], + fields: { + typeParameter: (0, _utils.validateType)("TSTypeParameter") + } + }); + (0, _utils.default)("TSParenthesizedType", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTypeOperator", { + aliases: ["TSType"], + visitor: ["typeAnnotation"], + fields: { + operator: (0, _utils.validate)((0, _utils.assertValueType)("string")), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSIndexedAccessType", { + aliases: ["TSType"], + visitor: ["objectType", "indexType"], + fields: { + objectType: (0, _utils.validateType)("TSType"), + indexType: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSMappedType", { + aliases: ["TSType"], + visitor: ["typeParameter", "typeAnnotation"], + fields: { + readonly: (0, _utils.validateOptional)(bool), + typeParameter: (0, _utils.validateType)("TSTypeParameter"), + optional: (0, _utils.validateOptional)(bool), + typeAnnotation: (0, _utils.validateOptionalType)("TSType") + } + }); + (0, _utils.default)("TSLiteralType", { + aliases: ["TSType", "TSBaseType"], + visitor: ["literal"], + fields: { + literal: (0, _utils.validateType)(["NumericLiteral", "StringLiteral", "BooleanLiteral", "BigIntLiteral"]) + } + }); + (0, _utils.default)("TSExpressionWithTypeArguments", { + aliases: ["TSType"], + visitor: ["expression", "typeParameters"], + fields: { + expression: (0, _utils.validateType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSInterfaceDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "extends", "body"], + fields: { + declare: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + extends: (0, _utils.validateOptional)((0, _utils.arrayOfType)("TSExpressionWithTypeArguments")), + body: (0, _utils.validateType)("TSInterfaceBody") + } + }); + (0, _utils.default)("TSInterfaceBody", { + visitor: ["body"], + fields: { + body: (0, _utils.validateArrayOfType)("TSTypeElement") + } + }); + (0, _utils.default)("TSTypeAliasDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "typeParameters", "typeAnnotation"], + fields: { + declare: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterDeclaration"), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSAsExpression", { + aliases: ["Expression"], + visitor: ["expression", "typeAnnotation"], + fields: { + expression: (0, _utils.validateType)("Expression"), + typeAnnotation: (0, _utils.validateType)("TSType") + } + }); + (0, _utils.default)("TSTypeAssertion", { + aliases: ["Expression"], + visitor: ["typeAnnotation", "expression"], + fields: { + typeAnnotation: (0, _utils.validateType)("TSType"), + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSEnumDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "members"], + fields: { + declare: (0, _utils.validateOptional)(bool), + const: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)("Identifier"), + members: (0, _utils.validateArrayOfType)("TSEnumMember"), + initializer: (0, _utils.validateOptionalType)("Expression") + } + }); + (0, _utils.default)("TSEnumMember", { + visitor: ["id", "initializer"], + fields: { + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + initializer: (0, _utils.validateOptionalType)("Expression") + } + }); + (0, _utils.default)("TSModuleDeclaration", { + aliases: ["Statement", "Declaration"], + visitor: ["id", "body"], + fields: { + declare: (0, _utils.validateOptional)(bool), + global: (0, _utils.validateOptional)(bool), + id: (0, _utils.validateType)(["Identifier", "StringLiteral"]), + body: (0, _utils.validateType)(["TSModuleBlock", "TSModuleDeclaration"]) + } + }); + (0, _utils.default)("TSModuleBlock", { + aliases: ["Scopable", "Block", "BlockParent"], + visitor: ["body"], + fields: { + body: (0, _utils.validateArrayOfType)("Statement") + } + }); + (0, _utils.default)("TSImportType", { + aliases: ["TSType"], + visitor: ["argument", "qualifier", "typeParameters"], + fields: { + argument: (0, _utils.validateType)("StringLiteral"), + qualifier: (0, _utils.validateOptionalType)("TSEntityName"), + typeParameters: (0, _utils.validateOptionalType)("TSTypeParameterInstantiation") + } + }); + (0, _utils.default)("TSImportEqualsDeclaration", { + aliases: ["Statement"], + visitor: ["id", "moduleReference"], + fields: { + isExport: (0, _utils.validate)(bool), + id: (0, _utils.validateType)("Identifier"), + moduleReference: (0, _utils.validateType)(["TSEntityName", "TSExternalModuleReference"]) + } + }); + (0, _utils.default)("TSExternalModuleReference", { + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("StringLiteral") + } + }); + (0, _utils.default)("TSNonNullExpression", { + aliases: ["Expression"], + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSExportAssignment", { + aliases: ["Statement"], + visitor: ["expression"], + fields: { + expression: (0, _utils.validateType)("Expression") + } + }); + (0, _utils.default)("TSNamespaceExportDeclaration", { + aliases: ["Statement"], + visitor: ["id"], + fields: { + id: (0, _utils.validateType)("Identifier") + } + }); + (0, _utils.default)("TSTypeAnnotation", { + visitor: ["typeAnnotation"], + fields: { + typeAnnotation: { + validate: (0, _utils.assertNodeType)("TSType") + } + } + }); + (0, _utils.default)("TSTypeParameterInstantiation", { + visitor: ["params"], + fields: { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSType"))) + } + } + }); + (0, _utils.default)("TSTypeParameterDeclaration", { + visitor: ["params"], + fields: { + params: { + validate: (0, _utils.chain)((0, _utils.assertValueType)("array"), (0, _utils.assertEach)((0, _utils.assertNodeType)("TSTypeParameter"))) + } + } + }); + (0, _utils.default)("TSTypeParameter", { + builder: ["constraint", "default", "name"], + visitor: ["constraint", "default"], + fields: { + name: { + validate: (0, _utils.assertValueType)("string") + }, + constraint: { + validate: (0, _utils.assertNodeType)("TSType"), + optional: true + }, + default: { + validate: (0, _utils.assertNodeType)("TSType"), + optional: true + } + } + }); + return typescript$3; + } + + var hasRequiredDefinitions; + + function requireDefinitions () { + if (hasRequiredDefinitions) return definitions; + hasRequiredDefinitions = 1; + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + Object.defineProperty(exports, "VISITOR_KEYS", { + enumerable: true, + get: function () { + return _utils.VISITOR_KEYS; + } + }); + Object.defineProperty(exports, "ALIAS_KEYS", { + enumerable: true, + get: function () { + return _utils.ALIAS_KEYS; + } + }); + Object.defineProperty(exports, "FLIPPED_ALIAS_KEYS", { + enumerable: true, + get: function () { + return _utils.FLIPPED_ALIAS_KEYS; + } + }); + Object.defineProperty(exports, "NODE_FIELDS", { + enumerable: true, + get: function () { + return _utils.NODE_FIELDS; + } + }); + Object.defineProperty(exports, "BUILDER_KEYS", { + enumerable: true, + get: function () { + return _utils.BUILDER_KEYS; + } + }); + Object.defineProperty(exports, "DEPRECATED_KEYS", { + enumerable: true, + get: function () { + return _utils.DEPRECATED_KEYS; + } + }); + Object.defineProperty(exports, "NODE_PARENT_VALIDATIONS", { + enumerable: true, + get: function () { + return _utils.NODE_PARENT_VALIDATIONS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS_ALIAS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS_ALIAS; + } + }); + Object.defineProperty(exports, "PLACEHOLDERS_FLIPPED_ALIAS", { + enumerable: true, + get: function () { + return _placeholders.PLACEHOLDERS_FLIPPED_ALIAS; + } + }); + exports.TYPES = void 0; + + var _toFastProperties = _interopRequireDefault(toFastProperties); + + requireCore(); + + requireEs2015(); + + requireFlow(); + + requireJsx(); + + requireMisc(); + + requireExperimental(); + + requireTypescript(); + + var _utils = requireUtils(); + + var _placeholders = requirePlaceholders(); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + (0, _toFastProperties.default)(_utils.VISITOR_KEYS); + (0, _toFastProperties.default)(_utils.ALIAS_KEYS); + (0, _toFastProperties.default)(_utils.FLIPPED_ALIAS_KEYS); + (0, _toFastProperties.default)(_utils.NODE_FIELDS); + (0, _toFastProperties.default)(_utils.BUILDER_KEYS); + (0, _toFastProperties.default)(_utils.DEPRECATED_KEYS); + (0, _toFastProperties.default)(_placeholders.PLACEHOLDERS_ALIAS); + (0, _toFastProperties.default)(_placeholders.PLACEHOLDERS_FLIPPED_ALIAS); + const TYPES = Object.keys(_utils.VISITOR_KEYS).concat(Object.keys(_utils.FLIPPED_ALIAS_KEYS)).concat(Object.keys(_utils.DEPRECATED_KEYS)); + exports.TYPES = TYPES; + } (definitions)); + return definitions; + } + + Object.defineProperty(builder$1, "__esModule", { + value: true + }); + builder$1.default = builder; + + var _clone = _interopRequireDefault$v(clone_1); + + var _definitions$6 = requireDefinitions(); + + var _validate = _interopRequireDefault$v(requireValidate()); + + function _interopRequireDefault$v(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function builder(type, ...args) { + const keys = _definitions$6.BUILDER_KEYS[type]; + const countArgs = args.length; + + if (countArgs > keys.length) { + throw new Error(`${type}: Too many arguments passed. Received ${countArgs} but can receive no more than ${keys.length}`); + } + + const node = { + type + }; + let i = 0; + keys.forEach(key => { + const field = _definitions$6.NODE_FIELDS[type][key]; + let arg; + if (i < countArgs) arg = args[i]; + if (arg === undefined) arg = (0, _clone.default)(field.default); + node[key] = arg; + i++; + }); + + for (const key of Object.keys(node)) { + (0, _validate.default)(node, key, node[key]); + } + + return node; + } + + Object.defineProperty(generated$2, "__esModule", { + value: true + }); + generated$2.arrayExpression = generated$2.ArrayExpression = ArrayExpression$1; + generated$2.assignmentExpression = generated$2.AssignmentExpression = AssignmentExpression$2; + generated$2.binaryExpression = generated$2.BinaryExpression = BinaryExpression$1; + generated$2.interpreterDirective = generated$2.InterpreterDirective = InterpreterDirective$1; + generated$2.directive = generated$2.Directive = Directive$1; + generated$2.directiveLiteral = generated$2.DirectiveLiteral = DirectiveLiteral$1; + generated$2.blockStatement = generated$2.BlockStatement = BlockStatement$1; + generated$2.breakStatement = generated$2.BreakStatement = BreakStatement$1; + generated$2.callExpression = generated$2.CallExpression = CallExpression$1; + generated$2.catchClause = generated$2.CatchClause = CatchClause$1; + generated$2.conditionalExpression = generated$2.ConditionalExpression = ConditionalExpression$2; + generated$2.continueStatement = generated$2.ContinueStatement = ContinueStatement$1; + generated$2.debuggerStatement = generated$2.DebuggerStatement = DebuggerStatement$1; + generated$2.doWhileStatement = generated$2.DoWhileStatement = DoWhileStatement$1; + generated$2.emptyStatement = generated$2.EmptyStatement = EmptyStatement$1; + generated$2.expressionStatement = generated$2.ExpressionStatement = ExpressionStatement$1; + generated$2.file = generated$2.File = File$1; + generated$2.forInStatement = generated$2.ForInStatement = ForInStatement$1; + generated$2.forStatement = generated$2.ForStatement = ForStatement$1; + generated$2.functionDeclaration = generated$2.FunctionDeclaration = FunctionDeclaration; + generated$2.functionExpression = generated$2.FunctionExpression = FunctionExpression$2; + generated$2.identifier = generated$2.Identifier = Identifier$2; + generated$2.ifStatement = generated$2.IfStatement = IfStatement$1; + generated$2.labeledStatement = generated$2.LabeledStatement = LabeledStatement$1; + generated$2.stringLiteral = generated$2.StringLiteral = StringLiteral$1; + generated$2.numericLiteral = generated$2.NumericLiteral = NumericLiteral$1; + generated$2.nullLiteral = generated$2.NullLiteral = NullLiteral$1; + generated$2.booleanLiteral = generated$2.BooleanLiteral = BooleanLiteral$1; + generated$2.regExpLiteral = generated$2.RegExpLiteral = RegExpLiteral$1; + generated$2.logicalExpression = generated$2.LogicalExpression = LogicalExpression$1; + generated$2.memberExpression = generated$2.MemberExpression = MemberExpression$1; + generated$2.newExpression = generated$2.NewExpression = NewExpression$1; + generated$2.program = generated$2.Program = Program$1; + generated$2.objectExpression = generated$2.ObjectExpression = ObjectExpression$2; + generated$2.objectMethod = generated$2.ObjectMethod = ObjectMethod$1; + generated$2.objectProperty = generated$2.ObjectProperty = ObjectProperty$1; + generated$2.restElement = generated$2.RestElement = RestElement$1; + generated$2.returnStatement = generated$2.ReturnStatement = ReturnStatement$1; + generated$2.sequenceExpression = generated$2.SequenceExpression = SequenceExpression$2; + generated$2.parenthesizedExpression = generated$2.ParenthesizedExpression = ParenthesizedExpression$1; + generated$2.switchCase = generated$2.SwitchCase = SwitchCase$1; + generated$2.switchStatement = generated$2.SwitchStatement = SwitchStatement$1; + generated$2.thisExpression = generated$2.ThisExpression = ThisExpression$1; + generated$2.throwStatement = generated$2.ThrowStatement = ThrowStatement$1; + generated$2.tryStatement = generated$2.TryStatement = TryStatement$1; + generated$2.unaryExpression = generated$2.UnaryExpression = UnaryExpression$1; + generated$2.updateExpression = generated$2.UpdateExpression = UpdateExpression$2; + generated$2.variableDeclaration = generated$2.VariableDeclaration = VariableDeclaration$1; + generated$2.variableDeclarator = generated$2.VariableDeclarator = VariableDeclarator$1; + generated$2.whileStatement = generated$2.WhileStatement = WhileStatement$1; + generated$2.withStatement = generated$2.WithStatement = WithStatement$1; + generated$2.assignmentPattern = generated$2.AssignmentPattern = AssignmentPattern$1; + generated$2.arrayPattern = generated$2.ArrayPattern = ArrayPattern; + generated$2.arrowFunctionExpression = generated$2.ArrowFunctionExpression = ArrowFunctionExpression$2; + generated$2.classBody = generated$2.ClassBody = ClassBody$1; + generated$2.classExpression = generated$2.ClassExpression = ClassExpression$1; + generated$2.classDeclaration = generated$2.ClassDeclaration = ClassDeclaration$1; + generated$2.exportAllDeclaration = generated$2.ExportAllDeclaration = ExportAllDeclaration$1; + generated$2.exportDefaultDeclaration = generated$2.ExportDefaultDeclaration = ExportDefaultDeclaration$1; + generated$2.exportNamedDeclaration = generated$2.ExportNamedDeclaration = ExportNamedDeclaration$1; + generated$2.exportSpecifier = generated$2.ExportSpecifier = ExportSpecifier$1; + generated$2.forOfStatement = generated$2.ForOfStatement = ForOfStatement$1; + generated$2.importDeclaration = generated$2.ImportDeclaration = ImportDeclaration$1; + generated$2.importDefaultSpecifier = generated$2.ImportDefaultSpecifier = ImportDefaultSpecifier$1; + generated$2.importNamespaceSpecifier = generated$2.ImportNamespaceSpecifier = ImportNamespaceSpecifier$1; + generated$2.importSpecifier = generated$2.ImportSpecifier = ImportSpecifier$1; + generated$2.metaProperty = generated$2.MetaProperty = MetaProperty$1; + generated$2.classMethod = generated$2.ClassMethod = ClassMethod$1; + generated$2.objectPattern = generated$2.ObjectPattern = ObjectPattern; + generated$2.spreadElement = generated$2.SpreadElement = SpreadElement; + generated$2.super = generated$2.Super = Super$1; + generated$2.taggedTemplateExpression = generated$2.TaggedTemplateExpression = TaggedTemplateExpression$1; + generated$2.templateElement = generated$2.TemplateElement = TemplateElement$1; + generated$2.templateLiteral = generated$2.TemplateLiteral = TemplateLiteral$1; + generated$2.yieldExpression = generated$2.YieldExpression = YieldExpression$2; + generated$2.anyTypeAnnotation = generated$2.AnyTypeAnnotation = AnyTypeAnnotation; + generated$2.arrayTypeAnnotation = generated$2.ArrayTypeAnnotation = ArrayTypeAnnotation; + generated$2.booleanTypeAnnotation = generated$2.BooleanTypeAnnotation = BooleanTypeAnnotation; + generated$2.booleanLiteralTypeAnnotation = generated$2.BooleanLiteralTypeAnnotation = BooleanLiteralTypeAnnotation; + generated$2.nullLiteralTypeAnnotation = generated$2.NullLiteralTypeAnnotation = NullLiteralTypeAnnotation; + generated$2.classImplements = generated$2.ClassImplements = ClassImplements; + generated$2.declareClass = generated$2.DeclareClass = DeclareClass; + generated$2.declareFunction = generated$2.DeclareFunction = DeclareFunction; + generated$2.declareInterface = generated$2.DeclareInterface = DeclareInterface; + generated$2.declareModule = generated$2.DeclareModule = DeclareModule; + generated$2.declareModuleExports = generated$2.DeclareModuleExports = DeclareModuleExports; + generated$2.declareTypeAlias = generated$2.DeclareTypeAlias = DeclareTypeAlias; + generated$2.declareOpaqueType = generated$2.DeclareOpaqueType = DeclareOpaqueType; + generated$2.declareVariable = generated$2.DeclareVariable = DeclareVariable; + generated$2.declareExportDeclaration = generated$2.DeclareExportDeclaration = DeclareExportDeclaration; + generated$2.declareExportAllDeclaration = generated$2.DeclareExportAllDeclaration = DeclareExportAllDeclaration; + generated$2.declaredPredicate = generated$2.DeclaredPredicate = DeclaredPredicate; + generated$2.existsTypeAnnotation = generated$2.ExistsTypeAnnotation = ExistsTypeAnnotation; + generated$2.functionTypeAnnotation = generated$2.FunctionTypeAnnotation = FunctionTypeAnnotation$1; + generated$2.functionTypeParam = generated$2.FunctionTypeParam = FunctionTypeParam; + generated$2.genericTypeAnnotation = generated$2.GenericTypeAnnotation = GenericTypeAnnotation; + generated$2.inferredPredicate = generated$2.InferredPredicate = InferredPredicate; + generated$2.interfaceExtends = generated$2.InterfaceExtends = InterfaceExtends; + generated$2.interfaceDeclaration = generated$2.InterfaceDeclaration = InterfaceDeclaration; + generated$2.interfaceTypeAnnotation = generated$2.InterfaceTypeAnnotation = InterfaceTypeAnnotation; + generated$2.intersectionTypeAnnotation = generated$2.IntersectionTypeAnnotation = IntersectionTypeAnnotation; + generated$2.mixedTypeAnnotation = generated$2.MixedTypeAnnotation = MixedTypeAnnotation; + generated$2.emptyTypeAnnotation = generated$2.EmptyTypeAnnotation = EmptyTypeAnnotation; + generated$2.nullableTypeAnnotation = generated$2.NullableTypeAnnotation = NullableTypeAnnotation$1; + generated$2.numberLiteralTypeAnnotation = generated$2.NumberLiteralTypeAnnotation = NumberLiteralTypeAnnotation; + generated$2.numberTypeAnnotation = generated$2.NumberTypeAnnotation = NumberTypeAnnotation; + generated$2.objectTypeAnnotation = generated$2.ObjectTypeAnnotation = ObjectTypeAnnotation; + generated$2.objectTypeInternalSlot = generated$2.ObjectTypeInternalSlot = ObjectTypeInternalSlot; + generated$2.objectTypeCallProperty = generated$2.ObjectTypeCallProperty = ObjectTypeCallProperty; + generated$2.objectTypeIndexer = generated$2.ObjectTypeIndexer = ObjectTypeIndexer; + generated$2.objectTypeProperty = generated$2.ObjectTypeProperty = ObjectTypeProperty; + generated$2.objectTypeSpreadProperty = generated$2.ObjectTypeSpreadProperty = ObjectTypeSpreadProperty; + generated$2.opaqueType = generated$2.OpaqueType = OpaqueType; + generated$2.qualifiedTypeIdentifier = generated$2.QualifiedTypeIdentifier = QualifiedTypeIdentifier; + generated$2.stringLiteralTypeAnnotation = generated$2.StringLiteralTypeAnnotation = StringLiteralTypeAnnotation; + generated$2.stringTypeAnnotation = generated$2.StringTypeAnnotation = StringTypeAnnotation; + generated$2.symbolTypeAnnotation = generated$2.SymbolTypeAnnotation = SymbolTypeAnnotation; + generated$2.thisTypeAnnotation = generated$2.ThisTypeAnnotation = ThisTypeAnnotation; + generated$2.tupleTypeAnnotation = generated$2.TupleTypeAnnotation = TupleTypeAnnotation; + generated$2.typeofTypeAnnotation = generated$2.TypeofTypeAnnotation = TypeofTypeAnnotation; + generated$2.typeAlias = generated$2.TypeAlias = TypeAlias; + generated$2.typeAnnotation = generated$2.TypeAnnotation = TypeAnnotation; + generated$2.typeCastExpression = generated$2.TypeCastExpression = TypeCastExpression; + generated$2.typeParameter = generated$2.TypeParameter = TypeParameter; + generated$2.typeParameterDeclaration = generated$2.TypeParameterDeclaration = TypeParameterDeclaration; + generated$2.typeParameterInstantiation = generated$2.TypeParameterInstantiation = TypeParameterInstantiation; + generated$2.unionTypeAnnotation = generated$2.UnionTypeAnnotation = UnionTypeAnnotation$1; + generated$2.variance = generated$2.Variance = Variance; + generated$2.voidTypeAnnotation = generated$2.VoidTypeAnnotation = VoidTypeAnnotation; + generated$2.enumDeclaration = generated$2.EnumDeclaration = EnumDeclaration; + generated$2.enumBooleanBody = generated$2.EnumBooleanBody = EnumBooleanBody; + generated$2.enumNumberBody = generated$2.EnumNumberBody = EnumNumberBody; + generated$2.enumStringBody = generated$2.EnumStringBody = EnumStringBody; + generated$2.enumSymbolBody = generated$2.EnumSymbolBody = EnumSymbolBody; + generated$2.enumBooleanMember = generated$2.EnumBooleanMember = EnumBooleanMember; + generated$2.enumNumberMember = generated$2.EnumNumberMember = EnumNumberMember; + generated$2.enumStringMember = generated$2.EnumStringMember = EnumStringMember; + generated$2.enumDefaultedMember = generated$2.EnumDefaultedMember = EnumDefaultedMember; + generated$2.jSXAttribute = generated$2.jsxAttribute = generated$2.JSXAttribute = JSXAttribute$1; + generated$2.jSXClosingElement = generated$2.jsxClosingElement = generated$2.JSXClosingElement = JSXClosingElement$1; + generated$2.jSXElement = generated$2.jsxElement = generated$2.JSXElement = JSXElement$1; + generated$2.jSXEmptyExpression = generated$2.jsxEmptyExpression = generated$2.JSXEmptyExpression = JSXEmptyExpression$1; + generated$2.jSXExpressionContainer = generated$2.jsxExpressionContainer = generated$2.JSXExpressionContainer = JSXExpressionContainer$1; + generated$2.jSXSpreadChild = generated$2.jsxSpreadChild = generated$2.JSXSpreadChild = JSXSpreadChild$1; + generated$2.jSXIdentifier = generated$2.jsxIdentifier = generated$2.JSXIdentifier = JSXIdentifier$1; + generated$2.jSXMemberExpression = generated$2.jsxMemberExpression = generated$2.JSXMemberExpression = JSXMemberExpression$1; + generated$2.jSXNamespacedName = generated$2.jsxNamespacedName = generated$2.JSXNamespacedName = JSXNamespacedName$1; + generated$2.jSXOpeningElement = generated$2.jsxOpeningElement = generated$2.JSXOpeningElement = JSXOpeningElement$1; + generated$2.jSXSpreadAttribute = generated$2.jsxSpreadAttribute = generated$2.JSXSpreadAttribute = JSXSpreadAttribute$1; + generated$2.jSXText = generated$2.jsxText = generated$2.JSXText = JSXText$1; + generated$2.jSXFragment = generated$2.jsxFragment = generated$2.JSXFragment = JSXFragment$1; + generated$2.jSXOpeningFragment = generated$2.jsxOpeningFragment = generated$2.JSXOpeningFragment = JSXOpeningFragment$1; + generated$2.jSXClosingFragment = generated$2.jsxClosingFragment = generated$2.JSXClosingFragment = JSXClosingFragment$1; + generated$2.noop = generated$2.Noop = Noop; + generated$2.placeholder = generated$2.Placeholder = Placeholder$1; + generated$2.v8IntrinsicIdentifier = generated$2.V8IntrinsicIdentifier = V8IntrinsicIdentifier$1; + generated$2.argumentPlaceholder = generated$2.ArgumentPlaceholder = ArgumentPlaceholder$1; + generated$2.awaitExpression = generated$2.AwaitExpression = AwaitExpression$1; + generated$2.bindExpression = generated$2.BindExpression = BindExpression$1; + generated$2.classProperty = generated$2.ClassProperty = ClassProperty$1; + generated$2.optionalMemberExpression = generated$2.OptionalMemberExpression = OptionalMemberExpression$2; + generated$2.pipelineTopicExpression = generated$2.PipelineTopicExpression = PipelineTopicExpression$1; + generated$2.pipelineBareFunction = generated$2.PipelineBareFunction = PipelineBareFunction$1; + generated$2.pipelinePrimaryTopicReference = generated$2.PipelinePrimaryTopicReference = PipelinePrimaryTopicReference$1; + generated$2.optionalCallExpression = generated$2.OptionalCallExpression = OptionalCallExpression$1; + generated$2.classPrivateProperty = generated$2.ClassPrivateProperty = ClassPrivateProperty$1; + generated$2.classPrivateMethod = generated$2.ClassPrivateMethod = ClassPrivateMethod$1; + generated$2.import = generated$2.Import = Import$1; + generated$2.importAttribute = generated$2.ImportAttribute = ImportAttribute$1; + generated$2.decorator = generated$2.Decorator = Decorator$1; + generated$2.doExpression = generated$2.DoExpression = DoExpression$2; + generated$2.exportDefaultSpecifier = generated$2.ExportDefaultSpecifier = ExportDefaultSpecifier$1; + generated$2.exportNamespaceSpecifier = generated$2.ExportNamespaceSpecifier = ExportNamespaceSpecifier$1; + generated$2.privateName = generated$2.PrivateName = PrivateName$1; + generated$2.bigIntLiteral = generated$2.BigIntLiteral = BigIntLiteral$1; + generated$2.recordExpression = generated$2.RecordExpression = RecordExpression$1; + generated$2.tupleExpression = generated$2.TupleExpression = TupleExpression$1; + generated$2.tSParameterProperty = generated$2.tsParameterProperty = generated$2.TSParameterProperty = TSParameterProperty$1; + generated$2.tSDeclareFunction = generated$2.tsDeclareFunction = generated$2.TSDeclareFunction = TSDeclareFunction$1; + generated$2.tSDeclareMethod = generated$2.tsDeclareMethod = generated$2.TSDeclareMethod = TSDeclareMethod$1; + generated$2.tSQualifiedName = generated$2.tsQualifiedName = generated$2.TSQualifiedName = TSQualifiedName$1; + generated$2.tSCallSignatureDeclaration = generated$2.tsCallSignatureDeclaration = generated$2.TSCallSignatureDeclaration = TSCallSignatureDeclaration$1; + generated$2.tSConstructSignatureDeclaration = generated$2.tsConstructSignatureDeclaration = generated$2.TSConstructSignatureDeclaration = TSConstructSignatureDeclaration$1; + generated$2.tSPropertySignature = generated$2.tsPropertySignature = generated$2.TSPropertySignature = TSPropertySignature$1; + generated$2.tSMethodSignature = generated$2.tsMethodSignature = generated$2.TSMethodSignature = TSMethodSignature$1; + generated$2.tSIndexSignature = generated$2.tsIndexSignature = generated$2.TSIndexSignature = TSIndexSignature$1; + generated$2.tSAnyKeyword = generated$2.tsAnyKeyword = generated$2.TSAnyKeyword = TSAnyKeyword$1; + generated$2.tSBooleanKeyword = generated$2.tsBooleanKeyword = generated$2.TSBooleanKeyword = TSBooleanKeyword$1; + generated$2.tSBigIntKeyword = generated$2.tsBigIntKeyword = generated$2.TSBigIntKeyword = TSBigIntKeyword$1; + generated$2.tSNeverKeyword = generated$2.tsNeverKeyword = generated$2.TSNeverKeyword = TSNeverKeyword$1; + generated$2.tSNullKeyword = generated$2.tsNullKeyword = generated$2.TSNullKeyword = TSNullKeyword$1; + generated$2.tSNumberKeyword = generated$2.tsNumberKeyword = generated$2.TSNumberKeyword = TSNumberKeyword$1; + generated$2.tSObjectKeyword = generated$2.tsObjectKeyword = generated$2.TSObjectKeyword = TSObjectKeyword$1; + generated$2.tSStringKeyword = generated$2.tsStringKeyword = generated$2.TSStringKeyword = TSStringKeyword$1; + generated$2.tSSymbolKeyword = generated$2.tsSymbolKeyword = generated$2.TSSymbolKeyword = TSSymbolKeyword$1; + generated$2.tSUndefinedKeyword = generated$2.tsUndefinedKeyword = generated$2.TSUndefinedKeyword = TSUndefinedKeyword$1; + generated$2.tSUnknownKeyword = generated$2.tsUnknownKeyword = generated$2.TSUnknownKeyword = TSUnknownKeyword$1; + generated$2.tSVoidKeyword = generated$2.tsVoidKeyword = generated$2.TSVoidKeyword = TSVoidKeyword$1; + generated$2.tSThisType = generated$2.tsThisType = generated$2.TSThisType = TSThisType$1; + generated$2.tSFunctionType = generated$2.tsFunctionType = generated$2.TSFunctionType = TSFunctionType$1; + generated$2.tSConstructorType = generated$2.tsConstructorType = generated$2.TSConstructorType = TSConstructorType$1; + generated$2.tSTypeReference = generated$2.tsTypeReference = generated$2.TSTypeReference = TSTypeReference$1; + generated$2.tSTypePredicate = generated$2.tsTypePredicate = generated$2.TSTypePredicate = TSTypePredicate$1; + generated$2.tSTypeQuery = generated$2.tsTypeQuery = generated$2.TSTypeQuery = TSTypeQuery$1; + generated$2.tSTypeLiteral = generated$2.tsTypeLiteral = generated$2.TSTypeLiteral = TSTypeLiteral$1; + generated$2.tSArrayType = generated$2.tsArrayType = generated$2.TSArrayType = TSArrayType$1; + generated$2.tSTupleType = generated$2.tsTupleType = generated$2.TSTupleType = TSTupleType$1; + generated$2.tSOptionalType = generated$2.tsOptionalType = generated$2.TSOptionalType = TSOptionalType$1; + generated$2.tSRestType = generated$2.tsRestType = generated$2.TSRestType = TSRestType$1; + generated$2.tSUnionType = generated$2.tsUnionType = generated$2.TSUnionType = TSUnionType$2; + generated$2.tSIntersectionType = generated$2.tsIntersectionType = generated$2.TSIntersectionType = TSIntersectionType$1; + generated$2.tSConditionalType = generated$2.tsConditionalType = generated$2.TSConditionalType = TSConditionalType$1; + generated$2.tSInferType = generated$2.tsInferType = generated$2.TSInferType = TSInferType$2; + generated$2.tSParenthesizedType = generated$2.tsParenthesizedType = generated$2.TSParenthesizedType = TSParenthesizedType$1; + generated$2.tSTypeOperator = generated$2.tsTypeOperator = generated$2.TSTypeOperator = TSTypeOperator$1; + generated$2.tSIndexedAccessType = generated$2.tsIndexedAccessType = generated$2.TSIndexedAccessType = TSIndexedAccessType$1; + generated$2.tSMappedType = generated$2.tsMappedType = generated$2.TSMappedType = TSMappedType$1; + generated$2.tSLiteralType = generated$2.tsLiteralType = generated$2.TSLiteralType = TSLiteralType$1; + generated$2.tSExpressionWithTypeArguments = generated$2.tsExpressionWithTypeArguments = generated$2.TSExpressionWithTypeArguments = TSExpressionWithTypeArguments$1; + generated$2.tSInterfaceDeclaration = generated$2.tsInterfaceDeclaration = generated$2.TSInterfaceDeclaration = TSInterfaceDeclaration$1; + generated$2.tSInterfaceBody = generated$2.tsInterfaceBody = generated$2.TSInterfaceBody = TSInterfaceBody$1; + generated$2.tSTypeAliasDeclaration = generated$2.tsTypeAliasDeclaration = generated$2.TSTypeAliasDeclaration = TSTypeAliasDeclaration$1; + generated$2.tSAsExpression = generated$2.tsAsExpression = generated$2.TSAsExpression = TSAsExpression$2; + generated$2.tSTypeAssertion = generated$2.tsTypeAssertion = generated$2.TSTypeAssertion = TSTypeAssertion$2; + generated$2.tSEnumDeclaration = generated$2.tsEnumDeclaration = generated$2.TSEnumDeclaration = TSEnumDeclaration$1; + generated$2.tSEnumMember = generated$2.tsEnumMember = generated$2.TSEnumMember = TSEnumMember$1; + generated$2.tSModuleDeclaration = generated$2.tsModuleDeclaration = generated$2.TSModuleDeclaration = TSModuleDeclaration$1; + generated$2.tSModuleBlock = generated$2.tsModuleBlock = generated$2.TSModuleBlock = TSModuleBlock$1; + generated$2.tSImportType = generated$2.tsImportType = generated$2.TSImportType = TSImportType$1; + generated$2.tSImportEqualsDeclaration = generated$2.tsImportEqualsDeclaration = generated$2.TSImportEqualsDeclaration = TSImportEqualsDeclaration$1; + generated$2.tSExternalModuleReference = generated$2.tsExternalModuleReference = generated$2.TSExternalModuleReference = TSExternalModuleReference$1; + generated$2.tSNonNullExpression = generated$2.tsNonNullExpression = generated$2.TSNonNullExpression = TSNonNullExpression$1; + generated$2.tSExportAssignment = generated$2.tsExportAssignment = generated$2.TSExportAssignment = TSExportAssignment$1; + generated$2.tSNamespaceExportDeclaration = generated$2.tsNamespaceExportDeclaration = generated$2.TSNamespaceExportDeclaration = TSNamespaceExportDeclaration$1; + generated$2.tSTypeAnnotation = generated$2.tsTypeAnnotation = generated$2.TSTypeAnnotation = TSTypeAnnotation$1; + generated$2.tSTypeParameterInstantiation = generated$2.tsTypeParameterInstantiation = generated$2.TSTypeParameterInstantiation = TSTypeParameterInstantiation$1; + generated$2.tSTypeParameterDeclaration = generated$2.tsTypeParameterDeclaration = generated$2.TSTypeParameterDeclaration = TSTypeParameterDeclaration; + generated$2.tSTypeParameter = generated$2.tsTypeParameter = generated$2.TSTypeParameter = TSTypeParameter$1; + generated$2.numberLiteral = generated$2.NumberLiteral = NumberLiteral; + generated$2.regexLiteral = generated$2.RegexLiteral = RegexLiteral; + generated$2.restProperty = generated$2.RestProperty = RestProperty; + generated$2.spreadProperty = generated$2.SpreadProperty = SpreadProperty; + + var _builder = _interopRequireDefault$u(builder$1); + + function _interopRequireDefault$u(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function ArrayExpression$1(...args) { + return (0, _builder.default)("ArrayExpression", ...args); + } + + function AssignmentExpression$2(...args) { + return (0, _builder.default)("AssignmentExpression", ...args); + } + + function BinaryExpression$1(...args) { + return (0, _builder.default)("BinaryExpression", ...args); + } + + function InterpreterDirective$1(...args) { + return (0, _builder.default)("InterpreterDirective", ...args); + } + + function Directive$1(...args) { + return (0, _builder.default)("Directive", ...args); + } + + function DirectiveLiteral$1(...args) { + return (0, _builder.default)("DirectiveLiteral", ...args); + } + + function BlockStatement$1(...args) { + return (0, _builder.default)("BlockStatement", ...args); + } + + function BreakStatement$1(...args) { + return (0, _builder.default)("BreakStatement", ...args); + } + + function CallExpression$1(...args) { + return (0, _builder.default)("CallExpression", ...args); + } + + function CatchClause$1(...args) { + return (0, _builder.default)("CatchClause", ...args); + } + + function ConditionalExpression$2(...args) { + return (0, _builder.default)("ConditionalExpression", ...args); + } + + function ContinueStatement$1(...args) { + return (0, _builder.default)("ContinueStatement", ...args); + } + + function DebuggerStatement$1(...args) { + return (0, _builder.default)("DebuggerStatement", ...args); + } + + function DoWhileStatement$1(...args) { + return (0, _builder.default)("DoWhileStatement", ...args); + } + + function EmptyStatement$1(...args) { + return (0, _builder.default)("EmptyStatement", ...args); + } + + function ExpressionStatement$1(...args) { + return (0, _builder.default)("ExpressionStatement", ...args); + } + + function File$1(...args) { + return (0, _builder.default)("File", ...args); + } + + function ForInStatement$1(...args) { + return (0, _builder.default)("ForInStatement", ...args); + } + + function ForStatement$1(...args) { + return (0, _builder.default)("ForStatement", ...args); + } + + function FunctionDeclaration(...args) { + return (0, _builder.default)("FunctionDeclaration", ...args); + } + + function FunctionExpression$2(...args) { + return (0, _builder.default)("FunctionExpression", ...args); + } + + function Identifier$2(...args) { + return (0, _builder.default)("Identifier", ...args); + } + + function IfStatement$1(...args) { + return (0, _builder.default)("IfStatement", ...args); + } + + function LabeledStatement$1(...args) { + return (0, _builder.default)("LabeledStatement", ...args); + } + + function StringLiteral$1(...args) { + return (0, _builder.default)("StringLiteral", ...args); + } + + function NumericLiteral$1(...args) { + return (0, _builder.default)("NumericLiteral", ...args); + } + + function NullLiteral$1(...args) { + return (0, _builder.default)("NullLiteral", ...args); + } + + function BooleanLiteral$1(...args) { + return (0, _builder.default)("BooleanLiteral", ...args); + } + + function RegExpLiteral$1(...args) { + return (0, _builder.default)("RegExpLiteral", ...args); + } + + function LogicalExpression$1(...args) { + return (0, _builder.default)("LogicalExpression", ...args); + } + + function MemberExpression$1(...args) { + return (0, _builder.default)("MemberExpression", ...args); + } + + function NewExpression$1(...args) { + return (0, _builder.default)("NewExpression", ...args); + } + + function Program$1(...args) { + return (0, _builder.default)("Program", ...args); + } + + function ObjectExpression$2(...args) { + return (0, _builder.default)("ObjectExpression", ...args); + } + + function ObjectMethod$1(...args) { + return (0, _builder.default)("ObjectMethod", ...args); + } + + function ObjectProperty$1(...args) { + return (0, _builder.default)("ObjectProperty", ...args); + } + + function RestElement$1(...args) { + return (0, _builder.default)("RestElement", ...args); + } + + function ReturnStatement$1(...args) { + return (0, _builder.default)("ReturnStatement", ...args); + } + + function SequenceExpression$2(...args) { + return (0, _builder.default)("SequenceExpression", ...args); + } + + function ParenthesizedExpression$1(...args) { + return (0, _builder.default)("ParenthesizedExpression", ...args); + } + + function SwitchCase$1(...args) { + return (0, _builder.default)("SwitchCase", ...args); + } + + function SwitchStatement$1(...args) { + return (0, _builder.default)("SwitchStatement", ...args); + } + + function ThisExpression$1(...args) { + return (0, _builder.default)("ThisExpression", ...args); + } + + function ThrowStatement$1(...args) { + return (0, _builder.default)("ThrowStatement", ...args); + } + + function TryStatement$1(...args) { + return (0, _builder.default)("TryStatement", ...args); + } + + function UnaryExpression$1(...args) { + return (0, _builder.default)("UnaryExpression", ...args); + } + + function UpdateExpression$2(...args) { + return (0, _builder.default)("UpdateExpression", ...args); + } + + function VariableDeclaration$1(...args) { + return (0, _builder.default)("VariableDeclaration", ...args); + } + + function VariableDeclarator$1(...args) { + return (0, _builder.default)("VariableDeclarator", ...args); + } + + function WhileStatement$1(...args) { + return (0, _builder.default)("WhileStatement", ...args); + } + + function WithStatement$1(...args) { + return (0, _builder.default)("WithStatement", ...args); + } + + function AssignmentPattern$1(...args) { + return (0, _builder.default)("AssignmentPattern", ...args); + } + + function ArrayPattern(...args) { + return (0, _builder.default)("ArrayPattern", ...args); + } + + function ArrowFunctionExpression$2(...args) { + return (0, _builder.default)("ArrowFunctionExpression", ...args); + } + + function ClassBody$1(...args) { + return (0, _builder.default)("ClassBody", ...args); + } + + function ClassExpression$1(...args) { + return (0, _builder.default)("ClassExpression", ...args); + } + + function ClassDeclaration$1(...args) { + return (0, _builder.default)("ClassDeclaration", ...args); + } + + function ExportAllDeclaration$1(...args) { + return (0, _builder.default)("ExportAllDeclaration", ...args); + } + + function ExportDefaultDeclaration$1(...args) { + return (0, _builder.default)("ExportDefaultDeclaration", ...args); + } + + function ExportNamedDeclaration$1(...args) { + return (0, _builder.default)("ExportNamedDeclaration", ...args); + } + + function ExportSpecifier$1(...args) { + return (0, _builder.default)("ExportSpecifier", ...args); + } + + function ForOfStatement$1(...args) { + return (0, _builder.default)("ForOfStatement", ...args); + } + + function ImportDeclaration$1(...args) { + return (0, _builder.default)("ImportDeclaration", ...args); + } + + function ImportDefaultSpecifier$1(...args) { + return (0, _builder.default)("ImportDefaultSpecifier", ...args); + } + + function ImportNamespaceSpecifier$1(...args) { + return (0, _builder.default)("ImportNamespaceSpecifier", ...args); + } + + function ImportSpecifier$1(...args) { + return (0, _builder.default)("ImportSpecifier", ...args); + } + + function MetaProperty$1(...args) { + return (0, _builder.default)("MetaProperty", ...args); + } + + function ClassMethod$1(...args) { + return (0, _builder.default)("ClassMethod", ...args); + } + + function ObjectPattern(...args) { + return (0, _builder.default)("ObjectPattern", ...args); + } + + function SpreadElement(...args) { + return (0, _builder.default)("SpreadElement", ...args); + } + + function Super$1(...args) { + return (0, _builder.default)("Super", ...args); + } + + function TaggedTemplateExpression$1(...args) { + return (0, _builder.default)("TaggedTemplateExpression", ...args); + } + + function TemplateElement$1(...args) { + return (0, _builder.default)("TemplateElement", ...args); + } + + function TemplateLiteral$1(...args) { + return (0, _builder.default)("TemplateLiteral", ...args); + } + + function YieldExpression$2(...args) { + return (0, _builder.default)("YieldExpression", ...args); + } + + function AnyTypeAnnotation(...args) { + return (0, _builder.default)("AnyTypeAnnotation", ...args); + } + + function ArrayTypeAnnotation(...args) { + return (0, _builder.default)("ArrayTypeAnnotation", ...args); + } + + function BooleanTypeAnnotation(...args) { + return (0, _builder.default)("BooleanTypeAnnotation", ...args); + } + + function BooleanLiteralTypeAnnotation(...args) { + return (0, _builder.default)("BooleanLiteralTypeAnnotation", ...args); + } + + function NullLiteralTypeAnnotation(...args) { + return (0, _builder.default)("NullLiteralTypeAnnotation", ...args); + } + + function ClassImplements(...args) { + return (0, _builder.default)("ClassImplements", ...args); + } + + function DeclareClass(...args) { + return (0, _builder.default)("DeclareClass", ...args); + } + + function DeclareFunction(...args) { + return (0, _builder.default)("DeclareFunction", ...args); + } + + function DeclareInterface(...args) { + return (0, _builder.default)("DeclareInterface", ...args); + } + + function DeclareModule(...args) { + return (0, _builder.default)("DeclareModule", ...args); + } + + function DeclareModuleExports(...args) { + return (0, _builder.default)("DeclareModuleExports", ...args); + } + + function DeclareTypeAlias(...args) { + return (0, _builder.default)("DeclareTypeAlias", ...args); + } + + function DeclareOpaqueType(...args) { + return (0, _builder.default)("DeclareOpaqueType", ...args); + } + + function DeclareVariable(...args) { + return (0, _builder.default)("DeclareVariable", ...args); + } + + function DeclareExportDeclaration(...args) { + return (0, _builder.default)("DeclareExportDeclaration", ...args); + } + + function DeclareExportAllDeclaration(...args) { + return (0, _builder.default)("DeclareExportAllDeclaration", ...args); + } + + function DeclaredPredicate(...args) { + return (0, _builder.default)("DeclaredPredicate", ...args); + } + + function ExistsTypeAnnotation(...args) { + return (0, _builder.default)("ExistsTypeAnnotation", ...args); + } + + function FunctionTypeAnnotation$1(...args) { + return (0, _builder.default)("FunctionTypeAnnotation", ...args); + } + + function FunctionTypeParam(...args) { + return (0, _builder.default)("FunctionTypeParam", ...args); + } + + function GenericTypeAnnotation(...args) { + return (0, _builder.default)("GenericTypeAnnotation", ...args); + } + + function InferredPredicate(...args) { + return (0, _builder.default)("InferredPredicate", ...args); + } + + function InterfaceExtends(...args) { + return (0, _builder.default)("InterfaceExtends", ...args); + } + + function InterfaceDeclaration(...args) { + return (0, _builder.default)("InterfaceDeclaration", ...args); + } + + function InterfaceTypeAnnotation(...args) { + return (0, _builder.default)("InterfaceTypeAnnotation", ...args); + } + + function IntersectionTypeAnnotation(...args) { + return (0, _builder.default)("IntersectionTypeAnnotation", ...args); + } + + function MixedTypeAnnotation(...args) { + return (0, _builder.default)("MixedTypeAnnotation", ...args); + } + + function EmptyTypeAnnotation(...args) { + return (0, _builder.default)("EmptyTypeAnnotation", ...args); + } + + function NullableTypeAnnotation$1(...args) { + return (0, _builder.default)("NullableTypeAnnotation", ...args); + } + + function NumberLiteralTypeAnnotation(...args) { + return (0, _builder.default)("NumberLiteralTypeAnnotation", ...args); + } + + function NumberTypeAnnotation(...args) { + return (0, _builder.default)("NumberTypeAnnotation", ...args); + } + + function ObjectTypeAnnotation(...args) { + return (0, _builder.default)("ObjectTypeAnnotation", ...args); + } + + function ObjectTypeInternalSlot(...args) { + return (0, _builder.default)("ObjectTypeInternalSlot", ...args); + } + + function ObjectTypeCallProperty(...args) { + return (0, _builder.default)("ObjectTypeCallProperty", ...args); + } + + function ObjectTypeIndexer(...args) { + return (0, _builder.default)("ObjectTypeIndexer", ...args); + } + + function ObjectTypeProperty(...args) { + return (0, _builder.default)("ObjectTypeProperty", ...args); + } + + function ObjectTypeSpreadProperty(...args) { + return (0, _builder.default)("ObjectTypeSpreadProperty", ...args); + } + + function OpaqueType(...args) { + return (0, _builder.default)("OpaqueType", ...args); + } + + function QualifiedTypeIdentifier(...args) { + return (0, _builder.default)("QualifiedTypeIdentifier", ...args); + } + + function StringLiteralTypeAnnotation(...args) { + return (0, _builder.default)("StringLiteralTypeAnnotation", ...args); + } + + function StringTypeAnnotation(...args) { + return (0, _builder.default)("StringTypeAnnotation", ...args); + } + + function SymbolTypeAnnotation(...args) { + return (0, _builder.default)("SymbolTypeAnnotation", ...args); + } + + function ThisTypeAnnotation(...args) { + return (0, _builder.default)("ThisTypeAnnotation", ...args); + } + + function TupleTypeAnnotation(...args) { + return (0, _builder.default)("TupleTypeAnnotation", ...args); + } + + function TypeofTypeAnnotation(...args) { + return (0, _builder.default)("TypeofTypeAnnotation", ...args); + } + + function TypeAlias(...args) { + return (0, _builder.default)("TypeAlias", ...args); + } + + function TypeAnnotation(...args) { + return (0, _builder.default)("TypeAnnotation", ...args); + } + + function TypeCastExpression(...args) { + return (0, _builder.default)("TypeCastExpression", ...args); + } + + function TypeParameter(...args) { + return (0, _builder.default)("TypeParameter", ...args); + } + + function TypeParameterDeclaration(...args) { + return (0, _builder.default)("TypeParameterDeclaration", ...args); + } + + function TypeParameterInstantiation(...args) { + return (0, _builder.default)("TypeParameterInstantiation", ...args); + } + + function UnionTypeAnnotation$1(...args) { + return (0, _builder.default)("UnionTypeAnnotation", ...args); + } + + function Variance(...args) { + return (0, _builder.default)("Variance", ...args); + } + + function VoidTypeAnnotation(...args) { + return (0, _builder.default)("VoidTypeAnnotation", ...args); + } + + function EnumDeclaration(...args) { + return (0, _builder.default)("EnumDeclaration", ...args); + } + + function EnumBooleanBody(...args) { + return (0, _builder.default)("EnumBooleanBody", ...args); + } + + function EnumNumberBody(...args) { + return (0, _builder.default)("EnumNumberBody", ...args); + } + + function EnumStringBody(...args) { + return (0, _builder.default)("EnumStringBody", ...args); + } + + function EnumSymbolBody(...args) { + return (0, _builder.default)("EnumSymbolBody", ...args); + } + + function EnumBooleanMember(...args) { + return (0, _builder.default)("EnumBooleanMember", ...args); + } + + function EnumNumberMember(...args) { + return (0, _builder.default)("EnumNumberMember", ...args); + } + + function EnumStringMember(...args) { + return (0, _builder.default)("EnumStringMember", ...args); + } + + function EnumDefaultedMember(...args) { + return (0, _builder.default)("EnumDefaultedMember", ...args); + } + + function JSXAttribute$1(...args) { + return (0, _builder.default)("JSXAttribute", ...args); + } + + function JSXClosingElement$1(...args) { + return (0, _builder.default)("JSXClosingElement", ...args); + } + + function JSXElement$1(...args) { + return (0, _builder.default)("JSXElement", ...args); + } + + function JSXEmptyExpression$1(...args) { + return (0, _builder.default)("JSXEmptyExpression", ...args); + } + + function JSXExpressionContainer$1(...args) { + return (0, _builder.default)("JSXExpressionContainer", ...args); + } + + function JSXSpreadChild$1(...args) { + return (0, _builder.default)("JSXSpreadChild", ...args); + } + + function JSXIdentifier$1(...args) { + return (0, _builder.default)("JSXIdentifier", ...args); + } + + function JSXMemberExpression$1(...args) { + return (0, _builder.default)("JSXMemberExpression", ...args); + } + + function JSXNamespacedName$1(...args) { + return (0, _builder.default)("JSXNamespacedName", ...args); + } + + function JSXOpeningElement$1(...args) { + return (0, _builder.default)("JSXOpeningElement", ...args); + } + + function JSXSpreadAttribute$1(...args) { + return (0, _builder.default)("JSXSpreadAttribute", ...args); + } + + function JSXText$1(...args) { + return (0, _builder.default)("JSXText", ...args); + } + + function JSXFragment$1(...args) { + return (0, _builder.default)("JSXFragment", ...args); + } + + function JSXOpeningFragment$1(...args) { + return (0, _builder.default)("JSXOpeningFragment", ...args); + } + + function JSXClosingFragment$1(...args) { + return (0, _builder.default)("JSXClosingFragment", ...args); + } + + function Noop(...args) { + return (0, _builder.default)("Noop", ...args); + } + + function Placeholder$1(...args) { + return (0, _builder.default)("Placeholder", ...args); + } + + function V8IntrinsicIdentifier$1(...args) { + return (0, _builder.default)("V8IntrinsicIdentifier", ...args); + } + + function ArgumentPlaceholder$1(...args) { + return (0, _builder.default)("ArgumentPlaceholder", ...args); + } + + function AwaitExpression$1(...args) { + return (0, _builder.default)("AwaitExpression", ...args); + } + + function BindExpression$1(...args) { + return (0, _builder.default)("BindExpression", ...args); + } + + function ClassProperty$1(...args) { + return (0, _builder.default)("ClassProperty", ...args); + } + + function OptionalMemberExpression$2(...args) { + return (0, _builder.default)("OptionalMemberExpression", ...args); + } + + function PipelineTopicExpression$1(...args) { + return (0, _builder.default)("PipelineTopicExpression", ...args); + } + + function PipelineBareFunction$1(...args) { + return (0, _builder.default)("PipelineBareFunction", ...args); + } + + function PipelinePrimaryTopicReference$1(...args) { + return (0, _builder.default)("PipelinePrimaryTopicReference", ...args); + } + + function OptionalCallExpression$1(...args) { + return (0, _builder.default)("OptionalCallExpression", ...args); + } + + function ClassPrivateProperty$1(...args) { + return (0, _builder.default)("ClassPrivateProperty", ...args); + } + + function ClassPrivateMethod$1(...args) { + return (0, _builder.default)("ClassPrivateMethod", ...args); + } + + function Import$1(...args) { + return (0, _builder.default)("Import", ...args); + } + + function ImportAttribute$1(...args) { + return (0, _builder.default)("ImportAttribute", ...args); + } + + function Decorator$1(...args) { + return (0, _builder.default)("Decorator", ...args); + } + + function DoExpression$2(...args) { + return (0, _builder.default)("DoExpression", ...args); + } + + function ExportDefaultSpecifier$1(...args) { + return (0, _builder.default)("ExportDefaultSpecifier", ...args); + } + + function ExportNamespaceSpecifier$1(...args) { + return (0, _builder.default)("ExportNamespaceSpecifier", ...args); + } + + function PrivateName$1(...args) { + return (0, _builder.default)("PrivateName", ...args); + } + + function BigIntLiteral$1(...args) { + return (0, _builder.default)("BigIntLiteral", ...args); + } + + function RecordExpression$1(...args) { + return (0, _builder.default)("RecordExpression", ...args); + } + + function TupleExpression$1(...args) { + return (0, _builder.default)("TupleExpression", ...args); + } + + function TSParameterProperty$1(...args) { + return (0, _builder.default)("TSParameterProperty", ...args); + } + + function TSDeclareFunction$1(...args) { + return (0, _builder.default)("TSDeclareFunction", ...args); + } + + function TSDeclareMethod$1(...args) { + return (0, _builder.default)("TSDeclareMethod", ...args); + } + + function TSQualifiedName$1(...args) { + return (0, _builder.default)("TSQualifiedName", ...args); + } + + function TSCallSignatureDeclaration$1(...args) { + return (0, _builder.default)("TSCallSignatureDeclaration", ...args); + } + + function TSConstructSignatureDeclaration$1(...args) { + return (0, _builder.default)("TSConstructSignatureDeclaration", ...args); + } + + function TSPropertySignature$1(...args) { + return (0, _builder.default)("TSPropertySignature", ...args); + } + + function TSMethodSignature$1(...args) { + return (0, _builder.default)("TSMethodSignature", ...args); + } + + function TSIndexSignature$1(...args) { + return (0, _builder.default)("TSIndexSignature", ...args); + } + + function TSAnyKeyword$1(...args) { + return (0, _builder.default)("TSAnyKeyword", ...args); + } + + function TSBooleanKeyword$1(...args) { + return (0, _builder.default)("TSBooleanKeyword", ...args); + } + + function TSBigIntKeyword$1(...args) { + return (0, _builder.default)("TSBigIntKeyword", ...args); + } + + function TSNeverKeyword$1(...args) { + return (0, _builder.default)("TSNeverKeyword", ...args); + } + + function TSNullKeyword$1(...args) { + return (0, _builder.default)("TSNullKeyword", ...args); + } + + function TSNumberKeyword$1(...args) { + return (0, _builder.default)("TSNumberKeyword", ...args); + } + + function TSObjectKeyword$1(...args) { + return (0, _builder.default)("TSObjectKeyword", ...args); + } + + function TSStringKeyword$1(...args) { + return (0, _builder.default)("TSStringKeyword", ...args); + } + + function TSSymbolKeyword$1(...args) { + return (0, _builder.default)("TSSymbolKeyword", ...args); + } + + function TSUndefinedKeyword$1(...args) { + return (0, _builder.default)("TSUndefinedKeyword", ...args); + } + + function TSUnknownKeyword$1(...args) { + return (0, _builder.default)("TSUnknownKeyword", ...args); + } + + function TSVoidKeyword$1(...args) { + return (0, _builder.default)("TSVoidKeyword", ...args); + } + + function TSThisType$1(...args) { + return (0, _builder.default)("TSThisType", ...args); + } + + function TSFunctionType$1(...args) { + return (0, _builder.default)("TSFunctionType", ...args); + } + + function TSConstructorType$1(...args) { + return (0, _builder.default)("TSConstructorType", ...args); + } + + function TSTypeReference$1(...args) { + return (0, _builder.default)("TSTypeReference", ...args); + } + + function TSTypePredicate$1(...args) { + return (0, _builder.default)("TSTypePredicate", ...args); + } + + function TSTypeQuery$1(...args) { + return (0, _builder.default)("TSTypeQuery", ...args); + } + + function TSTypeLiteral$1(...args) { + return (0, _builder.default)("TSTypeLiteral", ...args); + } + + function TSArrayType$1(...args) { + return (0, _builder.default)("TSArrayType", ...args); + } + + function TSTupleType$1(...args) { + return (0, _builder.default)("TSTupleType", ...args); + } + + function TSOptionalType$1(...args) { + return (0, _builder.default)("TSOptionalType", ...args); + } + + function TSRestType$1(...args) { + return (0, _builder.default)("TSRestType", ...args); + } + + function TSUnionType$2(...args) { + return (0, _builder.default)("TSUnionType", ...args); + } + + function TSIntersectionType$1(...args) { + return (0, _builder.default)("TSIntersectionType", ...args); + } + + function TSConditionalType$1(...args) { + return (0, _builder.default)("TSConditionalType", ...args); + } + + function TSInferType$2(...args) { + return (0, _builder.default)("TSInferType", ...args); + } + + function TSParenthesizedType$1(...args) { + return (0, _builder.default)("TSParenthesizedType", ...args); + } + + function TSTypeOperator$1(...args) { + return (0, _builder.default)("TSTypeOperator", ...args); + } + + function TSIndexedAccessType$1(...args) { + return (0, _builder.default)("TSIndexedAccessType", ...args); + } + + function TSMappedType$1(...args) { + return (0, _builder.default)("TSMappedType", ...args); + } + + function TSLiteralType$1(...args) { + return (0, _builder.default)("TSLiteralType", ...args); + } + + function TSExpressionWithTypeArguments$1(...args) { + return (0, _builder.default)("TSExpressionWithTypeArguments", ...args); + } + + function TSInterfaceDeclaration$1(...args) { + return (0, _builder.default)("TSInterfaceDeclaration", ...args); + } + + function TSInterfaceBody$1(...args) { + return (0, _builder.default)("TSInterfaceBody", ...args); + } + + function TSTypeAliasDeclaration$1(...args) { + return (0, _builder.default)("TSTypeAliasDeclaration", ...args); + } + + function TSAsExpression$2(...args) { + return (0, _builder.default)("TSAsExpression", ...args); + } + + function TSTypeAssertion$2(...args) { + return (0, _builder.default)("TSTypeAssertion", ...args); + } + + function TSEnumDeclaration$1(...args) { + return (0, _builder.default)("TSEnumDeclaration", ...args); + } + + function TSEnumMember$1(...args) { + return (0, _builder.default)("TSEnumMember", ...args); + } + + function TSModuleDeclaration$1(...args) { + return (0, _builder.default)("TSModuleDeclaration", ...args); + } + + function TSModuleBlock$1(...args) { + return (0, _builder.default)("TSModuleBlock", ...args); + } + + function TSImportType$1(...args) { + return (0, _builder.default)("TSImportType", ...args); + } + + function TSImportEqualsDeclaration$1(...args) { + return (0, _builder.default)("TSImportEqualsDeclaration", ...args); + } + + function TSExternalModuleReference$1(...args) { + return (0, _builder.default)("TSExternalModuleReference", ...args); + } + + function TSNonNullExpression$1(...args) { + return (0, _builder.default)("TSNonNullExpression", ...args); + } + + function TSExportAssignment$1(...args) { + return (0, _builder.default)("TSExportAssignment", ...args); + } + + function TSNamespaceExportDeclaration$1(...args) { + return (0, _builder.default)("TSNamespaceExportDeclaration", ...args); + } + + function TSTypeAnnotation$1(...args) { + return (0, _builder.default)("TSTypeAnnotation", ...args); + } + + function TSTypeParameterInstantiation$1(...args) { + return (0, _builder.default)("TSTypeParameterInstantiation", ...args); + } + + function TSTypeParameterDeclaration(...args) { + return (0, _builder.default)("TSTypeParameterDeclaration", ...args); + } + + function TSTypeParameter$1(...args) { + return (0, _builder.default)("TSTypeParameter", ...args); + } + + function NumberLiteral(...args) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + return NumberLiteral("NumberLiteral", ...args); + } + + function RegexLiteral(...args) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + return RegexLiteral("RegexLiteral", ...args); + } + + function RestProperty(...args) { + console.trace("The node type RestProperty has been renamed to RestElement"); + return RestProperty("RestProperty", ...args); + } + + function SpreadProperty(...args) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + return SpreadProperty("SpreadProperty", ...args); + } + + Object.defineProperty(cleanJSXElementLiteralChild$1, "__esModule", { + value: true + }); + cleanJSXElementLiteralChild$1.default = cleanJSXElementLiteralChild; + + var _generated$m = generated$2; + + function cleanJSXElementLiteralChild(child, args) { + const lines = child.value.split(/\r\n|\n|\r/); + let lastNonEmptyLine = 0; + + for (let i = 0; i < lines.length; i++) { + if (lines[i].match(/[^ \t]/)) { + lastNonEmptyLine = i; + } + } + + let str = ""; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const isFirstLine = i === 0; + const isLastLine = i === lines.length - 1; + const isLastNonEmptyLine = i === lastNonEmptyLine; + let trimmedLine = line.replace(/\t/g, " "); + + if (!isFirstLine) { + trimmedLine = trimmedLine.replace(/^[ ]+/, ""); + } + + if (!isLastLine) { + trimmedLine = trimmedLine.replace(/[ ]+$/, ""); + } + + if (trimmedLine) { + if (!isLastNonEmptyLine) { + trimmedLine += " "; + } + + str += trimmedLine; + } + } + + if (str) args.push((0, _generated$m.stringLiteral)(str)); + } + + Object.defineProperty(buildChildren$1, "__esModule", { + value: true + }); + buildChildren$1.default = buildChildren; + + var _generated$l = generated$3; + + var _cleanJSXElementLiteralChild = _interopRequireDefault$t(cleanJSXElementLiteralChild$1); + + function _interopRequireDefault$t(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function buildChildren(node) { + const elements = []; + + for (let i = 0; i < node.children.length; i++) { + let child = node.children[i]; + + if ((0, _generated$l.isJSXText)(child)) { + (0, _cleanJSXElementLiteralChild.default)(child, elements); + continue; + } + + if ((0, _generated$l.isJSXExpressionContainer)(child)) child = child.expression; + if ((0, _generated$l.isJSXEmptyExpression)(child)) continue; + elements.push(child); + } + + return elements; + } + + var assertNode$1 = {}; + + var isNode$2 = {}; + + Object.defineProperty(isNode$2, "__esModule", { + value: true + }); + isNode$2.default = isNode$1; + + var _definitions$5 = requireDefinitions(); + + function isNode$1(node) { + return !!(node && _definitions$5.VISITOR_KEYS[node.type]); + } + + Object.defineProperty(assertNode$1, "__esModule", { + value: true + }); + assertNode$1.default = assertNode; + + var _isNode = _interopRequireDefault$s(isNode$2); + + function _interopRequireDefault$s(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function assertNode(node) { + if (!(0, _isNode.default)(node)) { + var _node$type; + + const type = (_node$type = node == null ? void 0 : node.type) != null ? _node$type : JSON.stringify(node); + throw new TypeError(`Not a valid node of type "${type}"`); + } + } + + var generated$1 = {}; + + Object.defineProperty(generated$1, "__esModule", { + value: true + }); + generated$1.assertArrayExpression = assertArrayExpression; + generated$1.assertAssignmentExpression = assertAssignmentExpression; + generated$1.assertBinaryExpression = assertBinaryExpression; + generated$1.assertInterpreterDirective = assertInterpreterDirective; + generated$1.assertDirective = assertDirective; + generated$1.assertDirectiveLiteral = assertDirectiveLiteral; + generated$1.assertBlockStatement = assertBlockStatement; + generated$1.assertBreakStatement = assertBreakStatement; + generated$1.assertCallExpression = assertCallExpression; + generated$1.assertCatchClause = assertCatchClause; + generated$1.assertConditionalExpression = assertConditionalExpression; + generated$1.assertContinueStatement = assertContinueStatement; + generated$1.assertDebuggerStatement = assertDebuggerStatement; + generated$1.assertDoWhileStatement = assertDoWhileStatement; + generated$1.assertEmptyStatement = assertEmptyStatement; + generated$1.assertExpressionStatement = assertExpressionStatement; + generated$1.assertFile = assertFile; + generated$1.assertForInStatement = assertForInStatement; + generated$1.assertForStatement = assertForStatement; + generated$1.assertFunctionDeclaration = assertFunctionDeclaration; + generated$1.assertFunctionExpression = assertFunctionExpression; + generated$1.assertIdentifier = assertIdentifier; + generated$1.assertIfStatement = assertIfStatement; + generated$1.assertLabeledStatement = assertLabeledStatement; + generated$1.assertStringLiteral = assertStringLiteral; + generated$1.assertNumericLiteral = assertNumericLiteral; + generated$1.assertNullLiteral = assertNullLiteral; + generated$1.assertBooleanLiteral = assertBooleanLiteral; + generated$1.assertRegExpLiteral = assertRegExpLiteral; + generated$1.assertLogicalExpression = assertLogicalExpression; + generated$1.assertMemberExpression = assertMemberExpression; + generated$1.assertNewExpression = assertNewExpression; + generated$1.assertProgram = assertProgram; + generated$1.assertObjectExpression = assertObjectExpression; + generated$1.assertObjectMethod = assertObjectMethod; + generated$1.assertObjectProperty = assertObjectProperty; + generated$1.assertRestElement = assertRestElement; + generated$1.assertReturnStatement = assertReturnStatement; + generated$1.assertSequenceExpression = assertSequenceExpression; + generated$1.assertParenthesizedExpression = assertParenthesizedExpression; + generated$1.assertSwitchCase = assertSwitchCase; + generated$1.assertSwitchStatement = assertSwitchStatement; + generated$1.assertThisExpression = assertThisExpression; + generated$1.assertThrowStatement = assertThrowStatement; + generated$1.assertTryStatement = assertTryStatement; + generated$1.assertUnaryExpression = assertUnaryExpression; + generated$1.assertUpdateExpression = assertUpdateExpression; + generated$1.assertVariableDeclaration = assertVariableDeclaration; + generated$1.assertVariableDeclarator = assertVariableDeclarator; + generated$1.assertWhileStatement = assertWhileStatement; + generated$1.assertWithStatement = assertWithStatement; + generated$1.assertAssignmentPattern = assertAssignmentPattern; + generated$1.assertArrayPattern = assertArrayPattern; + generated$1.assertArrowFunctionExpression = assertArrowFunctionExpression; + generated$1.assertClassBody = assertClassBody; + generated$1.assertClassExpression = assertClassExpression; + generated$1.assertClassDeclaration = assertClassDeclaration; + generated$1.assertExportAllDeclaration = assertExportAllDeclaration; + generated$1.assertExportDefaultDeclaration = assertExportDefaultDeclaration; + generated$1.assertExportNamedDeclaration = assertExportNamedDeclaration; + generated$1.assertExportSpecifier = assertExportSpecifier; + generated$1.assertForOfStatement = assertForOfStatement; + generated$1.assertImportDeclaration = assertImportDeclaration; + generated$1.assertImportDefaultSpecifier = assertImportDefaultSpecifier; + generated$1.assertImportNamespaceSpecifier = assertImportNamespaceSpecifier; + generated$1.assertImportSpecifier = assertImportSpecifier; + generated$1.assertMetaProperty = assertMetaProperty; + generated$1.assertClassMethod = assertClassMethod; + generated$1.assertObjectPattern = assertObjectPattern; + generated$1.assertSpreadElement = assertSpreadElement; + generated$1.assertSuper = assertSuper; + generated$1.assertTaggedTemplateExpression = assertTaggedTemplateExpression; + generated$1.assertTemplateElement = assertTemplateElement; + generated$1.assertTemplateLiteral = assertTemplateLiteral; + generated$1.assertYieldExpression = assertYieldExpression; + generated$1.assertAnyTypeAnnotation = assertAnyTypeAnnotation; + generated$1.assertArrayTypeAnnotation = assertArrayTypeAnnotation; + generated$1.assertBooleanTypeAnnotation = assertBooleanTypeAnnotation; + generated$1.assertBooleanLiteralTypeAnnotation = assertBooleanLiteralTypeAnnotation; + generated$1.assertNullLiteralTypeAnnotation = assertNullLiteralTypeAnnotation; + generated$1.assertClassImplements = assertClassImplements; + generated$1.assertDeclareClass = assertDeclareClass; + generated$1.assertDeclareFunction = assertDeclareFunction; + generated$1.assertDeclareInterface = assertDeclareInterface; + generated$1.assertDeclareModule = assertDeclareModule; + generated$1.assertDeclareModuleExports = assertDeclareModuleExports; + generated$1.assertDeclareTypeAlias = assertDeclareTypeAlias; + generated$1.assertDeclareOpaqueType = assertDeclareOpaqueType; + generated$1.assertDeclareVariable = assertDeclareVariable; + generated$1.assertDeclareExportDeclaration = assertDeclareExportDeclaration; + generated$1.assertDeclareExportAllDeclaration = assertDeclareExportAllDeclaration; + generated$1.assertDeclaredPredicate = assertDeclaredPredicate; + generated$1.assertExistsTypeAnnotation = assertExistsTypeAnnotation; + generated$1.assertFunctionTypeAnnotation = assertFunctionTypeAnnotation; + generated$1.assertFunctionTypeParam = assertFunctionTypeParam; + generated$1.assertGenericTypeAnnotation = assertGenericTypeAnnotation; + generated$1.assertInferredPredicate = assertInferredPredicate; + generated$1.assertInterfaceExtends = assertInterfaceExtends; + generated$1.assertInterfaceDeclaration = assertInterfaceDeclaration; + generated$1.assertInterfaceTypeAnnotation = assertInterfaceTypeAnnotation; + generated$1.assertIntersectionTypeAnnotation = assertIntersectionTypeAnnotation; + generated$1.assertMixedTypeAnnotation = assertMixedTypeAnnotation; + generated$1.assertEmptyTypeAnnotation = assertEmptyTypeAnnotation; + generated$1.assertNullableTypeAnnotation = assertNullableTypeAnnotation; + generated$1.assertNumberLiteralTypeAnnotation = assertNumberLiteralTypeAnnotation; + generated$1.assertNumberTypeAnnotation = assertNumberTypeAnnotation; + generated$1.assertObjectTypeAnnotation = assertObjectTypeAnnotation; + generated$1.assertObjectTypeInternalSlot = assertObjectTypeInternalSlot; + generated$1.assertObjectTypeCallProperty = assertObjectTypeCallProperty; + generated$1.assertObjectTypeIndexer = assertObjectTypeIndexer; + generated$1.assertObjectTypeProperty = assertObjectTypeProperty; + generated$1.assertObjectTypeSpreadProperty = assertObjectTypeSpreadProperty; + generated$1.assertOpaqueType = assertOpaqueType; + generated$1.assertQualifiedTypeIdentifier = assertQualifiedTypeIdentifier; + generated$1.assertStringLiteralTypeAnnotation = assertStringLiteralTypeAnnotation; + generated$1.assertStringTypeAnnotation = assertStringTypeAnnotation; + generated$1.assertSymbolTypeAnnotation = assertSymbolTypeAnnotation; + generated$1.assertThisTypeAnnotation = assertThisTypeAnnotation; + generated$1.assertTupleTypeAnnotation = assertTupleTypeAnnotation; + generated$1.assertTypeofTypeAnnotation = assertTypeofTypeAnnotation; + generated$1.assertTypeAlias = assertTypeAlias; + generated$1.assertTypeAnnotation = assertTypeAnnotation; + generated$1.assertTypeCastExpression = assertTypeCastExpression; + generated$1.assertTypeParameter = assertTypeParameter; + generated$1.assertTypeParameterDeclaration = assertTypeParameterDeclaration; + generated$1.assertTypeParameterInstantiation = assertTypeParameterInstantiation; + generated$1.assertUnionTypeAnnotation = assertUnionTypeAnnotation; + generated$1.assertVariance = assertVariance; + generated$1.assertVoidTypeAnnotation = assertVoidTypeAnnotation; + generated$1.assertEnumDeclaration = assertEnumDeclaration; + generated$1.assertEnumBooleanBody = assertEnumBooleanBody; + generated$1.assertEnumNumberBody = assertEnumNumberBody; + generated$1.assertEnumStringBody = assertEnumStringBody; + generated$1.assertEnumSymbolBody = assertEnumSymbolBody; + generated$1.assertEnumBooleanMember = assertEnumBooleanMember; + generated$1.assertEnumNumberMember = assertEnumNumberMember; + generated$1.assertEnumStringMember = assertEnumStringMember; + generated$1.assertEnumDefaultedMember = assertEnumDefaultedMember; + generated$1.assertJSXAttribute = assertJSXAttribute; + generated$1.assertJSXClosingElement = assertJSXClosingElement; + generated$1.assertJSXElement = assertJSXElement; + generated$1.assertJSXEmptyExpression = assertJSXEmptyExpression; + generated$1.assertJSXExpressionContainer = assertJSXExpressionContainer; + generated$1.assertJSXSpreadChild = assertJSXSpreadChild; + generated$1.assertJSXIdentifier = assertJSXIdentifier; + generated$1.assertJSXMemberExpression = assertJSXMemberExpression; + generated$1.assertJSXNamespacedName = assertJSXNamespacedName; + generated$1.assertJSXOpeningElement = assertJSXOpeningElement; + generated$1.assertJSXSpreadAttribute = assertJSXSpreadAttribute; + generated$1.assertJSXText = assertJSXText; + generated$1.assertJSXFragment = assertJSXFragment; + generated$1.assertJSXOpeningFragment = assertJSXOpeningFragment; + generated$1.assertJSXClosingFragment = assertJSXClosingFragment; + generated$1.assertNoop = assertNoop; + generated$1.assertPlaceholder = assertPlaceholder; + generated$1.assertV8IntrinsicIdentifier = assertV8IntrinsicIdentifier; + generated$1.assertArgumentPlaceholder = assertArgumentPlaceholder; + generated$1.assertAwaitExpression = assertAwaitExpression; + generated$1.assertBindExpression = assertBindExpression; + generated$1.assertClassProperty = assertClassProperty; + generated$1.assertOptionalMemberExpression = assertOptionalMemberExpression; + generated$1.assertPipelineTopicExpression = assertPipelineTopicExpression; + generated$1.assertPipelineBareFunction = assertPipelineBareFunction; + generated$1.assertPipelinePrimaryTopicReference = assertPipelinePrimaryTopicReference; + generated$1.assertOptionalCallExpression = assertOptionalCallExpression; + generated$1.assertClassPrivateProperty = assertClassPrivateProperty; + generated$1.assertClassPrivateMethod = assertClassPrivateMethod; + generated$1.assertImport = assertImport; + generated$1.assertImportAttribute = assertImportAttribute; + generated$1.assertDecorator = assertDecorator; + generated$1.assertDoExpression = assertDoExpression; + generated$1.assertExportDefaultSpecifier = assertExportDefaultSpecifier; + generated$1.assertExportNamespaceSpecifier = assertExportNamespaceSpecifier; + generated$1.assertPrivateName = assertPrivateName; + generated$1.assertBigIntLiteral = assertBigIntLiteral; + generated$1.assertRecordExpression = assertRecordExpression; + generated$1.assertTupleExpression = assertTupleExpression; + generated$1.assertTSParameterProperty = assertTSParameterProperty; + generated$1.assertTSDeclareFunction = assertTSDeclareFunction; + generated$1.assertTSDeclareMethod = assertTSDeclareMethod; + generated$1.assertTSQualifiedName = assertTSQualifiedName; + generated$1.assertTSCallSignatureDeclaration = assertTSCallSignatureDeclaration; + generated$1.assertTSConstructSignatureDeclaration = assertTSConstructSignatureDeclaration; + generated$1.assertTSPropertySignature = assertTSPropertySignature; + generated$1.assertTSMethodSignature = assertTSMethodSignature; + generated$1.assertTSIndexSignature = assertTSIndexSignature; + generated$1.assertTSAnyKeyword = assertTSAnyKeyword; + generated$1.assertTSBooleanKeyword = assertTSBooleanKeyword; + generated$1.assertTSBigIntKeyword = assertTSBigIntKeyword; + generated$1.assertTSNeverKeyword = assertTSNeverKeyword; + generated$1.assertTSNullKeyword = assertTSNullKeyword; + generated$1.assertTSNumberKeyword = assertTSNumberKeyword; + generated$1.assertTSObjectKeyword = assertTSObjectKeyword; + generated$1.assertTSStringKeyword = assertTSStringKeyword; + generated$1.assertTSSymbolKeyword = assertTSSymbolKeyword; + generated$1.assertTSUndefinedKeyword = assertTSUndefinedKeyword; + generated$1.assertTSUnknownKeyword = assertTSUnknownKeyword; + generated$1.assertTSVoidKeyword = assertTSVoidKeyword; + generated$1.assertTSThisType = assertTSThisType; + generated$1.assertTSFunctionType = assertTSFunctionType; + generated$1.assertTSConstructorType = assertTSConstructorType; + generated$1.assertTSTypeReference = assertTSTypeReference; + generated$1.assertTSTypePredicate = assertTSTypePredicate; + generated$1.assertTSTypeQuery = assertTSTypeQuery; + generated$1.assertTSTypeLiteral = assertTSTypeLiteral; + generated$1.assertTSArrayType = assertTSArrayType; + generated$1.assertTSTupleType = assertTSTupleType; + generated$1.assertTSOptionalType = assertTSOptionalType; + generated$1.assertTSRestType = assertTSRestType; + generated$1.assertTSUnionType = assertTSUnionType; + generated$1.assertTSIntersectionType = assertTSIntersectionType; + generated$1.assertTSConditionalType = assertTSConditionalType; + generated$1.assertTSInferType = assertTSInferType; + generated$1.assertTSParenthesizedType = assertTSParenthesizedType; + generated$1.assertTSTypeOperator = assertTSTypeOperator; + generated$1.assertTSIndexedAccessType = assertTSIndexedAccessType; + generated$1.assertTSMappedType = assertTSMappedType; + generated$1.assertTSLiteralType = assertTSLiteralType; + generated$1.assertTSExpressionWithTypeArguments = assertTSExpressionWithTypeArguments; + generated$1.assertTSInterfaceDeclaration = assertTSInterfaceDeclaration; + generated$1.assertTSInterfaceBody = assertTSInterfaceBody; + generated$1.assertTSTypeAliasDeclaration = assertTSTypeAliasDeclaration; + generated$1.assertTSAsExpression = assertTSAsExpression; + generated$1.assertTSTypeAssertion = assertTSTypeAssertion; + generated$1.assertTSEnumDeclaration = assertTSEnumDeclaration; + generated$1.assertTSEnumMember = assertTSEnumMember; + generated$1.assertTSModuleDeclaration = assertTSModuleDeclaration; + generated$1.assertTSModuleBlock = assertTSModuleBlock; + generated$1.assertTSImportType = assertTSImportType; + generated$1.assertTSImportEqualsDeclaration = assertTSImportEqualsDeclaration; + generated$1.assertTSExternalModuleReference = assertTSExternalModuleReference; + generated$1.assertTSNonNullExpression = assertTSNonNullExpression; + generated$1.assertTSExportAssignment = assertTSExportAssignment; + generated$1.assertTSNamespaceExportDeclaration = assertTSNamespaceExportDeclaration; + generated$1.assertTSTypeAnnotation = assertTSTypeAnnotation; + generated$1.assertTSTypeParameterInstantiation = assertTSTypeParameterInstantiation; + generated$1.assertTSTypeParameterDeclaration = assertTSTypeParameterDeclaration; + generated$1.assertTSTypeParameter = assertTSTypeParameter; + generated$1.assertExpression = assertExpression; + generated$1.assertBinary = assertBinary; + generated$1.assertScopable = assertScopable; + generated$1.assertBlockParent = assertBlockParent; + generated$1.assertBlock = assertBlock; + generated$1.assertStatement = assertStatement; + generated$1.assertTerminatorless = assertTerminatorless; + generated$1.assertCompletionStatement = assertCompletionStatement; + generated$1.assertConditional = assertConditional; + generated$1.assertLoop = assertLoop; + generated$1.assertWhile = assertWhile; + generated$1.assertExpressionWrapper = assertExpressionWrapper; + generated$1.assertFor = assertFor; + generated$1.assertForXStatement = assertForXStatement; + generated$1.assertFunction = assertFunction; + generated$1.assertFunctionParent = assertFunctionParent; + generated$1.assertPureish = assertPureish; + generated$1.assertDeclaration = assertDeclaration; + generated$1.assertPatternLike = assertPatternLike; + generated$1.assertLVal = assertLVal; + generated$1.assertTSEntityName = assertTSEntityName; + generated$1.assertLiteral = assertLiteral; + generated$1.assertImmutable = assertImmutable; + generated$1.assertUserWhitespacable = assertUserWhitespacable; + generated$1.assertMethod = assertMethod; + generated$1.assertObjectMember = assertObjectMember; + generated$1.assertProperty = assertProperty; + generated$1.assertUnaryLike = assertUnaryLike; + generated$1.assertPattern = assertPattern; + generated$1.assertClass = assertClass; + generated$1.assertModuleDeclaration = assertModuleDeclaration; + generated$1.assertExportDeclaration = assertExportDeclaration; + generated$1.assertModuleSpecifier = assertModuleSpecifier; + generated$1.assertFlow = assertFlow; + generated$1.assertFlowType = assertFlowType; + generated$1.assertFlowBaseAnnotation = assertFlowBaseAnnotation; + generated$1.assertFlowDeclaration = assertFlowDeclaration; + generated$1.assertFlowPredicate = assertFlowPredicate; + generated$1.assertEnumBody = assertEnumBody; + generated$1.assertEnumMember = assertEnumMember; + generated$1.assertJSX = assertJSX; + generated$1.assertPrivate = assertPrivate; + generated$1.assertTSTypeElement = assertTSTypeElement; + generated$1.assertTSType = assertTSType; + generated$1.assertTSBaseType = assertTSBaseType; + generated$1.assertNumberLiteral = assertNumberLiteral; + generated$1.assertRegexLiteral = assertRegexLiteral; + generated$1.assertRestProperty = assertRestProperty; + generated$1.assertSpreadProperty = assertSpreadProperty; + + var _is = _interopRequireDefault$r(requireIs()); + + function _interopRequireDefault$r(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function assert$2(type, node, opts) { + if (!(0, _is.default)(type, node, opts)) { + throw new Error(`Expected type "${type}" with option ${JSON.stringify(opts)}, ` + `but instead got "${node.type}".`); + } + } + + function assertArrayExpression(node, opts = {}) { + assert$2("ArrayExpression", node, opts); + } + + function assertAssignmentExpression(node, opts = {}) { + assert$2("AssignmentExpression", node, opts); + } + + function assertBinaryExpression(node, opts = {}) { + assert$2("BinaryExpression", node, opts); + } + + function assertInterpreterDirective(node, opts = {}) { + assert$2("InterpreterDirective", node, opts); + } + + function assertDirective(node, opts = {}) { + assert$2("Directive", node, opts); + } + + function assertDirectiveLiteral(node, opts = {}) { + assert$2("DirectiveLiteral", node, opts); + } + + function assertBlockStatement(node, opts = {}) { + assert$2("BlockStatement", node, opts); + } + + function assertBreakStatement(node, opts = {}) { + assert$2("BreakStatement", node, opts); + } + + function assertCallExpression(node, opts = {}) { + assert$2("CallExpression", node, opts); + } + + function assertCatchClause(node, opts = {}) { + assert$2("CatchClause", node, opts); + } + + function assertConditionalExpression(node, opts = {}) { + assert$2("ConditionalExpression", node, opts); + } + + function assertContinueStatement(node, opts = {}) { + assert$2("ContinueStatement", node, opts); + } + + function assertDebuggerStatement(node, opts = {}) { + assert$2("DebuggerStatement", node, opts); + } + + function assertDoWhileStatement(node, opts = {}) { + assert$2("DoWhileStatement", node, opts); + } + + function assertEmptyStatement(node, opts = {}) { + assert$2("EmptyStatement", node, opts); + } + + function assertExpressionStatement(node, opts = {}) { + assert$2("ExpressionStatement", node, opts); + } + + function assertFile(node, opts = {}) { + assert$2("File", node, opts); + } + + function assertForInStatement(node, opts = {}) { + assert$2("ForInStatement", node, opts); + } + + function assertForStatement(node, opts = {}) { + assert$2("ForStatement", node, opts); + } + + function assertFunctionDeclaration(node, opts = {}) { + assert$2("FunctionDeclaration", node, opts); + } + + function assertFunctionExpression(node, opts = {}) { + assert$2("FunctionExpression", node, opts); + } + + function assertIdentifier(node, opts = {}) { + assert$2("Identifier", node, opts); + } + + function assertIfStatement(node, opts = {}) { + assert$2("IfStatement", node, opts); + } + + function assertLabeledStatement(node, opts = {}) { + assert$2("LabeledStatement", node, opts); + } + + function assertStringLiteral(node, opts = {}) { + assert$2("StringLiteral", node, opts); + } + + function assertNumericLiteral(node, opts = {}) { + assert$2("NumericLiteral", node, opts); + } + + function assertNullLiteral(node, opts = {}) { + assert$2("NullLiteral", node, opts); + } + + function assertBooleanLiteral(node, opts = {}) { + assert$2("BooleanLiteral", node, opts); + } + + function assertRegExpLiteral(node, opts = {}) { + assert$2("RegExpLiteral", node, opts); + } + + function assertLogicalExpression(node, opts = {}) { + assert$2("LogicalExpression", node, opts); + } + + function assertMemberExpression(node, opts = {}) { + assert$2("MemberExpression", node, opts); + } + + function assertNewExpression(node, opts = {}) { + assert$2("NewExpression", node, opts); + } + + function assertProgram(node, opts = {}) { + assert$2("Program", node, opts); + } + + function assertObjectExpression(node, opts = {}) { + assert$2("ObjectExpression", node, opts); + } + + function assertObjectMethod(node, opts = {}) { + assert$2("ObjectMethod", node, opts); + } + + function assertObjectProperty(node, opts = {}) { + assert$2("ObjectProperty", node, opts); + } + + function assertRestElement(node, opts = {}) { + assert$2("RestElement", node, opts); + } + + function assertReturnStatement(node, opts = {}) { + assert$2("ReturnStatement", node, opts); + } + + function assertSequenceExpression(node, opts = {}) { + assert$2("SequenceExpression", node, opts); + } + + function assertParenthesizedExpression(node, opts = {}) { + assert$2("ParenthesizedExpression", node, opts); + } + + function assertSwitchCase(node, opts = {}) { + assert$2("SwitchCase", node, opts); + } + + function assertSwitchStatement(node, opts = {}) { + assert$2("SwitchStatement", node, opts); + } + + function assertThisExpression(node, opts = {}) { + assert$2("ThisExpression", node, opts); + } + + function assertThrowStatement(node, opts = {}) { + assert$2("ThrowStatement", node, opts); + } + + function assertTryStatement(node, opts = {}) { + assert$2("TryStatement", node, opts); + } + + function assertUnaryExpression(node, opts = {}) { + assert$2("UnaryExpression", node, opts); + } + + function assertUpdateExpression(node, opts = {}) { + assert$2("UpdateExpression", node, opts); + } + + function assertVariableDeclaration(node, opts = {}) { + assert$2("VariableDeclaration", node, opts); + } + + function assertVariableDeclarator(node, opts = {}) { + assert$2("VariableDeclarator", node, opts); + } + + function assertWhileStatement(node, opts = {}) { + assert$2("WhileStatement", node, opts); + } + + function assertWithStatement(node, opts = {}) { + assert$2("WithStatement", node, opts); + } + + function assertAssignmentPattern(node, opts = {}) { + assert$2("AssignmentPattern", node, opts); + } + + function assertArrayPattern(node, opts = {}) { + assert$2("ArrayPattern", node, opts); + } + + function assertArrowFunctionExpression(node, opts = {}) { + assert$2("ArrowFunctionExpression", node, opts); + } + + function assertClassBody(node, opts = {}) { + assert$2("ClassBody", node, opts); + } + + function assertClassExpression(node, opts = {}) { + assert$2("ClassExpression", node, opts); + } + + function assertClassDeclaration(node, opts = {}) { + assert$2("ClassDeclaration", node, opts); + } + + function assertExportAllDeclaration(node, opts = {}) { + assert$2("ExportAllDeclaration", node, opts); + } + + function assertExportDefaultDeclaration(node, opts = {}) { + assert$2("ExportDefaultDeclaration", node, opts); + } + + function assertExportNamedDeclaration(node, opts = {}) { + assert$2("ExportNamedDeclaration", node, opts); + } + + function assertExportSpecifier(node, opts = {}) { + assert$2("ExportSpecifier", node, opts); + } + + function assertForOfStatement(node, opts = {}) { + assert$2("ForOfStatement", node, opts); + } + + function assertImportDeclaration(node, opts = {}) { + assert$2("ImportDeclaration", node, opts); + } + + function assertImportDefaultSpecifier(node, opts = {}) { + assert$2("ImportDefaultSpecifier", node, opts); + } + + function assertImportNamespaceSpecifier(node, opts = {}) { + assert$2("ImportNamespaceSpecifier", node, opts); + } + + function assertImportSpecifier(node, opts = {}) { + assert$2("ImportSpecifier", node, opts); + } + + function assertMetaProperty(node, opts = {}) { + assert$2("MetaProperty", node, opts); + } + + function assertClassMethod(node, opts = {}) { + assert$2("ClassMethod", node, opts); + } + + function assertObjectPattern(node, opts = {}) { + assert$2("ObjectPattern", node, opts); + } + + function assertSpreadElement(node, opts = {}) { + assert$2("SpreadElement", node, opts); + } + + function assertSuper(node, opts = {}) { + assert$2("Super", node, opts); + } + + function assertTaggedTemplateExpression(node, opts = {}) { + assert$2("TaggedTemplateExpression", node, opts); + } + + function assertTemplateElement(node, opts = {}) { + assert$2("TemplateElement", node, opts); + } + + function assertTemplateLiteral(node, opts = {}) { + assert$2("TemplateLiteral", node, opts); + } + + function assertYieldExpression(node, opts = {}) { + assert$2("YieldExpression", node, opts); + } + + function assertAnyTypeAnnotation(node, opts = {}) { + assert$2("AnyTypeAnnotation", node, opts); + } + + function assertArrayTypeAnnotation(node, opts = {}) { + assert$2("ArrayTypeAnnotation", node, opts); + } + + function assertBooleanTypeAnnotation(node, opts = {}) { + assert$2("BooleanTypeAnnotation", node, opts); + } + + function assertBooleanLiteralTypeAnnotation(node, opts = {}) { + assert$2("BooleanLiteralTypeAnnotation", node, opts); + } + + function assertNullLiteralTypeAnnotation(node, opts = {}) { + assert$2("NullLiteralTypeAnnotation", node, opts); + } + + function assertClassImplements(node, opts = {}) { + assert$2("ClassImplements", node, opts); + } + + function assertDeclareClass(node, opts = {}) { + assert$2("DeclareClass", node, opts); + } + + function assertDeclareFunction(node, opts = {}) { + assert$2("DeclareFunction", node, opts); + } + + function assertDeclareInterface(node, opts = {}) { + assert$2("DeclareInterface", node, opts); + } + + function assertDeclareModule(node, opts = {}) { + assert$2("DeclareModule", node, opts); + } + + function assertDeclareModuleExports(node, opts = {}) { + assert$2("DeclareModuleExports", node, opts); + } + + function assertDeclareTypeAlias(node, opts = {}) { + assert$2("DeclareTypeAlias", node, opts); + } + + function assertDeclareOpaqueType(node, opts = {}) { + assert$2("DeclareOpaqueType", node, opts); + } + + function assertDeclareVariable(node, opts = {}) { + assert$2("DeclareVariable", node, opts); + } + + function assertDeclareExportDeclaration(node, opts = {}) { + assert$2("DeclareExportDeclaration", node, opts); + } + + function assertDeclareExportAllDeclaration(node, opts = {}) { + assert$2("DeclareExportAllDeclaration", node, opts); + } + + function assertDeclaredPredicate(node, opts = {}) { + assert$2("DeclaredPredicate", node, opts); + } + + function assertExistsTypeAnnotation(node, opts = {}) { + assert$2("ExistsTypeAnnotation", node, opts); + } + + function assertFunctionTypeAnnotation(node, opts = {}) { + assert$2("FunctionTypeAnnotation", node, opts); + } + + function assertFunctionTypeParam(node, opts = {}) { + assert$2("FunctionTypeParam", node, opts); + } + + function assertGenericTypeAnnotation(node, opts = {}) { + assert$2("GenericTypeAnnotation", node, opts); + } + + function assertInferredPredicate(node, opts = {}) { + assert$2("InferredPredicate", node, opts); + } + + function assertInterfaceExtends(node, opts = {}) { + assert$2("InterfaceExtends", node, opts); + } + + function assertInterfaceDeclaration(node, opts = {}) { + assert$2("InterfaceDeclaration", node, opts); + } + + function assertInterfaceTypeAnnotation(node, opts = {}) { + assert$2("InterfaceTypeAnnotation", node, opts); + } + + function assertIntersectionTypeAnnotation(node, opts = {}) { + assert$2("IntersectionTypeAnnotation", node, opts); + } + + function assertMixedTypeAnnotation(node, opts = {}) { + assert$2("MixedTypeAnnotation", node, opts); + } + + function assertEmptyTypeAnnotation(node, opts = {}) { + assert$2("EmptyTypeAnnotation", node, opts); + } + + function assertNullableTypeAnnotation(node, opts = {}) { + assert$2("NullableTypeAnnotation", node, opts); + } + + function assertNumberLiteralTypeAnnotation(node, opts = {}) { + assert$2("NumberLiteralTypeAnnotation", node, opts); + } + + function assertNumberTypeAnnotation(node, opts = {}) { + assert$2("NumberTypeAnnotation", node, opts); + } + + function assertObjectTypeAnnotation(node, opts = {}) { + assert$2("ObjectTypeAnnotation", node, opts); + } + + function assertObjectTypeInternalSlot(node, opts = {}) { + assert$2("ObjectTypeInternalSlot", node, opts); + } + + function assertObjectTypeCallProperty(node, opts = {}) { + assert$2("ObjectTypeCallProperty", node, opts); + } + + function assertObjectTypeIndexer(node, opts = {}) { + assert$2("ObjectTypeIndexer", node, opts); + } + + function assertObjectTypeProperty(node, opts = {}) { + assert$2("ObjectTypeProperty", node, opts); + } + + function assertObjectTypeSpreadProperty(node, opts = {}) { + assert$2("ObjectTypeSpreadProperty", node, opts); + } + + function assertOpaqueType(node, opts = {}) { + assert$2("OpaqueType", node, opts); + } + + function assertQualifiedTypeIdentifier(node, opts = {}) { + assert$2("QualifiedTypeIdentifier", node, opts); + } + + function assertStringLiteralTypeAnnotation(node, opts = {}) { + assert$2("StringLiteralTypeAnnotation", node, opts); + } + + function assertStringTypeAnnotation(node, opts = {}) { + assert$2("StringTypeAnnotation", node, opts); + } + + function assertSymbolTypeAnnotation(node, opts = {}) { + assert$2("SymbolTypeAnnotation", node, opts); + } + + function assertThisTypeAnnotation(node, opts = {}) { + assert$2("ThisTypeAnnotation", node, opts); + } + + function assertTupleTypeAnnotation(node, opts = {}) { + assert$2("TupleTypeAnnotation", node, opts); + } + + function assertTypeofTypeAnnotation(node, opts = {}) { + assert$2("TypeofTypeAnnotation", node, opts); + } + + function assertTypeAlias(node, opts = {}) { + assert$2("TypeAlias", node, opts); + } + + function assertTypeAnnotation(node, opts = {}) { + assert$2("TypeAnnotation", node, opts); + } + + function assertTypeCastExpression(node, opts = {}) { + assert$2("TypeCastExpression", node, opts); + } + + function assertTypeParameter(node, opts = {}) { + assert$2("TypeParameter", node, opts); + } + + function assertTypeParameterDeclaration(node, opts = {}) { + assert$2("TypeParameterDeclaration", node, opts); + } + + function assertTypeParameterInstantiation(node, opts = {}) { + assert$2("TypeParameterInstantiation", node, opts); + } + + function assertUnionTypeAnnotation(node, opts = {}) { + assert$2("UnionTypeAnnotation", node, opts); + } + + function assertVariance(node, opts = {}) { + assert$2("Variance", node, opts); + } + + function assertVoidTypeAnnotation(node, opts = {}) { + assert$2("VoidTypeAnnotation", node, opts); + } + + function assertEnumDeclaration(node, opts = {}) { + assert$2("EnumDeclaration", node, opts); + } + + function assertEnumBooleanBody(node, opts = {}) { + assert$2("EnumBooleanBody", node, opts); + } + + function assertEnumNumberBody(node, opts = {}) { + assert$2("EnumNumberBody", node, opts); + } + + function assertEnumStringBody(node, opts = {}) { + assert$2("EnumStringBody", node, opts); + } + + function assertEnumSymbolBody(node, opts = {}) { + assert$2("EnumSymbolBody", node, opts); + } + + function assertEnumBooleanMember(node, opts = {}) { + assert$2("EnumBooleanMember", node, opts); + } + + function assertEnumNumberMember(node, opts = {}) { + assert$2("EnumNumberMember", node, opts); + } + + function assertEnumStringMember(node, opts = {}) { + assert$2("EnumStringMember", node, opts); + } + + function assertEnumDefaultedMember(node, opts = {}) { + assert$2("EnumDefaultedMember", node, opts); + } + + function assertJSXAttribute(node, opts = {}) { + assert$2("JSXAttribute", node, opts); + } + + function assertJSXClosingElement(node, opts = {}) { + assert$2("JSXClosingElement", node, opts); + } + + function assertJSXElement(node, opts = {}) { + assert$2("JSXElement", node, opts); + } + + function assertJSXEmptyExpression(node, opts = {}) { + assert$2("JSXEmptyExpression", node, opts); + } + + function assertJSXExpressionContainer(node, opts = {}) { + assert$2("JSXExpressionContainer", node, opts); + } + + function assertJSXSpreadChild(node, opts = {}) { + assert$2("JSXSpreadChild", node, opts); + } + + function assertJSXIdentifier(node, opts = {}) { + assert$2("JSXIdentifier", node, opts); + } + + function assertJSXMemberExpression(node, opts = {}) { + assert$2("JSXMemberExpression", node, opts); + } + + function assertJSXNamespacedName(node, opts = {}) { + assert$2("JSXNamespacedName", node, opts); + } + + function assertJSXOpeningElement(node, opts = {}) { + assert$2("JSXOpeningElement", node, opts); + } + + function assertJSXSpreadAttribute(node, opts = {}) { + assert$2("JSXSpreadAttribute", node, opts); + } + + function assertJSXText(node, opts = {}) { + assert$2("JSXText", node, opts); + } + + function assertJSXFragment(node, opts = {}) { + assert$2("JSXFragment", node, opts); + } + + function assertJSXOpeningFragment(node, opts = {}) { + assert$2("JSXOpeningFragment", node, opts); + } + + function assertJSXClosingFragment(node, opts = {}) { + assert$2("JSXClosingFragment", node, opts); + } + + function assertNoop(node, opts = {}) { + assert$2("Noop", node, opts); + } + + function assertPlaceholder(node, opts = {}) { + assert$2("Placeholder", node, opts); + } + + function assertV8IntrinsicIdentifier(node, opts = {}) { + assert$2("V8IntrinsicIdentifier", node, opts); + } + + function assertArgumentPlaceholder(node, opts = {}) { + assert$2("ArgumentPlaceholder", node, opts); + } + + function assertAwaitExpression(node, opts = {}) { + assert$2("AwaitExpression", node, opts); + } + + function assertBindExpression(node, opts = {}) { + assert$2("BindExpression", node, opts); + } + + function assertClassProperty(node, opts = {}) { + assert$2("ClassProperty", node, opts); + } + + function assertOptionalMemberExpression(node, opts = {}) { + assert$2("OptionalMemberExpression", node, opts); + } + + function assertPipelineTopicExpression(node, opts = {}) { + assert$2("PipelineTopicExpression", node, opts); + } + + function assertPipelineBareFunction(node, opts = {}) { + assert$2("PipelineBareFunction", node, opts); + } + + function assertPipelinePrimaryTopicReference(node, opts = {}) { + assert$2("PipelinePrimaryTopicReference", node, opts); + } + + function assertOptionalCallExpression(node, opts = {}) { + assert$2("OptionalCallExpression", node, opts); + } + + function assertClassPrivateProperty(node, opts = {}) { + assert$2("ClassPrivateProperty", node, opts); + } + + function assertClassPrivateMethod(node, opts = {}) { + assert$2("ClassPrivateMethod", node, opts); + } + + function assertImport(node, opts = {}) { + assert$2("Import", node, opts); + } + + function assertImportAttribute(node, opts = {}) { + assert$2("ImportAttribute", node, opts); + } + + function assertDecorator(node, opts = {}) { + assert$2("Decorator", node, opts); + } + + function assertDoExpression(node, opts = {}) { + assert$2("DoExpression", node, opts); + } + + function assertExportDefaultSpecifier(node, opts = {}) { + assert$2("ExportDefaultSpecifier", node, opts); + } + + function assertExportNamespaceSpecifier(node, opts = {}) { + assert$2("ExportNamespaceSpecifier", node, opts); + } + + function assertPrivateName(node, opts = {}) { + assert$2("PrivateName", node, opts); + } + + function assertBigIntLiteral(node, opts = {}) { + assert$2("BigIntLiteral", node, opts); + } + + function assertRecordExpression(node, opts = {}) { + assert$2("RecordExpression", node, opts); + } + + function assertTupleExpression(node, opts = {}) { + assert$2("TupleExpression", node, opts); + } + + function assertTSParameterProperty(node, opts = {}) { + assert$2("TSParameterProperty", node, opts); + } + + function assertTSDeclareFunction(node, opts = {}) { + assert$2("TSDeclareFunction", node, opts); + } + + function assertTSDeclareMethod(node, opts = {}) { + assert$2("TSDeclareMethod", node, opts); + } + + function assertTSQualifiedName(node, opts = {}) { + assert$2("TSQualifiedName", node, opts); + } + + function assertTSCallSignatureDeclaration(node, opts = {}) { + assert$2("TSCallSignatureDeclaration", node, opts); + } + + function assertTSConstructSignatureDeclaration(node, opts = {}) { + assert$2("TSConstructSignatureDeclaration", node, opts); + } + + function assertTSPropertySignature(node, opts = {}) { + assert$2("TSPropertySignature", node, opts); + } + + function assertTSMethodSignature(node, opts = {}) { + assert$2("TSMethodSignature", node, opts); + } + + function assertTSIndexSignature(node, opts = {}) { + assert$2("TSIndexSignature", node, opts); + } + + function assertTSAnyKeyword(node, opts = {}) { + assert$2("TSAnyKeyword", node, opts); + } + + function assertTSBooleanKeyword(node, opts = {}) { + assert$2("TSBooleanKeyword", node, opts); + } + + function assertTSBigIntKeyword(node, opts = {}) { + assert$2("TSBigIntKeyword", node, opts); + } + + function assertTSNeverKeyword(node, opts = {}) { + assert$2("TSNeverKeyword", node, opts); + } + + function assertTSNullKeyword(node, opts = {}) { + assert$2("TSNullKeyword", node, opts); + } + + function assertTSNumberKeyword(node, opts = {}) { + assert$2("TSNumberKeyword", node, opts); + } + + function assertTSObjectKeyword(node, opts = {}) { + assert$2("TSObjectKeyword", node, opts); + } + + function assertTSStringKeyword(node, opts = {}) { + assert$2("TSStringKeyword", node, opts); + } + + function assertTSSymbolKeyword(node, opts = {}) { + assert$2("TSSymbolKeyword", node, opts); + } + + function assertTSUndefinedKeyword(node, opts = {}) { + assert$2("TSUndefinedKeyword", node, opts); + } + + function assertTSUnknownKeyword(node, opts = {}) { + assert$2("TSUnknownKeyword", node, opts); + } + + function assertTSVoidKeyword(node, opts = {}) { + assert$2("TSVoidKeyword", node, opts); + } + + function assertTSThisType(node, opts = {}) { + assert$2("TSThisType", node, opts); + } + + function assertTSFunctionType(node, opts = {}) { + assert$2("TSFunctionType", node, opts); + } + + function assertTSConstructorType(node, opts = {}) { + assert$2("TSConstructorType", node, opts); + } + + function assertTSTypeReference(node, opts = {}) { + assert$2("TSTypeReference", node, opts); + } + + function assertTSTypePredicate(node, opts = {}) { + assert$2("TSTypePredicate", node, opts); + } + + function assertTSTypeQuery(node, opts = {}) { + assert$2("TSTypeQuery", node, opts); + } + + function assertTSTypeLiteral(node, opts = {}) { + assert$2("TSTypeLiteral", node, opts); + } + + function assertTSArrayType(node, opts = {}) { + assert$2("TSArrayType", node, opts); + } + + function assertTSTupleType(node, opts = {}) { + assert$2("TSTupleType", node, opts); + } + + function assertTSOptionalType(node, opts = {}) { + assert$2("TSOptionalType", node, opts); + } + + function assertTSRestType(node, opts = {}) { + assert$2("TSRestType", node, opts); + } + + function assertTSUnionType(node, opts = {}) { + assert$2("TSUnionType", node, opts); + } + + function assertTSIntersectionType(node, opts = {}) { + assert$2("TSIntersectionType", node, opts); + } + + function assertTSConditionalType(node, opts = {}) { + assert$2("TSConditionalType", node, opts); + } + + function assertTSInferType(node, opts = {}) { + assert$2("TSInferType", node, opts); + } + + function assertTSParenthesizedType(node, opts = {}) { + assert$2("TSParenthesizedType", node, opts); + } + + function assertTSTypeOperator(node, opts = {}) { + assert$2("TSTypeOperator", node, opts); + } + + function assertTSIndexedAccessType(node, opts = {}) { + assert$2("TSIndexedAccessType", node, opts); + } + + function assertTSMappedType(node, opts = {}) { + assert$2("TSMappedType", node, opts); + } + + function assertTSLiteralType(node, opts = {}) { + assert$2("TSLiteralType", node, opts); + } + + function assertTSExpressionWithTypeArguments(node, opts = {}) { + assert$2("TSExpressionWithTypeArguments", node, opts); + } + + function assertTSInterfaceDeclaration(node, opts = {}) { + assert$2("TSInterfaceDeclaration", node, opts); + } + + function assertTSInterfaceBody(node, opts = {}) { + assert$2("TSInterfaceBody", node, opts); + } + + function assertTSTypeAliasDeclaration(node, opts = {}) { + assert$2("TSTypeAliasDeclaration", node, opts); + } + + function assertTSAsExpression(node, opts = {}) { + assert$2("TSAsExpression", node, opts); + } + + function assertTSTypeAssertion(node, opts = {}) { + assert$2("TSTypeAssertion", node, opts); + } + + function assertTSEnumDeclaration(node, opts = {}) { + assert$2("TSEnumDeclaration", node, opts); + } + + function assertTSEnumMember(node, opts = {}) { + assert$2("TSEnumMember", node, opts); + } + + function assertTSModuleDeclaration(node, opts = {}) { + assert$2("TSModuleDeclaration", node, opts); + } + + function assertTSModuleBlock(node, opts = {}) { + assert$2("TSModuleBlock", node, opts); + } + + function assertTSImportType(node, opts = {}) { + assert$2("TSImportType", node, opts); + } + + function assertTSImportEqualsDeclaration(node, opts = {}) { + assert$2("TSImportEqualsDeclaration", node, opts); + } + + function assertTSExternalModuleReference(node, opts = {}) { + assert$2("TSExternalModuleReference", node, opts); + } + + function assertTSNonNullExpression(node, opts = {}) { + assert$2("TSNonNullExpression", node, opts); + } + + function assertTSExportAssignment(node, opts = {}) { + assert$2("TSExportAssignment", node, opts); + } + + function assertTSNamespaceExportDeclaration(node, opts = {}) { + assert$2("TSNamespaceExportDeclaration", node, opts); + } + + function assertTSTypeAnnotation(node, opts = {}) { + assert$2("TSTypeAnnotation", node, opts); + } + + function assertTSTypeParameterInstantiation(node, opts = {}) { + assert$2("TSTypeParameterInstantiation", node, opts); + } + + function assertTSTypeParameterDeclaration(node, opts = {}) { + assert$2("TSTypeParameterDeclaration", node, opts); + } + + function assertTSTypeParameter(node, opts = {}) { + assert$2("TSTypeParameter", node, opts); + } + + function assertExpression(node, opts = {}) { + assert$2("Expression", node, opts); + } + + function assertBinary(node, opts = {}) { + assert$2("Binary", node, opts); + } + + function assertScopable(node, opts = {}) { + assert$2("Scopable", node, opts); + } + + function assertBlockParent(node, opts = {}) { + assert$2("BlockParent", node, opts); + } + + function assertBlock(node, opts = {}) { + assert$2("Block", node, opts); + } + + function assertStatement(node, opts = {}) { + assert$2("Statement", node, opts); + } + + function assertTerminatorless(node, opts = {}) { + assert$2("Terminatorless", node, opts); + } + + function assertCompletionStatement(node, opts = {}) { + assert$2("CompletionStatement", node, opts); + } + + function assertConditional(node, opts = {}) { + assert$2("Conditional", node, opts); + } + + function assertLoop(node, opts = {}) { + assert$2("Loop", node, opts); + } + + function assertWhile(node, opts = {}) { + assert$2("While", node, opts); + } + + function assertExpressionWrapper(node, opts = {}) { + assert$2("ExpressionWrapper", node, opts); + } + + function assertFor(node, opts = {}) { + assert$2("For", node, opts); + } + + function assertForXStatement(node, opts = {}) { + assert$2("ForXStatement", node, opts); + } + + function assertFunction(node, opts = {}) { + assert$2("Function", node, opts); + } + + function assertFunctionParent(node, opts = {}) { + assert$2("FunctionParent", node, opts); + } + + function assertPureish(node, opts = {}) { + assert$2("Pureish", node, opts); + } + + function assertDeclaration(node, opts = {}) { + assert$2("Declaration", node, opts); + } + + function assertPatternLike(node, opts = {}) { + assert$2("PatternLike", node, opts); + } + + function assertLVal(node, opts = {}) { + assert$2("LVal", node, opts); + } + + function assertTSEntityName(node, opts = {}) { + assert$2("TSEntityName", node, opts); + } + + function assertLiteral(node, opts = {}) { + assert$2("Literal", node, opts); + } + + function assertImmutable(node, opts = {}) { + assert$2("Immutable", node, opts); + } + + function assertUserWhitespacable(node, opts = {}) { + assert$2("UserWhitespacable", node, opts); + } + + function assertMethod(node, opts = {}) { + assert$2("Method", node, opts); + } + + function assertObjectMember(node, opts = {}) { + assert$2("ObjectMember", node, opts); + } + + function assertProperty(node, opts = {}) { + assert$2("Property", node, opts); + } + + function assertUnaryLike(node, opts = {}) { + assert$2("UnaryLike", node, opts); + } + + function assertPattern(node, opts = {}) { + assert$2("Pattern", node, opts); + } + + function assertClass(node, opts = {}) { + assert$2("Class", node, opts); + } + + function assertModuleDeclaration(node, opts = {}) { + assert$2("ModuleDeclaration", node, opts); + } + + function assertExportDeclaration(node, opts = {}) { + assert$2("ExportDeclaration", node, opts); + } + + function assertModuleSpecifier(node, opts = {}) { + assert$2("ModuleSpecifier", node, opts); + } + + function assertFlow(node, opts = {}) { + assert$2("Flow", node, opts); + } + + function assertFlowType(node, opts = {}) { + assert$2("FlowType", node, opts); + } + + function assertFlowBaseAnnotation(node, opts = {}) { + assert$2("FlowBaseAnnotation", node, opts); + } + + function assertFlowDeclaration(node, opts = {}) { + assert$2("FlowDeclaration", node, opts); + } + + function assertFlowPredicate(node, opts = {}) { + assert$2("FlowPredicate", node, opts); + } + + function assertEnumBody(node, opts = {}) { + assert$2("EnumBody", node, opts); + } + + function assertEnumMember(node, opts = {}) { + assert$2("EnumMember", node, opts); + } + + function assertJSX(node, opts = {}) { + assert$2("JSX", node, opts); + } + + function assertPrivate(node, opts = {}) { + assert$2("Private", node, opts); + } + + function assertTSTypeElement(node, opts = {}) { + assert$2("TSTypeElement", node, opts); + } + + function assertTSType(node, opts = {}) { + assert$2("TSType", node, opts); + } + + function assertTSBaseType(node, opts = {}) { + assert$2("TSBaseType", node, opts); + } + + function assertNumberLiteral(node, opts) { + console.trace("The node type NumberLiteral has been renamed to NumericLiteral"); + assert$2("NumberLiteral", node, opts); + } + + function assertRegexLiteral(node, opts) { + console.trace("The node type RegexLiteral has been renamed to RegExpLiteral"); + assert$2("RegexLiteral", node, opts); + } + + function assertRestProperty(node, opts) { + console.trace("The node type RestProperty has been renamed to RestElement"); + assert$2("RestProperty", node, opts); + } + + function assertSpreadProperty(node, opts) { + console.trace("The node type SpreadProperty has been renamed to SpreadElement"); + assert$2("SpreadProperty", node, opts); + } + + var createTypeAnnotationBasedOnTypeof$1 = {}; + + Object.defineProperty(createTypeAnnotationBasedOnTypeof$1, "__esModule", { + value: true + }); + createTypeAnnotationBasedOnTypeof$1.default = createTypeAnnotationBasedOnTypeof; + + var _generated$k = generated$2; + + function createTypeAnnotationBasedOnTypeof(type) { + if (type === "string") { + return (0, _generated$k.stringTypeAnnotation)(); + } else if (type === "number") { + return (0, _generated$k.numberTypeAnnotation)(); + } else if (type === "undefined") { + return (0, _generated$k.voidTypeAnnotation)(); + } else if (type === "boolean") { + return (0, _generated$k.booleanTypeAnnotation)(); + } else if (type === "function") { + return (0, _generated$k.genericTypeAnnotation)((0, _generated$k.identifier)("Function")); + } else if (type === "object") { + return (0, _generated$k.genericTypeAnnotation)((0, _generated$k.identifier)("Object")); + } else if (type === "symbol") { + return (0, _generated$k.genericTypeAnnotation)((0, _generated$k.identifier)("Symbol")); + } else { + throw new Error("Invalid typeof value"); + } + } + + var createFlowUnionType$1 = {}; + + var removeTypeDuplicates$3 = {}; + + Object.defineProperty(removeTypeDuplicates$3, "__esModule", { + value: true + }); + removeTypeDuplicates$3.default = removeTypeDuplicates$2; + + var _generated$j = generated$3; + + function removeTypeDuplicates$2(nodes) { + const generics = {}; + const bases = {}; + const typeGroups = []; + const types = []; + + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (!node) continue; + + if (types.indexOf(node) >= 0) { + continue; + } + + if ((0, _generated$j.isAnyTypeAnnotation)(node)) { + return [node]; + } + + if ((0, _generated$j.isFlowBaseAnnotation)(node)) { + bases[node.type] = node; + continue; + } + + if ((0, _generated$j.isUnionTypeAnnotation)(node)) { + if (typeGroups.indexOf(node.types) < 0) { + nodes = nodes.concat(node.types); + typeGroups.push(node.types); + } + + continue; + } + + if ((0, _generated$j.isGenericTypeAnnotation)(node)) { + const name = node.id.name; + + if (generics[name]) { + let existing = generics[name]; + + if (existing.typeParameters) { + if (node.typeParameters) { + existing.typeParameters.params = removeTypeDuplicates$2(existing.typeParameters.params.concat(node.typeParameters.params)); + } + } else { + existing = node.typeParameters; + } + } else { + generics[name] = node; + } + + continue; + } + + types.push(node); + } + + for (const type of Object.keys(bases)) { + types.push(bases[type]); + } + + for (const name of Object.keys(generics)) { + types.push(generics[name]); + } + + return types; + } + + Object.defineProperty(createFlowUnionType$1, "__esModule", { + value: true + }); + createFlowUnionType$1.default = createFlowUnionType; + + var _generated$i = generated$2; + + var _removeTypeDuplicates$1 = _interopRequireDefault$q(removeTypeDuplicates$3); + + function _interopRequireDefault$q(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function createFlowUnionType(types) { + const flattened = (0, _removeTypeDuplicates$1.default)(types); + + if (flattened.length === 1) { + return flattened[0]; + } else { + return (0, _generated$i.unionTypeAnnotation)(flattened); + } + } + + var createTSUnionType$1 = {}; + + var removeTypeDuplicates$1 = {}; + + Object.defineProperty(removeTypeDuplicates$1, "__esModule", { + value: true + }); + removeTypeDuplicates$1.default = removeTypeDuplicates; + + var _generated$h = generated$3; + + function removeTypeDuplicates(nodes) { + const generics = {}; + const bases = {}; + const typeGroups = []; + const types = []; + + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (!node) continue; + + if (types.indexOf(node) >= 0) { + continue; + } + + if ((0, _generated$h.isTSAnyKeyword)(node.type)) { + return [node]; + } + + if ((0, _generated$h.isTSBaseType)(node)) { + bases[node.type] = node; + continue; + } + + if ((0, _generated$h.isTSUnionType)(node)) { + if (typeGroups.indexOf(node.types) < 0) { + nodes = nodes.concat(node.types); + typeGroups.push(node.types); + } + + continue; + } + + types.push(node); + } + + for (const type of Object.keys(bases)) { + types.push(bases[type]); + } + + for (const name of Object.keys(generics)) { + types.push(generics[name]); + } + + return types; + } + + Object.defineProperty(createTSUnionType$1, "__esModule", { + value: true + }); + createTSUnionType$1.default = createTSUnionType; + + var _generated$g = generated$2; + + var _removeTypeDuplicates = _interopRequireDefault$p(removeTypeDuplicates$1); + + function _interopRequireDefault$p(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function createTSUnionType(typeAnnotations) { + const types = typeAnnotations.map(type => type.typeAnnotations); + const flattened = (0, _removeTypeDuplicates.default)(types); + + if (flattened.length === 1) { + return flattened[0]; + } else { + return (0, _generated$g.TSUnionType)(flattened); + } + } + + var cloneNode$1 = {}; + + Object.defineProperty(cloneNode$1, "__esModule", { + value: true + }); + cloneNode$1.default = cloneNode; + + var _definitions$4 = requireDefinitions(); + + const has$1 = Function.call.bind(Object.prototype.hasOwnProperty); + + function cloneIfNode(obj, deep, withoutLoc) { + if (obj && typeof obj.type === "string") { + return cloneNode(obj, deep, withoutLoc); + } + + return obj; + } + + function cloneIfNodeOrArray(obj, deep, withoutLoc) { + if (Array.isArray(obj)) { + return obj.map(node => cloneIfNode(node, deep, withoutLoc)); + } + + return cloneIfNode(obj, deep, withoutLoc); + } + + function cloneNode(node, deep = true, withoutLoc = false) { + if (!node) return node; + const { + type + } = node; + const newNode = { + type + }; + + if (type === "Identifier") { + newNode.name = node.name; + + if (has$1(node, "optional") && typeof node.optional === "boolean") { + newNode.optional = node.optional; + } + + if (has$1(node, "typeAnnotation")) { + newNode.typeAnnotation = deep ? cloneIfNodeOrArray(node.typeAnnotation, true, withoutLoc) : node.typeAnnotation; + } + } else if (!has$1(_definitions$4.NODE_FIELDS, type)) { + throw new Error(`Unknown node type: "${type}"`); + } else { + for (const field of Object.keys(_definitions$4.NODE_FIELDS[type])) { + if (has$1(node, field)) { + if (deep) { + newNode[field] = type === "File" && field === "comments" ? maybeCloneComments(node.comments, deep, withoutLoc) : cloneIfNodeOrArray(node[field], true, withoutLoc); + } else { + newNode[field] = node[field]; + } + } + } + } + + if (has$1(node, "loc")) { + if (withoutLoc) { + newNode.loc = null; + } else { + newNode.loc = node.loc; + } + } + + if (has$1(node, "leadingComments")) { + newNode.leadingComments = maybeCloneComments(node.leadingComments, deep, withoutLoc); + } + + if (has$1(node, "innerComments")) { + newNode.innerComments = maybeCloneComments(node.innerComments, deep, withoutLoc); + } + + if (has$1(node, "trailingComments")) { + newNode.trailingComments = maybeCloneComments(node.trailingComments, deep, withoutLoc); + } + + if (has$1(node, "extra")) { + newNode.extra = Object.assign({}, node.extra); + } + + return newNode; + } + + function cloneCommentsWithoutLoc(comments) { + return comments.map(({ + type, + value + }) => ({ + type, + value, + loc: null + })); + } + + function maybeCloneComments(comments, deep, withoutLoc) { + return deep && withoutLoc ? cloneCommentsWithoutLoc(comments) : comments; + } + + var clone$1 = {}; + + Object.defineProperty(clone$1, "__esModule", { + value: true + }); + clone$1.default = clone; + + var _cloneNode$5 = _interopRequireDefault$o(cloneNode$1); + + function _interopRequireDefault$o(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function clone(node) { + return (0, _cloneNode$5.default)(node, false); + } + + var cloneDeep$1 = {}; + + Object.defineProperty(cloneDeep$1, "__esModule", { + value: true + }); + cloneDeep$1.default = cloneDeep; + + var _cloneNode$4 = _interopRequireDefault$n(cloneNode$1); + + function _interopRequireDefault$n(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function cloneDeep(node) { + return (0, _cloneNode$4.default)(node); + } + + var cloneDeepWithoutLoc$1 = {}; + + Object.defineProperty(cloneDeepWithoutLoc$1, "__esModule", { + value: true + }); + cloneDeepWithoutLoc$1.default = cloneDeepWithoutLoc; + + var _cloneNode$3 = _interopRequireDefault$m(cloneNode$1); + + function _interopRequireDefault$m(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function cloneDeepWithoutLoc(node) { + return (0, _cloneNode$3.default)(node, true, true); + } + + var cloneWithoutLoc$1 = {}; + + Object.defineProperty(cloneWithoutLoc$1, "__esModule", { + value: true + }); + cloneWithoutLoc$1.default = cloneWithoutLoc; + + var _cloneNode$2 = _interopRequireDefault$l(cloneNode$1); + + function _interopRequireDefault$l(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function cloneWithoutLoc(node) { + return (0, _cloneNode$2.default)(node, false, true); + } + + var addComment$1 = {}; + + var addComments$1 = {}; + + Object.defineProperty(addComments$1, "__esModule", { + value: true + }); + addComments$1.default = addComments; + + function addComments(node, type, comments) { + if (!comments || !node) return node; + const key = `${type}Comments`; + + if (node[key]) { + if (type === "leading") { + node[key] = comments.concat(node[key]); + } else { + node[key] = node[key].concat(comments); + } + } else { + node[key] = comments; + } + + return node; + } + + Object.defineProperty(addComment$1, "__esModule", { + value: true + }); + addComment$1.default = addComment; + + var _addComments = _interopRequireDefault$k(addComments$1); + + function _interopRequireDefault$k(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function addComment(node, type, content, line) { + return (0, _addComments.default)(node, type, [{ + type: line ? "CommentLine" : "CommentBlock", + value: content + }]); + } + + var inheritInnerComments$1 = {}; + + var inherit$1 = {}; + + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ + function setCacheAdd$1(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; + } + + var _setCacheAdd = setCacheAdd$1; + + function setCacheHas$1(value) { + return this.__data__.has(value); + } + + var _setCacheHas = setCacheHas$1; + + var MapCache = _MapCache, + setCacheAdd = _setCacheAdd, + setCacheHas = _setCacheHas; + + /** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ + function SetCache$1(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new MapCache; + while (++index < length) { + this.add(values[index]); + } + } + + // Add methods to `SetCache`. + SetCache$1.prototype.add = SetCache$1.prototype.push = setCacheAdd; + SetCache$1.prototype.has = setCacheHas; + + var _SetCache = SetCache$1; + + function baseFindIndex$1(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } + + var _baseFindIndex = baseFindIndex$1; + + function baseIsNaN$1(value) { + return value !== value; + } + + var _baseIsNaN = baseIsNaN$1; + + function strictIndexOf$1(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + var _strictIndexOf = strictIndexOf$1; + + var baseFindIndex = _baseFindIndex, + baseIsNaN = _baseIsNaN, + strictIndexOf = _strictIndexOf; + + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf$1(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + var _baseIndexOf = baseIndexOf$1; + + var baseIndexOf = _baseIndexOf; + + /** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes$1(array, value) { + var length = array == null ? 0 : array.length; + return !!length && baseIndexOf(array, value, 0) > -1; + } + + var _arrayIncludes = arrayIncludes$1; + + function arrayIncludesWith$1(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; + } + + var _arrayIncludesWith = arrayIncludesWith$1; + + function cacheHas$1(cache, key) { + return cache.has(key); + } + + var _cacheHas = cacheHas$1; + + function noop$1() { + // No operation performed. + } + + var noop_1 = noop$1; + + function setToArray$2(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; + } + + var _setToArray = setToArray$2; + + var Set$1 = _Set, + noop = noop_1, + setToArray$1 = _setToArray; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ + var createSet$1 = !(Set$1 && (1 / setToArray$1(new Set$1([,-0]))[1]) == INFINITY) ? noop : function(values) { + return new Set$1(values); + }; + + var _createSet = createSet$1; + + var SetCache = _SetCache, + arrayIncludes = _arrayIncludes, + arrayIncludesWith = _arrayIncludesWith, + cacheHas = _cacheHas, + createSet = _createSet, + setToArray = _setToArray; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ + function baseUniq$1(array, iteratee, comparator) { + var index = -1, + includes = arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : createSet(array); + if (set) { + return setToArray(set); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } + + var _baseUniq = baseUniq$1; + + var baseUniq = _baseUniq; + + /** + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @returns {Array} Returns the new duplicate free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + */ + function uniq(array) { + return (array && array.length) ? baseUniq(array) : []; + } + + var uniq_1 = uniq; + + Object.defineProperty(inherit$1, "__esModule", { + value: true + }); + inherit$1.default = inherit; + + var _uniq = _interopRequireDefault$j(uniq_1); + + function _interopRequireDefault$j(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inherit(key, child, parent) { + if (child && parent) { + child[key] = (0, _uniq.default)([].concat(child[key], parent[key]).filter(Boolean)); + } + } + + Object.defineProperty(inheritInnerComments$1, "__esModule", { + value: true + }); + inheritInnerComments$1.default = inheritInnerComments; + + var _inherit$2 = _interopRequireDefault$i(inherit$1); + + function _interopRequireDefault$i(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inheritInnerComments(child, parent) { + (0, _inherit$2.default)("innerComments", child, parent); + } + + var inheritLeadingComments$1 = {}; + + Object.defineProperty(inheritLeadingComments$1, "__esModule", { + value: true + }); + inheritLeadingComments$1.default = inheritLeadingComments; + + var _inherit$1 = _interopRequireDefault$h(inherit$1); + + function _interopRequireDefault$h(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inheritLeadingComments(child, parent) { + (0, _inherit$1.default)("leadingComments", child, parent); + } + + var inheritsComments$1 = {}; + + var inheritTrailingComments$1 = {}; + + Object.defineProperty(inheritTrailingComments$1, "__esModule", { + value: true + }); + inheritTrailingComments$1.default = inheritTrailingComments; + + var _inherit = _interopRequireDefault$g(inherit$1); + + function _interopRequireDefault$g(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inheritTrailingComments(child, parent) { + (0, _inherit.default)("trailingComments", child, parent); + } + + Object.defineProperty(inheritsComments$1, "__esModule", { + value: true + }); + inheritsComments$1.default = inheritsComments; + + var _inheritTrailingComments = _interopRequireDefault$f(inheritTrailingComments$1); + + var _inheritLeadingComments = _interopRequireDefault$f(inheritLeadingComments$1); + + var _inheritInnerComments = _interopRequireDefault$f(inheritInnerComments$1); + + function _interopRequireDefault$f(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inheritsComments(child, parent) { + (0, _inheritTrailingComments.default)(child, parent); + (0, _inheritLeadingComments.default)(child, parent); + (0, _inheritInnerComments.default)(child, parent); + return child; + } + + var removeComments$1 = {}; + + Object.defineProperty(removeComments$1, "__esModule", { + value: true + }); + removeComments$1.default = removeComments; + + var _constants$4 = constants; + + function removeComments(node) { + _constants$4.COMMENT_KEYS.forEach(key => { + node[key] = null; + }); + + return node; + } + + var generated = {}; + + Object.defineProperty(generated, "__esModule", { + value: true + }); + generated.TSBASETYPE_TYPES = generated.TSTYPE_TYPES = generated.TSTYPEELEMENT_TYPES = generated.PRIVATE_TYPES = generated.JSX_TYPES = generated.ENUMMEMBER_TYPES = generated.ENUMBODY_TYPES = generated.FLOWPREDICATE_TYPES = generated.FLOWDECLARATION_TYPES = generated.FLOWBASEANNOTATION_TYPES = generated.FLOWTYPE_TYPES = generated.FLOW_TYPES = generated.MODULESPECIFIER_TYPES = generated.EXPORTDECLARATION_TYPES = generated.MODULEDECLARATION_TYPES = generated.CLASS_TYPES = generated.PATTERN_TYPES = generated.UNARYLIKE_TYPES = generated.PROPERTY_TYPES = generated.OBJECTMEMBER_TYPES = generated.METHOD_TYPES = generated.USERWHITESPACABLE_TYPES = generated.IMMUTABLE_TYPES = generated.LITERAL_TYPES = generated.TSENTITYNAME_TYPES = generated.LVAL_TYPES = generated.PATTERNLIKE_TYPES = generated.DECLARATION_TYPES = generated.PUREISH_TYPES = generated.FUNCTIONPARENT_TYPES = generated.FUNCTION_TYPES = generated.FORXSTATEMENT_TYPES = generated.FOR_TYPES = generated.EXPRESSIONWRAPPER_TYPES = generated.WHILE_TYPES = generated.LOOP_TYPES = generated.CONDITIONAL_TYPES = generated.COMPLETIONSTATEMENT_TYPES = generated.TERMINATORLESS_TYPES = generated.STATEMENT_TYPES = generated.BLOCK_TYPES = generated.BLOCKPARENT_TYPES = generated.SCOPABLE_TYPES = generated.BINARY_TYPES = generated.EXPRESSION_TYPES = void 0; + + var _definitions$3 = requireDefinitions(); + + const EXPRESSION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Expression"]; + generated.EXPRESSION_TYPES = EXPRESSION_TYPES; + const BINARY_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Binary"]; + generated.BINARY_TYPES = BINARY_TYPES; + const SCOPABLE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Scopable"]; + generated.SCOPABLE_TYPES = SCOPABLE_TYPES; + const BLOCKPARENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["BlockParent"]; + generated.BLOCKPARENT_TYPES = BLOCKPARENT_TYPES; + const BLOCK_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Block"]; + generated.BLOCK_TYPES = BLOCK_TYPES; + const STATEMENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Statement"]; + generated.STATEMENT_TYPES = STATEMENT_TYPES; + const TERMINATORLESS_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Terminatorless"]; + generated.TERMINATORLESS_TYPES = TERMINATORLESS_TYPES; + const COMPLETIONSTATEMENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["CompletionStatement"]; + generated.COMPLETIONSTATEMENT_TYPES = COMPLETIONSTATEMENT_TYPES; + const CONDITIONAL_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Conditional"]; + generated.CONDITIONAL_TYPES = CONDITIONAL_TYPES; + const LOOP_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Loop"]; + generated.LOOP_TYPES = LOOP_TYPES; + const WHILE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["While"]; + generated.WHILE_TYPES = WHILE_TYPES; + const EXPRESSIONWRAPPER_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ExpressionWrapper"]; + generated.EXPRESSIONWRAPPER_TYPES = EXPRESSIONWRAPPER_TYPES; + const FOR_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["For"]; + generated.FOR_TYPES = FOR_TYPES; + const FORXSTATEMENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ForXStatement"]; + generated.FORXSTATEMENT_TYPES = FORXSTATEMENT_TYPES; + const FUNCTION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Function"]; + generated.FUNCTION_TYPES = FUNCTION_TYPES; + const FUNCTIONPARENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["FunctionParent"]; + generated.FUNCTIONPARENT_TYPES = FUNCTIONPARENT_TYPES; + const PUREISH_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Pureish"]; + generated.PUREISH_TYPES = PUREISH_TYPES; + const DECLARATION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Declaration"]; + generated.DECLARATION_TYPES = DECLARATION_TYPES; + const PATTERNLIKE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["PatternLike"]; + generated.PATTERNLIKE_TYPES = PATTERNLIKE_TYPES; + const LVAL_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["LVal"]; + generated.LVAL_TYPES = LVAL_TYPES; + const TSENTITYNAME_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["TSEntityName"]; + generated.TSENTITYNAME_TYPES = TSENTITYNAME_TYPES; + const LITERAL_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Literal"]; + generated.LITERAL_TYPES = LITERAL_TYPES; + const IMMUTABLE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Immutable"]; + generated.IMMUTABLE_TYPES = IMMUTABLE_TYPES; + const USERWHITESPACABLE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["UserWhitespacable"]; + generated.USERWHITESPACABLE_TYPES = USERWHITESPACABLE_TYPES; + const METHOD_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Method"]; + generated.METHOD_TYPES = METHOD_TYPES; + const OBJECTMEMBER_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ObjectMember"]; + generated.OBJECTMEMBER_TYPES = OBJECTMEMBER_TYPES; + const PROPERTY_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Property"]; + generated.PROPERTY_TYPES = PROPERTY_TYPES; + const UNARYLIKE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["UnaryLike"]; + generated.UNARYLIKE_TYPES = UNARYLIKE_TYPES; + const PATTERN_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Pattern"]; + generated.PATTERN_TYPES = PATTERN_TYPES; + const CLASS_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Class"]; + generated.CLASS_TYPES = CLASS_TYPES; + const MODULEDECLARATION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ModuleDeclaration"]; + generated.MODULEDECLARATION_TYPES = MODULEDECLARATION_TYPES; + const EXPORTDECLARATION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ExportDeclaration"]; + generated.EXPORTDECLARATION_TYPES = EXPORTDECLARATION_TYPES; + const MODULESPECIFIER_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["ModuleSpecifier"]; + generated.MODULESPECIFIER_TYPES = MODULESPECIFIER_TYPES; + const FLOW_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Flow"]; + generated.FLOW_TYPES = FLOW_TYPES; + const FLOWTYPE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["FlowType"]; + generated.FLOWTYPE_TYPES = FLOWTYPE_TYPES; + const FLOWBASEANNOTATION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["FlowBaseAnnotation"]; + generated.FLOWBASEANNOTATION_TYPES = FLOWBASEANNOTATION_TYPES; + const FLOWDECLARATION_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["FlowDeclaration"]; + generated.FLOWDECLARATION_TYPES = FLOWDECLARATION_TYPES; + const FLOWPREDICATE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["FlowPredicate"]; + generated.FLOWPREDICATE_TYPES = FLOWPREDICATE_TYPES; + const ENUMBODY_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["EnumBody"]; + generated.ENUMBODY_TYPES = ENUMBODY_TYPES; + const ENUMMEMBER_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["EnumMember"]; + generated.ENUMMEMBER_TYPES = ENUMMEMBER_TYPES; + const JSX_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["JSX"]; + generated.JSX_TYPES = JSX_TYPES; + const PRIVATE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["Private"]; + generated.PRIVATE_TYPES = PRIVATE_TYPES; + const TSTYPEELEMENT_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["TSTypeElement"]; + generated.TSTYPEELEMENT_TYPES = TSTYPEELEMENT_TYPES; + const TSTYPE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["TSType"]; + generated.TSTYPE_TYPES = TSTYPE_TYPES; + const TSBASETYPE_TYPES = _definitions$3.FLIPPED_ALIAS_KEYS["TSBaseType"]; + generated.TSBASETYPE_TYPES = TSBASETYPE_TYPES; + + var ensureBlock$1 = {}; + + var toBlock$1 = {}; + + Object.defineProperty(toBlock$1, "__esModule", { + value: true + }); + toBlock$1.default = toBlock; + + var _generated$f = generated$3; + + var _generated2$3 = generated$2; + + function toBlock(node, parent) { + if ((0, _generated$f.isBlockStatement)(node)) { + return node; + } + + let blockNodes = []; + + if ((0, _generated$f.isEmptyStatement)(node)) { + blockNodes = []; + } else { + if (!(0, _generated$f.isStatement)(node)) { + if ((0, _generated$f.isFunction)(parent)) { + node = (0, _generated2$3.returnStatement)(node); + } else { + node = (0, _generated2$3.expressionStatement)(node); + } + } + + blockNodes = [node]; + } + + return (0, _generated2$3.blockStatement)(blockNodes); + } + + Object.defineProperty(ensureBlock$1, "__esModule", { + value: true + }); + ensureBlock$1.default = ensureBlock; + + var _toBlock = _interopRequireDefault$e(toBlock$1); + + function _interopRequireDefault$e(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function ensureBlock(node, key = "body") { + return node[key] = (0, _toBlock.default)(node[key], node); + } + + var toBindingIdentifierName$1 = {}; + + var toIdentifier$1 = {}; + + Object.defineProperty(toIdentifier$1, "__esModule", { + value: true + }); + toIdentifier$1.default = toIdentifier; + + var _isValidIdentifier$2 = _interopRequireDefault$d(isValidIdentifier$1); + + function _interopRequireDefault$d(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function toIdentifier(name) { + name = name + ""; + name = name.replace(/[^a-zA-Z0-9$_]/g, "-"); + name = name.replace(/^[-0-9]+/, ""); + name = name.replace(/[-\s]+(.)?/g, function (match, c) { + return c ? c.toUpperCase() : ""; + }); + + if (!(0, _isValidIdentifier$2.default)(name)) { + name = `_${name}`; + } + + return name || "_"; + } + + Object.defineProperty(toBindingIdentifierName$1, "__esModule", { + value: true + }); + toBindingIdentifierName$1.default = toBindingIdentifierName; + + var _toIdentifier = _interopRequireDefault$c(toIdentifier$1); + + function _interopRequireDefault$c(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function toBindingIdentifierName(name) { + name = (0, _toIdentifier.default)(name); + if (name === "eval" || name === "arguments") name = "_" + name; + return name; + } + + var toComputedKey$1 = {}; + + Object.defineProperty(toComputedKey$1, "__esModule", { + value: true + }); + toComputedKey$1.default = toComputedKey; + + var _generated$e = generated$3; + + var _generated2$2 = generated$2; + + function toComputedKey(node, key = node.key || node.property) { + if (!node.computed && (0, _generated$e.isIdentifier)(key)) key = (0, _generated2$2.stringLiteral)(key.name); + return key; + } + + var toExpression$1 = {}; + + Object.defineProperty(toExpression$1, "__esModule", { + value: true + }); + toExpression$1.default = toExpression; + + var _generated$d = generated$3; + + function toExpression(node) { + if ((0, _generated$d.isExpressionStatement)(node)) { + node = node.expression; + } + + if ((0, _generated$d.isExpression)(node)) { + return node; + } + + if ((0, _generated$d.isClass)(node)) { + node.type = "ClassExpression"; + } else if ((0, _generated$d.isFunction)(node)) { + node.type = "FunctionExpression"; + } + + if (!(0, _generated$d.isExpression)(node)) { + throw new Error(`cannot turn ${node.type} to an expression`); + } + + return node; + } + + var toKeyAlias$1 = {}; + + var removePropertiesDeep$1 = {}; + + var traverseFast$1 = {}; + + Object.defineProperty(traverseFast$1, "__esModule", { + value: true + }); + traverseFast$1.default = traverseFast; + + var _definitions$2 = requireDefinitions(); + + function traverseFast(node, enter, opts) { + if (!node) return; + const keys = _definitions$2.VISITOR_KEYS[node.type]; + if (!keys) return; + opts = opts || {}; + enter(node, opts); + + for (const key of keys) { + const subNode = node[key]; + + if (Array.isArray(subNode)) { + for (const node of subNode) { + traverseFast(node, enter, opts); + } + } else { + traverseFast(subNode, enter, opts); + } + } + } + + var removeProperties$1 = {}; + + Object.defineProperty(removeProperties$1, "__esModule", { + value: true + }); + removeProperties$1.default = removeProperties; + + var _constants$3 = constants; + + const CLEAR_KEYS = ["tokens", "start", "end", "loc", "raw", "rawValue"]; + + const CLEAR_KEYS_PLUS_COMMENTS = _constants$3.COMMENT_KEYS.concat(["comments"]).concat(CLEAR_KEYS); + + function removeProperties(node, opts = {}) { + const map = opts.preserveComments ? CLEAR_KEYS : CLEAR_KEYS_PLUS_COMMENTS; + + for (const key of map) { + if (node[key] != null) node[key] = undefined; + } + + for (const key of Object.keys(node)) { + if (key[0] === "_" && node[key] != null) node[key] = undefined; + } + + const symbols = Object.getOwnPropertySymbols(node); + + for (const sym of symbols) { + node[sym] = null; + } + } + + Object.defineProperty(removePropertiesDeep$1, "__esModule", { + value: true + }); + removePropertiesDeep$1.default = removePropertiesDeep; + + var _traverseFast = _interopRequireDefault$b(traverseFast$1); + + var _removeProperties = _interopRequireDefault$b(removeProperties$1); + + function _interopRequireDefault$b(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function removePropertiesDeep(tree, opts) { + (0, _traverseFast.default)(tree, _removeProperties.default, opts); + return tree; + } + + Object.defineProperty(toKeyAlias$1, "__esModule", { + value: true + }); + toKeyAlias$1.default = toKeyAlias; + + var _generated$c = generated$3; + + var _cloneNode$1 = _interopRequireDefault$a(cloneNode$1); + + var _removePropertiesDeep = _interopRequireDefault$a(removePropertiesDeep$1); + + function _interopRequireDefault$a(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function toKeyAlias(node, key = node.key) { + let alias; + + if (node.kind === "method") { + return toKeyAlias.increment() + ""; + } else if ((0, _generated$c.isIdentifier)(key)) { + alias = key.name; + } else if ((0, _generated$c.isStringLiteral)(key)) { + alias = JSON.stringify(key.value); + } else { + alias = JSON.stringify((0, _removePropertiesDeep.default)((0, _cloneNode$1.default)(key))); + } + + if (node.computed) { + alias = `[${alias}]`; + } + + if (node.static) { + alias = `static:${alias}`; + } + + return alias; + } + + toKeyAlias.uid = 0; + + toKeyAlias.increment = function () { + if (toKeyAlias.uid >= Number.MAX_SAFE_INTEGER) { + return toKeyAlias.uid = 0; + } else { + return toKeyAlias.uid++; + } + }; + + var toSequenceExpression$1 = {}; + + var gatherSequenceExpressions$1 = {}; + + var getBindingIdentifiers$1 = {}; + + Object.defineProperty(getBindingIdentifiers$1, "__esModule", { + value: true + }); + getBindingIdentifiers$1.default = getBindingIdentifiers; + + var _generated$b = generated$3; + + function getBindingIdentifiers(node, duplicates, outerOnly) { + let search = [].concat(node); + const ids = Object.create(null); + + while (search.length) { + const id = search.shift(); + if (!id) continue; + const keys = getBindingIdentifiers.keys[id.type]; + + if ((0, _generated$b.isIdentifier)(id)) { + if (duplicates) { + const _ids = ids[id.name] = ids[id.name] || []; + + _ids.push(id); + } else { + ids[id.name] = id; + } + + continue; + } + + if ((0, _generated$b.isExportDeclaration)(id)) { + if ((0, _generated$b.isDeclaration)(id.declaration)) { + search.push(id.declaration); + } + + continue; + } + + if (outerOnly) { + if ((0, _generated$b.isFunctionDeclaration)(id)) { + search.push(id.id); + continue; + } + + if ((0, _generated$b.isFunctionExpression)(id)) { + continue; + } + } + + if (keys) { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if (id[key]) { + search = search.concat(id[key]); + } + } + } + } + + return ids; + } + + getBindingIdentifiers.keys = { + DeclareClass: ["id"], + DeclareFunction: ["id"], + DeclareModule: ["id"], + DeclareVariable: ["id"], + DeclareInterface: ["id"], + DeclareTypeAlias: ["id"], + DeclareOpaqueType: ["id"], + InterfaceDeclaration: ["id"], + TypeAlias: ["id"], + OpaqueType: ["id"], + CatchClause: ["param"], + LabeledStatement: ["label"], + UnaryExpression: ["argument"], + AssignmentExpression: ["left"], + ImportSpecifier: ["local"], + ImportNamespaceSpecifier: ["local"], + ImportDefaultSpecifier: ["local"], + ImportDeclaration: ["specifiers"], + ExportSpecifier: ["exported"], + ExportNamespaceSpecifier: ["exported"], + ExportDefaultSpecifier: ["exported"], + FunctionDeclaration: ["id", "params"], + FunctionExpression: ["id", "params"], + ArrowFunctionExpression: ["params"], + ObjectMethod: ["params"], + ClassMethod: ["params"], + ForInStatement: ["left"], + ForOfStatement: ["left"], + ClassDeclaration: ["id"], + ClassExpression: ["id"], + RestElement: ["argument"], + UpdateExpression: ["argument"], + ObjectProperty: ["value"], + AssignmentPattern: ["left"], + ArrayPattern: ["elements"], + ObjectPattern: ["properties"], + VariableDeclaration: ["declarations"], + VariableDeclarator: ["id"] + }; + + Object.defineProperty(gatherSequenceExpressions$1, "__esModule", { + value: true + }); + gatherSequenceExpressions$1.default = gatherSequenceExpressions; + + var _getBindingIdentifiers$2 = _interopRequireDefault$9(getBindingIdentifiers$1); + + var _generated$a = generated$3; + + var _generated2$1 = generated$2; + + var _cloneNode = _interopRequireDefault$9(cloneNode$1); + + function _interopRequireDefault$9(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function gatherSequenceExpressions(nodes, scope, declars) { + const exprs = []; + let ensureLastUndefined = true; + + for (const node of nodes) { + if (!(0, _generated$a.isEmptyStatement)(node)) { + ensureLastUndefined = false; + } + + if ((0, _generated$a.isExpression)(node)) { + exprs.push(node); + } else if ((0, _generated$a.isExpressionStatement)(node)) { + exprs.push(node.expression); + } else if ((0, _generated$a.isVariableDeclaration)(node)) { + if (node.kind !== "var") return; + + for (const declar of node.declarations) { + const bindings = (0, _getBindingIdentifiers$2.default)(declar); + + for (const key of Object.keys(bindings)) { + declars.push({ + kind: node.kind, + id: (0, _cloneNode.default)(bindings[key]) + }); + } + + if (declar.init) { + exprs.push((0, _generated2$1.assignmentExpression)("=", declar.id, declar.init)); + } + } + + ensureLastUndefined = true; + } else if ((0, _generated$a.isIfStatement)(node)) { + const consequent = node.consequent ? gatherSequenceExpressions([node.consequent], scope, declars) : scope.buildUndefinedNode(); + const alternate = node.alternate ? gatherSequenceExpressions([node.alternate], scope, declars) : scope.buildUndefinedNode(); + if (!consequent || !alternate) return; + exprs.push((0, _generated2$1.conditionalExpression)(node.test, consequent, alternate)); + } else if ((0, _generated$a.isBlockStatement)(node)) { + const body = gatherSequenceExpressions(node.body, scope, declars); + if (!body) return; + exprs.push(body); + } else if ((0, _generated$a.isEmptyStatement)(node)) { + if (nodes.indexOf(node) === 0) { + ensureLastUndefined = true; + } + } else { + return; + } + } + + if (ensureLastUndefined) { + exprs.push(scope.buildUndefinedNode()); + } + + if (exprs.length === 1) { + return exprs[0]; + } else { + return (0, _generated2$1.sequenceExpression)(exprs); + } + } + + Object.defineProperty(toSequenceExpression$1, "__esModule", { + value: true + }); + toSequenceExpression$1.default = toSequenceExpression; + + var _gatherSequenceExpressions = _interopRequireDefault$8(gatherSequenceExpressions$1); + + function _interopRequireDefault$8(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function toSequenceExpression(nodes, scope) { + if (!(nodes == null ? void 0 : nodes.length)) return; + const declars = []; + const result = (0, _gatherSequenceExpressions.default)(nodes, scope, declars); + if (!result) return; + + for (const declar of declars) { + scope.push(declar); + } + + return result; + } + + var toStatement$1 = {}; + + Object.defineProperty(toStatement$1, "__esModule", { + value: true + }); + toStatement$1.default = toStatement; + + var _generated$9 = generated$3; + + var _generated2 = generated$2; + + function toStatement(node, ignore) { + if ((0, _generated$9.isStatement)(node)) { + return node; + } + + let mustHaveId = false; + let newType; + + if ((0, _generated$9.isClass)(node)) { + mustHaveId = true; + newType = "ClassDeclaration"; + } else if ((0, _generated$9.isFunction)(node)) { + mustHaveId = true; + newType = "FunctionDeclaration"; + } else if ((0, _generated$9.isAssignmentExpression)(node)) { + return (0, _generated2.expressionStatement)(node); + } + + if (mustHaveId && !node.id) { + newType = false; + } + + if (!newType) { + if (ignore) { + return false; + } else { + throw new Error(`cannot turn ${node.type} to a statement`); + } + } + + node.type = newType; + return node; + } + + var valueToNode$1 = {}; + + var baseGetTag$1 = _baseGetTag, + getPrototype = _getPrototype, + isObjectLike$1 = isObjectLike_1; + + /** `Object#toString` result references. */ + var objectTag = '[object Object]'; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto.hasOwnProperty; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * @static + * @memberOf _ + * @since 0.8.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. + * @example + * + * function Foo() { + * this.a = 1; + * } + * + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + function isPlainObject(value) { + if (!isObjectLike$1(value) || baseGetTag$1(value) != objectTag) { + return false; + } + var proto = getPrototype(value); + if (proto === null) { + return true; + } + var Ctor = hasOwnProperty$1.call(proto, 'constructor') && proto.constructor; + return typeof Ctor == 'function' && Ctor instanceof Ctor && + funcToString.call(Ctor) == objectCtorString; + } + + var isPlainObject_1 = isPlainObject; + + var baseGetTag = _baseGetTag, + isObjectLike = isObjectLike_1; + + /** `Object#toString` result references. */ + var regexpTag = '[object RegExp]'; + + /** + * The base implementation of `_.isRegExp` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + */ + function baseIsRegExp$1(value) { + return isObjectLike(value) && baseGetTag(value) == regexpTag; + } + + var _baseIsRegExp = baseIsRegExp$1; + + var baseIsRegExp = _baseIsRegExp, + baseUnary = _baseUnary, + nodeUtil = _nodeUtilExports; + + /* Node.js helper references. */ + var nodeIsRegExp = nodeUtil && nodeUtil.isRegExp; + + /** + * Checks if `value` is classified as a `RegExp` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. + * @example + * + * _.isRegExp(/abc/); + * // => true + * + * _.isRegExp('/abc/'); + * // => false + */ + var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; + + var isRegExp_1 = isRegExp; + + Object.defineProperty(valueToNode$1, "__esModule", { + value: true + }); + valueToNode$1.default = valueToNode; + + var _isPlainObject = _interopRequireDefault$7(isPlainObject_1); + + var _isRegExp = _interopRequireDefault$7(isRegExp_1); + + var _isValidIdentifier$1 = _interopRequireDefault$7(isValidIdentifier$1); + + var _generated$8 = generated$2; + + function _interopRequireDefault$7(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function valueToNode(value) { + if (value === undefined) { + return (0, _generated$8.identifier)("undefined"); + } + + if (value === true || value === false) { + return (0, _generated$8.booleanLiteral)(value); + } + + if (value === null) { + return (0, _generated$8.nullLiteral)(); + } + + if (typeof value === "string") { + return (0, _generated$8.stringLiteral)(value); + } + + if (typeof value === "number") { + let result; + + if (Number.isFinite(value)) { + result = (0, _generated$8.numericLiteral)(Math.abs(value)); + } else { + let numerator; + + if (Number.isNaN(value)) { + numerator = (0, _generated$8.numericLiteral)(0); + } else { + numerator = (0, _generated$8.numericLiteral)(1); + } + + result = (0, _generated$8.binaryExpression)("/", numerator, (0, _generated$8.numericLiteral)(0)); + } + + if (value < 0 || Object.is(value, -0)) { + result = (0, _generated$8.unaryExpression)("-", result); + } + + return result; + } + + if ((0, _isRegExp.default)(value)) { + const pattern = value.source; + const flags = value.toString().match(/\/([a-z]+|)$/)[1]; + return (0, _generated$8.regExpLiteral)(pattern, flags); + } + + if (Array.isArray(value)) { + return (0, _generated$8.arrayExpression)(value.map(valueToNode)); + } + + if ((0, _isPlainObject.default)(value)) { + const props = []; + + for (const key of Object.keys(value)) { + let nodeKey; + + if ((0, _isValidIdentifier$1.default)(key)) { + nodeKey = (0, _generated$8.identifier)(key); + } else { + nodeKey = (0, _generated$8.stringLiteral)(key); + } + + props.push((0, _generated$8.objectProperty)(nodeKey, valueToNode(value[key]))); + } + + return (0, _generated$8.objectExpression)(props); + } + + throw new Error("don't know how to turn this value into a node"); + } + + var appendToMemberExpression$1 = {}; + + Object.defineProperty(appendToMemberExpression$1, "__esModule", { + value: true + }); + appendToMemberExpression$1.default = appendToMemberExpression; + + var _generated$7 = generated$2; + + function appendToMemberExpression(member, append, computed = false) { + member.object = (0, _generated$7.memberExpression)(member.object, member.property, member.computed); + member.property = append; + member.computed = !!computed; + return member; + } + + var inherits$1 = {}; + + Object.defineProperty(inherits$1, "__esModule", { + value: true + }); + inherits$1.default = inherits; + + var _constants$2 = constants; + + var _inheritsComments = _interopRequireDefault$6(inheritsComments$1); + + function _interopRequireDefault$6(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function inherits(child, parent) { + if (!child || !parent) return child; + + for (const key of _constants$2.INHERIT_KEYS.optional) { + if (child[key] == null) { + child[key] = parent[key]; + } + } + + for (const key of Object.keys(parent)) { + if (key[0] === "_" && key !== "__clone") child[key] = parent[key]; + } + + for (const key of _constants$2.INHERIT_KEYS.force) { + child[key] = parent[key]; + } + + (0, _inheritsComments.default)(child, parent); + return child; + } + + var prependToMemberExpression$1 = {}; + + Object.defineProperty(prependToMemberExpression$1, "__esModule", { + value: true + }); + prependToMemberExpression$1.default = prependToMemberExpression; + + var _generated$6 = generated$2; + + function prependToMemberExpression(member, prepend) { + member.object = (0, _generated$6.memberExpression)(prepend, member.object); + return member; + } + + var getOuterBindingIdentifiers$1 = {}; + + Object.defineProperty(getOuterBindingIdentifiers$1, "__esModule", { + value: true + }); + getOuterBindingIdentifiers$1.default = getOuterBindingIdentifiers; + + var _getBindingIdentifiers$1 = _interopRequireDefault$5(getBindingIdentifiers$1); + + function _interopRequireDefault$5(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function getOuterBindingIdentifiers(node, duplicates) { + return (0, _getBindingIdentifiers$1.default)(node, duplicates, true); + } + + var traverse$1 = {}; + + Object.defineProperty(traverse$1, "__esModule", { + value: true + }); + traverse$1.default = traverse; + + var _definitions$1 = requireDefinitions(); + + function traverse(node, handlers, state) { + if (typeof handlers === "function") { + handlers = { + enter: handlers + }; + } + + const { + enter, + exit + } = handlers; + traverseSimpleImpl(node, enter, exit, state, []); + } + + function traverseSimpleImpl(node, enter, exit, state, ancestors) { + const keys = _definitions$1.VISITOR_KEYS[node.type]; + if (!keys) return; + if (enter) enter(node, ancestors, state); + + for (const key of keys) { + const subNode = node[key]; + + if (Array.isArray(subNode)) { + for (let i = 0; i < subNode.length; i++) { + const child = subNode[i]; + if (!child) continue; + ancestors.push({ + node, + key, + index: i + }); + traverseSimpleImpl(child, enter, exit, state, ancestors); + ancestors.pop(); + } + } else if (subNode) { + ancestors.push({ + node, + key + }); + traverseSimpleImpl(subNode, enter, exit, state, ancestors); + ancestors.pop(); + } + } + + if (exit) exit(node, ancestors, state); + } + + var isBinding$1 = {}; + + Object.defineProperty(isBinding$1, "__esModule", { + value: true + }); + isBinding$1.default = isBinding; + + var _getBindingIdentifiers = _interopRequireDefault$4(getBindingIdentifiers$1); + + function _interopRequireDefault$4(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function isBinding(node, parent, grandparent) { + if (grandparent && node.type === "Identifier" && parent.type === "ObjectProperty" && grandparent.type === "ObjectExpression") { + return false; + } + + const keys = _getBindingIdentifiers.default.keys[parent.type]; + + if (keys) { + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + const val = parent[key]; + + if (Array.isArray(val)) { + if (val.indexOf(node) >= 0) return true; + } else { + if (val === node) return true; + } + } + } + + return false; + } + + var isBlockScoped$1 = {}; + + var isLet$1 = {}; + + Object.defineProperty(isLet$1, "__esModule", { + value: true + }); + isLet$1.default = isLet; + + var _generated$5 = generated$3; + + var _constants$1 = constants; + + function isLet(node) { + return (0, _generated$5.isVariableDeclaration)(node) && (node.kind !== "var" || node[_constants$1.BLOCK_SCOPED_SYMBOL]); + } + + Object.defineProperty(isBlockScoped$1, "__esModule", { + value: true + }); + isBlockScoped$1.default = isBlockScoped; + + var _generated$4 = generated$3; + + var _isLet = _interopRequireDefault$3(isLet$1); + + function _interopRequireDefault$3(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function isBlockScoped(node) { + return (0, _generated$4.isFunctionDeclaration)(node) || (0, _generated$4.isClassDeclaration)(node) || (0, _isLet.default)(node); + } + + var isImmutable$1 = {}; + + Object.defineProperty(isImmutable$1, "__esModule", { + value: true + }); + isImmutable$1.default = isImmutable; + + var _isType = _interopRequireDefault$2(requireIsType()); + + var _generated$3 = generated$3; + + function _interopRequireDefault$2(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function isImmutable(node) { + if ((0, _isType.default)(node.type, "Immutable")) return true; + + if ((0, _generated$3.isIdentifier)(node)) { + if (node.name === "undefined") { + return true; + } else { + return false; + } + } + + return false; + } + + var isNodesEquivalent$1 = {}; + + Object.defineProperty(isNodesEquivalent$1, "__esModule", { + value: true + }); + isNodesEquivalent$1.default = isNodesEquivalent; + + var _definitions = requireDefinitions(); + + function isNodesEquivalent(a, b) { + if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) { + return a === b; + } + + if (a.type !== b.type) { + return false; + } + + const fields = Object.keys(_definitions.NODE_FIELDS[a.type] || a.type); + const visitorKeys = _definitions.VISITOR_KEYS[a.type]; + + for (const field of fields) { + if (typeof a[field] !== typeof b[field]) { + return false; + } + + if (a[field] == null && b[field] == null) { + continue; + } else if (a[field] == null || b[field] == null) { + return false; + } + + if (Array.isArray(a[field])) { + if (!Array.isArray(b[field])) { + return false; + } + + if (a[field].length !== b[field].length) { + return false; + } + + for (let i = 0; i < a[field].length; i++) { + if (!isNodesEquivalent(a[field][i], b[field][i])) { + return false; + } + } + + continue; + } + + if (typeof a[field] === "object" && !(visitorKeys == null ? void 0 : visitorKeys.includes(field))) { + for (const key of Object.keys(a[field])) { + if (a[field][key] !== b[field][key]) { + return false; + } + } + + continue; + } + + if (!isNodesEquivalent(a[field], b[field])) { + return false; + } + } + + return true; + } + + var isReferenced$1 = {}; + + Object.defineProperty(isReferenced$1, "__esModule", { + value: true + }); + isReferenced$1.default = isReferenced; + + function isReferenced(node, parent, grandparent) { + switch (parent.type) { + case "MemberExpression": + case "JSXMemberExpression": + case "OptionalMemberExpression": + if (parent.property === node) { + return !!parent.computed; + } + + return parent.object === node; + + case "VariableDeclarator": + return parent.init === node; + + case "ArrowFunctionExpression": + return parent.body === node; + + case "ExportSpecifier": + if (parent.source) { + return false; + } + + return parent.local === node; + + case "PrivateName": + return false; + + case "ClassMethod": + case "ClassPrivateMethod": + case "ObjectMethod": + if (parent.params.includes(node)) { + return false; + } + + case "ObjectProperty": + case "ClassProperty": + case "ClassPrivateProperty": + if (parent.key === node) { + return !!parent.computed; + } + + if (parent.value === node) { + return !grandparent || grandparent.type !== "ObjectPattern"; + } + + return true; + + case "ClassDeclaration": + case "ClassExpression": + return parent.superClass === node; + + case "AssignmentExpression": + return parent.right === node; + + case "AssignmentPattern": + return parent.right === node; + + case "LabeledStatement": + return false; + + case "CatchClause": + return false; + + case "RestElement": + return false; + + case "BreakStatement": + case "ContinueStatement": + return false; + + case "FunctionDeclaration": + case "FunctionExpression": + return false; + + case "ExportNamespaceSpecifier": + case "ExportDefaultSpecifier": + return false; + + case "ImportDefaultSpecifier": + case "ImportNamespaceSpecifier": + case "ImportSpecifier": + return false; + + case "JSXAttribute": + return false; + + case "ObjectPattern": + case "ArrayPattern": + return false; + + case "MetaProperty": + return false; + + case "ObjectTypeProperty": + return parent.key !== node; + + case "TSEnumMember": + return parent.id !== node; + + case "TSPropertySignature": + if (parent.key === node) { + return !!parent.computed; + } + + return true; + } + + return true; + } + + var isScope$1 = {}; + + Object.defineProperty(isScope$1, "__esModule", { + value: true + }); + isScope$1.default = isScope; + + var _generated$2 = generated$3; + + function isScope(node, parent) { + if ((0, _generated$2.isBlockStatement)(node) && (0, _generated$2.isFunction)(parent, { + body: node + })) { + return false; + } + + if ((0, _generated$2.isBlockStatement)(node) && (0, _generated$2.isCatchClause)(parent, { + body: node + })) { + return false; + } + + if ((0, _generated$2.isPattern)(node) && (0, _generated$2.isFunction)(parent)) { + return true; + } + + return (0, _generated$2.isScopable)(node); + } + + var isSpecifierDefault$1 = {}; + + Object.defineProperty(isSpecifierDefault$1, "__esModule", { + value: true + }); + isSpecifierDefault$1.default = isSpecifierDefault; + + var _generated$1 = generated$3; + + function isSpecifierDefault(specifier) { + return (0, _generated$1.isImportDefaultSpecifier)(specifier) || (0, _generated$1.isIdentifier)(specifier.imported || specifier.exported, { + name: "default" + }); + } + + var isValidES3Identifier$1 = {}; + + Object.defineProperty(isValidES3Identifier$1, "__esModule", { + value: true + }); + isValidES3Identifier$1.default = isValidES3Identifier; + + var _isValidIdentifier = _interopRequireDefault$1(isValidIdentifier$1); + + function _interopRequireDefault$1(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + const RESERVED_WORDS_ES3_ONLY = new Set(["abstract", "boolean", "byte", "char", "double", "enum", "final", "float", "goto", "implements", "int", "interface", "long", "native", "package", "private", "protected", "public", "short", "static", "synchronized", "throws", "transient", "volatile"]); + + function isValidES3Identifier(name) { + return (0, _isValidIdentifier.default)(name) && !RESERVED_WORDS_ES3_ONLY.has(name); + } + + var isVar$1 = {}; + + Object.defineProperty(isVar$1, "__esModule", { + value: true + }); + isVar$1.default = isVar; + + var _generated = generated$3; + + var _constants = constants; + + function isVar(node) { + return (0, _generated.isVariableDeclaration)(node, { + kind: "var" + }) && !node[_constants.BLOCK_SCOPED_SYMBOL]; + } + + (function (exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + var _exportNames = { + react: true, + assertNode: true, + createTypeAnnotationBasedOnTypeof: true, + createUnionTypeAnnotation: true, + createFlowUnionType: true, + createTSUnionType: true, + cloneNode: true, + clone: true, + cloneDeep: true, + cloneDeepWithoutLoc: true, + cloneWithoutLoc: true, + addComment: true, + addComments: true, + inheritInnerComments: true, + inheritLeadingComments: true, + inheritsComments: true, + inheritTrailingComments: true, + removeComments: true, + ensureBlock: true, + toBindingIdentifierName: true, + toBlock: true, + toComputedKey: true, + toExpression: true, + toIdentifier: true, + toKeyAlias: true, + toSequenceExpression: true, + toStatement: true, + valueToNode: true, + appendToMemberExpression: true, + inherits: true, + prependToMemberExpression: true, + removeProperties: true, + removePropertiesDeep: true, + removeTypeDuplicates: true, + getBindingIdentifiers: true, + getOuterBindingIdentifiers: true, + traverse: true, + traverseFast: true, + shallowEqual: true, + is: true, + isBinding: true, + isBlockScoped: true, + isImmutable: true, + isLet: true, + isNode: true, + isNodesEquivalent: true, + isPlaceholderType: true, + isReferenced: true, + isScope: true, + isSpecifierDefault: true, + isType: true, + isValidES3Identifier: true, + isValidIdentifier: true, + isVar: true, + matchesPattern: true, + validate: true, + buildMatchMemberExpression: true + }; + Object.defineProperty(exports, "assertNode", { + enumerable: true, + get: function () { + return _assertNode.default; + } + }); + Object.defineProperty(exports, "createTypeAnnotationBasedOnTypeof", { + enumerable: true, + get: function () { + return _createTypeAnnotationBasedOnTypeof.default; + } + }); + Object.defineProperty(exports, "createUnionTypeAnnotation", { + enumerable: true, + get: function () { + return _createFlowUnionType.default; + } + }); + Object.defineProperty(exports, "createFlowUnionType", { + enumerable: true, + get: function () { + return _createFlowUnionType.default; + } + }); + Object.defineProperty(exports, "createTSUnionType", { + enumerable: true, + get: function () { + return _createTSUnionType.default; + } + }); + Object.defineProperty(exports, "cloneNode", { + enumerable: true, + get: function () { + return _cloneNode.default; + } + }); + Object.defineProperty(exports, "clone", { + enumerable: true, + get: function () { + return _clone.default; + } + }); + Object.defineProperty(exports, "cloneDeep", { + enumerable: true, + get: function () { + return _cloneDeep.default; + } + }); + Object.defineProperty(exports, "cloneDeepWithoutLoc", { + enumerable: true, + get: function () { + return _cloneDeepWithoutLoc.default; + } + }); + Object.defineProperty(exports, "cloneWithoutLoc", { + enumerable: true, + get: function () { + return _cloneWithoutLoc.default; + } + }); + Object.defineProperty(exports, "addComment", { + enumerable: true, + get: function () { + return _addComment.default; + } + }); + Object.defineProperty(exports, "addComments", { + enumerable: true, + get: function () { + return _addComments.default; + } + }); + Object.defineProperty(exports, "inheritInnerComments", { + enumerable: true, + get: function () { + return _inheritInnerComments.default; + } + }); + Object.defineProperty(exports, "inheritLeadingComments", { + enumerable: true, + get: function () { + return _inheritLeadingComments.default; + } + }); + Object.defineProperty(exports, "inheritsComments", { + enumerable: true, + get: function () { + return _inheritsComments.default; + } + }); + Object.defineProperty(exports, "inheritTrailingComments", { + enumerable: true, + get: function () { + return _inheritTrailingComments.default; + } + }); + Object.defineProperty(exports, "removeComments", { + enumerable: true, + get: function () { + return _removeComments.default; + } + }); + Object.defineProperty(exports, "ensureBlock", { + enumerable: true, + get: function () { + return _ensureBlock.default; + } + }); + Object.defineProperty(exports, "toBindingIdentifierName", { + enumerable: true, + get: function () { + return _toBindingIdentifierName.default; + } + }); + Object.defineProperty(exports, "toBlock", { + enumerable: true, + get: function () { + return _toBlock.default; + } + }); + Object.defineProperty(exports, "toComputedKey", { + enumerable: true, + get: function () { + return _toComputedKey.default; + } + }); + Object.defineProperty(exports, "toExpression", { + enumerable: true, + get: function () { + return _toExpression.default; + } + }); + Object.defineProperty(exports, "toIdentifier", { + enumerable: true, + get: function () { + return _toIdentifier.default; + } + }); + Object.defineProperty(exports, "toKeyAlias", { + enumerable: true, + get: function () { + return _toKeyAlias.default; + } + }); + Object.defineProperty(exports, "toSequenceExpression", { + enumerable: true, + get: function () { + return _toSequenceExpression.default; + } + }); + Object.defineProperty(exports, "toStatement", { + enumerable: true, + get: function () { + return _toStatement.default; + } + }); + Object.defineProperty(exports, "valueToNode", { + enumerable: true, + get: function () { + return _valueToNode.default; + } + }); + Object.defineProperty(exports, "appendToMemberExpression", { + enumerable: true, + get: function () { + return _appendToMemberExpression.default; + } + }); + Object.defineProperty(exports, "inherits", { + enumerable: true, + get: function () { + return _inherits.default; + } + }); + Object.defineProperty(exports, "prependToMemberExpression", { + enumerable: true, + get: function () { + return _prependToMemberExpression.default; + } + }); + Object.defineProperty(exports, "removeProperties", { + enumerable: true, + get: function () { + return _removeProperties.default; + } + }); + Object.defineProperty(exports, "removePropertiesDeep", { + enumerable: true, + get: function () { + return _removePropertiesDeep.default; + } + }); + Object.defineProperty(exports, "removeTypeDuplicates", { + enumerable: true, + get: function () { + return _removeTypeDuplicates.default; + } + }); + Object.defineProperty(exports, "getBindingIdentifiers", { + enumerable: true, + get: function () { + return _getBindingIdentifiers.default; + } + }); + Object.defineProperty(exports, "getOuterBindingIdentifiers", { + enumerable: true, + get: function () { + return _getOuterBindingIdentifiers.default; + } + }); + Object.defineProperty(exports, "traverse", { + enumerable: true, + get: function () { + return _traverse.default; + } + }); + Object.defineProperty(exports, "traverseFast", { + enumerable: true, + get: function () { + return _traverseFast.default; + } + }); + Object.defineProperty(exports, "shallowEqual", { + enumerable: true, + get: function () { + return _shallowEqual.default; + } + }); + Object.defineProperty(exports, "is", { + enumerable: true, + get: function () { + return _is.default; + } + }); + Object.defineProperty(exports, "isBinding", { + enumerable: true, + get: function () { + return _isBinding.default; + } + }); + Object.defineProperty(exports, "isBlockScoped", { + enumerable: true, + get: function () { + return _isBlockScoped.default; + } + }); + Object.defineProperty(exports, "isImmutable", { + enumerable: true, + get: function () { + return _isImmutable.default; + } + }); + Object.defineProperty(exports, "isLet", { + enumerable: true, + get: function () { + return _isLet.default; + } + }); + Object.defineProperty(exports, "isNode", { + enumerable: true, + get: function () { + return _isNode.default; + } + }); + Object.defineProperty(exports, "isNodesEquivalent", { + enumerable: true, + get: function () { + return _isNodesEquivalent.default; + } + }); + Object.defineProperty(exports, "isPlaceholderType", { + enumerable: true, + get: function () { + return _isPlaceholderType.default; + } + }); + Object.defineProperty(exports, "isReferenced", { + enumerable: true, + get: function () { + return _isReferenced.default; + } + }); + Object.defineProperty(exports, "isScope", { + enumerable: true, + get: function () { + return _isScope.default; + } + }); + Object.defineProperty(exports, "isSpecifierDefault", { + enumerable: true, + get: function () { + return _isSpecifierDefault.default; + } + }); + Object.defineProperty(exports, "isType", { + enumerable: true, + get: function () { + return _isType.default; + } + }); + Object.defineProperty(exports, "isValidES3Identifier", { + enumerable: true, + get: function () { + return _isValidES3Identifier.default; + } + }); + Object.defineProperty(exports, "isValidIdentifier", { + enumerable: true, + get: function () { + return _isValidIdentifier.default; + } + }); + Object.defineProperty(exports, "isVar", { + enumerable: true, + get: function () { + return _isVar.default; + } + }); + Object.defineProperty(exports, "matchesPattern", { + enumerable: true, + get: function () { + return _matchesPattern.default; + } + }); + Object.defineProperty(exports, "validate", { + enumerable: true, + get: function () { + return _validate.default; + } + }); + Object.defineProperty(exports, "buildMatchMemberExpression", { + enumerable: true, + get: function () { + return _buildMatchMemberExpression.default; + } + }); + exports.react = void 0; + + var _isReactComponent = _interopRequireDefault(isReactComponent$2); + + var _isCompatTag = _interopRequireDefault(isCompatTag$1); + + var _buildChildren = _interopRequireDefault(buildChildren$1); + + var _assertNode = _interopRequireDefault(assertNode$1); + + var _generated = generated$1; + + Object.keys(_generated).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated[key]; + } + }); + }); + + var _createTypeAnnotationBasedOnTypeof = _interopRequireDefault(createTypeAnnotationBasedOnTypeof$1); + + var _createFlowUnionType = _interopRequireDefault(createFlowUnionType$1); + + var _createTSUnionType = _interopRequireDefault(createTSUnionType$1); + + var _generated2 = generated$2; + + Object.keys(_generated2).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated2[key]; + } + }); + }); + + var _cloneNode = _interopRequireDefault(cloneNode$1); + + var _clone = _interopRequireDefault(clone$1); + + var _cloneDeep = _interopRequireDefault(cloneDeep$1); + + var _cloneDeepWithoutLoc = _interopRequireDefault(cloneDeepWithoutLoc$1); + + var _cloneWithoutLoc = _interopRequireDefault(cloneWithoutLoc$1); + + var _addComment = _interopRequireDefault(addComment$1); + + var _addComments = _interopRequireDefault(addComments$1); + + var _inheritInnerComments = _interopRequireDefault(inheritInnerComments$1); + + var _inheritLeadingComments = _interopRequireDefault(inheritLeadingComments$1); + + var _inheritsComments = _interopRequireDefault(inheritsComments$1); + + var _inheritTrailingComments = _interopRequireDefault(inheritTrailingComments$1); + + var _removeComments = _interopRequireDefault(removeComments$1); + + var _generated3 = generated; + + Object.keys(_generated3).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated3[key]; + } + }); + }); + + var _constants = constants; + + Object.keys(_constants).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _constants[key]; + } + }); + }); + + var _ensureBlock = _interopRequireDefault(ensureBlock$1); + + var _toBindingIdentifierName = _interopRequireDefault(toBindingIdentifierName$1); + + var _toBlock = _interopRequireDefault(toBlock$1); + + var _toComputedKey = _interopRequireDefault(toComputedKey$1); + + var _toExpression = _interopRequireDefault(toExpression$1); + + var _toIdentifier = _interopRequireDefault(toIdentifier$1); + + var _toKeyAlias = _interopRequireDefault(toKeyAlias$1); + + var _toSequenceExpression = _interopRequireDefault(toSequenceExpression$1); + + var _toStatement = _interopRequireDefault(toStatement$1); + + var _valueToNode = _interopRequireDefault(valueToNode$1); + + var _definitions = requireDefinitions(); + + Object.keys(_definitions).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _definitions[key]; + } + }); + }); + + var _appendToMemberExpression = _interopRequireDefault(appendToMemberExpression$1); + + var _inherits = _interopRequireDefault(inherits$1); + + var _prependToMemberExpression = _interopRequireDefault(prependToMemberExpression$1); + + var _removeProperties = _interopRequireDefault(removeProperties$1); + + var _removePropertiesDeep = _interopRequireDefault(removePropertiesDeep$1); + + var _removeTypeDuplicates = _interopRequireDefault(removeTypeDuplicates$3); + + var _getBindingIdentifiers = _interopRequireDefault(getBindingIdentifiers$1); + + var _getOuterBindingIdentifiers = _interopRequireDefault(getOuterBindingIdentifiers$1); + + var _traverse = _interopRequireDefault(traverse$1); + + var _traverseFast = _interopRequireDefault(traverseFast$1); + + var _shallowEqual = _interopRequireDefault(shallowEqual$1); + + var _is = _interopRequireDefault(requireIs()); + + var _isBinding = _interopRequireDefault(isBinding$1); + + var _isBlockScoped = _interopRequireDefault(isBlockScoped$1); + + var _isImmutable = _interopRequireDefault(isImmutable$1); + + var _isLet = _interopRequireDefault(isLet$1); + + var _isNode = _interopRequireDefault(isNode$2); + + var _isNodesEquivalent = _interopRequireDefault(isNodesEquivalent$1); + + var _isPlaceholderType = _interopRequireDefault(requireIsPlaceholderType()); + + var _isReferenced = _interopRequireDefault(isReferenced$1); + + var _isScope = _interopRequireDefault(isScope$1); + + var _isSpecifierDefault = _interopRequireDefault(isSpecifierDefault$1); + + var _isType = _interopRequireDefault(requireIsType()); + + var _isValidES3Identifier = _interopRequireDefault(isValidES3Identifier$1); + + var _isValidIdentifier = _interopRequireDefault(isValidIdentifier$1); + + var _isVar = _interopRequireDefault(isVar$1); + + var _matchesPattern = _interopRequireDefault(matchesPattern$1); + + var _validate = _interopRequireDefault(requireValidate()); + + var _buildMatchMemberExpression = _interopRequireDefault(buildMatchMemberExpression$1); + + var _generated4 = generated$3; + + Object.keys(_generated4).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + Object.defineProperty(exports, key, { + enumerable: true, + get: function () { + return _generated4[key]; + } + }); + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + const react = { + isReactComponent: _isReactComponent.default, + isCompatTag: _isCompatTag.default, + buildChildren: _buildChildren.default + }; + exports.react = react; + } (lib$4)); + + var lib$2 = {}; + + Object.defineProperty(lib$2, '__esModule', { value: true }); + + const beforeExpr$1 = true; + const startsExpr$1 = true; + const isLoop$1 = true; + const isAssign$1 = true; + const prefix$1 = true; + const postfix$1 = true; + class TokenType { + constructor(label, conf = {}) { + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.rightAssociative = !!conf.rightAssociative; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop != null ? conf.binop : null; + this.updateContext = null; + } + + } + const keywords$2 = new Map(); + + function createKeyword$1(name, options = {}) { + options.keyword = name; + const token = new TokenType(name, options); + keywords$2.set(name, token); + return token; + } + + function createBinop$1(name, binop) { + return new TokenType(name, { + beforeExpr: beforeExpr$1, + binop + }); + } + + const types$4 = { + num: new TokenType("num", { + startsExpr: startsExpr$1 + }), + bigint: new TokenType("bigint", { + startsExpr: startsExpr$1 + }), + regexp: new TokenType("regexp", { + startsExpr: startsExpr$1 + }), + string: new TokenType("string", { + startsExpr: startsExpr$1 + }), + name: new TokenType("name", { + startsExpr: startsExpr$1 + }), + eof: new TokenType("eof"), + bracketL: new TokenType("[", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + bracketHashL: new TokenType("#[", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + bracketBarL: new TokenType("[|", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + bracketR: new TokenType("]"), + bracketBarR: new TokenType("|]"), + braceL: new TokenType("{", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + braceBarL: new TokenType("{|", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + braceHashL: new TokenType("#{", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + braceR: new TokenType("}"), + braceBarR: new TokenType("|}"), + parenL: new TokenType("(", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + parenR: new TokenType(")"), + comma: new TokenType(",", { + beforeExpr: beforeExpr$1 + }), + semi: new TokenType(";", { + beforeExpr: beforeExpr$1 + }), + colon: new TokenType(":", { + beforeExpr: beforeExpr$1 + }), + doubleColon: new TokenType("::", { + beforeExpr: beforeExpr$1 + }), + dot: new TokenType("."), + question: new TokenType("?", { + beforeExpr: beforeExpr$1 + }), + questionDot: new TokenType("?."), + arrow: new TokenType("=>", { + beforeExpr: beforeExpr$1 + }), + template: new TokenType("template"), + ellipsis: new TokenType("...", { + beforeExpr: beforeExpr$1 + }), + backQuote: new TokenType("`", { + startsExpr: startsExpr$1 + }), + dollarBraceL: new TokenType("${", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + at: new TokenType("@"), + hash: new TokenType("#", { + startsExpr: startsExpr$1 + }), + interpreterDirective: new TokenType("#!..."), + eq: new TokenType("=", { + beforeExpr: beforeExpr$1, + isAssign: isAssign$1 + }), + assign: new TokenType("_=", { + beforeExpr: beforeExpr$1, + isAssign: isAssign$1 + }), + incDec: new TokenType("++/--", { + prefix: prefix$1, + postfix: postfix$1, + startsExpr: startsExpr$1 + }), + bang: new TokenType("!", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + tilde: new TokenType("~", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + pipeline: createBinop$1("|>", 0), + nullishCoalescing: createBinop$1("??", 1), + logicalOR: createBinop$1("||", 1), + logicalAND: createBinop$1("&&", 2), + bitwiseOR: createBinop$1("|", 3), + bitwiseXOR: createBinop$1("^", 4), + bitwiseAND: createBinop$1("&", 5), + equality: createBinop$1("==/!=/===/!==", 6), + relational: createBinop$1("/<=/>=", 7), + bitShift: createBinop$1("<>/>>>", 8), + plusMin: new TokenType("+/-", { + beforeExpr: beforeExpr$1, + binop: 9, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + modulo: new TokenType("%", { + beforeExpr: beforeExpr$1, + binop: 10, + startsExpr: startsExpr$1 + }), + star: createBinop$1("*", 10), + slash: createBinop$1("/", 10), + exponent: new TokenType("**", { + beforeExpr: beforeExpr$1, + binop: 11, + rightAssociative: true + }), + _break: createKeyword$1("break"), + _case: createKeyword$1("case", { + beforeExpr: beforeExpr$1 + }), + _catch: createKeyword$1("catch"), + _continue: createKeyword$1("continue"), + _debugger: createKeyword$1("debugger"), + _default: createKeyword$1("default", { + beforeExpr: beforeExpr$1 + }), + _do: createKeyword$1("do", { + isLoop: isLoop$1, + beforeExpr: beforeExpr$1 + }), + _else: createKeyword$1("else", { + beforeExpr: beforeExpr$1 + }), + _finally: createKeyword$1("finally"), + _for: createKeyword$1("for", { + isLoop: isLoop$1 + }), + _function: createKeyword$1("function", { + startsExpr: startsExpr$1 + }), + _if: createKeyword$1("if"), + _return: createKeyword$1("return", { + beforeExpr: beforeExpr$1 + }), + _switch: createKeyword$1("switch"), + _throw: createKeyword$1("throw", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + _try: createKeyword$1("try"), + _var: createKeyword$1("var"), + _const: createKeyword$1("const"), + _while: createKeyword$1("while", { + isLoop: isLoop$1 + }), + _with: createKeyword$1("with"), + _new: createKeyword$1("new", { + beforeExpr: beforeExpr$1, + startsExpr: startsExpr$1 + }), + _this: createKeyword$1("this", { + startsExpr: startsExpr$1 + }), + _super: createKeyword$1("super", { + startsExpr: startsExpr$1 + }), + _class: createKeyword$1("class", { + startsExpr: startsExpr$1 + }), + _extends: createKeyword$1("extends", { + beforeExpr: beforeExpr$1 + }), + _export: createKeyword$1("export"), + _import: createKeyword$1("import", { + startsExpr: startsExpr$1 + }), + _null: createKeyword$1("null", { + startsExpr: startsExpr$1 + }), + _true: createKeyword$1("true", { + startsExpr: startsExpr$1 + }), + _false: createKeyword$1("false", { + startsExpr: startsExpr$1 + }), + _in: createKeyword$1("in", { + beforeExpr: beforeExpr$1, + binop: 7 + }), + _instanceof: createKeyword$1("instanceof", { + beforeExpr: beforeExpr$1, + binop: 7 + }), + _typeof: createKeyword$1("typeof", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + _void: createKeyword$1("void", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }), + _delete: createKeyword$1("delete", { + beforeExpr: beforeExpr$1, + prefix: prefix$1, + startsExpr: startsExpr$1 + }) + }; + + const SCOPE_OTHER$1 = 0b00000000, + SCOPE_PROGRAM$1 = 0b00000001, + SCOPE_FUNCTION$1 = 0b00000010, + SCOPE_ARROW$1 = 0b00000100, + SCOPE_SIMPLE_CATCH$1 = 0b00001000, + SCOPE_SUPER$1 = 0b00010000, + SCOPE_DIRECT_SUPER$1 = 0b00100000, + SCOPE_CLASS$1 = 0b01000000, + SCOPE_TS_MODULE$1 = 0b10000000, + SCOPE_VAR$1 = SCOPE_PROGRAM$1 | SCOPE_FUNCTION$1 | SCOPE_TS_MODULE$1; + const BIND_KIND_VALUE$1 = 0b00000000001, + BIND_KIND_TYPE$1 = 0b00000000010, + BIND_SCOPE_VAR$1 = 0b00000000100, + BIND_SCOPE_LEXICAL$1 = 0b00000001000, + BIND_SCOPE_FUNCTION$1 = 0b00000010000, + BIND_FLAGS_NONE$1 = 0b00001000000, + BIND_FLAGS_CLASS$1 = 0b00010000000, + BIND_FLAGS_TS_ENUM$1 = 0b00100000000, + BIND_FLAGS_TS_CONST_ENUM$1 = 0b01000000000, + BIND_FLAGS_TS_EXPORT_ONLY$1 = 0b10000000000; + const BIND_CLASS$1 = BIND_KIND_VALUE$1 | BIND_KIND_TYPE$1 | BIND_SCOPE_LEXICAL$1 | BIND_FLAGS_CLASS$1, + BIND_LEXICAL$1 = BIND_KIND_VALUE$1 | 0 | BIND_SCOPE_LEXICAL$1 | 0, + BIND_VAR$1 = BIND_KIND_VALUE$1 | 0 | BIND_SCOPE_VAR$1 | 0, + BIND_FUNCTION$1 = BIND_KIND_VALUE$1 | 0 | BIND_SCOPE_FUNCTION$1 | 0, + BIND_TS_INTERFACE$1 = 0 | BIND_KIND_TYPE$1 | 0 | BIND_FLAGS_CLASS$1, + BIND_TS_TYPE$1 = 0 | BIND_KIND_TYPE$1 | 0 | 0, + BIND_TS_ENUM$1 = BIND_KIND_VALUE$1 | BIND_KIND_TYPE$1 | BIND_SCOPE_LEXICAL$1 | BIND_FLAGS_TS_ENUM$1, + BIND_TS_AMBIENT$1 = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY$1, + BIND_NONE$1 = 0 | 0 | 0 | BIND_FLAGS_NONE$1, + BIND_OUTSIDE$1 = BIND_KIND_VALUE$1 | 0 | 0 | BIND_FLAGS_NONE$1, + BIND_TS_CONST_ENUM$1 = BIND_TS_ENUM$1 | BIND_FLAGS_TS_CONST_ENUM$1, + BIND_TS_NAMESPACE$1 = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY$1; + const CLASS_ELEMENT_FLAG_STATIC$1 = 0b100, + CLASS_ELEMENT_KIND_GETTER$1 = 0b010, + CLASS_ELEMENT_KIND_SETTER$1 = 0b001, + CLASS_ELEMENT_KIND_ACCESSOR$1 = CLASS_ELEMENT_KIND_GETTER$1 | CLASS_ELEMENT_KIND_SETTER$1; + const CLASS_ELEMENT_STATIC_GETTER$1 = CLASS_ELEMENT_KIND_GETTER$1 | CLASS_ELEMENT_FLAG_STATIC$1, + CLASS_ELEMENT_STATIC_SETTER$1 = CLASS_ELEMENT_KIND_SETTER$1 | CLASS_ELEMENT_FLAG_STATIC$1, + CLASS_ELEMENT_INSTANCE_GETTER$1 = CLASS_ELEMENT_KIND_GETTER$1, + CLASS_ELEMENT_INSTANCE_SETTER$1 = CLASS_ELEMENT_KIND_SETTER$1, + CLASS_ELEMENT_OTHER$1 = 0; + + const lineBreak$1 = /\r\n?|[\n\u2028\u2029]/; + const lineBreakG$1 = new RegExp(lineBreak$1.source, "g"); + function isNewLine$1(code) { + switch (code) { + case 10: + case 13: + case 8232: + case 8233: + return true; + + default: + return false; + } + } + const skipWhiteSpace$1 = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + function isWhitespace$1(code) { + switch (code) { + case 0x0009: + case 0x000b: + case 0x000c: + case 32: + case 160: + case 5760: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200a: + case 0x202f: + case 0x205f: + case 0x3000: + case 0xfeff: + return true; + + default: + return false; + } + } + + let Position$1 = class Position { + constructor(line, col) { + this.line = line; + this.column = col; + } + + }; + let SourceLocation$1 = class SourceLocation { + constructor(start, end) { + this.start = start; + this.end = end; + } + + }; + function getLineInfo$1(input, offset) { + let line = 1; + let lineStart = 0; + let match; + lineBreakG$1.lastIndex = 0; + + while ((match = lineBreakG$1.exec(input)) && match.index < offset) { + line++; + lineStart = lineBreakG$1.lastIndex; + } + + return new Position$1(line, offset - lineStart); + } + + let BaseParser$1 = class BaseParser { + constructor() { + this.sawUnambiguousESM = false; + this.ambiguousScriptDifferentAst = false; + } + + hasPlugin(name) { + return this.plugins.has(name); + } + + getPluginOption(plugin, name) { + if (this.hasPlugin(plugin)) return this.plugins.get(plugin)[name]; + } + + }; + + function last(stack) { + return stack[stack.length - 1]; + } + + let CommentsParser$1 = class CommentsParser extends BaseParser$1 { + addComment(comment) { + if (this.filename) comment.loc.filename = this.filename; + this.state.trailingComments.push(comment); + this.state.leadingComments.push(comment); + } + + adjustCommentsAfterTrailingComma(node, elements, takeAllComments) { + if (this.state.leadingComments.length === 0) { + return; + } + + let lastElement = null; + let i = elements.length; + + while (lastElement === null && i > 0) { + lastElement = elements[--i]; + } + + if (lastElement === null) { + return; + } + + for (let j = 0; j < this.state.leadingComments.length; j++) { + if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { + this.state.leadingComments.splice(j, 1); + j--; + } + } + + const newTrailingComments = []; + + for (let i = 0; i < this.state.leadingComments.length; i++) { + const leadingComment = this.state.leadingComments[i]; + + if (leadingComment.end < node.end) { + newTrailingComments.push(leadingComment); + + if (!takeAllComments) { + this.state.leadingComments.splice(i, 1); + i--; + } + } else { + if (node.trailingComments === undefined) { + node.trailingComments = []; + } + + node.trailingComments.push(leadingComment); + } + } + + if (takeAllComments) this.state.leadingComments = []; + + if (newTrailingComments.length > 0) { + lastElement.trailingComments = newTrailingComments; + } else if (lastElement.trailingComments !== undefined) { + lastElement.trailingComments = []; + } + } + + processComment(node) { + if (node.type === "Program" && node.body.length > 0) return; + const stack = this.state.commentStack; + let firstChild, lastChild, trailingComments, i, j; + + if (this.state.trailingComments.length > 0) { + if (this.state.trailingComments[0].start >= node.end) { + trailingComments = this.state.trailingComments; + this.state.trailingComments = []; + } else { + this.state.trailingComments.length = 0; + } + } else if (stack.length > 0) { + const lastInStack = last(stack); + + if (lastInStack.trailingComments && lastInStack.trailingComments[0].start >= node.end) { + trailingComments = lastInStack.trailingComments; + delete lastInStack.trailingComments; + } + } + + if (stack.length > 0 && last(stack).start >= node.start) { + firstChild = stack.pop(); + } + + while (stack.length > 0 && last(stack).start >= node.start) { + lastChild = stack.pop(); + } + + if (!lastChild && firstChild) lastChild = firstChild; + + if (firstChild) { + switch (node.type) { + case "ObjectExpression": + this.adjustCommentsAfterTrailingComma(node, node.properties); + break; + + case "ObjectPattern": + this.adjustCommentsAfterTrailingComma(node, node.properties, true); + break; + + case "CallExpression": + this.adjustCommentsAfterTrailingComma(node, node.arguments); + break; + + case "ArrayExpression": + this.adjustCommentsAfterTrailingComma(node, node.elements); + break; + + case "ArrayPattern": + this.adjustCommentsAfterTrailingComma(node, node.elements, true); + break; + } + } else if (this.state.commentPreviousNode && (this.state.commentPreviousNode.type === "ImportSpecifier" && node.type !== "ImportSpecifier" || this.state.commentPreviousNode.type === "ExportSpecifier" && node.type !== "ExportSpecifier")) { + this.adjustCommentsAfterTrailingComma(node, [this.state.commentPreviousNode]); + } + + if (lastChild) { + if (lastChild.leadingComments) { + if (lastChild !== node && lastChild.leadingComments.length > 0 && last(lastChild.leadingComments).end <= node.start) { + node.leadingComments = lastChild.leadingComments; + delete lastChild.leadingComments; + } else { + for (i = lastChild.leadingComments.length - 2; i >= 0; --i) { + if (lastChild.leadingComments[i].end <= node.start) { + node.leadingComments = lastChild.leadingComments.splice(0, i + 1); + break; + } + } + } + } + } else if (this.state.leadingComments.length > 0) { + if (last(this.state.leadingComments).end <= node.start) { + if (this.state.commentPreviousNode) { + for (j = 0; j < this.state.leadingComments.length; j++) { + if (this.state.leadingComments[j].end < this.state.commentPreviousNode.end) { + this.state.leadingComments.splice(j, 1); + j--; + } + } + } + + if (this.state.leadingComments.length > 0) { + node.leadingComments = this.state.leadingComments; + this.state.leadingComments = []; + } + } else { + for (i = 0; i < this.state.leadingComments.length; i++) { + if (this.state.leadingComments[i].end > node.start) { + break; + } + } + + const leadingComments = this.state.leadingComments.slice(0, i); + + if (leadingComments.length) { + node.leadingComments = leadingComments; + } + + trailingComments = this.state.leadingComments.slice(i); + + if (trailingComments.length === 0) { + trailingComments = null; + } + } + } + + this.state.commentPreviousNode = node; + + if (trailingComments) { + if (trailingComments.length && trailingComments[0].start >= node.start && last(trailingComments).end <= node.end) { + node.innerComments = trailingComments; + } else { + const firstTrailingCommentIndex = trailingComments.findIndex(comment => comment.end >= node.end); + + if (firstTrailingCommentIndex > 0) { + node.innerComments = trailingComments.slice(0, firstTrailingCommentIndex); + node.trailingComments = trailingComments.slice(firstTrailingCommentIndex); + } else { + node.trailingComments = trailingComments; + } + } + } + + stack.push(node); + } + + }; + + const ErrorMessages$1 = Object.freeze({ + ArgumentsDisallowedInInitializer: "'arguments' is not allowed in class field initializer", + AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block", + AwaitBindingIdentifier: "Can not use 'await' as identifier inside an async function", + AwaitExpressionFormalParameter: "await is not allowed in async function parameters", + AwaitNotInAsyncFunction: "Can not use keyword 'await' outside an async function", + BadGetterArity: "getter must not have any formal parameters", + BadSetterArity: "setter must have exactly one formal parameter", + BadSetterRestParameter: "setter function argument must not be a rest parameter", + ConstructorClassField: "Classes may not have a field named 'constructor'", + ConstructorClassPrivateField: "Classes may not have a private field named '#constructor'", + ConstructorIsAccessor: "Class constructor may not be an accessor", + ConstructorIsAsync: "Constructor can't be an async function", + ConstructorIsGenerator: "Constructor can't be a generator", + DeclarationMissingInitializer: "%0 require an initialization value", + DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax", + DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?", + DecoratorExportClass: "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.", + DecoratorSemicolon: "Decorators must not be followed by a semicolon", + DeletePrivateField: "Deleting a private field is not allowed", + DestructureNamedImport: "ES2015 named imports do not destructure. Use another statement for destructuring after the import.", + DuplicateConstructor: "Duplicate constructor in the same class", + DuplicateDefaultExport: "Only one default export allowed per module.", + DuplicateExport: "`%0` has already been exported. Exported identifiers must be unique.", + DuplicateProto: "Redefinition of __proto__ property", + DuplicateRegExpFlags: "Duplicate regular expression flag", + ElementAfterRest: "Rest element must be last element", + EscapedCharNotAnIdentifier: "Invalid Unicode escape", + ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'", + ForInOfLoopInitializer: "%0 loop variable declaration may not have an initializer", + GeneratorInSingleStatementContext: "Generators can only be declared at the top level or inside a block", + IllegalBreakContinue: "Unsyntactic %0", + IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list", + IllegalReturn: "'return' outside of function", + ImportCallArgumentTrailingComma: "Trailing comma is disallowed inside import(...) arguments", + ImportCallArity: "import() requires exactly %0", + ImportCallNotNewExpression: "Cannot use new with import(...)", + ImportCallSpreadArgument: "... is not allowed in import()", + ImportMetaOutsideModule: `import.meta may appear only with 'sourceType: "module"'`, + ImportOutsideModule: `'import' and 'export' may appear only with 'sourceType: "module"'`, + InvalidBigIntLiteral: "Invalid BigIntLiteral", + InvalidCodePoint: "Code point out of bounds", + InvalidDigit: "Expected number in radix %0", + InvalidEscapeSequence: "Bad character escape sequence", + InvalidEscapeSequenceTemplate: "Invalid escape sequence in template", + InvalidEscapedReservedWord: "Escape sequence in keyword %0", + InvalidIdentifier: "Invalid identifier %0", + InvalidLhs: "Invalid left-hand side in %0", + InvalidLhsBinding: "Binding invalid left-hand side in %0", + InvalidNumber: "Invalid number", + InvalidOrUnexpectedToken: "Unexpected character '%0'", + InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern", + InvalidPrivateFieldResolution: "Private name #%0 is not defined", + InvalidPropertyBindingPattern: "Binding member expression", + InvalidRecordProperty: "Only properties and spread elements are allowed in record definitions", + InvalidRestAssignmentPattern: "Invalid rest operator's argument", + LabelRedeclaration: "Label '%0' is already declared", + LetInLexicalBinding: "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", + MalformedRegExpFlags: "Invalid regular expression flag", + MissingClassName: "A class name is required", + MissingEqInAssignment: "Only '=' operator can be used for specifying default value.", + MissingUnicodeEscape: "Expecting Unicode escape sequence \\uXXXX", + MixingCoalesceWithLogical: "Nullish coalescing operator(??) requires parens when mixing with logical operators", + ModuleAttributeDifferentFromType: "The only accepted module attribute is `type`", + ModuleAttributeInvalidValue: "Only string literals are allowed as module attribute values", + ModuleAttributesWithDuplicateKeys: 'Duplicate key "%0" is not allowed in module attributes', + ModuleExportUndefined: "Export '%0' is not defined", + MultipleDefaultsInSwitch: "Multiple default clauses", + NewlineAfterThrow: "Illegal newline after throw", + NoCatchOrFinally: "Missing catch or finally clause", + NumberIdentifier: "Identifier directly after number", + NumericSeparatorInEscapeSequence: "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences", + ObsoleteAwaitStar: "await* has been removed from the async functions proposal. Use Promise.all() instead.", + OptionalChainingNoNew: "constructors in/after an Optional Chain are not allowed", + OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain", + ParamDupe: "Argument name clash", + PatternHasAccessor: "Object pattern can't contain getter or setter", + PatternHasMethod: "Object pattern can't contain methods", + PipelineBodyNoArrow: 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized', + PipelineBodySequenceExpression: "Pipeline body may not be a comma-separated sequence expression", + PipelineHeadSequenceExpression: "Pipeline head should not be a comma-separated sequence expression", + PipelineTopicUnused: "Pipeline is in topic style but does not use topic reference", + PrimaryTopicNotAllowed: "Topic reference was used in a lexical context without topic binding", + PrimaryTopicRequiresSmartPipeline: "Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option.", + PrivateInExpectedIn: "Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`)", + PrivateNameRedeclaration: "Duplicate private name #%0", + RecordExpressionBarIncorrectEndSyntaxType: "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + RecordExpressionBarIncorrectStartSyntaxType: "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'", + RecordNoProto: "'__proto__' is not allowed in Record expressions", + RestTrailingComma: "Unexpected trailing comma after rest element", + SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement", + StaticPrototype: "Classes may not have static property named prototype", + StrictDelete: "Deleting local variable in strict mode", + StrictEvalArguments: "Assigning to '%0' in strict mode", + StrictEvalArgumentsBinding: "Binding '%0' in strict mode", + StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block", + StrictOctalLiteral: "Legacy octal literals are not allowed in strict mode", + StrictWith: "'with' in strict mode", + SuperNotAllowed: "super() is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?", + SuperPrivateField: "Private fields can't be accessed on super", + TrailingDecorator: "Decorators must be attached to a class element", + TupleExpressionBarIncorrectEndSyntaxType: "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + TupleExpressionBarIncorrectStartSyntaxType: "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + TupleExpressionHashIncorrectStartSyntaxType: "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'", + UnexpectedArgumentPlaceholder: "Unexpected argument placeholder", + UnexpectedAwaitAfterPipelineBody: 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal', + UnexpectedDigitAfterHash: "Unexpected digit after hash token", + UnexpectedImportExport: "'import' and 'export' may only appear at the top level", + UnexpectedKeyword: "Unexpected keyword '%0'", + UnexpectedLeadingDecorator: "Leading decorators must be attached to a class declaration", + UnexpectedLexicalDeclaration: "Lexical declaration cannot appear in a single-statement context", + UnexpectedNewTarget: "new.target can only be used in functions", + UnexpectedNumericSeparator: "A numeric separator is only allowed between two digits", + UnexpectedPrivateField: "Private names can only be used as the name of a class element (i.e. class C { #p = 42; #m() {} } )\n or a property of member expression (i.e. this.#p).", + UnexpectedReservedWord: "Unexpected reserved word '%0'", + UnexpectedSuper: "super is only allowed in object methods and classes", + UnexpectedToken: "Unexpected token '%0'", + UnexpectedTokenUnaryExponentiation: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.", + UnsupportedBind: "Binding should be performed on object property.", + UnsupportedDecoratorExport: "A decorated export must export a class declaration", + UnsupportedDefaultExport: "Only expressions, functions or classes are allowed as the `default` export.", + UnsupportedImport: "import can only be used in import() or import.meta", + UnsupportedMetaProperty: "The only valid meta property for %0 is %0.%1", + UnsupportedParameterDecorator: "Decorators cannot be used to decorate parameters", + UnsupportedPropertyDecorator: "Decorators cannot be used to decorate object literal properties", + UnsupportedSuper: "super can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop])", + UnterminatedComment: "Unterminated comment", + UnterminatedRegExp: "Unterminated regular expression", + UnterminatedString: "Unterminated string constant", + UnterminatedTemplate: "Unterminated template", + VarRedeclaration: "Identifier '%0' has already been declared", + YieldBindingIdentifier: "Can not use 'yield' as identifier inside a generator", + YieldInParameter: "yield is not allowed in generator parameters", + ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0" + }); + + let ParserError$1 = class ParserError extends CommentsParser$1 { + getLocationForPosition(pos) { + let loc; + if (pos === this.state.start) loc = this.state.startLoc;else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc;else if (pos === this.state.end) loc = this.state.endLoc;else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc;else loc = getLineInfo$1(this.input, pos); + return loc; + } + + raise(pos, errorTemplate, ...params) { + return this.raiseWithData(pos, undefined, errorTemplate, ...params); + } + + raiseWithData(pos, data, errorTemplate, ...params) { + const loc = this.getLocationForPosition(pos); + const message = errorTemplate.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`; + return this._raise(Object.assign({ + loc, + pos + }, data), message); + } + + _raise(errorContext, message) { + const err = new SyntaxError(message); + Object.assign(err, errorContext); + + if (this.options.errorRecovery) { + if (!this.isLookahead) this.state.errors.push(err); + return err; + } else { + throw err; + } + } + + }; + + function isSimpleProperty(node) { + return node != null && node.type === "Property" && node.kind === "init" && node.method === false; + } + + var estree$1 = (superClass => class extends superClass { + estreeParseRegExpLiteral({ + pattern, + flags + }) { + let regex = null; + + try { + regex = new RegExp(pattern, flags); + } catch (e) {} + + const node = this.estreeParseLiteral(regex); + node.regex = { + pattern, + flags + }; + return node; + } + + estreeParseBigIntLiteral(value) { + const bigInt = typeof BigInt !== "undefined" ? BigInt(value) : null; + const node = this.estreeParseLiteral(bigInt); + node.bigint = String(node.value || value); + return node; + } + + estreeParseLiteral(value) { + return this.parseLiteral(value, "Literal"); + } + + directiveToStmt(directive) { + const directiveLiteral = directive.value; + const stmt = this.startNodeAt(directive.start, directive.loc.start); + const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); + expression.value = directiveLiteral.value; + expression.raw = directiveLiteral.extra.raw; + stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); + stmt.directive = directiveLiteral.extra.raw.slice(1, -1); + return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); + } + + initFunction(node, isAsync) { + super.initFunction(node, isAsync); + node.expression = false; + } + + checkDeclaration(node) { + if (isSimpleProperty(node)) { + this.checkDeclaration(node.value); + } else { + super.checkDeclaration(node); + } + } + + checkGetterSetterParams(method) { + const prop = method; + const paramCount = prop.kind === "get" ? 0 : 1; + const start = prop.start; + + if (prop.value.params.length !== paramCount) { + if (method.kind === "get") { + this.raise(start, ErrorMessages$1.BadGetterArity); + } else { + this.raise(start, ErrorMessages$1.BadSetterArity); + } + } else if (prop.kind === "set" && prop.value.params[0].type === "RestElement") { + this.raise(start, ErrorMessages$1.BadSetterRestParameter); + } + } + + checkLVal(expr, bindingType = BIND_NONE$1, checkClashes, contextDescription, disallowLetBinding) { + switch (expr.type) { + case "ObjectPattern": + expr.properties.forEach(prop => { + this.checkLVal(prop.type === "Property" ? prop.value : prop, bindingType, checkClashes, "object destructuring pattern", disallowLetBinding); + }); + break; + + default: + super.checkLVal(expr, bindingType, checkClashes, contextDescription, disallowLetBinding); + } + } + + checkProto(prop, isRecord, protoRef, refExpressionErrors) { + if (prop.method) { + return; + } + + super.checkProto(prop, isRecord, protoRef, refExpressionErrors); + } + + isValidDirective(stmt) { + var _stmt$expression$extr; + + return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && !((_stmt$expression$extr = stmt.expression.extra) == null ? void 0 : _stmt$expression$extr.parenthesized); + } + + stmtToDirective(stmt) { + const directive = super.stmtToDirective(stmt); + const value = stmt.expression.value; + directive.value.value = value; + return directive; + } + + parseBlockBody(node, allowDirectives, topLevel, end) { + super.parseBlockBody(node, allowDirectives, topLevel, end); + const directiveStatements = node.directives.map(d => this.directiveToStmt(d)); + node.body = directiveStatements.concat(node.body); + delete node.directives; + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true); + + if (method.typeParameters) { + method.value.typeParameters = method.typeParameters; + delete method.typeParameters; + } + + classBody.body.push(method); + } + + parseExprAtom(refExpressionErrors) { + switch (this.state.type) { + case types$4.num: + case types$4.string: + return this.estreeParseLiteral(this.state.value); + + case types$4.regexp: + return this.estreeParseRegExpLiteral(this.state.value); + + case types$4.bigint: + return this.estreeParseBigIntLiteral(this.state.value); + + case types$4._null: + return this.estreeParseLiteral(null); + + case types$4._true: + return this.estreeParseLiteral(true); + + case types$4._false: + return this.estreeParseLiteral(false); + + default: + return super.parseExprAtom(refExpressionErrors); + } + } + + parseLiteral(value, type, startPos, startLoc) { + const node = super.parseLiteral(value, type, startPos, startLoc); + node.raw = node.extra.raw; + delete node.extra; + return node; + } + + parseFunctionBody(node, allowExpression, isMethod = false) { + super.parseFunctionBody(node, allowExpression, isMethod); + node.expression = node.body.type !== "BlockStatement"; + } + + parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { + let funcNode = this.startNode(); + funcNode.kind = node.kind; + funcNode = super.parseMethod(funcNode, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope); + funcNode.type = "FunctionExpression"; + delete funcNode.kind; + node.value = funcNode; + type = type === "ClassMethod" ? "MethodDefinition" : type; + return this.finishNode(node, type); + } + + parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) { + const node = super.parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc); + + if (node) { + node.type = "Property"; + if (node.kind === "method") node.kind = "init"; + node.shorthand = false; + } + + return node; + } + + parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) { + const node = super.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors); + + if (node) { + node.kind = "init"; + node.type = "Property"; + } + + return node; + } + + toAssignable(node) { + if (isSimpleProperty(node)) { + this.toAssignable(node.value); + return node; + } + + return super.toAssignable(node); + } + + toAssignableObjectExpressionProp(prop, isLast) { + if (prop.kind === "get" || prop.kind === "set") { + throw this.raise(prop.key.start, ErrorMessages$1.PatternHasAccessor); + } else if (prop.method) { + throw this.raise(prop.key.start, ErrorMessages$1.PatternHasMethod); + } else { + super.toAssignableObjectExpressionProp(prop, isLast); + } + } + + finishCallExpression(node, optional) { + super.finishCallExpression(node, optional); + + if (node.callee.type === "Import") { + node.type = "ImportExpression"; + node.source = node.arguments[0]; + delete node.arguments; + delete node.callee; + } else if (node.type === "CallExpression") { + node.optional = false; + } + + return node; + } + + toReferencedListDeep(exprList, isParenthesizedExpr) { + if (!exprList) { + return; + } + + super.toReferencedListDeep(exprList, isParenthesizedExpr); + } + + parseExport(node) { + super.parseExport(node); + + switch (node.type) { + case "ExportAllDeclaration": + node.exported = null; + break; + + case "ExportNamedDeclaration": + if (node.specifiers.length === 1 && node.specifiers[0].type === "ExportNamespaceSpecifier") { + node.type = "ExportAllDeclaration"; + node.exported = node.specifiers[0].exported; + delete node.specifiers; + } + + break; + } + + return node; + } + + parseSubscript(...args) { + const node = super.parseSubscript(...args); + + if (node.type === "MemberExpression") { + node.optional = false; + } + + return node; + } + + }); + + let TokContext$1 = class TokContext { + constructor(token, isExpr, preserveSpace, override) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + } + + }; + const types$1$1 = { + braceStatement: new TokContext$1("{", false), + braceExpression: new TokContext$1("{", true), + templateQuasi: new TokContext$1("${", false), + parenStatement: new TokContext$1("(", false), + parenExpression: new TokContext$1("(", true), + template: new TokContext$1("`", true, true, p => p.readTmplToken()), + functionExpression: new TokContext$1("function", true), + functionStatement: new TokContext$1("function", false) + }; + + types$4.parenR.updateContext = types$4.braceR.updateContext = function () { + if (this.state.context.length === 1) { + this.state.exprAllowed = true; + return; + } + + let out = this.state.context.pop(); + + if (out === types$1$1.braceStatement && this.curContext().token === "function") { + out = this.state.context.pop(); + } + + this.state.exprAllowed = !out.isExpr; + }; + + types$4.name.updateContext = function (prevType) { + let allowed = false; + + if (prevType !== types$4.dot) { + if (this.state.value === "of" && !this.state.exprAllowed && prevType !== types$4._function && prevType !== types$4._class || this.state.value === "yield" && this.prodParam.hasYield) { + allowed = true; + } + } + + this.state.exprAllowed = allowed; + + if (this.state.isIterator) { + this.state.isIterator = false; + } + }; + + types$4.braceL.updateContext = function (prevType) { + this.state.context.push(this.braceIsBlock(prevType) ? types$1$1.braceStatement : types$1$1.braceExpression); + this.state.exprAllowed = true; + }; + + types$4.dollarBraceL.updateContext = function () { + this.state.context.push(types$1$1.templateQuasi); + this.state.exprAllowed = true; + }; + + types$4.parenL.updateContext = function (prevType) { + const statementParens = prevType === types$4._if || prevType === types$4._for || prevType === types$4._with || prevType === types$4._while; + this.state.context.push(statementParens ? types$1$1.parenStatement : types$1$1.parenExpression); + this.state.exprAllowed = true; + }; + + types$4.incDec.updateContext = function () {}; + + types$4._function.updateContext = types$4._class.updateContext = function (prevType) { + if (prevType === types$4.dot || prevType === types$4.questionDot) ; else if (prevType.beforeExpr && prevType !== types$4.semi && prevType !== types$4._else && !(prevType === types$4._return && lineBreak$1.test(this.input.slice(this.state.lastTokEnd, this.state.start))) && !((prevType === types$4.colon || prevType === types$4.braceL) && this.curContext() === types$1$1.b_stat)) { + this.state.context.push(types$1$1.functionExpression); + } else { + this.state.context.push(types$1$1.functionStatement); + } + + this.state.exprAllowed = false; + }; + + types$4.backQuote.updateContext = function () { + if (this.curContext() === types$1$1.template) { + this.state.context.pop(); + } else { + this.state.context.push(types$1$1.template); + } + + this.state.exprAllowed = false; + }; + + types$4.star.updateContext = function () { + this.state.exprAllowed = false; + }; + + let nonASCIIidentifierStartChars$1 = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + let nonASCIIidentifierChars$1 = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + const nonASCIIidentifierStart$1 = new RegExp("[" + nonASCIIidentifierStartChars$1 + "]"); + const nonASCIIidentifier$1 = new RegExp("[" + nonASCIIidentifierStartChars$1 + nonASCIIidentifierChars$1 + "]"); + nonASCIIidentifierStartChars$1 = nonASCIIidentifierChars$1 = null; + const astralIdentifierStartCodes$1 = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; + const astralIdentifierCodes$1 = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + function isInAstralSet$1(code, set) { + let pos = 0x10000; + + for (let i = 0, length = set.length; i < length; i += 2) { + pos += set[i]; + if (pos > code) return false; + pos += set[i + 1]; + if (pos >= code) return true; + } + + return false; + } + + function isIdentifierStart$1(code) { + if (code < 65) return code === 36; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart$1.test(String.fromCharCode(code)); + } + + return isInAstralSet$1(code, astralIdentifierStartCodes$1); + } + function isIdentifierChar$1(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier$1.test(String.fromCharCode(code)); + } + + return isInAstralSet$1(code, astralIdentifierStartCodes$1) || isInAstralSet$1(code, astralIdentifierCodes$1); + } + + const reservedWords$1 = { + keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], + strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], + strictBind: ["eval", "arguments"] + }; + const keywords$1$1 = new Set(reservedWords$1.keyword); + const reservedWordsStrictSet$1 = new Set(reservedWords$1.strict); + const reservedWordsStrictBindSet$1 = new Set(reservedWords$1.strictBind); + function isReservedWord$1(word, inModule) { + return inModule && word === "await" || word === "enum"; + } + function isStrictReservedWord$1(word, inModule) { + return isReservedWord$1(word, inModule) || reservedWordsStrictSet$1.has(word); + } + function isStrictBindOnlyReservedWord$1(word) { + return reservedWordsStrictBindSet$1.has(word); + } + function isStrictBindReservedWord$1(word, inModule) { + return isStrictReservedWord$1(word, inModule) || isStrictBindOnlyReservedWord$1(word); + } + function isKeyword$1(word) { + return keywords$1$1.has(word); + } + + const keywordRelationalOperator$1 = /^in(stanceof)?$/; + function isIteratorStart$1(current, next) { + return current === 64 && next === 64; + } + + const reservedTypes$1 = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]); + const FlowErrors$1 = Object.freeze({ + AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.", + AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module", + AssignReservedType: "Cannot overwrite reserved type %0", + DeclareClassElement: "The `declare` modifier can only appear on class fields.", + DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.", + DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement", + EnumBooleanMemberNotInitialized: "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.", + EnumDuplicateMemberName: "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.", + EnumInconsistentMemberValues: "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.", + EnumInvalidExplicitType: "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + EnumInvalidExplicitTypeUnknownSupplied: "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + EnumInvalidMemberInitializerPrimaryType: "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.", + EnumInvalidMemberInitializerSymbolType: "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.", + EnumInvalidMemberInitializerUnknownType: "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.", + EnumInvalidMemberName: "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.", + EnumNumberMemberNotInitialized: "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.", + EnumStringMemberInconsistentlyInitailized: "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.", + ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements", + InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type", + InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions", + InexactVariance: "Explicit inexact syntax cannot have variance", + InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`", + MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.", + NestedDeclareModule: "`declare module` cannot be used inside another `declare module`", + NestedFlowComment: "Cannot have a flow comment inside another flow comment", + OptionalBindingPattern: "A binding pattern parameter cannot be optional in an implementation signature.", + SpreadVariance: "Spread properties cannot have variance", + TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", + TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis", + UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object", + UnexpectedReservedType: "Unexpected reserved type %0", + UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new", + UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.", + UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions", + UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint"', + UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration", + UnsupportedDeclareExportKind: "`declare export %0` is not supported. Use `%1` instead", + UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module", + UnterminatedFlowComment: "Unterminated flow-comment" + }); + + function isEsModuleType$1(bodyElement) { + return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration"); + } + + function hasTypeImportKind$1(node) { + return node.importKind === "type" || node.importKind === "typeof"; + } + + function isMaybeDefaultImport$1(state) { + return (state.type === types$4.name || !!state.type.keyword) && state.value !== "from"; + } + + const exportSuggestions$1 = { + const: "declare export var", + let: "declare export var", + type: "export type", + interface: "export interface" + }; + + function partition$1(list, test) { + const list1 = []; + const list2 = []; + + for (let i = 0; i < list.length; i++) { + (test(list[i], i, list) ? list1 : list2).push(list[i]); + } + + return [list1, list2]; + } + + const FLOW_PRAGMA_REGEX$1 = /\*?\s*@((?:no)?flow)\b/; + var flow$2 = (superClass => class extends superClass { + constructor(options, input) { + super(options, input); + this.flowPragma = undefined; + } + + shouldParseTypes() { + return this.getPluginOption("flow", "all") || this.flowPragma === "flow"; + } + + shouldParseEnums() { + return !!this.getPluginOption("flow", "enums"); + } + + finishToken(type, val) { + if (type !== types$4.string && type !== types$4.semi && type !== types$4.interpreterDirective) { + if (this.flowPragma === undefined) { + this.flowPragma = null; + } + } + + return super.finishToken(type, val); + } + + addComment(comment) { + if (this.flowPragma === undefined) { + const matches = FLOW_PRAGMA_REGEX$1.exec(comment.value); + + if (!matches) ; else if (matches[1] === "flow") { + this.flowPragma = "flow"; + } else if (matches[1] === "noflow") { + this.flowPragma = "noflow"; + } else { + throw new Error("Unexpected flow pragma"); + } + } + + return super.addComment(comment); + } + + flowParseTypeInitialiser(tok) { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(tok || types$4.colon); + const type = this.flowParseType(); + this.state.inType = oldInType; + return type; + } + + flowParsePredicate() { + const node = this.startNode(); + const moduloLoc = this.state.startLoc; + const moduloPos = this.state.start; + this.expect(types$4.modulo); + const checksLoc = this.state.startLoc; + this.expectContextual("checks"); + + if (moduloLoc.line !== checksLoc.line || moduloLoc.column !== checksLoc.column - 1) { + this.raise(moduloPos, FlowErrors$1.UnexpectedSpaceBetweenModuloChecks); + } + + if (this.eat(types$4.parenL)) { + node.value = this.parseExpression(); + this.expect(types$4.parenR); + return this.finishNode(node, "DeclaredPredicate"); + } else { + return this.finishNode(node, "InferredPredicate"); + } + } + + flowParseTypeAndPredicateInitialiser() { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(types$4.colon); + let type = null; + let predicate = null; + + if (this.match(types$4.modulo)) { + this.state.inType = oldInType; + predicate = this.flowParsePredicate(); + } else { + type = this.flowParseType(); + this.state.inType = oldInType; + + if (this.match(types$4.modulo)) { + predicate = this.flowParsePredicate(); + } + } + + return [type, predicate]; + } + + flowParseDeclareClass(node) { + this.next(); + this.flowParseInterfaceish(node, true); + return this.finishNode(node, "DeclareClass"); + } + + flowParseDeclareFunction(node) { + this.next(); + const id = node.id = this.parseIdentifier(); + const typeNode = this.startNode(); + const typeContainer = this.startNode(); + + if (this.isRelational("<")) { + typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + typeNode.typeParameters = null; + } + + this.expect(types$4.parenL); + const tmp = this.flowParseFunctionTypeParams(); + typeNode.params = tmp.params; + typeNode.rest = tmp.rest; + this.expect(types$4.parenR); + [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); + id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); + this.resetEndLocation(id); + this.semicolon(); + return this.finishNode(node, "DeclareFunction"); + } + + flowParseDeclare(node, insideModule) { + if (this.match(types$4._class)) { + return this.flowParseDeclareClass(node); + } else if (this.match(types$4._function)) { + return this.flowParseDeclareFunction(node); + } else if (this.match(types$4._var)) { + return this.flowParseDeclareVariable(node); + } else if (this.eatContextual("module")) { + if (this.match(types$4.dot)) { + return this.flowParseDeclareModuleExports(node); + } else { + if (insideModule) { + this.raise(this.state.lastTokStart, FlowErrors$1.NestedDeclareModule); + } + + return this.flowParseDeclareModule(node); + } + } else if (this.isContextual("type")) { + return this.flowParseDeclareTypeAlias(node); + } else if (this.isContextual("opaque")) { + return this.flowParseDeclareOpaqueType(node); + } else if (this.isContextual("interface")) { + return this.flowParseDeclareInterface(node); + } else if (this.match(types$4._export)) { + return this.flowParseDeclareExportDeclaration(node, insideModule); + } else { + throw this.unexpected(); + } + } + + flowParseDeclareVariable(node) { + this.next(); + node.id = this.flowParseTypeAnnotatableIdentifier(true); + this.scope.declareName(node.id.name, BIND_VAR$1, node.id.start); + this.semicolon(); + return this.finishNode(node, "DeclareVariable"); + } + + flowParseDeclareModule(node) { + this.scope.enter(SCOPE_OTHER$1); + + if (this.match(types$4.string)) { + node.id = this.parseExprAtom(); + } else { + node.id = this.parseIdentifier(); + } + + const bodyNode = node.body = this.startNode(); + const body = bodyNode.body = []; + this.expect(types$4.braceL); + + while (!this.match(types$4.braceR)) { + let bodyNode = this.startNode(); + + if (this.match(types$4._import)) { + this.next(); + + if (!this.isContextual("type") && !this.match(types$4._typeof)) { + this.raise(this.state.lastTokStart, FlowErrors$1.InvalidNonTypeImportInDeclareModule); + } + + this.parseImport(bodyNode); + } else { + this.expectContextual("declare", FlowErrors$1.UnsupportedStatementInDeclareModule); + bodyNode = this.flowParseDeclare(bodyNode, true); + } + + body.push(bodyNode); + } + + this.scope.exit(); + this.expect(types$4.braceR); + this.finishNode(bodyNode, "BlockStatement"); + let kind = null; + let hasModuleExport = false; + body.forEach(bodyElement => { + if (isEsModuleType$1(bodyElement)) { + if (kind === "CommonJS") { + this.raise(bodyElement.start, FlowErrors$1.AmbiguousDeclareModuleKind); + } + + kind = "ES"; + } else if (bodyElement.type === "DeclareModuleExports") { + if (hasModuleExport) { + this.raise(bodyElement.start, FlowErrors$1.DuplicateDeclareModuleExports); + } + + if (kind === "ES") { + this.raise(bodyElement.start, FlowErrors$1.AmbiguousDeclareModuleKind); + } + + kind = "CommonJS"; + hasModuleExport = true; + } + }); + node.kind = kind || "CommonJS"; + return this.finishNode(node, "DeclareModule"); + } + + flowParseDeclareExportDeclaration(node, insideModule) { + this.expect(types$4._export); + + if (this.eat(types$4._default)) { + if (this.match(types$4._function) || this.match(types$4._class)) { + node.declaration = this.flowParseDeclare(this.startNode()); + } else { + node.declaration = this.flowParseType(); + this.semicolon(); + } + + node.default = true; + return this.finishNode(node, "DeclareExportDeclaration"); + } else { + if (this.match(types$4._const) || this.isLet() || (this.isContextual("type") || this.isContextual("interface")) && !insideModule) { + const label = this.state.value; + const suggestion = exportSuggestions$1[label]; + throw this.raise(this.state.start, FlowErrors$1.UnsupportedDeclareExportKind, label, suggestion); + } + + if (this.match(types$4._var) || this.match(types$4._function) || this.match(types$4._class) || this.isContextual("opaque")) { + node.declaration = this.flowParseDeclare(this.startNode()); + node.default = false; + return this.finishNode(node, "DeclareExportDeclaration"); + } else if (this.match(types$4.star) || this.match(types$4.braceL) || this.isContextual("interface") || this.isContextual("type") || this.isContextual("opaque")) { + node = this.parseExport(node); + + if (node.type === "ExportNamedDeclaration") { + node.type = "ExportDeclaration"; + node.default = false; + delete node.exportKind; + } + + node.type = "Declare" + node.type; + return node; + } + } + + throw this.unexpected(); + } + + flowParseDeclareModuleExports(node) { + this.next(); + this.expectContextual("exports"); + node.typeAnnotation = this.flowParseTypeAnnotation(); + this.semicolon(); + return this.finishNode(node, "DeclareModuleExports"); + } + + flowParseDeclareTypeAlias(node) { + this.next(); + this.flowParseTypeAlias(node); + node.type = "DeclareTypeAlias"; + return node; + } + + flowParseDeclareOpaqueType(node) { + this.next(); + this.flowParseOpaqueType(node, true); + node.type = "DeclareOpaqueType"; + return node; + } + + flowParseDeclareInterface(node) { + this.next(); + this.flowParseInterfaceish(node); + return this.finishNode(node, "DeclareInterface"); + } + + flowParseInterfaceish(node, isClass = false) { + node.id = this.flowParseRestrictedIdentifier(!isClass, true); + this.scope.declareName(node.id.name, isClass ? BIND_FUNCTION$1 : BIND_LEXICAL$1, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.extends = []; + node.implements = []; + node.mixins = []; + + if (this.eat(types$4._extends)) { + do { + node.extends.push(this.flowParseInterfaceExtends()); + } while (!isClass && this.eat(types$4.comma)); + } + + if (this.isContextual("mixins")) { + this.next(); + + do { + node.mixins.push(this.flowParseInterfaceExtends()); + } while (this.eat(types$4.comma)); + } + + if (this.isContextual("implements")) { + this.next(); + + do { + node.implements.push(this.flowParseInterfaceExtends()); + } while (this.eat(types$4.comma)); + } + + node.body = this.flowParseObjectType({ + allowStatic: isClass, + allowExact: false, + allowSpread: false, + allowProto: isClass, + allowInexact: false + }); + } + + flowParseInterfaceExtends() { + const node = this.startNode(); + node.id = this.flowParseQualifiedTypeIdentifier(); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + + return this.finishNode(node, "InterfaceExtends"); + } + + flowParseInterface(node) { + this.flowParseInterfaceish(node); + return this.finishNode(node, "InterfaceDeclaration"); + } + + checkNotUnderscore(word) { + if (word === "_") { + this.raise(this.state.start, FlowErrors$1.UnexpectedReservedUnderscore); + } + } + + checkReservedType(word, startLoc, declaration) { + if (!reservedTypes$1.has(word)) return; + this.raise(startLoc, declaration ? FlowErrors$1.AssignReservedType : FlowErrors$1.UnexpectedReservedType, word); + } + + flowParseRestrictedIdentifier(liberal, declaration) { + this.checkReservedType(this.state.value, this.state.start, declaration); + return this.parseIdentifier(liberal); + } + + flowParseTypeAlias(node) { + node.id = this.flowParseRestrictedIdentifier(false, true); + this.scope.declareName(node.id.name, BIND_LEXICAL$1, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.right = this.flowParseTypeInitialiser(types$4.eq); + this.semicolon(); + return this.finishNode(node, "TypeAlias"); + } + + flowParseOpaqueType(node, declare) { + this.expectContextual("type"); + node.id = this.flowParseRestrictedIdentifier(true, true); + this.scope.declareName(node.id.name, BIND_LEXICAL$1, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.supertype = null; + + if (this.match(types$4.colon)) { + node.supertype = this.flowParseTypeInitialiser(types$4.colon); + } + + node.impltype = null; + + if (!declare) { + node.impltype = this.flowParseTypeInitialiser(types$4.eq); + } + + this.semicolon(); + return this.finishNode(node, "OpaqueType"); + } + + flowParseTypeParameter(requireDefault = false) { + const nodeStart = this.state.start; + const node = this.startNode(); + const variance = this.flowParseVariance(); + const ident = this.flowParseTypeAnnotatableIdentifier(); + node.name = ident.name; + node.variance = variance; + node.bound = ident.typeAnnotation; + + if (this.match(types$4.eq)) { + this.eat(types$4.eq); + node.default = this.flowParseType(); + } else { + if (requireDefault) { + this.raise(nodeStart, FlowErrors$1.MissingTypeParamDefault); + } + } + + return this.finishNode(node, "TypeParameter"); + } + + flowParseTypeParameterDeclaration() { + const oldInType = this.state.inType; + const node = this.startNode(); + node.params = []; + this.state.inType = true; + + if (this.isRelational("<") || this.match(types$4.jsxTagStart)) { + this.next(); + } else { + this.unexpected(); + } + + let defaultRequired = false; + + do { + const typeParameter = this.flowParseTypeParameter(defaultRequired); + node.params.push(typeParameter); + + if (typeParameter.default) { + defaultRequired = true; + } + + if (!this.isRelational(">")) { + this.expect(types$4.comma); + } + } while (!this.isRelational(">")); + + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterDeclaration"); + } + + flowParseTypeParameterInstantiation() { + const node = this.startNode(); + const oldInType = this.state.inType; + node.params = []; + this.state.inType = true; + this.expectRelational("<"); + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = false; + + while (!this.isRelational(">")) { + node.params.push(this.flowParseType()); + + if (!this.isRelational(">")) { + this.expect(types$4.comma); + } + } + + this.state.noAnonFunctionType = oldNoAnonFunctionType; + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterInstantiation"); + } + + flowParseTypeParameterInstantiationCallOrNew() { + const node = this.startNode(); + const oldInType = this.state.inType; + node.params = []; + this.state.inType = true; + this.expectRelational("<"); + + while (!this.isRelational(">")) { + node.params.push(this.flowParseTypeOrImplicitInstantiation()); + + if (!this.isRelational(">")) { + this.expect(types$4.comma); + } + } + + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterInstantiation"); + } + + flowParseInterfaceType() { + const node = this.startNode(); + this.expectContextual("interface"); + node.extends = []; + + if (this.eat(types$4._extends)) { + do { + node.extends.push(this.flowParseInterfaceExtends()); + } while (this.eat(types$4.comma)); + } + + node.body = this.flowParseObjectType({ + allowStatic: false, + allowExact: false, + allowSpread: false, + allowProto: false, + allowInexact: false + }); + return this.finishNode(node, "InterfaceTypeAnnotation"); + } + + flowParseObjectPropertyKey() { + return this.match(types$4.num) || this.match(types$4.string) ? this.parseExprAtom() : this.parseIdentifier(true); + } + + flowParseObjectTypeIndexer(node, isStatic, variance) { + node.static = isStatic; + + if (this.lookahead().type === types$4.colon) { + node.id = this.flowParseObjectPropertyKey(); + node.key = this.flowParseTypeInitialiser(); + } else { + node.id = null; + node.key = this.flowParseType(); + } + + this.expect(types$4.bracketR); + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + return this.finishNode(node, "ObjectTypeIndexer"); + } + + flowParseObjectTypeInternalSlot(node, isStatic) { + node.static = isStatic; + node.id = this.flowParseObjectPropertyKey(); + this.expect(types$4.bracketR); + this.expect(types$4.bracketR); + + if (this.isRelational("<") || this.match(types$4.parenL)) { + node.method = true; + node.optional = false; + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + } else { + node.method = false; + + if (this.eat(types$4.question)) { + node.optional = true; + } + + node.value = this.flowParseTypeInitialiser(); + } + + return this.finishNode(node, "ObjectTypeInternalSlot"); + } + + flowParseObjectTypeMethodish(node) { + node.params = []; + node.rest = null; + node.typeParameters = null; + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + this.expect(types$4.parenL); + + while (!this.match(types$4.parenR) && !this.match(types$4.ellipsis)) { + node.params.push(this.flowParseFunctionTypeParam()); + + if (!this.match(types$4.parenR)) { + this.expect(types$4.comma); + } + } + + if (this.eat(types$4.ellipsis)) { + node.rest = this.flowParseFunctionTypeParam(); + } + + this.expect(types$4.parenR); + node.returnType = this.flowParseTypeInitialiser(); + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + flowParseObjectTypeCallProperty(node, isStatic) { + const valueNode = this.startNode(); + node.static = isStatic; + node.value = this.flowParseObjectTypeMethodish(valueNode); + return this.finishNode(node, "ObjectTypeCallProperty"); + } + + flowParseObjectType({ + allowStatic, + allowExact, + allowSpread, + allowProto, + allowInexact + }) { + const oldInType = this.state.inType; + this.state.inType = true; + const nodeStart = this.startNode(); + nodeStart.callProperties = []; + nodeStart.properties = []; + nodeStart.indexers = []; + nodeStart.internalSlots = []; + let endDelim; + let exact; + let inexact = false; + + if (allowExact && this.match(types$4.braceBarL)) { + this.expect(types$4.braceBarL); + endDelim = types$4.braceBarR; + exact = true; + } else { + this.expect(types$4.braceL); + endDelim = types$4.braceR; + exact = false; + } + + nodeStart.exact = exact; + + while (!this.match(endDelim)) { + let isStatic = false; + let protoStart = null; + let inexactStart = null; + const node = this.startNode(); + + if (allowProto && this.isContextual("proto")) { + const lookahead = this.lookahead(); + + if (lookahead.type !== types$4.colon && lookahead.type !== types$4.question) { + this.next(); + protoStart = this.state.start; + allowStatic = false; + } + } + + if (allowStatic && this.isContextual("static")) { + const lookahead = this.lookahead(); + + if (lookahead.type !== types$4.colon && lookahead.type !== types$4.question) { + this.next(); + isStatic = true; + } + } + + const variance = this.flowParseVariance(); + + if (this.eat(types$4.bracketL)) { + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (this.eat(types$4.bracketL)) { + if (variance) { + this.unexpected(variance.start); + } + + nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic)); + } else { + nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); + } + } else if (this.match(types$4.parenL) || this.isRelational("<")) { + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.unexpected(variance.start); + } + + nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); + } else { + let kind = "init"; + + if (this.isContextual("get") || this.isContextual("set")) { + const lookahead = this.lookahead(); + + if (lookahead.type === types$4.name || lookahead.type === types$4.string || lookahead.type === types$4.num) { + kind = this.state.value; + this.next(); + } + } + + const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact); + + if (propOrInexact === null) { + inexact = true; + inexactStart = this.state.lastTokStart; + } else { + nodeStart.properties.push(propOrInexact); + } + } + + this.flowObjectTypeSemicolon(); + + if (inexactStart && !this.match(types$4.braceR) && !this.match(types$4.braceBarR)) { + this.raise(inexactStart, FlowErrors$1.UnexpectedExplicitInexactInObject); + } + } + + this.expect(endDelim); + + if (allowSpread) { + nodeStart.inexact = inexact; + } + + const out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); + this.state.inType = oldInType; + return out; + } + + flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) { + if (this.eat(types$4.ellipsis)) { + const isInexactToken = this.match(types$4.comma) || this.match(types$4.semi) || this.match(types$4.braceR) || this.match(types$4.braceBarR); + + if (isInexactToken) { + if (!allowSpread) { + this.raise(this.state.lastTokStart, FlowErrors$1.InexactInsideNonObject); + } else if (!allowInexact) { + this.raise(this.state.lastTokStart, FlowErrors$1.InexactInsideExact); + } + + if (variance) { + this.raise(variance.start, FlowErrors$1.InexactVariance); + } + + return null; + } + + if (!allowSpread) { + this.raise(this.state.lastTokStart, FlowErrors$1.UnexpectedSpreadType); + } + + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.raise(variance.start, FlowErrors$1.SpreadVariance); + } + + node.argument = this.flowParseType(); + return this.finishNode(node, "ObjectTypeSpreadProperty"); + } else { + node.key = this.flowParseObjectPropertyKey(); + node.static = isStatic; + node.proto = protoStart != null; + node.kind = kind; + let optional = false; + + if (this.isRelational("<") || this.match(types$4.parenL)) { + node.method = true; + + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.unexpected(variance.start); + } + + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + + if (kind === "get" || kind === "set") { + this.flowCheckGetterSetterParams(node); + } + } else { + if (kind !== "init") this.unexpected(); + node.method = false; + + if (this.eat(types$4.question)) { + optional = true; + } + + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + } + + node.optional = optional; + return this.finishNode(node, "ObjectTypeProperty"); + } + } + + flowCheckGetterSetterParams(property) { + const paramCount = property.kind === "get" ? 0 : 1; + const start = property.start; + const length = property.value.params.length + (property.value.rest ? 1 : 0); + + if (length !== paramCount) { + if (property.kind === "get") { + this.raise(start, ErrorMessages$1.BadGetterArity); + } else { + this.raise(start, ErrorMessages$1.BadSetterArity); + } + } + + if (property.kind === "set" && property.value.rest) { + this.raise(start, ErrorMessages$1.BadSetterRestParameter); + } + } + + flowObjectTypeSemicolon() { + if (!this.eat(types$4.semi) && !this.eat(types$4.comma) && !this.match(types$4.braceR) && !this.match(types$4.braceBarR)) { + this.unexpected(); + } + } + + flowParseQualifiedTypeIdentifier(startPos, startLoc, id) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + let node = id || this.flowParseRestrictedIdentifier(true); + + while (this.eat(types$4.dot)) { + const node2 = this.startNodeAt(startPos, startLoc); + node2.qualification = node; + node2.id = this.flowParseRestrictedIdentifier(true); + node = this.finishNode(node2, "QualifiedTypeIdentifier"); + } + + return node; + } + + flowParseGenericType(startPos, startLoc, id) { + const node = this.startNodeAt(startPos, startLoc); + node.typeParameters = null; + node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } + + return this.finishNode(node, "GenericTypeAnnotation"); + } + + flowParseTypeofType() { + const node = this.startNode(); + this.expect(types$4._typeof); + node.argument = this.flowParsePrimaryType(); + return this.finishNode(node, "TypeofTypeAnnotation"); + } + + flowParseTupleType() { + const node = this.startNode(); + node.types = []; + this.expect(types$4.bracketL); + + while (this.state.pos < this.length && !this.match(types$4.bracketR)) { + node.types.push(this.flowParseType()); + if (this.match(types$4.bracketR)) break; + this.expect(types$4.comma); + } + + this.expect(types$4.bracketR); + return this.finishNode(node, "TupleTypeAnnotation"); + } + + flowParseFunctionTypeParam() { + let name = null; + let optional = false; + let typeAnnotation = null; + const node = this.startNode(); + const lh = this.lookahead(); + + if (lh.type === types$4.colon || lh.type === types$4.question) { + name = this.parseIdentifier(); + + if (this.eat(types$4.question)) { + optional = true; + } + + typeAnnotation = this.flowParseTypeInitialiser(); + } else { + typeAnnotation = this.flowParseType(); + } + + node.name = name; + node.optional = optional; + node.typeAnnotation = typeAnnotation; + return this.finishNode(node, "FunctionTypeParam"); + } + + reinterpretTypeAsFunctionTypeParam(type) { + const node = this.startNodeAt(type.start, type.loc.start); + node.name = null; + node.optional = false; + node.typeAnnotation = type; + return this.finishNode(node, "FunctionTypeParam"); + } + + flowParseFunctionTypeParams(params = []) { + let rest = null; + + while (!this.match(types$4.parenR) && !this.match(types$4.ellipsis)) { + params.push(this.flowParseFunctionTypeParam()); + + if (!this.match(types$4.parenR)) { + this.expect(types$4.comma); + } + } + + if (this.eat(types$4.ellipsis)) { + rest = this.flowParseFunctionTypeParam(); + } + + return { + params, + rest + }; + } + + flowIdentToTypeAnnotation(startPos, startLoc, node, id) { + switch (id.name) { + case "any": + return this.finishNode(node, "AnyTypeAnnotation"); + + case "bool": + case "boolean": + return this.finishNode(node, "BooleanTypeAnnotation"); + + case "mixed": + return this.finishNode(node, "MixedTypeAnnotation"); + + case "empty": + return this.finishNode(node, "EmptyTypeAnnotation"); + + case "number": + return this.finishNode(node, "NumberTypeAnnotation"); + + case "string": + return this.finishNode(node, "StringTypeAnnotation"); + + case "symbol": + return this.finishNode(node, "SymbolTypeAnnotation"); + + default: + this.checkNotUnderscore(id.name); + return this.flowParseGenericType(startPos, startLoc, id); + } + } + + flowParsePrimaryType() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const node = this.startNode(); + let tmp; + let type; + let isGroupedType = false; + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + + switch (this.state.type) { + case types$4.name: + if (this.isContextual("interface")) { + return this.flowParseInterfaceType(); + } + + return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); + + case types$4.braceL: + return this.flowParseObjectType({ + allowStatic: false, + allowExact: false, + allowSpread: true, + allowProto: false, + allowInexact: true + }); + + case types$4.braceBarL: + return this.flowParseObjectType({ + allowStatic: false, + allowExact: true, + allowSpread: true, + allowProto: false, + allowInexact: false + }); + + case types$4.bracketL: + this.state.noAnonFunctionType = false; + type = this.flowParseTupleType(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + return type; + + case types$4.relational: + if (this.state.value === "<") { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + this.expect(types$4.parenL); + tmp = this.flowParseFunctionTypeParams(); + node.params = tmp.params; + node.rest = tmp.rest; + this.expect(types$4.parenR); + this.expect(types$4.arrow); + node.returnType = this.flowParseType(); + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + break; + + case types$4.parenL: + this.next(); + + if (!this.match(types$4.parenR) && !this.match(types$4.ellipsis)) { + if (this.match(types$4.name)) { + const token = this.lookahead().type; + isGroupedType = token !== types$4.question && token !== types$4.colon; + } else { + isGroupedType = true; + } + } + + if (isGroupedType) { + this.state.noAnonFunctionType = false; + type = this.flowParseType(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + + if (this.state.noAnonFunctionType || !(this.match(types$4.comma) || this.match(types$4.parenR) && this.lookahead().type === types$4.arrow)) { + this.expect(types$4.parenR); + return type; + } else { + this.eat(types$4.comma); + } + } + + if (type) { + tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]); + } else { + tmp = this.flowParseFunctionTypeParams(); + } + + node.params = tmp.params; + node.rest = tmp.rest; + this.expect(types$4.parenR); + this.expect(types$4.arrow); + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + + case types$4.string: + return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); + + case types$4._true: + case types$4._false: + node.value = this.match(types$4._true); + this.next(); + return this.finishNode(node, "BooleanLiteralTypeAnnotation"); + + case types$4.plusMin: + if (this.state.value === "-") { + this.next(); + + if (this.match(types$4.num)) { + return this.parseLiteral(-this.state.value, "NumberLiteralTypeAnnotation", node.start, node.loc.start); + } + + if (this.match(types$4.bigint)) { + return this.parseLiteral(-this.state.value, "BigIntLiteralTypeAnnotation", node.start, node.loc.start); + } + + throw this.raise(this.state.start, FlowErrors$1.UnexpectedSubtractionOperand); + } + + throw this.unexpected(); + + case types$4.num: + return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); + + case types$4.bigint: + return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation"); + + case types$4._void: + this.next(); + return this.finishNode(node, "VoidTypeAnnotation"); + + case types$4._null: + this.next(); + return this.finishNode(node, "NullLiteralTypeAnnotation"); + + case types$4._this: + this.next(); + return this.finishNode(node, "ThisTypeAnnotation"); + + case types$4.star: + this.next(); + return this.finishNode(node, "ExistsTypeAnnotation"); + + default: + if (this.state.type.keyword === "typeof") { + return this.flowParseTypeofType(); + } else if (this.state.type.keyword) { + const label = this.state.type.label; + this.next(); + return super.createIdentifier(node, label); + } + + } + + throw this.unexpected(); + } + + flowParsePostfixType() { + const startPos = this.state.start, + startLoc = this.state.startLoc; + let type = this.flowParsePrimaryType(); + + while (this.match(types$4.bracketL) && !this.canInsertSemicolon()) { + const node = this.startNodeAt(startPos, startLoc); + node.elementType = type; + this.expect(types$4.bracketL); + this.expect(types$4.bracketR); + type = this.finishNode(node, "ArrayTypeAnnotation"); + } + + return type; + } + + flowParsePrefixType() { + const node = this.startNode(); + + if (this.eat(types$4.question)) { + node.typeAnnotation = this.flowParsePrefixType(); + return this.finishNode(node, "NullableTypeAnnotation"); + } else { + return this.flowParsePostfixType(); + } + } + + flowParseAnonFunctionWithoutParens() { + const param = this.flowParsePrefixType(); + + if (!this.state.noAnonFunctionType && this.eat(types$4.arrow)) { + const node = this.startNodeAt(param.start, param.loc.start); + node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; + node.rest = null; + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + return param; + } + + flowParseIntersectionType() { + const node = this.startNode(); + this.eat(types$4.bitwiseAND); + const type = this.flowParseAnonFunctionWithoutParens(); + node.types = [type]; + + while (this.eat(types$4.bitwiseAND)) { + node.types.push(this.flowParseAnonFunctionWithoutParens()); + } + + return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); + } + + flowParseUnionType() { + const node = this.startNode(); + this.eat(types$4.bitwiseOR); + const type = this.flowParseIntersectionType(); + node.types = [type]; + + while (this.eat(types$4.bitwiseOR)) { + node.types.push(this.flowParseIntersectionType()); + } + + return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); + } + + flowParseType() { + const oldInType = this.state.inType; + this.state.inType = true; + const type = this.flowParseUnionType(); + this.state.inType = oldInType; + this.state.exprAllowed = this.state.exprAllowed || this.state.noAnonFunctionType; + return type; + } + + flowParseTypeOrImplicitInstantiation() { + if (this.state.type === types$4.name && this.state.value === "_") { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const node = this.parseIdentifier(); + return this.flowParseGenericType(startPos, startLoc, node); + } else { + return this.flowParseType(); + } + } + + flowParseTypeAnnotation() { + const node = this.startNode(); + node.typeAnnotation = this.flowParseTypeInitialiser(); + return this.finishNode(node, "TypeAnnotation"); + } + + flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) { + const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier(); + + if (this.match(types$4.colon)) { + ident.typeAnnotation = this.flowParseTypeAnnotation(); + this.resetEndLocation(ident); + } + + return ident; + } + + typeCastToParameter(node) { + node.expression.typeAnnotation = node.typeAnnotation; + this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + return node.expression; + } + + flowParseVariance() { + let variance = null; + + if (this.match(types$4.plusMin)) { + variance = this.startNode(); + + if (this.state.value === "+") { + variance.kind = "plus"; + } else { + variance.kind = "minus"; + } + + this.next(); + this.finishNode(variance, "Variance"); + } + + return variance; + } + + parseFunctionBody(node, allowExpressionBody, isMethod = false) { + if (allowExpressionBody) { + return this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod)); + } + + return super.parseFunctionBody(node, false, isMethod); + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + if (this.match(types$4.colon)) { + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null; + } + + super.parseFunctionBodyAndFinish(node, type, isMethod); + } + + parseStatement(context, topLevel) { + if (this.state.strict && this.match(types$4.name) && this.state.value === "interface") { + const node = this.startNode(); + this.next(); + return this.flowParseInterface(node); + } else if (this.shouldParseEnums() && this.isContextual("enum")) { + const node = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(node); + } else { + const stmt = super.parseStatement(context, topLevel); + + if (this.flowPragma === undefined && !this.isValidDirective(stmt)) { + this.flowPragma = null; + } + + return stmt; + } + } + + parseExpressionStatement(node, expr) { + if (expr.type === "Identifier") { + if (expr.name === "declare") { + if (this.match(types$4._class) || this.match(types$4.name) || this.match(types$4._function) || this.match(types$4._var) || this.match(types$4._export)) { + return this.flowParseDeclare(node); + } + } else if (this.match(types$4.name)) { + if (expr.name === "interface") { + return this.flowParseInterface(node); + } else if (expr.name === "type") { + return this.flowParseTypeAlias(node); + } else if (expr.name === "opaque") { + return this.flowParseOpaqueType(node, false); + } + } + } + + return super.parseExpressionStatement(node, expr); + } + + shouldParseExportDeclaration() { + return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || this.shouldParseEnums() && this.isContextual("enum") || super.shouldParseExportDeclaration(); + } + + isExportDefaultSpecifier() { + if (this.match(types$4.name) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque" || this.shouldParseEnums() && this.state.value === "enum")) { + return false; + } + + return super.isExportDefaultSpecifier(); + } + + parseExportDefaultExpression() { + if (this.shouldParseEnums() && this.isContextual("enum")) { + const node = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(node); + } + + return super.parseExportDefaultExpression(); + } + + parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { + if (!this.match(types$4.question)) return expr; + + if (refNeedsArrowPos) { + const result = this.tryParse(() => super.parseConditional(expr, noIn, startPos, startLoc)); + + if (!result.node) { + refNeedsArrowPos.start = result.error.pos || this.state.start; + return expr; + } + + if (result.error) this.state = result.failState; + return result.node; + } + + this.expect(types$4.question); + const state = this.state.clone(); + const originalNoArrowAt = this.state.noArrowAt; + const node = this.startNodeAt(startPos, startLoc); + let { + consequent, + failed + } = this.tryParseConditionalConsequent(); + let [valid, invalid] = this.getArrowLikeExpressions(consequent); + + if (failed || invalid.length > 0) { + const noArrowAt = [...originalNoArrowAt]; + + if (invalid.length > 0) { + this.state = state; + this.state.noArrowAt = noArrowAt; + + for (let i = 0; i < invalid.length; i++) { + noArrowAt.push(invalid[i].start); + } + + ({ + consequent, + failed + } = this.tryParseConditionalConsequent()); + [valid, invalid] = this.getArrowLikeExpressions(consequent); + } + + if (failed && valid.length > 1) { + this.raise(state.start, FlowErrors$1.AmbiguousConditionalArrow); + } + + if (failed && valid.length === 1) { + this.state = state; + this.state.noArrowAt = noArrowAt.concat(valid[0].start); + ({ + consequent, + failed + } = this.tryParseConditionalConsequent()); + } + } + + this.getArrowLikeExpressions(consequent, true); + this.state.noArrowAt = originalNoArrowAt; + this.expect(types$4.colon); + node.test = expr; + node.consequent = consequent; + node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(noIn, undefined, undefined, undefined)); + return this.finishNode(node, "ConditionalExpression"); + } + + tryParseConditionalConsequent() { + this.state.noArrowParamsConversionAt.push(this.state.start); + const consequent = this.parseMaybeAssign(); + const failed = !this.match(types$4.colon); + this.state.noArrowParamsConversionAt.pop(); + return { + consequent, + failed + }; + } + + getArrowLikeExpressions(node, disallowInvalid) { + const stack = [node]; + const arrows = []; + + while (stack.length !== 0) { + const node = stack.pop(); + + if (node.type === "ArrowFunctionExpression") { + if (node.typeParameters || !node.returnType) { + this.finishArrowValidation(node); + } else { + arrows.push(node); + } + + stack.push(node.body); + } else if (node.type === "ConditionalExpression") { + stack.push(node.consequent); + stack.push(node.alternate); + } + } + + if (disallowInvalid) { + arrows.forEach(node => this.finishArrowValidation(node)); + return [arrows, []]; + } + + return partition$1(arrows, node => node.params.every(param => this.isAssignable(param, true))); + } + + finishArrowValidation(node) { + var _node$extra; + + this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingComma); + this.scope.enter(SCOPE_FUNCTION$1 | SCOPE_ARROW$1); + super.checkParams(node, false, true); + this.scope.exit(); + } + + forwardNoArrowParamsConversionAt(node, parse) { + let result; + + if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + this.state.noArrowParamsConversionAt.push(this.state.start); + result = parse(); + this.state.noArrowParamsConversionAt.pop(); + } else { + result = parse(); + } + + return result; + } + + parseParenItem(node, startPos, startLoc) { + node = super.parseParenItem(node, startPos, startLoc); + + if (this.eat(types$4.question)) { + node.optional = true; + this.resetEndLocation(node); + } + + if (this.match(types$4.colon)) { + const typeCastNode = this.startNodeAt(startPos, startLoc); + typeCastNode.expression = node; + typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); + return this.finishNode(typeCastNode, "TypeCastExpression"); + } + + return node; + } + + assertModuleNodeAllowed(node) { + if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") { + return; + } + + super.assertModuleNodeAllowed(node); + } + + parseExport(node) { + const decl = super.parseExport(node); + + if (decl.type === "ExportNamedDeclaration" || decl.type === "ExportAllDeclaration") { + decl.exportKind = decl.exportKind || "value"; + } + + return decl; + } + + parseExportDeclaration(node) { + if (this.isContextual("type")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + + if (this.match(types$4.braceL)) { + node.specifiers = this.parseExportSpecifiers(); + this.parseExportFrom(node); + return null; + } else { + return this.flowParseTypeAlias(declarationNode); + } + } else if (this.isContextual("opaque")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseOpaqueType(declarationNode, false); + } else if (this.isContextual("interface")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseInterface(declarationNode); + } else if (this.shouldParseEnums() && this.isContextual("enum")) { + node.exportKind = "value"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(declarationNode); + } else { + return super.parseExportDeclaration(node); + } + } + + eatExportStar(node) { + if (super.eatExportStar(...arguments)) return true; + + if (this.isContextual("type") && this.lookahead().type === types$4.star) { + node.exportKind = "type"; + this.next(); + this.next(); + return true; + } + + return false; + } + + maybeParseExportNamespaceSpecifier(node) { + const pos = this.state.start; + const hasNamespace = super.maybeParseExportNamespaceSpecifier(node); + + if (hasNamespace && node.exportKind === "type") { + this.unexpected(pos); + } + + return hasNamespace; + } + + parseClassId(node, isStatement, optionalId) { + super.parseClassId(node, isStatement, optionalId); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + } + + parseClassMember(classBody, member, state, constructorAllowsSuper) { + const pos = this.state.start; + + if (this.isContextual("declare")) { + if (this.parseClassMemberFromModifier(classBody, member)) { + return; + } + + member.declare = true; + } + + super.parseClassMember(classBody, member, state, constructorAllowsSuper); + + if (member.declare) { + if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty") { + this.raise(pos, FlowErrors$1.DeclareClassElement); + } else if (member.value) { + this.raise(member.value.start, FlowErrors$1.DeclareClassFieldInitializer); + } + } + } + + getTokenFromCode(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 123 && next === 124) { + return this.finishOp(types$4.braceBarL, 2); + } else if (this.state.inType && (code === 62 || code === 60)) { + return this.finishOp(types$4.relational, 1); + } else if (isIteratorStart$1(code, next)) { + this.state.isIterator = true; + return super.readWord(); + } else { + return super.getTokenFromCode(code); + } + } + + isAssignable(node, isBinding) { + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + return true; + + case "ObjectExpression": + { + const last = node.properties.length - 1; + return node.properties.every((prop, i) => { + return prop.type !== "ObjectMethod" && (i === last || prop.type === "SpreadElement") && this.isAssignable(prop); + }); + } + + case "ObjectProperty": + return this.isAssignable(node.value); + + case "SpreadElement": + return this.isAssignable(node.argument); + + case "ArrayExpression": + return node.elements.every(element => this.isAssignable(element)); + + case "AssignmentExpression": + return node.operator === "="; + + case "ParenthesizedExpression": + case "TypeCastExpression": + return this.isAssignable(node.expression); + + case "MemberExpression": + case "OptionalMemberExpression": + return !isBinding; + + default: + return false; + } + } + + toAssignable(node) { + if (node.type === "TypeCastExpression") { + return super.toAssignable(this.typeCastToParameter(node)); + } else { + return super.toAssignable(node); + } + } + + toAssignableList(exprList, trailingCommaPos) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + + if ((expr == null ? void 0 : expr.type) === "TypeCastExpression") { + exprList[i] = this.typeCastToParameter(expr); + } + } + + return super.toAssignableList(exprList, trailingCommaPos); + } + + toReferencedList(exprList, isParenthesizedExpr) { + for (let i = 0; i < exprList.length; i++) { + var _expr$extra; + + const expr = exprList[i]; + + if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) == null ? void 0 : _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) { + this.raise(expr.typeAnnotation.start, FlowErrors$1.TypeCastInPattern); + } + } + + return exprList; + } + + checkLVal(expr, bindingType = BIND_NONE$1, checkClashes, contextDescription) { + if (expr.type !== "TypeCastExpression") { + return super.checkLVal(expr, bindingType, checkClashes, contextDescription); + } + } + + parseClassProperty(node) { + if (this.match(types$4.colon)) { + node.typeAnnotation = this.flowParseTypeAnnotation(); + } + + return super.parseClassProperty(node); + } + + parseClassPrivateProperty(node) { + if (this.match(types$4.colon)) { + node.typeAnnotation = this.flowParseTypeAnnotation(); + } + + return super.parseClassPrivateProperty(node); + } + + isClassMethod() { + return this.isRelational("<") || super.isClassMethod(); + } + + isClassProperty() { + return this.match(types$4.colon) || super.isClassProperty(); + } + + isNonstaticConstructor(method) { + return !this.match(types$4.colon) && super.isNonstaticConstructor(method); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + if (method.variance) { + this.unexpected(method.variance.start); + } + + delete method.variance; + + if (this.isRelational("<")) { + method.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + if (method.variance) { + this.unexpected(method.variance.start); + } + + delete method.variance; + + if (this.isRelational("<")) { + method.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); + } + + parseClassSuper(node) { + super.parseClassSuper(node); + + if (node.superClass && this.isRelational("<")) { + node.superTypeParameters = this.flowParseTypeParameterInstantiation(); + } + + if (this.isContextual("implements")) { + this.next(); + const implemented = node.implements = []; + + do { + const node = this.startNode(); + node.id = this.flowParseRestrictedIdentifier(true); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + + implemented.push(this.finishNode(node, "ClassImplements")); + } while (this.eat(types$4.comma)); + } + } + + parsePropertyName(node, isPrivateNameAllowed) { + const variance = this.flowParseVariance(); + const key = super.parsePropertyName(node, isPrivateNameAllowed); + node.variance = variance; + return key; + } + + parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refExpressionErrors, containsEsc) { + if (prop.variance) { + this.unexpected(prop.variance.start); + } + + delete prop.variance; + let typeParameters; + + if (this.isRelational("<")) { + typeParameters = this.flowParseTypeParameterDeclaration(); + if (!this.match(types$4.parenL)) this.unexpected(); + } + + super.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refExpressionErrors, containsEsc); + + if (typeParameters) { + (prop.value || prop).typeParameters = typeParameters; + } + } + + parseAssignableListItemTypes(param) { + if (this.eat(types$4.question)) { + if (param.type !== "Identifier") { + this.raise(param.start, FlowErrors$1.OptionalBindingPattern); + } + + param.optional = true; + } + + if (this.match(types$4.colon)) { + param.typeAnnotation = this.flowParseTypeAnnotation(); + } + + this.resetEndLocation(param); + return param; + } + + parseMaybeDefault(startPos, startLoc, left) { + const node = super.parseMaybeDefault(startPos, startLoc, left); + + if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { + this.raise(node.typeAnnotation.start, FlowErrors$1.TypeBeforeInitializer); + } + + return node; + } + + shouldParseDefaultImport(node) { + if (!hasTypeImportKind$1(node)) { + return super.shouldParseDefaultImport(node); + } + + return isMaybeDefaultImport$1(this.state); + } + + parseImportSpecifierLocal(node, specifier, type, contextDescription) { + specifier.local = hasTypeImportKind$1(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier(); + this.checkLVal(specifier.local, BIND_LEXICAL$1, undefined, contextDescription); + node.specifiers.push(this.finishNode(specifier, type)); + } + + maybeParseDefaultImportSpecifier(node) { + node.importKind = "value"; + let kind = null; + + if (this.match(types$4._typeof)) { + kind = "typeof"; + } else if (this.isContextual("type")) { + kind = "type"; + } + + if (kind) { + const lh = this.lookahead(); + + if (kind === "type" && lh.type === types$4.star) { + this.unexpected(lh.start); + } + + if (isMaybeDefaultImport$1(lh) || lh.type === types$4.braceL || lh.type === types$4.star) { + this.next(); + node.importKind = kind; + } + } + + return super.maybeParseDefaultImportSpecifier(node); + } + + parseImportSpecifier(node) { + const specifier = this.startNode(); + const firstIdentLoc = this.state.start; + const firstIdent = this.parseIdentifier(true); + let specifierTypeKind = null; + + if (firstIdent.name === "type") { + specifierTypeKind = "type"; + } else if (firstIdent.name === "typeof") { + specifierTypeKind = "typeof"; + } + + let isBinding = false; + + if (this.isContextual("as") && !this.isLookaheadContextual("as")) { + const as_ident = this.parseIdentifier(true); + + if (specifierTypeKind !== null && !this.match(types$4.name) && !this.state.type.keyword) { + specifier.imported = as_ident; + specifier.importKind = specifierTypeKind; + specifier.local = as_ident.__clone(); + } else { + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = this.parseIdentifier(); + } + } else if (specifierTypeKind !== null && (this.match(types$4.name) || this.state.type.keyword)) { + specifier.imported = this.parseIdentifier(true); + specifier.importKind = specifierTypeKind; + + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + isBinding = true; + specifier.local = specifier.imported.__clone(); + } + } else { + isBinding = true; + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = specifier.imported.__clone(); + } + + const nodeIsTypeImport = hasTypeImportKind$1(node); + const specifierIsTypeImport = hasTypeImportKind$1(specifier); + + if (nodeIsTypeImport && specifierIsTypeImport) { + this.raise(firstIdentLoc, FlowErrors$1.ImportTypeShorthandOnlyInPureImport); + } + + if (nodeIsTypeImport || specifierIsTypeImport) { + this.checkReservedType(specifier.local.name, specifier.local.start, true); + } + + if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) { + this.checkReservedWord(specifier.local.name, specifier.start, true, true); + } + + this.checkLVal(specifier.local, BIND_LEXICAL$1, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + } + + parseFunctionParams(node, allowModifiers) { + const kind = node.kind; + + if (kind !== "get" && kind !== "set" && this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.parseFunctionParams(node, allowModifiers); + } + + parseVarId(decl, kind) { + super.parseVarId(decl, kind); + + if (this.match(types$4.colon)) { + decl.id.typeAnnotation = this.flowParseTypeAnnotation(); + this.resetEndLocation(decl.id); + } + } + + parseAsyncArrowFromCallExpression(node, call) { + if (this.match(types$4.colon)) { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + node.returnType = this.flowParseTypeAnnotation(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + } + + return super.parseAsyncArrowFromCallExpression(node, call); + } + + shouldParseAsyncArrow() { + return this.match(types$4.colon) || super.shouldParseAsyncArrow(); + } + + parseMaybeAssign(noIn, refExpressionErrors, afterLeftParse, refNeedsArrowPos) { + var _jsx; + + let state = null; + let jsx; + + if (this.hasPlugin("jsx") && (this.match(types$4.jsxTagStart) || this.isRelational("<"))) { + state = this.state.clone(); + jsx = this.tryParse(() => super.parseMaybeAssign(noIn, refExpressionErrors, afterLeftParse, refNeedsArrowPos), state); + if (!jsx.error) return jsx.node; + const { + context + } = this.state; + + if (context[context.length - 1] === types$1$1.j_oTag) { + context.length -= 2; + } else if (context[context.length - 1] === types$1$1.j_expr) { + context.length -= 1; + } + } + + if (((_jsx = jsx) == null ? void 0 : _jsx.error) || this.isRelational("<")) { + var _arrow$node, _jsx2, _jsx3; + + state = state || this.state.clone(); + let typeParameters; + const arrow = this.tryParse(() => { + typeParameters = this.flowParseTypeParameterDeclaration(); + const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => super.parseMaybeAssign(noIn, refExpressionErrors, afterLeftParse, refNeedsArrowPos)); + arrowExpression.typeParameters = typeParameters; + this.resetStartLocationFromNode(arrowExpression, typeParameters); + return arrowExpression; + }, state); + const arrowExpression = ((_arrow$node = arrow.node) == null ? void 0 : _arrow$node.type) === "ArrowFunctionExpression" ? arrow.node : null; + if (!arrow.error && arrowExpression) return arrowExpression; + + if ((_jsx2 = jsx) == null ? void 0 : _jsx2.node) { + this.state = jsx.failState; + return jsx.node; + } + + if (arrowExpression) { + this.state = arrow.failState; + return arrowExpression; + } + + if ((_jsx3 = jsx) == null ? void 0 : _jsx3.thrown) throw jsx.error; + if (arrow.thrown) throw arrow.error; + throw this.raise(typeParameters.start, FlowErrors$1.UnexpectedTokenAfterTypeParameter); + } + + return super.parseMaybeAssign(noIn, refExpressionErrors, afterLeftParse, refNeedsArrowPos); + } + + parseArrow(node) { + if (this.match(types$4.colon)) { + const result = this.tryParse(() => { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + if (this.canInsertSemicolon()) this.unexpected(); + if (!this.match(types$4.arrow)) this.unexpected(); + return typeNode; + }); + if (result.thrown) return null; + if (result.error) this.state = result.failState; + node.returnType = result.node.typeAnnotation ? this.finishNode(result.node, "TypeAnnotation") : null; + } + + return super.parseArrow(node); + } + + shouldParseArrow() { + return this.match(types$4.colon) || super.shouldParseArrow(); + } + + setArrowFunctionParameters(node, params) { + if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + node.params = params; + } else { + super.setArrowFunctionParameters(node, params); + } + } + + checkParams(node, allowDuplicates, isArrowFunction) { + if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + return; + } + + return super.checkParams(...arguments); + } + + parseParenAndDistinguishExpression(canBeArrow) { + return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1); + } + + parseSubscripts(base, startPos, startLoc, noCalls) { + if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startPos) !== -1) { + this.next(); + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + base = this.finishNode(node, "CallExpression"); + } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) { + const state = this.state.clone(); + const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startPos, startLoc) || abort(), state); + if (!arrow.error && !arrow.aborted) return arrow.node; + const result = this.tryParse(() => super.parseSubscripts(base, startPos, startLoc, noCalls), state); + if (result.node && !result.error) return result.node; + + if (arrow.node) { + this.state = arrow.failState; + return arrow.node; + } + + if (result.node) { + this.state = result.failState; + return result.node; + } + + throw arrow.error || result.error; + } + + return super.parseSubscripts(base, startPos, startLoc, noCalls); + } + + parseSubscript(base, startPos, startLoc, noCalls, subscriptState) { + if (this.match(types$4.questionDot) && this.isLookaheadRelational("<")) { + subscriptState.optionalChainMember = true; + + if (noCalls) { + subscriptState.stop = true; + return base; + } + + this.next(); + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + node.typeArguments = this.flowParseTypeParameterInstantiation(); + this.expect(types$4.parenL); + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + node.optional = true; + return this.finishCallExpression(node, true); + } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) { + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + const result = this.tryParse(() => { + node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew(); + this.expect(types$4.parenL); + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + if (subscriptState.optionalChainMember) node.optional = false; + return this.finishCallExpression(node, subscriptState.optionalChainMember); + }); + + if (result.node) { + if (result.error) this.state = result.failState; + return result.node; + } + } + + return super.parseSubscript(base, startPos, startLoc, noCalls, subscriptState); + } + + parseNewArguments(node) { + let targs = null; + + if (this.shouldParseTypes() && this.isRelational("<")) { + targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node; + } + + node.typeArguments = targs; + super.parseNewArguments(node); + } + + parseAsyncArrowWithTypeParameters(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + this.parseFunctionParams(node); + if (!this.parseArrow(node)) return; + return this.parseArrowExpression(node, undefined, true); + } + + readToken_mult_modulo(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 42 && next === 47 && this.state.hasFlowComment) { + this.state.hasFlowComment = false; + this.state.pos += 2; + this.nextToken(); + return; + } + + super.readToken_mult_modulo(code); + } + + readToken_pipe_amp(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 124 && next === 125) { + this.finishOp(types$4.braceBarR, 2); + return; + } + + super.readToken_pipe_amp(code); + } + + parseTopLevel(file, program) { + const fileNode = super.parseTopLevel(file, program); + + if (this.state.hasFlowComment) { + this.raise(this.state.pos, FlowErrors$1.UnterminatedFlowComment); + } + + return fileNode; + } + + skipBlockComment() { + if (this.hasPlugin("flowComments") && this.skipFlowComment()) { + if (this.state.hasFlowComment) { + this.unexpected(null, FlowErrors$1.NestedFlowComment); + } + + this.hasFlowCommentCompletion(); + this.state.pos += this.skipFlowComment(); + this.state.hasFlowComment = true; + return; + } + + if (this.state.hasFlowComment) { + const end = this.input.indexOf("*-/", this.state.pos += 2); + + if (end === -1) { + throw this.raise(this.state.pos - 2, ErrorMessages$1.UnterminatedComment); + } + + this.state.pos = end + 3; + return; + } + + super.skipBlockComment(); + } + + skipFlowComment() { + const { + pos + } = this.state; + let shiftToFirstNonWhiteSpace = 2; + + while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) { + shiftToFirstNonWhiteSpace++; + } + + const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos); + const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1); + + if (ch2 === 58 && ch3 === 58) { + return shiftToFirstNonWhiteSpace + 2; + } + + if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") { + return shiftToFirstNonWhiteSpace + 12; + } + + if (ch2 === 58 && ch3 !== 58) { + return shiftToFirstNonWhiteSpace; + } + + return false; + } + + hasFlowCommentCompletion() { + const end = this.input.indexOf("*/", this.state.pos); + + if (end === -1) { + throw this.raise(this.state.pos, ErrorMessages$1.UnterminatedComment); + } + } + + flowEnumErrorBooleanMemberNotInitialized(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors$1.EnumBooleanMemberNotInitialized, memberName, enumName); + } + + flowEnumErrorInvalidMemberName(pos, { + enumName, + memberName + }) { + const suggestion = memberName[0].toUpperCase() + memberName.slice(1); + this.raise(pos, FlowErrors$1.EnumInvalidMemberName, memberName, suggestion, enumName); + } + + flowEnumErrorDuplicateMemberName(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors$1.EnumDuplicateMemberName, memberName, enumName); + } + + flowEnumErrorInconsistentMemberValues(pos, { + enumName + }) { + this.raise(pos, FlowErrors$1.EnumInconsistentMemberValues, enumName); + } + + flowEnumErrorInvalidExplicitType(pos, { + enumName, + suppliedType + }) { + return this.raise(pos, suppliedType === null ? FlowErrors$1.EnumInvalidExplicitTypeUnknownSupplied : FlowErrors$1.EnumInvalidExplicitType, enumName, suppliedType); + } + + flowEnumErrorInvalidMemberInitializer(pos, { + enumName, + explicitType, + memberName + }) { + let message = null; + + switch (explicitType) { + case "boolean": + case "number": + case "string": + message = FlowErrors$1.EnumInvalidMemberInitializerPrimaryType; + break; + + case "symbol": + message = FlowErrors$1.EnumInvalidMemberInitializerSymbolType; + break; + + default: + message = FlowErrors$1.EnumInvalidMemberInitializerUnknownType; + } + + return this.raise(pos, message, enumName, memberName, explicitType); + } + + flowEnumErrorNumberMemberNotInitialized(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors$1.EnumNumberMemberNotInitialized, enumName, memberName); + } + + flowEnumErrorStringMemberInconsistentlyInitailized(pos, { + enumName + }) { + this.raise(pos, FlowErrors$1.EnumStringMemberInconsistentlyInitailized, enumName); + } + + flowEnumMemberInit() { + const startPos = this.state.start; + + const endOfInit = () => this.match(types$4.comma) || this.match(types$4.braceR); + + switch (this.state.type) { + case types$4.num: + { + const literal = this.parseLiteral(this.state.value, "NumericLiteral"); + + if (endOfInit()) { + return { + type: "number", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + case types$4.string: + { + const literal = this.parseLiteral(this.state.value, "StringLiteral"); + + if (endOfInit()) { + return { + type: "string", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + case types$4._true: + case types$4._false: + { + const literal = this.parseBooleanLiteral(); + + if (endOfInit()) { + return { + type: "boolean", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + default: + return { + type: "invalid", + pos: startPos + }; + } + } + + flowEnumMemberRaw() { + const pos = this.state.start; + const id = this.parseIdentifier(true); + const init = this.eat(types$4.eq) ? this.flowEnumMemberInit() : { + type: "none", + pos + }; + return { + id, + init + }; + } + + flowEnumCheckExplicitTypeMismatch(pos, context, expectedType) { + const { + explicitType + } = context; + + if (explicitType === null) { + return; + } + + if (explicitType !== expectedType) { + this.flowEnumErrorInvalidMemberInitializer(pos, context); + } + } + + flowEnumMembers({ + enumName, + explicitType + }) { + const seenNames = new Set(); + const members = { + booleanMembers: [], + numberMembers: [], + stringMembers: [], + defaultedMembers: [] + }; + + while (!this.match(types$4.braceR)) { + const memberNode = this.startNode(); + const { + id, + init + } = this.flowEnumMemberRaw(); + const memberName = id.name; + + if (memberName === "") { + continue; + } + + if (/^[a-z]/.test(memberName)) { + this.flowEnumErrorInvalidMemberName(id.start, { + enumName, + memberName + }); + } + + if (seenNames.has(memberName)) { + this.flowEnumErrorDuplicateMemberName(id.start, { + enumName, + memberName + }); + } + + seenNames.add(memberName); + const context = { + enumName, + explicitType, + memberName + }; + memberNode.id = id; + + switch (init.type) { + case "boolean": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "boolean"); + memberNode.init = init.value; + members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember")); + break; + } + + case "number": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "number"); + memberNode.init = init.value; + members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember")); + break; + } + + case "string": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "string"); + memberNode.init = init.value; + members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember")); + break; + } + + case "invalid": + { + throw this.flowEnumErrorInvalidMemberInitializer(init.pos, context); + } + + case "none": + { + switch (explicitType) { + case "boolean": + this.flowEnumErrorBooleanMemberNotInitialized(init.pos, context); + break; + + case "number": + this.flowEnumErrorNumberMemberNotInitialized(init.pos, context); + break; + + default: + members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember")); + } + } + } + + if (!this.match(types$4.braceR)) { + this.expect(types$4.comma); + } + } + + return members; + } + + flowEnumStringMembers(initializedMembers, defaultedMembers, { + enumName + }) { + if (initializedMembers.length === 0) { + return defaultedMembers; + } else if (defaultedMembers.length === 0) { + return initializedMembers; + } else if (defaultedMembers.length > initializedMembers.length) { + for (let _i = 0; _i < initializedMembers.length; _i++) { + const member = initializedMembers[_i]; + this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + enumName + }); + } + + return defaultedMembers; + } else { + for (let _i2 = 0; _i2 < defaultedMembers.length; _i2++) { + const member = defaultedMembers[_i2]; + this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + enumName + }); + } + + return initializedMembers; + } + } + + flowEnumParseExplicitType({ + enumName + }) { + if (this.eatContextual("of")) { + if (!this.match(types$4.name)) { + throw this.flowEnumErrorInvalidExplicitType(this.state.start, { + enumName, + suppliedType: null + }); + } + + const { + value + } = this.state; + this.next(); + + if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") { + this.flowEnumErrorInvalidExplicitType(this.state.start, { + enumName, + suppliedType: value + }); + } + + return value; + } + + return null; + } + + flowEnumBody(node, { + enumName, + nameLoc + }) { + const explicitType = this.flowEnumParseExplicitType({ + enumName + }); + this.expect(types$4.braceL); + const members = this.flowEnumMembers({ + enumName, + explicitType + }); + + switch (explicitType) { + case "boolean": + node.explicitType = true; + node.members = members.booleanMembers; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumBooleanBody"); + + case "number": + node.explicitType = true; + node.members = members.numberMembers; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumNumberBody"); + + case "string": + node.explicitType = true; + node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, { + enumName + }); + this.expect(types$4.braceR); + return this.finishNode(node, "EnumStringBody"); + + case "symbol": + node.members = members.defaultedMembers; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumSymbolBody"); + + default: + { + const empty = () => { + node.members = []; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumStringBody"); + }; + + node.explicitType = false; + const boolsLen = members.booleanMembers.length; + const numsLen = members.numberMembers.length; + const strsLen = members.stringMembers.length; + const defaultedLen = members.defaultedMembers.length; + + if (!boolsLen && !numsLen && !strsLen && !defaultedLen) { + return empty(); + } else if (!boolsLen && !numsLen) { + node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, { + enumName + }); + this.expect(types$4.braceR); + return this.finishNode(node, "EnumStringBody"); + } else if (!numsLen && !strsLen && boolsLen >= defaultedLen) { + for (let _i3 = 0, _members$defaultedMem = members.defaultedMembers; _i3 < _members$defaultedMem.length; _i3++) { + const member = _members$defaultedMem[_i3]; + this.flowEnumErrorBooleanMemberNotInitialized(member.start, { + enumName, + memberName: member.id.name + }); + } + + node.members = members.booleanMembers; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumBooleanBody"); + } else if (!boolsLen && !strsLen && numsLen >= defaultedLen) { + for (let _i4 = 0, _members$defaultedMem2 = members.defaultedMembers; _i4 < _members$defaultedMem2.length; _i4++) { + const member = _members$defaultedMem2[_i4]; + this.flowEnumErrorNumberMemberNotInitialized(member.start, { + enumName, + memberName: member.id.name + }); + } + + node.members = members.numberMembers; + this.expect(types$4.braceR); + return this.finishNode(node, "EnumNumberBody"); + } else { + this.flowEnumErrorInconsistentMemberValues(nameLoc, { + enumName + }); + return empty(); + } + } + } + } + + flowParseEnumDeclaration(node) { + const id = this.parseIdentifier(); + node.id = id; + node.body = this.flowEnumBody(this.startNode(), { + enumName: id.name, + nameLoc: id.start + }); + return this.finishNode(node, "EnumDeclaration"); + } + + updateContext(prevType) { + if (this.match(types$4.name) && this.state.value === "of" && prevType === types$4.name && this.input.slice(this.state.lastTokStart, this.state.lastTokEnd) === "interface") { + this.state.exprAllowed = false; + } else { + super.updateContext(prevType); + } + } + + }); + + const entities$1 = { + quot: "\u0022", + amp: "&", + apos: "\u0027", + lt: "<", + gt: ">", + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + fnof: "\u0192", + circ: "\u02C6", + tilde: "\u02DC", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + bull: "\u2022", + hellip: "\u2026", + permil: "\u2030", + prime: "\u2032", + Prime: "\u2033", + lsaquo: "\u2039", + rsaquo: "\u203A", + oline: "\u203E", + frasl: "\u2044", + euro: "\u20AC", + image: "\u2111", + weierp: "\u2118", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666" + }; + + const HEX_NUMBER$1 = /^[\da-fA-F]+$/; + const DECIMAL_NUMBER$1 = /^\d+$/; + const JsxErrors$1 = Object.freeze({ + AttributeIsEmpty: "JSX attributes must only be assigned a non-empty expression", + MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>", + MissingClosingTagElement: "Expected corresponding JSX closing tag for <%0>", + UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text", + UnterminatedJsxContent: "Unterminated JSX contents", + UnwrappedAdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...?" + }); + types$1$1.j_oTag = new TokContext$1("...", true, true); + types$4.jsxName = new TokenType("jsxName"); + types$4.jsxText = new TokenType("jsxText", { + beforeExpr: true + }); + types$4.jsxTagStart = new TokenType("jsxTagStart", { + startsExpr: true + }); + types$4.jsxTagEnd = new TokenType("jsxTagEnd"); + + types$4.jsxTagStart.updateContext = function () { + this.state.context.push(types$1$1.j_expr); + this.state.context.push(types$1$1.j_oTag); + this.state.exprAllowed = false; + }; + + types$4.jsxTagEnd.updateContext = function (prevType) { + const out = this.state.context.pop(); + + if (out === types$1$1.j_oTag && prevType === types$4.slash || out === types$1$1.j_cTag) { + this.state.context.pop(); + this.state.exprAllowed = this.curContext() === types$1$1.j_expr; + } else { + this.state.exprAllowed = true; + } + }; + + function isFragment$1(object) { + return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false; + } + + function getQualifiedJSXName$1(object) { + if (object.type === "JSXIdentifier") { + return object.name; + } + + if (object.type === "JSXNamespacedName") { + return object.namespace.name + ":" + object.name.name; + } + + if (object.type === "JSXMemberExpression") { + return getQualifiedJSXName$1(object.object) + "." + getQualifiedJSXName$1(object.property); + } + + throw new Error("Node had unexpected type: " + object.type); + } + + var jsx$2 = (superClass => class extends superClass { + jsxReadToken() { + let out = ""; + let chunkStart = this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, JsxErrors$1.UnterminatedJsxContent); + } + + const ch = this.input.charCodeAt(this.state.pos); + + switch (ch) { + case 60: + case 123: + if (this.state.pos === this.state.start) { + if (ch === 60 && this.state.exprAllowed) { + ++this.state.pos; + return this.finishToken(types$4.jsxTagStart); + } + + return super.getTokenFromCode(ch); + } + + out += this.input.slice(chunkStart, this.state.pos); + return this.finishToken(types$4.jsxText, out); + + case 38: + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + break; + + default: + if (isNewLine$1(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(true); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + + } + } + } + + jsxReadNewLine(normalizeCRLF) { + const ch = this.input.charCodeAt(this.state.pos); + let out; + ++this.state.pos; + + if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + out = normalizeCRLF ? "\n" : "\r\n"; + } else { + out = String.fromCharCode(ch); + } + + ++this.state.curLine; + this.state.lineStart = this.state.pos; + return out; + } + + jsxReadString(quote) { + let out = ""; + let chunkStart = ++this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages$1.UnterminatedString); + } + + const ch = this.input.charCodeAt(this.state.pos); + if (ch === quote) break; + + if (ch === 38) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + } else if (isNewLine$1(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(false); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + + out += this.input.slice(chunkStart, this.state.pos++); + return this.finishToken(types$4.string, out); + } + + jsxReadEntity() { + let str = ""; + let count = 0; + let entity; + let ch = this.input[this.state.pos]; + const startPos = ++this.state.pos; + + while (this.state.pos < this.length && count++ < 10) { + ch = this.input[this.state.pos++]; + + if (ch === ";") { + if (str[0] === "#") { + if (str[1] === "x") { + str = str.substr(2); + + if (HEX_NUMBER$1.test(str)) { + entity = String.fromCodePoint(parseInt(str, 16)); + } + } else { + str = str.substr(1); + + if (DECIMAL_NUMBER$1.test(str)) { + entity = String.fromCodePoint(parseInt(str, 10)); + } + } + } else { + entity = entities$1[str]; + } + + break; + } + + str += ch; + } + + if (!entity) { + this.state.pos = startPos; + return "&"; + } + + return entity; + } + + jsxReadWord() { + let ch; + const start = this.state.pos; + + do { + ch = this.input.charCodeAt(++this.state.pos); + } while (isIdentifierChar$1(ch) || ch === 45); + + return this.finishToken(types$4.jsxName, this.input.slice(start, this.state.pos)); + } + + jsxParseIdentifier() { + const node = this.startNode(); + + if (this.match(types$4.jsxName)) { + node.name = this.state.value; + } else if (this.state.type.keyword) { + node.name = this.state.type.keyword; + } else { + this.unexpected(); + } + + this.next(); + return this.finishNode(node, "JSXIdentifier"); + } + + jsxParseNamespacedName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const name = this.jsxParseIdentifier(); + if (!this.eat(types$4.colon)) return name; + const node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsxParseIdentifier(); + return this.finishNode(node, "JSXNamespacedName"); + } + + jsxParseElementName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let node = this.jsxParseNamespacedName(); + + if (node.type === "JSXNamespacedName") { + return node; + } + + while (this.eat(types$4.dot)) { + const newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsxParseIdentifier(); + node = this.finishNode(newNode, "JSXMemberExpression"); + } + + return node; + } + + jsxParseAttributeValue() { + let node; + + switch (this.state.type) { + case types$4.braceL: + node = this.startNode(); + this.next(); + node = this.jsxParseExpressionContainer(node); + + if (node.expression.type === "JSXEmptyExpression") { + this.raise(node.start, JsxErrors$1.AttributeIsEmpty); + } + + return node; + + case types$4.jsxTagStart: + case types$4.string: + return this.parseExprAtom(); + + default: + throw this.raise(this.state.start, JsxErrors$1.UnsupportedJsxValue); + } + } + + jsxParseEmptyExpression() { + const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); + return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); + } + + jsxParseSpreadChild(node) { + this.next(); + node.expression = this.parseExpression(); + this.expect(types$4.braceR); + return this.finishNode(node, "JSXSpreadChild"); + } + + jsxParseExpressionContainer(node) { + if (this.match(types$4.braceR)) { + node.expression = this.jsxParseEmptyExpression(); + } else { + node.expression = this.parseExpression(); + } + + this.expect(types$4.braceR); + return this.finishNode(node, "JSXExpressionContainer"); + } + + jsxParseAttribute() { + const node = this.startNode(); + + if (this.eat(types$4.braceL)) { + this.expect(types$4.ellipsis); + node.argument = this.parseMaybeAssign(); + this.expect(types$4.braceR); + return this.finishNode(node, "JSXSpreadAttribute"); + } + + node.name = this.jsxParseNamespacedName(); + node.value = this.eat(types$4.eq) ? this.jsxParseAttributeValue() : null; + return this.finishNode(node, "JSXAttribute"); + } + + jsxParseOpeningElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + + if (this.match(types$4.jsxTagEnd)) { + this.expect(types$4.jsxTagEnd); + return this.finishNode(node, "JSXOpeningFragment"); + } + + node.name = this.jsxParseElementName(); + return this.jsxParseOpeningElementAfterName(node); + } + + jsxParseOpeningElementAfterName(node) { + const attributes = []; + + while (!this.match(types$4.slash) && !this.match(types$4.jsxTagEnd)) { + attributes.push(this.jsxParseAttribute()); + } + + node.attributes = attributes; + node.selfClosing = this.eat(types$4.slash); + this.expect(types$4.jsxTagEnd); + return this.finishNode(node, "JSXOpeningElement"); + } + + jsxParseClosingElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + + if (this.match(types$4.jsxTagEnd)) { + this.expect(types$4.jsxTagEnd); + return this.finishNode(node, "JSXClosingFragment"); + } + + node.name = this.jsxParseElementName(); + this.expect(types$4.jsxTagEnd); + return this.finishNode(node, "JSXClosingElement"); + } + + jsxParseElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + const children = []; + const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); + let closingElement = null; + + if (!openingElement.selfClosing) { + contents: for (;;) { + switch (this.state.type) { + case types$4.jsxTagStart: + startPos = this.state.start; + startLoc = this.state.startLoc; + this.next(); + + if (this.eat(types$4.slash)) { + closingElement = this.jsxParseClosingElementAt(startPos, startLoc); + break contents; + } + + children.push(this.jsxParseElementAt(startPos, startLoc)); + break; + + case types$4.jsxText: + children.push(this.parseExprAtom()); + break; + + case types$4.braceL: + { + const node = this.startNode(); + this.next(); + + if (this.match(types$4.ellipsis)) { + children.push(this.jsxParseSpreadChild(node)); + } else { + children.push(this.jsxParseExpressionContainer(node)); + } + + break; + } + + default: + throw this.unexpected(); + } + } + + if (isFragment$1(openingElement) && !isFragment$1(closingElement)) { + this.raise(closingElement.start, JsxErrors$1.MissingClosingTagFragment); + } else if (!isFragment$1(openingElement) && isFragment$1(closingElement)) { + this.raise(closingElement.start, JsxErrors$1.MissingClosingTagElement, getQualifiedJSXName$1(openingElement.name)); + } else if (!isFragment$1(openingElement) && !isFragment$1(closingElement)) { + if (getQualifiedJSXName$1(closingElement.name) !== getQualifiedJSXName$1(openingElement.name)) { + this.raise(closingElement.start, JsxErrors$1.MissingClosingTagElement, getQualifiedJSXName$1(openingElement.name)); + } + } + } + + if (isFragment$1(openingElement)) { + node.openingFragment = openingElement; + node.closingFragment = closingElement; + } else { + node.openingElement = openingElement; + node.closingElement = closingElement; + } + + node.children = children; + + if (this.isRelational("<")) { + throw this.raise(this.state.start, JsxErrors$1.UnwrappedAdjacentJSXElements); + } + + return isFragment$1(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement"); + } + + jsxParseElement() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.next(); + return this.jsxParseElementAt(startPos, startLoc); + } + + parseExprAtom(refExpressionErrors) { + if (this.match(types$4.jsxText)) { + return this.parseLiteral(this.state.value, "JSXText"); + } else if (this.match(types$4.jsxTagStart)) { + return this.jsxParseElement(); + } else if (this.isRelational("<") && this.input.charCodeAt(this.state.pos) !== 33) { + this.finishToken(types$4.jsxTagStart); + return this.jsxParseElement(); + } else { + return super.parseExprAtom(refExpressionErrors); + } + } + + getTokenFromCode(code) { + if (this.state.inPropertyName) return super.getTokenFromCode(code); + const context = this.curContext(); + + if (context === types$1$1.j_expr) { + return this.jsxReadToken(); + } + + if (context === types$1$1.j_oTag || context === types$1$1.j_cTag) { + if (isIdentifierStart$1(code)) { + return this.jsxReadWord(); + } + + if (code === 62) { + ++this.state.pos; + return this.finishToken(types$4.jsxTagEnd); + } + + if ((code === 34 || code === 39) && context === types$1$1.j_oTag) { + return this.jsxReadString(code); + } + } + + if (code === 60 && this.state.exprAllowed && this.input.charCodeAt(this.state.pos + 1) !== 33) { + ++this.state.pos; + return this.finishToken(types$4.jsxTagStart); + } + + return super.getTokenFromCode(code); + } + + updateContext(prevType) { + if (this.match(types$4.braceL)) { + const curContext = this.curContext(); + + if (curContext === types$1$1.j_oTag) { + this.state.context.push(types$1$1.braceExpression); + } else if (curContext === types$1$1.j_expr) { + this.state.context.push(types$1$1.templateQuasi); + } else { + super.updateContext(prevType); + } + + this.state.exprAllowed = true; + } else if (this.match(types$4.slash) && prevType === types$4.jsxTagStart) { + this.state.context.length -= 2; + this.state.context.push(types$1$1.j_cTag); + this.state.exprAllowed = false; + } else { + return super.updateContext(prevType); + } + } + + }); + + let Scope$1 = class Scope { + constructor(flags) { + this.var = []; + this.lexical = []; + this.functions = []; + this.flags = flags; + } + + }; + let ScopeHandler$1 = class ScopeHandler { + constructor(raise, inModule) { + this.scopeStack = []; + this.undefinedExports = new Map(); + this.undefinedPrivateNames = new Map(); + this.raise = raise; + this.inModule = inModule; + } + + get inFunction() { + return (this.currentVarScope().flags & SCOPE_FUNCTION$1) > 0; + } + + get allowSuper() { + return (this.currentThisScope().flags & SCOPE_SUPER$1) > 0; + } + + get allowDirectSuper() { + return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER$1) > 0; + } + + get inClass() { + return (this.currentThisScope().flags & SCOPE_CLASS$1) > 0; + } + + get inNonArrowFunction() { + return (this.currentThisScope().flags & SCOPE_FUNCTION$1) > 0; + } + + get treatFunctionsAsVar() { + return this.treatFunctionsAsVarInScope(this.currentScope()); + } + + createScope(flags) { + return new Scope$1(flags); + } + + enter(flags) { + this.scopeStack.push(this.createScope(flags)); + } + + exit() { + this.scopeStack.pop(); + } + + treatFunctionsAsVarInScope(scope) { + return !!(scope.flags & SCOPE_FUNCTION$1 || !this.inModule && scope.flags & SCOPE_PROGRAM$1); + } + + declareName(name, bindingType, pos) { + let scope = this.currentScope(); + + if (bindingType & BIND_SCOPE_LEXICAL$1 || bindingType & BIND_SCOPE_FUNCTION$1) { + this.checkRedeclarationInScope(scope, name, bindingType, pos); + + if (bindingType & BIND_SCOPE_FUNCTION$1) { + scope.functions.push(name); + } else { + scope.lexical.push(name); + } + + if (bindingType & BIND_SCOPE_LEXICAL$1) { + this.maybeExportDefined(scope, name); + } + } else if (bindingType & BIND_SCOPE_VAR$1) { + for (let i = this.scopeStack.length - 1; i >= 0; --i) { + scope = this.scopeStack[i]; + this.checkRedeclarationInScope(scope, name, bindingType, pos); + scope.var.push(name); + this.maybeExportDefined(scope, name); + if (scope.flags & SCOPE_VAR$1) break; + } + } + + if (this.inModule && scope.flags & SCOPE_PROGRAM$1) { + this.undefinedExports.delete(name); + } + } + + maybeExportDefined(scope, name) { + if (this.inModule && scope.flags & SCOPE_PROGRAM$1) { + this.undefinedExports.delete(name); + } + } + + checkRedeclarationInScope(scope, name, bindingType, pos) { + if (this.isRedeclaredInScope(scope, name, bindingType)) { + this.raise(pos, ErrorMessages$1.VarRedeclaration, name); + } + } + + isRedeclaredInScope(scope, name, bindingType) { + if (!(bindingType & BIND_KIND_VALUE$1)) return false; + + if (bindingType & BIND_SCOPE_LEXICAL$1) { + return scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + } + + if (bindingType & BIND_SCOPE_FUNCTION$1) { + return scope.lexical.indexOf(name) > -1 || !this.treatFunctionsAsVarInScope(scope) && scope.var.indexOf(name) > -1; + } + + return scope.lexical.indexOf(name) > -1 && !(scope.flags & SCOPE_SIMPLE_CATCH$1 && scope.lexical[0] === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.indexOf(name) > -1; + } + + checkLocalExport(id) { + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && this.scopeStack[0].var.indexOf(id.name) === -1 && this.scopeStack[0].functions.indexOf(id.name) === -1) { + this.undefinedExports.set(id.name, id.start); + } + } + + currentScope() { + return this.scopeStack[this.scopeStack.length - 1]; + } + + currentVarScope() { + for (let i = this.scopeStack.length - 1;; i--) { + const scope = this.scopeStack[i]; + + if (scope.flags & SCOPE_VAR$1) { + return scope; + } + } + } + + currentThisScope() { + for (let i = this.scopeStack.length - 1;; i--) { + const scope = this.scopeStack[i]; + + if ((scope.flags & SCOPE_VAR$1 || scope.flags & SCOPE_CLASS$1) && !(scope.flags & SCOPE_ARROW$1)) { + return scope; + } + } + } + + }; + + let TypeScriptScope$1 = class TypeScriptScope extends Scope$1 { + constructor(...args) { + super(...args); + this.types = []; + this.enums = []; + this.constEnums = []; + this.classes = []; + this.exportOnlyBindings = []; + } + + }; + + let TypeScriptScopeHandler$1 = class TypeScriptScopeHandler extends ScopeHandler$1 { + createScope(flags) { + return new TypeScriptScope$1(flags); + } + + declareName(name, bindingType, pos) { + const scope = this.currentScope(); + + if (bindingType & BIND_FLAGS_TS_EXPORT_ONLY$1) { + this.maybeExportDefined(scope, name); + scope.exportOnlyBindings.push(name); + return; + } + + super.declareName(...arguments); + + if (bindingType & BIND_KIND_TYPE$1) { + if (!(bindingType & BIND_KIND_VALUE$1)) { + this.checkRedeclarationInScope(scope, name, bindingType, pos); + this.maybeExportDefined(scope, name); + } + + scope.types.push(name); + } + + if (bindingType & BIND_FLAGS_TS_ENUM$1) scope.enums.push(name); + if (bindingType & BIND_FLAGS_TS_CONST_ENUM$1) scope.constEnums.push(name); + if (bindingType & BIND_FLAGS_CLASS$1) scope.classes.push(name); + } + + isRedeclaredInScope(scope, name, bindingType) { + if (scope.enums.indexOf(name) > -1) { + if (bindingType & BIND_FLAGS_TS_ENUM$1) { + const isConst = !!(bindingType & BIND_FLAGS_TS_CONST_ENUM$1); + const wasConst = scope.constEnums.indexOf(name) > -1; + return isConst !== wasConst; + } + + return true; + } + + if (bindingType & BIND_FLAGS_CLASS$1 && scope.classes.indexOf(name) > -1) { + if (scope.lexical.indexOf(name) > -1) { + return !!(bindingType & BIND_KIND_VALUE$1); + } else { + return false; + } + } + + if (bindingType & BIND_KIND_TYPE$1 && scope.types.indexOf(name) > -1) { + return true; + } + + return super.isRedeclaredInScope(...arguments); + } + + checkLocalExport(id) { + if (this.scopeStack[0].types.indexOf(id.name) === -1 && this.scopeStack[0].exportOnlyBindings.indexOf(id.name) === -1) { + super.checkLocalExport(id); + } + } + + }; + + const PARAM$1 = 0b000, + PARAM_YIELD$1 = 0b001, + PARAM_AWAIT$1 = 0b010, + PARAM_RETURN$1 = 0b100; + let ProductionParameterHandler$1 = class ProductionParameterHandler { + constructor() { + this.stacks = []; + } + + enter(flags) { + this.stacks.push(flags); + } + + exit() { + this.stacks.pop(); + } + + currentFlags() { + return this.stacks[this.stacks.length - 1]; + } + + get hasAwait() { + return (this.currentFlags() & PARAM_AWAIT$1) > 0; + } + + get hasYield() { + return (this.currentFlags() & PARAM_YIELD$1) > 0; + } + + get hasReturn() { + return (this.currentFlags() & PARAM_RETURN$1) > 0; + } + + }; + function functionFlags$1(isAsync, isGenerator) { + return (isAsync ? PARAM_AWAIT$1 : 0) | (isGenerator ? PARAM_YIELD$1 : 0); + } + + function nonNull$1(x) { + if (x == null) { + throw new Error(`Unexpected ${x} value.`); + } + + return x; + } + + function assert$1(x) { + if (!x) { + throw new Error("Assert fail"); + } + } + + const TSErrors$1 = Object.freeze({ + ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier", + ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier", + DeclareClassFieldHasInitializer: "'declare' class fields cannot have an initializer", + DuplicateModifier: "Duplicate modifier: '%0'", + EmptyHeritageClauseType: "'%0' list cannot be empty.", + IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier", + IndexSignatureHasAccessibility: "Index signatures cannot have an accessibility modifier ('%0')", + IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier", + OptionalTypeBeforeRequired: "A required element cannot follow an optional element.", + PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.", + PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.", + PrivateElementHasAccessibility: "Private elements cannot have an accessibility modifier ('%0')", + TemplateTypeHasSubstitution: "Template literal types cannot have any substitution", + TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", + UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.", + UnexpectedTypeAnnotation: "Did not expect a type annotation here.", + UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.", + UnsupportedImportTypeArgument: "Argument in a type import must be a string literal", + UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.", + UnsupportedSignatureParameterKind: "Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got %0" + }); + + function keywordTypeFromName$1(value) { + switch (value) { + case "any": + return "TSAnyKeyword"; + + case "boolean": + return "TSBooleanKeyword"; + + case "bigint": + return "TSBigIntKeyword"; + + case "never": + return "TSNeverKeyword"; + + case "number": + return "TSNumberKeyword"; + + case "object": + return "TSObjectKeyword"; + + case "string": + return "TSStringKeyword"; + + case "symbol": + return "TSSymbolKeyword"; + + case "undefined": + return "TSUndefinedKeyword"; + + case "unknown": + return "TSUnknownKeyword"; + + default: + return undefined; + } + } + + var typescript$2 = (superClass => class extends superClass { + getScopeHandler() { + return TypeScriptScopeHandler$1; + } + + tsIsIdentifier() { + return this.match(types$4.name); + } + + tsNextTokenCanFollowModifier() { + this.next(); + return !this.hasPrecedingLineBreak() && !this.match(types$4.parenL) && !this.match(types$4.parenR) && !this.match(types$4.colon) && !this.match(types$4.eq) && !this.match(types$4.question) && !this.match(types$4.bang); + } + + tsParseModifier(allowedModifiers) { + if (!this.match(types$4.name)) { + return undefined; + } + + const modifier = this.state.value; + + if (allowedModifiers.indexOf(modifier) !== -1 && this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) { + return modifier; + } + + return undefined; + } + + tsParseModifiers(modified, allowedModifiers) { + for (;;) { + const startPos = this.state.start; + const modifier = this.tsParseModifier(allowedModifiers); + if (!modifier) break; + + if (Object.hasOwnProperty.call(modified, modifier)) { + this.raise(startPos, TSErrors$1.DuplicateModifier, modifier); + } + + modified[modifier] = true; + } + } + + tsIsListTerminator(kind) { + switch (kind) { + case "EnumMembers": + case "TypeMembers": + return this.match(types$4.braceR); + + case "HeritageClauseElement": + return this.match(types$4.braceL); + + case "TupleElementTypes": + return this.match(types$4.bracketR); + + case "TypeParametersOrArguments": + return this.isRelational(">"); + } + + throw new Error("Unreachable"); + } + + tsParseList(kind, parseElement) { + const result = []; + + while (!this.tsIsListTerminator(kind)) { + result.push(parseElement()); + } + + return result; + } + + tsParseDelimitedList(kind, parseElement) { + return nonNull$1(this.tsParseDelimitedListWorker(kind, parseElement, true)); + } + + tsParseDelimitedListWorker(kind, parseElement, expectSuccess) { + const result = []; + + for (;;) { + if (this.tsIsListTerminator(kind)) { + break; + } + + const element = parseElement(); + + if (element == null) { + return undefined; + } + + result.push(element); + + if (this.eat(types$4.comma)) { + continue; + } + + if (this.tsIsListTerminator(kind)) { + break; + } + + if (expectSuccess) { + this.expect(types$4.comma); + } + + return undefined; + } + + return result; + } + + tsParseBracketedList(kind, parseElement, bracket, skipFirstToken) { + if (!skipFirstToken) { + if (bracket) { + this.expect(types$4.bracketL); + } else { + this.expectRelational("<"); + } + } + + const result = this.tsParseDelimitedList(kind, parseElement); + + if (bracket) { + this.expect(types$4.bracketR); + } else { + this.expectRelational(">"); + } + + return result; + } + + tsParseImportType() { + const node = this.startNode(); + this.expect(types$4._import); + this.expect(types$4.parenL); + + if (!this.match(types$4.string)) { + this.raise(this.state.start, TSErrors$1.UnsupportedImportTypeArgument); + } + + node.argument = this.parseExprAtom(); + this.expect(types$4.parenR); + + if (this.eat(types$4.dot)) { + node.qualifier = this.tsParseEntityName(true); + } + + if (this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSImportType"); + } + + tsParseEntityName(allowReservedWords) { + let entity = this.parseIdentifier(); + + while (this.eat(types$4.dot)) { + const node = this.startNodeAtNode(entity); + node.left = entity; + node.right = this.parseIdentifier(allowReservedWords); + entity = this.finishNode(node, "TSQualifiedName"); + } + + return entity; + } + + tsParseTypeReference() { + const node = this.startNode(); + node.typeName = this.tsParseEntityName(false); + + if (!this.hasPrecedingLineBreak() && this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSTypeReference"); + } + + tsParseThisTypePredicate(lhs) { + this.next(); + const node = this.startNodeAtNode(lhs); + node.parameterName = lhs; + node.typeAnnotation = this.tsParseTypeAnnotation(false); + return this.finishNode(node, "TSTypePredicate"); + } + + tsParseThisTypeNode() { + const node = this.startNode(); + this.next(); + return this.finishNode(node, "TSThisType"); + } + + tsParseTypeQuery() { + const node = this.startNode(); + this.expect(types$4._typeof); + + if (this.match(types$4._import)) { + node.exprName = this.tsParseImportType(); + } else { + node.exprName = this.tsParseEntityName(true); + } + + return this.finishNode(node, "TSTypeQuery"); + } + + tsParseTypeParameter() { + const node = this.startNode(); + node.name = this.parseIdentifierName(node.start); + node.constraint = this.tsEatThenParseType(types$4._extends); + node.default = this.tsEatThenParseType(types$4.eq); + return this.finishNode(node, "TSTypeParameter"); + } + + tsTryParseTypeParameters() { + if (this.isRelational("<")) { + return this.tsParseTypeParameters(); + } + } + + tsParseTypeParameters() { + const node = this.startNode(); + + if (this.isRelational("<") || this.match(types$4.jsxTagStart)) { + this.next(); + } else { + this.unexpected(); + } + + node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true); + return this.finishNode(node, "TSTypeParameterDeclaration"); + } + + tsTryNextParseConstantContext() { + if (this.lookahead().type === types$4._const) { + this.next(); + return this.tsParseTypeReference(); + } + + return null; + } + + tsFillSignature(returnToken, signature) { + const returnTokenRequired = returnToken === types$4.arrow; + signature.typeParameters = this.tsTryParseTypeParameters(); + this.expect(types$4.parenL); + signature.parameters = this.tsParseBindingListForSignature(); + + if (returnTokenRequired) { + signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + } else if (this.match(returnToken)) { + signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + } + } + + tsParseBindingListForSignature() { + return this.parseBindingList(types$4.parenR, 41).map(pattern => { + if (pattern.type !== "Identifier" && pattern.type !== "RestElement" && pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") { + this.raise(pattern.start, TSErrors$1.UnsupportedSignatureParameterKind, pattern.type); + } + + return pattern; + }); + } + + tsParseTypeMemberSemicolon() { + if (!this.eat(types$4.comma)) { + this.semicolon(); + } + } + + tsParseSignatureMember(kind, node) { + this.tsFillSignature(types$4.colon, node); + this.tsParseTypeMemberSemicolon(); + return this.finishNode(node, kind); + } + + tsIsUnambiguouslyIndexSignature() { + this.next(); + return this.eat(types$4.name) && this.match(types$4.colon); + } + + tsTryParseIndexSignature(node) { + if (!(this.match(types$4.bracketL) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) { + return undefined; + } + + this.expect(types$4.bracketL); + const id = this.parseIdentifier(); + id.typeAnnotation = this.tsParseTypeAnnotation(); + this.resetEndLocation(id); + this.expect(types$4.bracketR); + node.parameters = [id]; + const type = this.tsTryParseTypeAnnotation(); + if (type) node.typeAnnotation = type; + this.tsParseTypeMemberSemicolon(); + return this.finishNode(node, "TSIndexSignature"); + } + + tsParsePropertyOrMethodSignature(node, readonly) { + if (this.eat(types$4.question)) node.optional = true; + const nodeAny = node; + + if (!readonly && (this.match(types$4.parenL) || this.isRelational("<"))) { + const method = nodeAny; + this.tsFillSignature(types$4.colon, method); + this.tsParseTypeMemberSemicolon(); + return this.finishNode(method, "TSMethodSignature"); + } else { + const property = nodeAny; + if (readonly) property.readonly = true; + const type = this.tsTryParseTypeAnnotation(); + if (type) property.typeAnnotation = type; + this.tsParseTypeMemberSemicolon(); + return this.finishNode(property, "TSPropertySignature"); + } + } + + tsParseTypeMember() { + const node = this.startNode(); + + if (this.match(types$4.parenL) || this.isRelational("<")) { + return this.tsParseSignatureMember("TSCallSignatureDeclaration", node); + } + + if (this.match(types$4._new)) { + const id = this.startNode(); + this.next(); + + if (this.match(types$4.parenL) || this.isRelational("<")) { + return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node); + } else { + node.key = this.createIdentifier(id, "new"); + return this.tsParsePropertyOrMethodSignature(node, false); + } + } + + const readonly = !!this.tsParseModifier(["readonly"]); + const idx = this.tsTryParseIndexSignature(node); + + if (idx) { + if (readonly) node.readonly = true; + return idx; + } + + this.parsePropertyName(node, false); + return this.tsParsePropertyOrMethodSignature(node, readonly); + } + + tsParseTypeLiteral() { + const node = this.startNode(); + node.members = this.tsParseObjectTypeMembers(); + return this.finishNode(node, "TSTypeLiteral"); + } + + tsParseObjectTypeMembers() { + this.expect(types$4.braceL); + const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this)); + this.expect(types$4.braceR); + return members; + } + + tsIsStartOfMappedType() { + this.next(); + + if (this.eat(types$4.plusMin)) { + return this.isContextual("readonly"); + } + + if (this.isContextual("readonly")) { + this.next(); + } + + if (!this.match(types$4.bracketL)) { + return false; + } + + this.next(); + + if (!this.tsIsIdentifier()) { + return false; + } + + this.next(); + return this.match(types$4._in); + } + + tsParseMappedTypeParameter() { + const node = this.startNode(); + node.name = this.parseIdentifierName(node.start); + node.constraint = this.tsExpectThenParseType(types$4._in); + return this.finishNode(node, "TSTypeParameter"); + } + + tsParseMappedType() { + const node = this.startNode(); + this.expect(types$4.braceL); + + if (this.match(types$4.plusMin)) { + node.readonly = this.state.value; + this.next(); + this.expectContextual("readonly"); + } else if (this.eatContextual("readonly")) { + node.readonly = true; + } + + this.expect(types$4.bracketL); + node.typeParameter = this.tsParseMappedTypeParameter(); + this.expect(types$4.bracketR); + + if (this.match(types$4.plusMin)) { + node.optional = this.state.value; + this.next(); + this.expect(types$4.question); + } else if (this.eat(types$4.question)) { + node.optional = true; + } + + node.typeAnnotation = this.tsTryParseType(); + this.semicolon(); + this.expect(types$4.braceR); + return this.finishNode(node, "TSMappedType"); + } + + tsParseTupleType() { + const node = this.startNode(); + node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false); + let seenOptionalElement = false; + node.elementTypes.forEach(elementNode => { + if (elementNode.type === "TSOptionalType") { + seenOptionalElement = true; + } else if (seenOptionalElement && elementNode.type !== "TSRestType") { + this.raise(elementNode.start, TSErrors$1.OptionalTypeBeforeRequired); + } + }); + return this.finishNode(node, "TSTupleType"); + } + + tsParseTupleElementType() { + if (this.match(types$4.ellipsis)) { + const restNode = this.startNode(); + this.next(); + restNode.typeAnnotation = this.tsParseType(); + + if (this.match(types$4.comma) && this.lookaheadCharCode() !== 93) { + this.raiseRestNotLast(this.state.start); + } + + return this.finishNode(restNode, "TSRestType"); + } + + const type = this.tsParseType(); + + if (this.eat(types$4.question)) { + const optionalTypeNode = this.startNodeAtNode(type); + optionalTypeNode.typeAnnotation = type; + return this.finishNode(optionalTypeNode, "TSOptionalType"); + } + + return type; + } + + tsParseParenthesizedType() { + const node = this.startNode(); + this.expect(types$4.parenL); + node.typeAnnotation = this.tsParseType(); + this.expect(types$4.parenR); + return this.finishNode(node, "TSParenthesizedType"); + } + + tsParseFunctionOrConstructorType(type) { + const node = this.startNode(); + + if (type === "TSConstructorType") { + this.expect(types$4._new); + } + + this.tsFillSignature(types$4.arrow, node); + return this.finishNode(node, type); + } + + tsParseLiteralTypeNode() { + const node = this.startNode(); + + node.literal = (() => { + switch (this.state.type) { + case types$4.num: + case types$4.bigint: + case types$4.string: + case types$4._true: + case types$4._false: + return this.parseExprAtom(); + + default: + throw this.unexpected(); + } + })(); + + return this.finishNode(node, "TSLiteralType"); + } + + tsParseTemplateLiteralType() { + const node = this.startNode(); + const templateNode = this.parseTemplate(false); + + if (templateNode.expressions.length > 0) { + this.raise(templateNode.expressions[0].start, TSErrors$1.TemplateTypeHasSubstitution); + } + + node.literal = templateNode; + return this.finishNode(node, "TSLiteralType"); + } + + tsParseThisTypeOrThisTypePredicate() { + const thisKeyword = this.tsParseThisTypeNode(); + + if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { + return this.tsParseThisTypePredicate(thisKeyword); + } else { + return thisKeyword; + } + } + + tsParseNonArrayType() { + switch (this.state.type) { + case types$4.name: + case types$4._void: + case types$4._null: + { + const type = this.match(types$4._void) ? "TSVoidKeyword" : this.match(types$4._null) ? "TSNullKeyword" : keywordTypeFromName$1(this.state.value); + + if (type !== undefined && this.lookaheadCharCode() !== 46) { + const node = this.startNode(); + this.next(); + return this.finishNode(node, type); + } + + return this.tsParseTypeReference(); + } + + case types$4.string: + case types$4.num: + case types$4.bigint: + case types$4._true: + case types$4._false: + return this.tsParseLiteralTypeNode(); + + case types$4.plusMin: + if (this.state.value === "-") { + const node = this.startNode(); + const nextToken = this.lookahead(); + + if (nextToken.type !== types$4.num && nextToken.type !== types$4.bigint) { + throw this.unexpected(); + } + + node.literal = this.parseMaybeUnary(); + return this.finishNode(node, "TSLiteralType"); + } + + break; + + case types$4._this: + return this.tsParseThisTypeOrThisTypePredicate(); + + case types$4._typeof: + return this.tsParseTypeQuery(); + + case types$4._import: + return this.tsParseImportType(); + + case types$4.braceL: + return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral(); + + case types$4.bracketL: + return this.tsParseTupleType(); + + case types$4.parenL: + return this.tsParseParenthesizedType(); + + case types$4.backQuote: + return this.tsParseTemplateLiteralType(); + } + + throw this.unexpected(); + } + + tsParseArrayTypeOrHigher() { + let type = this.tsParseNonArrayType(); + + while (!this.hasPrecedingLineBreak() && this.eat(types$4.bracketL)) { + if (this.match(types$4.bracketR)) { + const node = this.startNodeAtNode(type); + node.elementType = type; + this.expect(types$4.bracketR); + type = this.finishNode(node, "TSArrayType"); + } else { + const node = this.startNodeAtNode(type); + node.objectType = type; + node.indexType = this.tsParseType(); + this.expect(types$4.bracketR); + type = this.finishNode(node, "TSIndexedAccessType"); + } + } + + return type; + } + + tsParseTypeOperator(operator) { + const node = this.startNode(); + this.expectContextual(operator); + node.operator = operator; + node.typeAnnotation = this.tsParseTypeOperatorOrHigher(); + + if (operator === "readonly") { + this.tsCheckTypeAnnotationForReadOnly(node); + } + + return this.finishNode(node, "TSTypeOperator"); + } + + tsCheckTypeAnnotationForReadOnly(node) { + switch (node.typeAnnotation.type) { + case "TSTupleType": + case "TSArrayType": + return; + + default: + this.raise(node.start, TSErrors$1.UnexpectedReadonly); + } + } + + tsParseInferType() { + const node = this.startNode(); + this.expectContextual("infer"); + const typeParameter = this.startNode(); + typeParameter.name = this.parseIdentifierName(typeParameter.start); + node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter"); + return this.finishNode(node, "TSInferType"); + } + + tsParseTypeOperatorOrHigher() { + const operator = ["keyof", "unique", "readonly"].find(kw => this.isContextual(kw)); + return operator ? this.tsParseTypeOperator(operator) : this.isContextual("infer") ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher(); + } + + tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) { + this.eat(operator); + let type = parseConstituentType(); + + if (this.match(operator)) { + const types = [type]; + + while (this.eat(operator)) { + types.push(parseConstituentType()); + } + + const node = this.startNodeAtNode(type); + node.types = types; + type = this.finishNode(node, kind); + } + + return type; + } + + tsParseIntersectionTypeOrHigher() { + return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), types$4.bitwiseAND); + } + + tsParseUnionTypeOrHigher() { + return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), types$4.bitwiseOR); + } + + tsIsStartOfFunctionType() { + if (this.isRelational("<")) { + return true; + } + + return this.match(types$4.parenL) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this)); + } + + tsSkipParameterStart() { + if (this.match(types$4.name) || this.match(types$4._this)) { + this.next(); + return true; + } + + if (this.match(types$4.braceL)) { + let braceStackCounter = 1; + this.next(); + + while (braceStackCounter > 0) { + if (this.match(types$4.braceL)) { + ++braceStackCounter; + } else if (this.match(types$4.braceR)) { + --braceStackCounter; + } + + this.next(); + } + + return true; + } + + if (this.match(types$4.bracketL)) { + let braceStackCounter = 1; + this.next(); + + while (braceStackCounter > 0) { + if (this.match(types$4.bracketL)) { + ++braceStackCounter; + } else if (this.match(types$4.bracketR)) { + --braceStackCounter; + } + + this.next(); + } + + return true; + } + + return false; + } + + tsIsUnambiguouslyStartOfFunctionType() { + this.next(); + + if (this.match(types$4.parenR) || this.match(types$4.ellipsis)) { + return true; + } + + if (this.tsSkipParameterStart()) { + if (this.match(types$4.colon) || this.match(types$4.comma) || this.match(types$4.question) || this.match(types$4.eq)) { + return true; + } + + if (this.match(types$4.parenR)) { + this.next(); + + if (this.match(types$4.arrow)) { + return true; + } + } + } + + return false; + } + + tsParseTypeOrTypePredicateAnnotation(returnToken) { + return this.tsInType(() => { + const t = this.startNode(); + this.expect(returnToken); + const asserts = this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this)); + + if (asserts && this.match(types$4._this)) { + let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate(); + + if (thisTypePredicate.type === "TSThisType") { + const node = this.startNodeAtNode(t); + node.parameterName = thisTypePredicate; + node.asserts = true; + thisTypePredicate = this.finishNode(node, "TSTypePredicate"); + } else { + thisTypePredicate.asserts = true; + } + + t.typeAnnotation = thisTypePredicate; + return this.finishNode(t, "TSTypeAnnotation"); + } + + const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this)); + + if (!typePredicateVariable) { + if (!asserts) { + return this.tsParseTypeAnnotation(false, t); + } + + const node = this.startNodeAtNode(t); + node.parameterName = this.parseIdentifier(); + node.asserts = asserts; + t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); + return this.finishNode(t, "TSTypeAnnotation"); + } + + const type = this.tsParseTypeAnnotation(false); + const node = this.startNodeAtNode(t); + node.parameterName = typePredicateVariable; + node.typeAnnotation = type; + node.asserts = asserts; + t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); + return this.finishNode(t, "TSTypeAnnotation"); + }); + } + + tsTryParseTypeOrTypePredicateAnnotation() { + return this.match(types$4.colon) ? this.tsParseTypeOrTypePredicateAnnotation(types$4.colon) : undefined; + } + + tsTryParseTypeAnnotation() { + return this.match(types$4.colon) ? this.tsParseTypeAnnotation() : undefined; + } + + tsTryParseType() { + return this.tsEatThenParseType(types$4.colon); + } + + tsParseTypePredicatePrefix() { + const id = this.parseIdentifier(); + + if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { + this.next(); + return id; + } + } + + tsParseTypePredicateAsserts() { + if (!this.match(types$4.name) || this.state.value !== "asserts" || this.hasPrecedingLineBreak()) { + return false; + } + + const containsEsc = this.state.containsEsc; + this.next(); + + if (!this.match(types$4.name) && !this.match(types$4._this)) { + return false; + } + + if (containsEsc) { + this.raise(this.state.lastTokStart, ErrorMessages$1.InvalidEscapedReservedWord, "asserts"); + } + + return true; + } + + tsParseTypeAnnotation(eatColon = true, t = this.startNode()) { + this.tsInType(() => { + if (eatColon) this.expect(types$4.colon); + t.typeAnnotation = this.tsParseType(); + }); + return this.finishNode(t, "TSTypeAnnotation"); + } + + tsParseType() { + assert$1(this.state.inType); + const type = this.tsParseNonConditionalType(); + + if (this.hasPrecedingLineBreak() || !this.eat(types$4._extends)) { + return type; + } + + const node = this.startNodeAtNode(type); + node.checkType = type; + node.extendsType = this.tsParseNonConditionalType(); + this.expect(types$4.question); + node.trueType = this.tsParseType(); + this.expect(types$4.colon); + node.falseType = this.tsParseType(); + return this.finishNode(node, "TSConditionalType"); + } + + tsParseNonConditionalType() { + if (this.tsIsStartOfFunctionType()) { + return this.tsParseFunctionOrConstructorType("TSFunctionType"); + } + + if (this.match(types$4._new)) { + return this.tsParseFunctionOrConstructorType("TSConstructorType"); + } + + return this.tsParseUnionTypeOrHigher(); + } + + tsParseTypeAssertion() { + const node = this.startNode(); + + const _const = this.tsTryNextParseConstantContext(); + + node.typeAnnotation = _const || this.tsNextThenParseType(); + this.expectRelational(">"); + node.expression = this.parseMaybeUnary(); + return this.finishNode(node, "TSTypeAssertion"); + } + + tsParseHeritageClause(descriptor) { + const originalStart = this.state.start; + const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", this.tsParseExpressionWithTypeArguments.bind(this)); + + if (!delimitedList.length) { + this.raise(originalStart, TSErrors$1.EmptyHeritageClauseType, descriptor); + } + + return delimitedList; + } + + tsParseExpressionWithTypeArguments() { + const node = this.startNode(); + node.expression = this.tsParseEntityName(false); + + if (this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSExpressionWithTypeArguments"); + } + + tsParseInterfaceDeclaration(node) { + node.id = this.parseIdentifier(); + this.checkLVal(node.id, BIND_TS_INTERFACE$1, undefined, "typescript interface declaration"); + node.typeParameters = this.tsTryParseTypeParameters(); + + if (this.eat(types$4._extends)) { + node.extends = this.tsParseHeritageClause("extends"); + } + + const body = this.startNode(); + body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this)); + node.body = this.finishNode(body, "TSInterfaceBody"); + return this.finishNode(node, "TSInterfaceDeclaration"); + } + + tsParseTypeAliasDeclaration(node) { + node.id = this.parseIdentifier(); + this.checkLVal(node.id, BIND_TS_TYPE$1, undefined, "typescript type alias"); + node.typeParameters = this.tsTryParseTypeParameters(); + node.typeAnnotation = this.tsExpectThenParseType(types$4.eq); + this.semicolon(); + return this.finishNode(node, "TSTypeAliasDeclaration"); + } + + tsInNoContext(cb) { + const oldContext = this.state.context; + this.state.context = [oldContext[0]]; + + try { + return cb(); + } finally { + this.state.context = oldContext; + } + } + + tsInType(cb) { + const oldInType = this.state.inType; + this.state.inType = true; + + try { + return cb(); + } finally { + this.state.inType = oldInType; + } + } + + tsEatThenParseType(token) { + return !this.match(token) ? undefined : this.tsNextThenParseType(); + } + + tsExpectThenParseType(token) { + return this.tsDoThenParseType(() => this.expect(token)); + } + + tsNextThenParseType() { + return this.tsDoThenParseType(() => this.next()); + } + + tsDoThenParseType(cb) { + return this.tsInType(() => { + cb(); + return this.tsParseType(); + }); + } + + tsParseEnumMember() { + const node = this.startNode(); + node.id = this.match(types$4.string) ? this.parseExprAtom() : this.parseIdentifier(true); + + if (this.eat(types$4.eq)) { + node.initializer = this.parseMaybeAssign(); + } + + return this.finishNode(node, "TSEnumMember"); + } + + tsParseEnumDeclaration(node, isConst) { + if (isConst) node.const = true; + node.id = this.parseIdentifier(); + this.checkLVal(node.id, isConst ? BIND_TS_CONST_ENUM$1 : BIND_TS_ENUM$1, undefined, "typescript enum declaration"); + this.expect(types$4.braceL); + node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this)); + this.expect(types$4.braceR); + return this.finishNode(node, "TSEnumDeclaration"); + } + + tsParseModuleBlock() { + const node = this.startNode(); + this.scope.enter(SCOPE_OTHER$1); + this.expect(types$4.braceL); + this.parseBlockOrModuleBlockBody(node.body = [], undefined, true, types$4.braceR); + this.scope.exit(); + return this.finishNode(node, "TSModuleBlock"); + } + + tsParseModuleOrNamespaceDeclaration(node, nested = false) { + node.id = this.parseIdentifier(); + + if (!nested) { + this.checkLVal(node.id, BIND_TS_NAMESPACE$1, null, "module or namespace declaration"); + } + + if (this.eat(types$4.dot)) { + const inner = this.startNode(); + this.tsParseModuleOrNamespaceDeclaration(inner, true); + node.body = inner; + } else { + this.scope.enter(SCOPE_TS_MODULE$1); + this.prodParam.enter(PARAM$1); + node.body = this.tsParseModuleBlock(); + this.prodParam.exit(); + this.scope.exit(); + } + + return this.finishNode(node, "TSModuleDeclaration"); + } + + tsParseAmbientExternalModuleDeclaration(node) { + if (this.isContextual("global")) { + node.global = true; + node.id = this.parseIdentifier(); + } else if (this.match(types$4.string)) { + node.id = this.parseExprAtom(); + } else { + this.unexpected(); + } + + if (this.match(types$4.braceL)) { + this.scope.enter(SCOPE_TS_MODULE$1); + this.prodParam.enter(PARAM$1); + node.body = this.tsParseModuleBlock(); + this.prodParam.exit(); + this.scope.exit(); + } else { + this.semicolon(); + } + + return this.finishNode(node, "TSModuleDeclaration"); + } + + tsParseImportEqualsDeclaration(node, isExport) { + node.isExport = isExport || false; + node.id = this.parseIdentifier(); + this.checkLVal(node.id, BIND_LEXICAL$1, undefined, "import equals declaration"); + this.expect(types$4.eq); + node.moduleReference = this.tsParseModuleReference(); + this.semicolon(); + return this.finishNode(node, "TSImportEqualsDeclaration"); + } + + tsIsExternalModuleReference() { + return this.isContextual("require") && this.lookaheadCharCode() === 40; + } + + tsParseModuleReference() { + return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(false); + } + + tsParseExternalModuleReference() { + const node = this.startNode(); + this.expectContextual("require"); + this.expect(types$4.parenL); + + if (!this.match(types$4.string)) { + throw this.unexpected(); + } + + node.expression = this.parseExprAtom(); + this.expect(types$4.parenR); + return this.finishNode(node, "TSExternalModuleReference"); + } + + tsLookAhead(f) { + const state = this.state.clone(); + const res = f(); + this.state = state; + return res; + } + + tsTryParseAndCatch(f) { + const result = this.tryParse(abort => f() || abort()); + if (result.aborted || !result.node) return undefined; + if (result.error) this.state = result.failState; + return result.node; + } + + tsTryParse(f) { + const state = this.state.clone(); + const result = f(); + + if (result !== undefined && result !== false) { + return result; + } else { + this.state = state; + return undefined; + } + } + + tsTryParseDeclare(nany) { + if (this.isLineTerminator()) { + return; + } + + let starttype = this.state.type; + let kind; + + if (this.isContextual("let")) { + starttype = types$4._var; + kind = "let"; + } + + switch (starttype) { + case types$4._function: + return this.parseFunctionStatement(nany, false, true); + + case types$4._class: + nany.declare = true; + return this.parseClass(nany, true, false); + + case types$4._const: + if (this.match(types$4._const) && this.isLookaheadContextual("enum")) { + this.expect(types$4._const); + this.expectContextual("enum"); + return this.tsParseEnumDeclaration(nany, true); + } + + case types$4._var: + kind = kind || this.state.value; + return this.parseVarStatement(nany, kind); + + case types$4.name: + { + const value = this.state.value; + + if (value === "global") { + return this.tsParseAmbientExternalModuleDeclaration(nany); + } else { + return this.tsParseDeclaration(nany, value, true); + } + } + } + } + + tsTryParseExportDeclaration() { + return this.tsParseDeclaration(this.startNode(), this.state.value, true); + } + + tsParseExpressionStatement(node, expr) { + switch (expr.name) { + case "declare": + { + const declaration = this.tsTryParseDeclare(node); + + if (declaration) { + declaration.declare = true; + return declaration; + } + + break; + } + + case "global": + if (this.match(types$4.braceL)) { + this.scope.enter(SCOPE_TS_MODULE$1); + this.prodParam.enter(PARAM$1); + const mod = node; + mod.global = true; + mod.id = expr; + mod.body = this.tsParseModuleBlock(); + this.scope.exit(); + this.prodParam.exit(); + return this.finishNode(mod, "TSModuleDeclaration"); + } + + break; + + default: + return this.tsParseDeclaration(node, expr.name, false); + } + } + + tsParseDeclaration(node, value, next) { + switch (value) { + case "abstract": + if (this.tsCheckLineTerminatorAndMatch(types$4._class, next)) { + const cls = node; + cls.abstract = true; + + if (next) { + this.next(); + + if (!this.match(types$4._class)) { + this.unexpected(null, types$4._class); + } + } + + return this.parseClass(cls, true, false); + } + + break; + + case "enum": + if (next || this.match(types$4.name)) { + if (next) this.next(); + return this.tsParseEnumDeclaration(node, false); + } + + break; + + case "interface": + if (this.tsCheckLineTerminatorAndMatch(types$4.name, next)) { + if (next) this.next(); + return this.tsParseInterfaceDeclaration(node); + } + + break; + + case "module": + if (next) this.next(); + + if (this.match(types$4.string)) { + return this.tsParseAmbientExternalModuleDeclaration(node); + } else if (this.tsCheckLineTerminatorAndMatch(types$4.name, next)) { + return this.tsParseModuleOrNamespaceDeclaration(node); + } + + break; + + case "namespace": + if (this.tsCheckLineTerminatorAndMatch(types$4.name, next)) { + if (next) this.next(); + return this.tsParseModuleOrNamespaceDeclaration(node); + } + + break; + + case "type": + if (this.tsCheckLineTerminatorAndMatch(types$4.name, next)) { + if (next) this.next(); + return this.tsParseTypeAliasDeclaration(node); + } + + break; + } + } + + tsCheckLineTerminatorAndMatch(tokenType, next) { + return (next || this.match(tokenType)) && !this.isLineTerminator(); + } + + tsTryParseGenericAsyncArrowFunction(startPos, startLoc) { + if (!this.isRelational("<")) { + return undefined; + } + + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + this.state.maybeInArrowParameters = true; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + const res = this.tsTryParseAndCatch(() => { + const node = this.startNodeAt(startPos, startLoc); + node.typeParameters = this.tsParseTypeParameters(); + super.parseFunctionParams(node); + node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation(); + this.expect(types$4.arrow); + return node; + }); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + + if (!res) { + return undefined; + } + + return this.parseArrowExpression(res, null, true); + } + + tsParseTypeArguments() { + const node = this.startNode(); + node.params = this.tsInType(() => this.tsInNoContext(() => { + this.expectRelational("<"); + return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this)); + })); + this.state.exprAllowed = false; + this.expectRelational(">"); + return this.finishNode(node, "TSTypeParameterInstantiation"); + } + + tsIsDeclarationStart() { + if (this.match(types$4.name)) { + switch (this.state.value) { + case "abstract": + case "declare": + case "enum": + case "interface": + case "module": + case "namespace": + case "type": + return true; + } + } + + return false; + } + + isExportDefaultSpecifier() { + if (this.tsIsDeclarationStart()) return false; + return super.isExportDefaultSpecifier(); + } + + parseAssignableListItem(allowModifiers, decorators) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let accessibility; + let readonly = false; + + if (allowModifiers) { + accessibility = this.parseAccessModifier(); + readonly = !!this.tsParseModifier(["readonly"]); + } + + const left = this.parseMaybeDefault(); + this.parseAssignableListItemTypes(left); + const elt = this.parseMaybeDefault(left.start, left.loc.start, left); + + if (accessibility || readonly) { + const pp = this.startNodeAt(startPos, startLoc); + + if (decorators.length) { + pp.decorators = decorators; + } + + if (accessibility) pp.accessibility = accessibility; + if (readonly) pp.readonly = readonly; + + if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") { + this.raise(pp.start, TSErrors$1.UnsupportedParameterPropertyKind); + } + + pp.parameter = elt; + return this.finishNode(pp, "TSParameterProperty"); + } + + if (decorators.length) { + left.decorators = decorators; + } + + return elt; + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + if (this.match(types$4.colon)) { + node.returnType = this.tsParseTypeOrTypePredicateAnnotation(types$4.colon); + } + + const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" ? "TSDeclareMethod" : undefined; + + if (bodilessType && !this.match(types$4.braceL) && this.isLineTerminator()) { + this.finishNode(node, bodilessType); + return; + } + + super.parseFunctionBodyAndFinish(node, type, isMethod); + } + + registerFunctionStatementId(node) { + if (!node.body && node.id) { + this.checkLVal(node.id, BIND_TS_AMBIENT$1, null, "function name"); + } else { + super.registerFunctionStatementId(...arguments); + } + } + + parseSubscript(base, startPos, startLoc, noCalls, state) { + if (!this.hasPrecedingLineBreak() && this.match(types$4.bang)) { + this.state.exprAllowed = false; + this.next(); + const nonNullExpression = this.startNodeAt(startPos, startLoc); + nonNullExpression.expression = base; + return this.finishNode(nonNullExpression, "TSNonNullExpression"); + } + + if (this.isRelational("<")) { + const result = this.tsTryParseAndCatch(() => { + if (!noCalls && this.atPossibleAsyncArrow(base)) { + const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startPos, startLoc); + + if (asyncArrowFn) { + return asyncArrowFn; + } + } + + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + const typeArguments = this.tsParseTypeArguments(); + + if (typeArguments) { + if (!noCalls && this.eat(types$4.parenL)) { + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + node.typeParameters = typeArguments; + return this.finishCallExpression(node, state.optionalChainMember); + } else if (this.match(types$4.backQuote)) { + return this.parseTaggedTemplateExpression(startPos, startLoc, base, state, typeArguments); + } + } + + this.unexpected(); + }); + if (result) return result; + } + + return super.parseSubscript(base, startPos, startLoc, noCalls, state); + } + + parseNewArguments(node) { + if (this.isRelational("<")) { + const typeParameters = this.tsTryParseAndCatch(() => { + const args = this.tsParseTypeArguments(); + if (!this.match(types$4.parenL)) this.unexpected(); + return args; + }); + + if (typeParameters) { + node.typeParameters = typeParameters; + } + } + + super.parseNewArguments(node); + } + + parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { + if (nonNull$1(types$4._in.binop) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual("as")) { + const node = this.startNodeAt(leftStartPos, leftStartLoc); + node.expression = left; + + const _const = this.tsTryNextParseConstantContext(); + + if (_const) { + node.typeAnnotation = _const; + } else { + node.typeAnnotation = this.tsNextThenParseType(); + } + + this.finishNode(node, "TSAsExpression"); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); + } + + return super.parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn); + } + + checkReservedWord(word, startLoc, checkKeywords, isBinding) {} + + checkDuplicateExports() {} + + parseImport(node) { + if (this.match(types$4.name) || this.match(types$4.star) || this.match(types$4.braceL)) { + const ahead = this.lookahead(); + + if (this.match(types$4.name) && ahead.type === types$4.eq) { + return this.tsParseImportEqualsDeclaration(node); + } + + if (this.isContextual("type") && ahead.type !== types$4.comma && !(ahead.type === types$4.name && ahead.value === "from")) { + node.importKind = "type"; + this.next(); + } else { + node.importKind = "value"; + } + } + + const importNode = super.parseImport(node); + + if (importNode.importKind === "type" && importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier") { + this.raise(importNode.start, "A type-only import can specify a default import or named bindings, but not both."); + } + + return importNode; + } + + parseExport(node) { + if (this.match(types$4._import)) { + this.expect(types$4._import); + return this.tsParseImportEqualsDeclaration(node, true); + } else if (this.eat(types$4.eq)) { + const assign = node; + assign.expression = this.parseExpression(); + this.semicolon(); + return this.finishNode(assign, "TSExportAssignment"); + } else if (this.eatContextual("as")) { + const decl = node; + this.expectContextual("namespace"); + decl.id = this.parseIdentifier(); + this.semicolon(); + return this.finishNode(decl, "TSNamespaceExportDeclaration"); + } else { + if (this.isContextual("type") && this.lookahead().type === types$4.braceL) { + this.next(); + node.exportKind = "type"; + } else { + node.exportKind = "value"; + } + + return super.parseExport(node); + } + } + + isAbstractClass() { + return this.isContextual("abstract") && this.lookahead().type === types$4._class; + } + + parseExportDefaultExpression() { + if (this.isAbstractClass()) { + const cls = this.startNode(); + this.next(); + this.parseClass(cls, true, true); + cls.abstract = true; + return cls; + } + + if (this.state.value === "interface") { + const result = this.tsParseDeclaration(this.startNode(), this.state.value, true); + if (result) return result; + } + + return super.parseExportDefaultExpression(); + } + + parseStatementContent(context, topLevel) { + if (this.state.type === types$4._const) { + const ahead = this.lookahead(); + + if (ahead.type === types$4.name && ahead.value === "enum") { + const node = this.startNode(); + this.expect(types$4._const); + this.expectContextual("enum"); + return this.tsParseEnumDeclaration(node, true); + } + } + + return super.parseStatementContent(context, topLevel); + } + + parseAccessModifier() { + return this.tsParseModifier(["public", "protected", "private"]); + } + + parseClassMember(classBody, member, state, constructorAllowsSuper) { + this.tsParseModifiers(member, ["declare"]); + const accessibility = this.parseAccessModifier(); + if (accessibility) member.accessibility = accessibility; + this.tsParseModifiers(member, ["declare"]); + super.parseClassMember(classBody, member, state, constructorAllowsSuper); + } + + parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) { + this.tsParseModifiers(member, ["abstract", "readonly", "declare"]); + const idx = this.tsTryParseIndexSignature(member); + + if (idx) { + classBody.body.push(idx); + + if (member.abstract) { + this.raise(member.start, TSErrors$1.IndexSignatureHasAbstract); + } + + if (isStatic) { + this.raise(member.start, TSErrors$1.IndexSignatureHasStatic); + } + + if (member.accessibility) { + this.raise(member.start, TSErrors$1.IndexSignatureHasAccessibility, member.accessibility); + } + + return; + } + + super.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper); + } + + parsePostMemberNameModifiers(methodOrProp) { + const optional = this.eat(types$4.question); + if (optional) methodOrProp.optional = true; + + if (methodOrProp.readonly && this.match(types$4.parenL)) { + this.raise(methodOrProp.start, TSErrors$1.ClassMethodHasReadonly); + } + + if (methodOrProp.declare && this.match(types$4.parenL)) { + this.raise(methodOrProp.start, TSErrors$1.ClassMethodHasDeclare); + } + } + + parseExpressionStatement(node, expr) { + const decl = expr.type === "Identifier" ? this.tsParseExpressionStatement(node, expr) : undefined; + return decl || super.parseExpressionStatement(node, expr); + } + + shouldParseExportDeclaration() { + if (this.tsIsDeclarationStart()) return true; + return super.shouldParseExportDeclaration(); + } + + parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { + if (!refNeedsArrowPos || !this.match(types$4.question)) { + return super.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); + } + + const result = this.tryParse(() => super.parseConditional(expr, noIn, startPos, startLoc)); + + if (!result.node) { + refNeedsArrowPos.start = result.error.pos || this.state.start; + return expr; + } + + if (result.error) this.state = result.failState; + return result.node; + } + + parseParenItem(node, startPos, startLoc) { + node = super.parseParenItem(node, startPos, startLoc); + + if (this.eat(types$4.question)) { + node.optional = true; + this.resetEndLocation(node); + } + + if (this.match(types$4.colon)) { + const typeCastNode = this.startNodeAt(startPos, startLoc); + typeCastNode.expression = node; + typeCastNode.typeAnnotation = this.tsParseTypeAnnotation(); + return this.finishNode(typeCastNode, "TSTypeCastExpression"); + } + + return node; + } + + parseExportDeclaration(node) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const isDeclare = this.eatContextual("declare"); + let declaration; + + if (this.match(types$4.name)) { + declaration = this.tsTryParseExportDeclaration(); + } + + if (!declaration) { + declaration = super.parseExportDeclaration(node); + } + + if (declaration && (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare)) { + node.exportKind = "type"; + } + + if (declaration && isDeclare) { + this.resetStartLocation(declaration, startPos, startLoc); + declaration.declare = true; + } + + return declaration; + } + + parseClassId(node, isStatement, optionalId) { + if ((!isStatement || optionalId) && this.isContextual("implements")) { + return; + } + + super.parseClassId(node, isStatement, optionalId, node.declare ? BIND_TS_AMBIENT$1 : BIND_CLASS$1); + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) node.typeParameters = typeParameters; + } + + parseClassPropertyAnnotation(node) { + if (!node.optional && this.eat(types$4.bang)) { + node.definite = true; + } + + const type = this.tsTryParseTypeAnnotation(); + if (type) node.typeAnnotation = type; + } + + parseClassProperty(node) { + this.parseClassPropertyAnnotation(node); + + if (node.declare && this.match(types$4.equal)) { + this.raise(this.state.start, TSErrors$1.DeclareClassFieldHasInitializer); + } + + return super.parseClassProperty(node); + } + + parseClassPrivateProperty(node) { + if (node.abstract) { + this.raise(node.start, TSErrors$1.PrivateElementHasAbstract); + } + + if (node.accessibility) { + this.raise(node.start, TSErrors$1.PrivateElementHasAccessibility, node.accessibility); + } + + this.parseClassPropertyAnnotation(node); + return super.parseClassPrivateProperty(node); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) method.typeParameters = typeParameters; + super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) method.typeParameters = typeParameters; + super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); + } + + parseClassSuper(node) { + super.parseClassSuper(node); + + if (node.superClass && this.isRelational("<")) { + node.superTypeParameters = this.tsParseTypeArguments(); + } + + if (this.eatContextual("implements")) { + node.implements = this.tsParseHeritageClause("implements"); + } + } + + parseObjPropValue(prop, ...args) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) prop.typeParameters = typeParameters; + super.parseObjPropValue(prop, ...args); + } + + parseFunctionParams(node, allowModifiers) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) node.typeParameters = typeParameters; + super.parseFunctionParams(node, allowModifiers); + } + + parseVarId(decl, kind) { + super.parseVarId(decl, kind); + + if (decl.id.type === "Identifier" && this.eat(types$4.bang)) { + decl.definite = true; + } + + const type = this.tsTryParseTypeAnnotation(); + + if (type) { + decl.id.typeAnnotation = type; + this.resetEndLocation(decl.id); + } + } + + parseAsyncArrowFromCallExpression(node, call) { + if (this.match(types$4.colon)) { + node.returnType = this.tsParseTypeAnnotation(); + } + + return super.parseAsyncArrowFromCallExpression(node, call); + } + + parseMaybeAssign(...args) { + var _jsx, _jsx2, _typeCast, _jsx3, _typeCast2, _jsx4, _typeCast3; + + let state; + let jsx; + let typeCast; + + if (this.match(types$4.jsxTagStart)) { + state = this.state.clone(); + jsx = this.tryParse(() => super.parseMaybeAssign(...args), state); + if (!jsx.error) return jsx.node; + const { + context + } = this.state; + + if (context[context.length - 1] === types$1$1.j_oTag) { + context.length -= 2; + } else if (context[context.length - 1] === types$1$1.j_expr) { + context.length -= 1; + } + } + + if (!((_jsx = jsx) == null ? void 0 : _jsx.error) && !this.isRelational("<")) { + return super.parseMaybeAssign(...args); + } + + let typeParameters; + state = state || this.state.clone(); + const arrow = this.tryParse(abort => { + var _typeParameters; + + typeParameters = this.tsParseTypeParameters(); + const expr = super.parseMaybeAssign(...args); + + if (expr.type !== "ArrowFunctionExpression" || expr.extra && expr.extra.parenthesized) { + abort(); + } + + if (((_typeParameters = typeParameters) == null ? void 0 : _typeParameters.params.length) !== 0) { + this.resetStartLocationFromNode(expr, typeParameters); + } + + expr.typeParameters = typeParameters; + return expr; + }, state); + if (!arrow.error && !arrow.aborted) return arrow.node; + + if (!jsx) { + assert$1(!this.hasPlugin("jsx")); + typeCast = this.tryParse(() => super.parseMaybeAssign(...args), state); + if (!typeCast.error) return typeCast.node; + } + + if ((_jsx2 = jsx) == null ? void 0 : _jsx2.node) { + this.state = jsx.failState; + return jsx.node; + } + + if (arrow.node) { + this.state = arrow.failState; + return arrow.node; + } + + if ((_typeCast = typeCast) == null ? void 0 : _typeCast.node) { + this.state = typeCast.failState; + return typeCast.node; + } + + if ((_jsx3 = jsx) == null ? void 0 : _jsx3.thrown) throw jsx.error; + if (arrow.thrown) throw arrow.error; + if ((_typeCast2 = typeCast) == null ? void 0 : _typeCast2.thrown) throw typeCast.error; + throw ((_jsx4 = jsx) == null ? void 0 : _jsx4.error) || arrow.error || ((_typeCast3 = typeCast) == null ? void 0 : _typeCast3.error); + } + + parseMaybeUnary(refExpressionErrors) { + if (!this.hasPlugin("jsx") && this.isRelational("<")) { + return this.tsParseTypeAssertion(); + } else { + return super.parseMaybeUnary(refExpressionErrors); + } + } + + parseArrow(node) { + if (this.match(types$4.colon)) { + const result = this.tryParse(abort => { + const returnType = this.tsParseTypeOrTypePredicateAnnotation(types$4.colon); + if (this.canInsertSemicolon() || !this.match(types$4.arrow)) abort(); + return returnType; + }); + if (result.aborted) return; + + if (!result.thrown) { + if (result.error) this.state = result.failState; + node.returnType = result.node; + } + } + + return super.parseArrow(node); + } + + parseAssignableListItemTypes(param) { + if (this.eat(types$4.question)) { + if (param.type !== "Identifier") { + this.raise(param.start, TSErrors$1.PatternIsOptional); + } + + param.optional = true; + } + + const type = this.tsTryParseTypeAnnotation(); + if (type) param.typeAnnotation = type; + this.resetEndLocation(param); + return param; + } + + toAssignable(node) { + switch (node.type) { + case "TSTypeCastExpression": + return super.toAssignable(this.typeCastToParameter(node)); + + case "TSParameterProperty": + return super.toAssignable(node); + + case "TSAsExpression": + case "TSNonNullExpression": + case "TSTypeAssertion": + node.expression = this.toAssignable(node.expression); + return node; + + default: + return super.toAssignable(node); + } + } + + checkLVal(expr, bindingType = BIND_NONE$1, checkClashes, contextDescription) { + switch (expr.type) { + case "TSTypeCastExpression": + return; + + case "TSParameterProperty": + this.checkLVal(expr.parameter, bindingType, checkClashes, "parameter property"); + return; + + case "TSAsExpression": + case "TSNonNullExpression": + case "TSTypeAssertion": + this.checkLVal(expr.expression, bindingType, checkClashes, contextDescription); + return; + + default: + super.checkLVal(expr, bindingType, checkClashes, contextDescription); + return; + } + } + + parseBindingAtom() { + switch (this.state.type) { + case types$4._this: + return this.parseIdentifier(true); + + default: + return super.parseBindingAtom(); + } + } + + parseMaybeDecoratorArguments(expr) { + if (this.isRelational("<")) { + const typeArguments = this.tsParseTypeArguments(); + + if (this.match(types$4.parenL)) { + const call = super.parseMaybeDecoratorArguments(expr); + call.typeParameters = typeArguments; + return call; + } + + this.unexpected(this.state.start, types$4.parenL); + } + + return super.parseMaybeDecoratorArguments(expr); + } + + isClassMethod() { + return this.isRelational("<") || super.isClassMethod(); + } + + isClassProperty() { + return this.match(types$4.bang) || this.match(types$4.colon) || super.isClassProperty(); + } + + parseMaybeDefault(...args) { + const node = super.parseMaybeDefault(...args); + + if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { + this.raise(node.typeAnnotation.start, TSErrors$1.TypeAnnotationAfterAssign); + } + + return node; + } + + getTokenFromCode(code) { + if (this.state.inType && (code === 62 || code === 60)) { + return this.finishOp(types$4.relational, 1); + } else { + return super.getTokenFromCode(code); + } + } + + toAssignableList(exprList) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + if (!expr) continue; + + switch (expr.type) { + case "TSTypeCastExpression": + exprList[i] = this.typeCastToParameter(expr); + break; + + case "TSAsExpression": + case "TSTypeAssertion": + if (!this.state.maybeInArrowParameters) { + exprList[i] = this.typeCastToParameter(expr); + } else { + this.raise(expr.start, TSErrors$1.UnexpectedTypeCastInParameter); + } + + break; + } + } + + return super.toAssignableList(...arguments); + } + + typeCastToParameter(node) { + node.expression.typeAnnotation = node.typeAnnotation; + this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + return node.expression; + } + + toReferencedList(exprList, isInParens) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + + if ((expr == null ? void 0 : expr.type) === "TSTypeCastExpression") { + this.raise(expr.start, TSErrors$1.UnexpectedTypeAnnotation); + } + } + + return exprList; + } + + shouldParseArrow() { + return this.match(types$4.colon) || super.shouldParseArrow(); + } + + shouldParseAsyncArrow() { + return this.match(types$4.colon) || super.shouldParseAsyncArrow(); + } + + canHaveLeadingDecorator() { + return super.canHaveLeadingDecorator() || this.isAbstractClass(); + } + + jsxParseOpeningElementAfterName(node) { + if (this.isRelational("<")) { + const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArguments()); + if (typeArguments) node.typeParameters = typeArguments; + } + + return super.jsxParseOpeningElementAfterName(node); + } + + getGetterSetterExpectedParamCount(method) { + const baseCount = super.getGetterSetterExpectedParamCount(method); + const firstParam = method.params[0]; + const hasContextParam = firstParam && firstParam.type === "Identifier" && firstParam.name === "this"; + return hasContextParam ? baseCount + 1 : baseCount; + } + + }); + + types$4.placeholder = new TokenType("%%", { + startsExpr: true + }); + var placeholders$1 = (superClass => class extends superClass { + parsePlaceholder(expectedNode) { + if (this.match(types$4.placeholder)) { + const node = this.startNode(); + this.next(); + this.assertNoSpace("Unexpected space in placeholder."); + node.name = super.parseIdentifier(true); + this.assertNoSpace("Unexpected space in placeholder."); + this.expect(types$4.placeholder); + return this.finishPlaceholder(node, expectedNode); + } + } + + finishPlaceholder(node, expectedNode) { + const isFinished = !!(node.expectedNode && node.type === "Placeholder"); + node.expectedNode = expectedNode; + return isFinished ? node : this.finishNode(node, "Placeholder"); + } + + getTokenFromCode(code) { + if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) { + return this.finishOp(types$4.placeholder, 2); + } + + return super.getTokenFromCode(...arguments); + } + + parseExprAtom() { + return this.parsePlaceholder("Expression") || super.parseExprAtom(...arguments); + } + + parseIdentifier() { + return this.parsePlaceholder("Identifier") || super.parseIdentifier(...arguments); + } + + checkReservedWord(word) { + if (word !== undefined) super.checkReservedWord(...arguments); + } + + parseBindingAtom() { + return this.parsePlaceholder("Pattern") || super.parseBindingAtom(...arguments); + } + + checkLVal(expr) { + if (expr.type !== "Placeholder") super.checkLVal(...arguments); + } + + toAssignable(node) { + if (node && node.type === "Placeholder" && node.expectedNode === "Expression") { + node.expectedNode = "Pattern"; + return node; + } + + return super.toAssignable(...arguments); + } + + verifyBreakContinue(node) { + if (node.label && node.label.type === "Placeholder") return; + super.verifyBreakContinue(...arguments); + } + + parseExpressionStatement(node, expr) { + if (expr.type !== "Placeholder" || expr.extra && expr.extra.parenthesized) { + return super.parseExpressionStatement(...arguments); + } + + if (this.match(types$4.colon)) { + const stmt = node; + stmt.label = this.finishPlaceholder(expr, "Identifier"); + this.next(); + stmt.body = this.parseStatement("label"); + return this.finishNode(stmt, "LabeledStatement"); + } + + this.semicolon(); + node.name = expr.name; + return this.finishPlaceholder(node, "Statement"); + } + + parseBlock() { + return this.parsePlaceholder("BlockStatement") || super.parseBlock(...arguments); + } + + parseFunctionId() { + return this.parsePlaceholder("Identifier") || super.parseFunctionId(...arguments); + } + + parseClass(node, isStatement, optionalId) { + const type = isStatement ? "ClassDeclaration" : "ClassExpression"; + this.next(); + this.takeDecorators(node); + const placeholder = this.parsePlaceholder("Identifier"); + + if (placeholder) { + if (this.match(types$4._extends) || this.match(types$4.placeholder) || this.match(types$4.braceL)) { + node.id = placeholder; + } else if (optionalId || !isStatement) { + node.id = null; + node.body = this.finishPlaceholder(placeholder, "ClassBody"); + return this.finishNode(node, type); + } else { + this.unexpected(null, "A class name is required"); + } + } else { + this.parseClassId(node, isStatement, optionalId); + } + + this.parseClassSuper(node); + node.body = this.parsePlaceholder("ClassBody") || this.parseClassBody(!!node.superClass); + return this.finishNode(node, type); + } + + parseExport(node) { + const placeholder = this.parsePlaceholder("Identifier"); + if (!placeholder) return super.parseExport(...arguments); + + if (!this.isContextual("from") && !this.match(types$4.comma)) { + node.specifiers = []; + node.source = null; + node.declaration = this.finishPlaceholder(placeholder, "Declaration"); + return this.finishNode(node, "ExportNamedDeclaration"); + } + + this.expectPlugin("exportDefaultFrom"); + const specifier = this.startNode(); + specifier.exported = placeholder; + node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + return super.parseExport(node); + } + + isExportDefaultSpecifier() { + if (this.match(types$4._default)) { + const next = this.nextTokenStart(); + + if (this.isUnparsedContextual(next, "from")) { + if (this.input.startsWith(types$4.placeholder.label, this.nextTokenStartSince(next + 4))) { + return true; + } + } + } + + return super.isExportDefaultSpecifier(); + } + + maybeParseExportDefaultSpecifier(node) { + if (node.specifiers && node.specifiers.length > 0) { + return true; + } + + return super.maybeParseExportDefaultSpecifier(...arguments); + } + + checkExport(node) { + const { + specifiers + } = node; + + if (specifiers == null ? void 0 : specifiers.length) { + node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder"); + } + + super.checkExport(node); + node.specifiers = specifiers; + } + + parseImport(node) { + const placeholder = this.parsePlaceholder("Identifier"); + if (!placeholder) return super.parseImport(...arguments); + node.specifiers = []; + + if (!this.isContextual("from") && !this.match(types$4.comma)) { + node.source = this.finishPlaceholder(placeholder, "StringLiteral"); + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + const specifier = this.startNodeAtNode(placeholder); + specifier.local = placeholder; + this.finishNode(specifier, "ImportDefaultSpecifier"); + node.specifiers.push(specifier); + + if (this.eat(types$4.comma)) { + const hasStarImport = this.maybeParseStarImportSpecifier(node); + if (!hasStarImport) this.parseNamedImportSpecifiers(node); + } + + this.expectContextual("from"); + node.source = this.parseImportSource(); + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportSource() { + return this.parsePlaceholder("StringLiteral") || super.parseImportSource(...arguments); + } + + }); + + var v8intrinsic$1 = (superClass => class extends superClass { + parseV8Intrinsic() { + if (this.match(types$4.modulo)) { + const v8IntrinsicStart = this.state.start; + const node = this.startNode(); + this.eat(types$4.modulo); + + if (this.match(types$4.name)) { + const name = this.parseIdentifierName(this.state.start); + const identifier = this.createIdentifier(node, name); + identifier.type = "V8IntrinsicIdentifier"; + + if (this.match(types$4.parenL)) { + return identifier; + } + } + + this.unexpected(v8IntrinsicStart); + } + } + + parseExprAtom() { + return this.parseV8Intrinsic() || super.parseExprAtom(...arguments); + } + + }); + + function hasPlugin$1(plugins, name) { + return plugins.some(plugin => { + if (Array.isArray(plugin)) { + return plugin[0] === name; + } else { + return plugin === name; + } + }); + } + function getPluginOption$1(plugins, name, option) { + const plugin = plugins.find(plugin => { + if (Array.isArray(plugin)) { + return plugin[0] === name; + } else { + return plugin === name; + } + }); + + if (plugin && Array.isArray(plugin)) { + return plugin[1][option]; + } + + return null; + } + const PIPELINE_PROPOSALS$1 = ["minimal", "smart", "fsharp"]; + const RECORD_AND_TUPLE_SYNTAX_TYPES$1 = ["hash", "bar"]; + function validatePlugins$1(plugins) { + if (hasPlugin$1(plugins, "decorators")) { + if (hasPlugin$1(plugins, "decorators-legacy")) { + throw new Error("Cannot use the decorators and decorators-legacy plugin together"); + } + + const decoratorsBeforeExport = getPluginOption$1(plugins, "decorators", "decoratorsBeforeExport"); + + if (decoratorsBeforeExport == null) { + throw new Error("The 'decorators' plugin requires a 'decoratorsBeforeExport' option," + " whose value must be a boolean. If you are migrating from" + " Babylon/Babel 6 or want to use the old decorators proposal, you" + " should use the 'decorators-legacy' plugin instead of 'decorators'."); + } else if (typeof decoratorsBeforeExport !== "boolean") { + throw new Error("'decoratorsBeforeExport' must be a boolean."); + } + } + + if (hasPlugin$1(plugins, "flow") && hasPlugin$1(plugins, "typescript")) { + throw new Error("Cannot combine flow and typescript plugins."); + } + + if (hasPlugin$1(plugins, "placeholders") && hasPlugin$1(plugins, "v8intrinsic")) { + throw new Error("Cannot combine placeholders and v8intrinsic plugins."); + } + + if (hasPlugin$1(plugins, "pipelineOperator") && !PIPELINE_PROPOSALS$1.includes(getPluginOption$1(plugins, "pipelineOperator", "proposal"))) { + throw new Error("'pipelineOperator' requires 'proposal' option whose value should be one of: " + PIPELINE_PROPOSALS$1.map(p => `'${p}'`).join(", ")); + } + + if (hasPlugin$1(plugins, "moduleAttributes")) { + const moduleAttributesVerionPluginOption = getPluginOption$1(plugins, "moduleAttributes", "version"); + + if (moduleAttributesVerionPluginOption !== "may-2020") { + throw new Error("The 'moduleAttributes' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is 'may-2020'."); + } + } + + if (hasPlugin$1(plugins, "recordAndTuple") && !RECORD_AND_TUPLE_SYNTAX_TYPES$1.includes(getPluginOption$1(plugins, "recordAndTuple", "syntaxType"))) { + throw new Error("'recordAndTuple' requires 'syntaxType' option whose value should be one of: " + RECORD_AND_TUPLE_SYNTAX_TYPES$1.map(p => `'${p}'`).join(", ")); + } + } + const mixinPlugins$1 = { + estree: estree$1, + jsx: jsx$2, + flow: flow$2, + typescript: typescript$2, + v8intrinsic: v8intrinsic$1, + placeholders: placeholders$1 + }; + const mixinPluginNames$1 = Object.keys(mixinPlugins$1); + + const defaultOptions$1 = { + sourceType: "script", + sourceFilename: undefined, + startLine: 1, + allowAwaitOutsideFunction: false, + allowReturnOutsideFunction: false, + allowImportExportEverywhere: false, + allowSuperOutsideMethod: false, + allowUndeclaredExports: false, + plugins: [], + strictMode: null, + ranges: false, + tokens: false, + createParenthesizedExpressions: false, + errorRecovery: false + }; + function getOptions$1(opts) { + const options = {}; + + for (let _i = 0, _Object$keys = Object.keys(defaultOptions$1); _i < _Object$keys.length; _i++) { + const key = _Object$keys[_i]; + options[key] = opts && opts[key] != null ? opts[key] : defaultOptions$1[key]; + } + + return options; + } + + let State$1 = class State { + constructor() { + this.errors = []; + this.potentialArrowAt = -1; + this.noArrowAt = []; + this.noArrowParamsConversionAt = []; + this.inParameters = false; + this.maybeInArrowParameters = false; + this.maybeInAsyncArrowHead = false; + this.inPipeline = false; + this.inType = false; + this.noAnonFunctionType = false; + this.inPropertyName = false; + this.hasFlowComment = false; + this.isIterator = false; + this.topicContext = { + maxNumOfResolvableTopics: 0, + maxTopicIndex: null + }; + this.soloAwait = false; + this.inFSharpPipelineDirectBody = false; + this.labels = []; + this.decoratorStack = [[]]; + this.yieldPos = -1; + this.awaitPos = -1; + this.comments = []; + this.trailingComments = []; + this.leadingComments = []; + this.commentStack = []; + this.commentPreviousNode = null; + this.pos = 0; + this.lineStart = 0; + this.type = types$4.eof; + this.value = null; + this.start = 0; + this.end = 0; + this.lastTokEndLoc = null; + this.lastTokStartLoc = null; + this.lastTokStart = 0; + this.lastTokEnd = 0; + this.context = [types$1$1.braceStatement]; + this.exprAllowed = true; + this.containsEsc = false; + this.octalPositions = []; + this.exportedIdentifiers = []; + this.tokensLength = 0; + } + + init(options) { + this.strict = options.strictMode === false ? false : options.sourceType === "module"; + this.curLine = options.startLine; + this.startLoc = this.endLoc = this.curPosition(); + } + + curPosition() { + return new Position$1(this.curLine, this.pos - this.lineStart); + } + + clone(skipArrays) { + const state = new State(); + const keys = Object.keys(this); + + for (let i = 0, length = keys.length; i < length; i++) { + const key = keys[i]; + let val = this[key]; + + if (!skipArrays && Array.isArray(val)) { + val = val.slice(); + } + + state[key] = val; + } + + return state; + } + + }; + + var _isDigit$1 = function isDigit(code) { + return code >= 48 && code <= 57; + }; + const VALID_REGEX_FLAGS$1 = new Set(["g", "m", "s", "i", "y", "u"]); + const forbiddenNumericSeparatorSiblings$1 = { + decBinOct: [46, 66, 69, 79, 95, 98, 101, 111], + hex: [46, 88, 95, 120] + }; + const allowedNumericSeparatorSiblings$1 = {}; + allowedNumericSeparatorSiblings$1.bin = [48, 49]; + allowedNumericSeparatorSiblings$1.oct = [...allowedNumericSeparatorSiblings$1.bin, 50, 51, 52, 53, 54, 55]; + allowedNumericSeparatorSiblings$1.dec = [...allowedNumericSeparatorSiblings$1.oct, 56, 57]; + allowedNumericSeparatorSiblings$1.hex = [...allowedNumericSeparatorSiblings$1.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102]; + let Token$1 = class Token { + constructor(state) { + this.type = state.type; + this.value = state.value; + this.start = state.start; + this.end = state.end; + this.loc = new SourceLocation$1(state.startLoc, state.endLoc); + } + + }; + let Tokenizer$1 = class Tokenizer extends ParserError$1 { + constructor(options, input) { + super(); + this.tokens = []; + this.state = new State$1(); + this.state.init(options); + this.input = input; + this.length = input.length; + this.isLookahead = false; + } + + pushToken(token) { + this.tokens.length = this.state.tokensLength; + this.tokens.push(token); + ++this.state.tokensLength; + } + + next() { + if (!this.isLookahead) { + this.checkKeywordEscapes(); + + if (this.options.tokens) { + this.pushToken(new Token$1(this.state)); + } + } + + this.state.lastTokEnd = this.state.end; + this.state.lastTokStart = this.state.start; + this.state.lastTokEndLoc = this.state.endLoc; + this.state.lastTokStartLoc = this.state.startLoc; + this.nextToken(); + } + + eat(type) { + if (this.match(type)) { + this.next(); + return true; + } else { + return false; + } + } + + match(type) { + return this.state.type === type; + } + + lookahead() { + const old = this.state; + this.state = old.clone(true); + this.isLookahead = true; + this.next(); + this.isLookahead = false; + const curr = this.state; + this.state = old; + return curr; + } + + nextTokenStart() { + return this.nextTokenStartSince(this.state.pos); + } + + nextTokenStartSince(pos) { + skipWhiteSpace$1.lastIndex = pos; + const skip = skipWhiteSpace$1.exec(this.input); + return pos + skip[0].length; + } + + lookaheadCharCode() { + return this.input.charCodeAt(this.nextTokenStart()); + } + + setStrict(strict) { + this.state.strict = strict; + if (!this.match(types$4.num) && !this.match(types$4.string)) return; + this.state.pos = this.state.start; + + while (this.state.pos < this.state.lineStart) { + this.state.lineStart = this.input.lastIndexOf("\n", this.state.lineStart - 2) + 1; + --this.state.curLine; + } + + this.nextToken(); + } + + curContext() { + return this.state.context[this.state.context.length - 1]; + } + + nextToken() { + const curContext = this.curContext(); + if (!(curContext == null ? void 0 : curContext.preserveSpace)) this.skipSpace(); + this.state.octalPositions = []; + this.state.start = this.state.pos; + this.state.startLoc = this.state.curPosition(); + + if (this.state.pos >= this.length) { + this.finishToken(types$4.eof); + return; + } + + const override = curContext == null ? void 0 : curContext.override; + + if (override) { + override(this); + } else { + this.getTokenFromCode(this.input.codePointAt(this.state.pos)); + } + } + + pushComment(block, text, start, end, startLoc, endLoc) { + const comment = { + type: block ? "CommentBlock" : "CommentLine", + value: text, + start: start, + end: end, + loc: new SourceLocation$1(startLoc, endLoc) + }; + if (this.options.tokens) this.pushToken(comment); + this.state.comments.push(comment); + this.addComment(comment); + } + + skipBlockComment() { + const startLoc = this.state.curPosition(); + const start = this.state.pos; + const end = this.input.indexOf("*/", this.state.pos + 2); + if (end === -1) throw this.raise(start, ErrorMessages$1.UnterminatedComment); + this.state.pos = end + 2; + lineBreakG$1.lastIndex = start; + let match; + + while ((match = lineBreakG$1.exec(this.input)) && match.index < this.state.pos) { + ++this.state.curLine; + this.state.lineStart = match.index + match[0].length; + } + + if (this.isLookahead) return; + this.pushComment(true, this.input.slice(start + 2, end), start, this.state.pos, startLoc, this.state.curPosition()); + } + + skipLineComment(startSkip) { + const start = this.state.pos; + const startLoc = this.state.curPosition(); + let ch = this.input.charCodeAt(this.state.pos += startSkip); + + if (this.state.pos < this.length) { + while (!isNewLine$1(ch) && ++this.state.pos < this.length) { + ch = this.input.charCodeAt(this.state.pos); + } + } + + if (this.isLookahead) return; + this.pushComment(false, this.input.slice(start + startSkip, this.state.pos), start, this.state.pos, startLoc, this.state.curPosition()); + } + + skipSpace() { + loop: while (this.state.pos < this.length) { + const ch = this.input.charCodeAt(this.state.pos); + + switch (ch) { + case 32: + case 160: + case 9: + ++this.state.pos; + break; + + case 13: + if (this.input.charCodeAt(this.state.pos + 1) === 10) { + ++this.state.pos; + } + + case 10: + case 8232: + case 8233: + ++this.state.pos; + ++this.state.curLine; + this.state.lineStart = this.state.pos; + break; + + case 47: + switch (this.input.charCodeAt(this.state.pos + 1)) { + case 42: + this.skipBlockComment(); + break; + + case 47: + this.skipLineComment(2); + break; + + default: + break loop; + } + + break; + + default: + if (isWhitespace$1(ch)) { + ++this.state.pos; + } else { + break loop; + } + + } + } + } + + finishToken(type, val) { + this.state.end = this.state.pos; + this.state.endLoc = this.state.curPosition(); + const prevType = this.state.type; + this.state.type = type; + this.state.value = val; + if (!this.isLookahead) this.updateContext(prevType); + } + + readToken_numberSign() { + if (this.state.pos === 0 && this.readToken_interpreter()) { + return; + } + + const nextPos = this.state.pos + 1; + const next = this.input.charCodeAt(nextPos); + + if (next >= 48 && next <= 57) { + throw this.raise(this.state.pos, ErrorMessages$1.UnexpectedDigitAfterHash); + } + + if (next === 123 || next === 91 && this.hasPlugin("recordAndTuple")) { + this.expectPlugin("recordAndTuple"); + + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "hash") { + throw this.raise(this.state.pos, next === 123 ? ErrorMessages$1.RecordExpressionHashIncorrectStartSyntaxType : ErrorMessages$1.TupleExpressionHashIncorrectStartSyntaxType); + } + + if (next === 123) { + this.finishToken(types$4.braceHashL); + } else { + this.finishToken(types$4.bracketHashL); + } + + this.state.pos += 2; + } else { + this.finishOp(types$4.hash, 1); + } + } + + readToken_dot() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next >= 48 && next <= 57) { + this.readNumber(true); + return; + } + + if (next === 46 && this.input.charCodeAt(this.state.pos + 2) === 46) { + this.state.pos += 3; + this.finishToken(types$4.ellipsis); + } else { + ++this.state.pos; + this.finishToken(types$4.dot); + } + } + + readToken_slash() { + if (this.state.exprAllowed && !this.state.inType) { + ++this.state.pos; + this.readRegexp(); + return; + } + + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(types$4.assign, 2); + } else { + this.finishOp(types$4.slash, 1); + } + } + + readToken_interpreter() { + if (this.state.pos !== 0 || this.length < 2) return false; + let ch = this.input.charCodeAt(this.state.pos + 1); + if (ch !== 33) return false; + const start = this.state.pos; + this.state.pos += 1; + + while (!isNewLine$1(ch) && ++this.state.pos < this.length) { + ch = this.input.charCodeAt(this.state.pos); + } + + const value = this.input.slice(start + 2, this.state.pos); + this.finishToken(types$4.interpreterDirective, value); + return true; + } + + readToken_mult_modulo(code) { + let type = code === 42 ? types$4.star : types$4.modulo; + let width = 1; + let next = this.input.charCodeAt(this.state.pos + 1); + const exprAllowed = this.state.exprAllowed; + + if (code === 42 && next === 42) { + width++; + next = this.input.charCodeAt(this.state.pos + 2); + type = types$4.exponent; + } + + if (next === 61 && !exprAllowed) { + width++; + type = types$4.assign; + } + + this.finishOp(type, width); + } + + readToken_pipe_amp(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === code) { + if (this.input.charCodeAt(this.state.pos + 2) === 61) { + this.finishOp(types$4.assign, 3); + } else { + this.finishOp(code === 124 ? types$4.logicalOR : types$4.logicalAND, 2); + } + + return; + } + + if (code === 124) { + if (next === 62) { + this.finishOp(types$4.pipeline, 2); + return; + } + + if (this.hasPlugin("recordAndTuple") && next === 125) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages$1.RecordExpressionBarIncorrectEndSyntaxType); + } + + this.finishOp(types$4.braceBarR, 2); + return; + } + + if (this.hasPlugin("recordAndTuple") && next === 93) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages$1.TupleExpressionBarIncorrectEndSyntaxType); + } + + this.finishOp(types$4.bracketBarR, 2); + return; + } + } + + if (next === 61) { + this.finishOp(types$4.assign, 2); + return; + } + + this.finishOp(code === 124 ? types$4.bitwiseOR : types$4.bitwiseAND, 1); + } + + readToken_caret() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(types$4.assign, 2); + } else { + this.finishOp(types$4.bitwiseXOR, 1); + } + } + + readToken_plus_min(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 62 && (this.state.lastTokEnd === 0 || lineBreak$1.test(this.input.slice(this.state.lastTokEnd, this.state.pos)))) { + this.skipLineComment(3); + this.skipSpace(); + this.nextToken(); + return; + } + + this.finishOp(types$4.incDec, 2); + return; + } + + if (next === 61) { + this.finishOp(types$4.assign, 2); + } else { + this.finishOp(types$4.plusMin, 1); + } + } + + readToken_lt_gt(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + let size = 1; + + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; + + if (this.input.charCodeAt(this.state.pos + size) === 61) { + this.finishOp(types$4.assign, size + 1); + return; + } + + this.finishOp(types$4.bitShift, size); + return; + } + + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.state.pos + 2) === 45 && this.input.charCodeAt(this.state.pos + 3) === 45) { + this.skipLineComment(4); + this.skipSpace(); + this.nextToken(); + return; + } + + if (next === 61) { + size = 2; + } + + this.finishOp(types$4.relational, size); + } + + readToken_eq_excl(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(types$4.equality, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); + return; + } + + if (code === 61 && next === 62) { + this.state.pos += 2; + this.finishToken(types$4.arrow); + return; + } + + this.finishOp(code === 61 ? types$4.eq : types$4.bang, 1); + } + + readToken_question() { + const next = this.input.charCodeAt(this.state.pos + 1); + const next2 = this.input.charCodeAt(this.state.pos + 2); + + if (next === 63 && !this.state.inType) { + if (next2 === 61) { + this.finishOp(types$4.assign, 3); + } else { + this.finishOp(types$4.nullishCoalescing, 2); + } + } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) { + this.state.pos += 2; + this.finishToken(types$4.questionDot); + } else { + ++this.state.pos; + this.finishToken(types$4.question); + } + } + + getTokenFromCode(code) { + switch (code) { + case 46: + this.readToken_dot(); + return; + + case 40: + ++this.state.pos; + this.finishToken(types$4.parenL); + return; + + case 41: + ++this.state.pos; + this.finishToken(types$4.parenR); + return; + + case 59: + ++this.state.pos; + this.finishToken(types$4.semi); + return; + + case 44: + ++this.state.pos; + this.finishToken(types$4.comma); + return; + + case 91: + if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages$1.TupleExpressionBarIncorrectStartSyntaxType); + } + + this.finishToken(types$4.bracketBarL); + this.state.pos += 2; + } else { + ++this.state.pos; + this.finishToken(types$4.bracketL); + } + + return; + + case 93: + ++this.state.pos; + this.finishToken(types$4.bracketR); + return; + + case 123: + if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages$1.RecordExpressionBarIncorrectStartSyntaxType); + } + + this.finishToken(types$4.braceBarL); + this.state.pos += 2; + } else { + ++this.state.pos; + this.finishToken(types$4.braceL); + } + + return; + + case 125: + ++this.state.pos; + this.finishToken(types$4.braceR); + return; + + case 58: + if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) { + this.finishOp(types$4.doubleColon, 2); + } else { + ++this.state.pos; + this.finishToken(types$4.colon); + } + + return; + + case 63: + this.readToken_question(); + return; + + case 96: + ++this.state.pos; + this.finishToken(types$4.backQuote); + return; + + case 48: + { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 120 || next === 88) { + this.readRadixNumber(16); + return; + } + + if (next === 111 || next === 79) { + this.readRadixNumber(8); + return; + } + + if (next === 98 || next === 66) { + this.readRadixNumber(2); + return; + } + } + + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + this.readNumber(false); + return; + + case 34: + case 39: + this.readString(code); + return; + + case 47: + this.readToken_slash(); + return; + + case 37: + case 42: + this.readToken_mult_modulo(code); + return; + + case 124: + case 38: + this.readToken_pipe_amp(code); + return; + + case 94: + this.readToken_caret(); + return; + + case 43: + case 45: + this.readToken_plus_min(code); + return; + + case 60: + case 62: + this.readToken_lt_gt(code); + return; + + case 61: + case 33: + this.readToken_eq_excl(code); + return; + + case 126: + this.finishOp(types$4.tilde, 1); + return; + + case 64: + ++this.state.pos; + this.finishToken(types$4.at); + return; + + case 35: + this.readToken_numberSign(); + return; + + case 92: + this.readWord(); + return; + + default: + if (isIdentifierStart$1(code)) { + this.readWord(); + return; + } + + } + + throw this.raise(this.state.pos, ErrorMessages$1.InvalidOrUnexpectedToken, String.fromCodePoint(code)); + } + + finishOp(type, size) { + const str = this.input.slice(this.state.pos, this.state.pos + size); + this.state.pos += size; + this.finishToken(type, str); + } + + readRegexp() { + const start = this.state.pos; + let escaped, inClass; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(start, ErrorMessages$1.UnterminatedRegExp); + } + + const ch = this.input.charAt(this.state.pos); + + if (lineBreak$1.test(ch)) { + throw this.raise(start, ErrorMessages$1.UnterminatedRegExp); + } + + if (escaped) { + escaped = false; + } else { + if (ch === "[") { + inClass = true; + } else if (ch === "]" && inClass) { + inClass = false; + } else if (ch === "/" && !inClass) { + break; + } + + escaped = ch === "\\"; + } + + ++this.state.pos; + } + + const content = this.input.slice(start, this.state.pos); + ++this.state.pos; + let mods = ""; + + while (this.state.pos < this.length) { + const char = this.input[this.state.pos]; + const charCode = this.input.codePointAt(this.state.pos); + + if (VALID_REGEX_FLAGS$1.has(char)) { + if (mods.indexOf(char) > -1) { + this.raise(this.state.pos + 1, ErrorMessages$1.DuplicateRegExpFlags); + } + } else if (isIdentifierChar$1(charCode) || charCode === 92) { + this.raise(this.state.pos + 1, ErrorMessages$1.MalformedRegExpFlags); + } else { + break; + } + + ++this.state.pos; + mods += char; + } + + this.finishToken(types$4.regexp, { + pattern: content, + flags: mods + }); + } + + readInt(radix, len, forceLen, allowNumSeparator = true) { + const start = this.state.pos; + const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings$1.hex : forbiddenNumericSeparatorSiblings$1.decBinOct; + const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings$1.hex : radix === 10 ? allowedNumericSeparatorSiblings$1.dec : radix === 8 ? allowedNumericSeparatorSiblings$1.oct : allowedNumericSeparatorSiblings$1.bin; + let invalid = false; + let total = 0; + + for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) { + const code = this.input.charCodeAt(this.state.pos); + let val; + + if (this.hasPlugin("numericSeparator")) { + if (code === 95) { + const prev = this.input.charCodeAt(this.state.pos - 1); + const next = this.input.charCodeAt(this.state.pos + 1); + + if (allowedSiblings.indexOf(next) === -1) { + this.raise(this.state.pos, ErrorMessages$1.UnexpectedNumericSeparator); + } else if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) { + this.raise(this.state.pos, ErrorMessages$1.UnexpectedNumericSeparator); + } + + if (!allowNumSeparator) { + this.raise(this.state.pos, ErrorMessages$1.NumericSeparatorInEscapeSequence); + } + + ++this.state.pos; + continue; + } + } + + if (code >= 97) { + val = code - 97 + 10; + } else if (code >= 65) { + val = code - 65 + 10; + } else if (_isDigit$1(code)) { + val = code - 48; + } else { + val = Infinity; + } + + if (val >= radix) { + if (this.options.errorRecovery && val <= 9) { + val = 0; + this.raise(this.state.start + i + 2, ErrorMessages$1.InvalidDigit, radix); + } else if (forceLen) { + val = 0; + invalid = true; + } else { + break; + } + } + + ++this.state.pos; + total = total * radix + val; + } + + if (this.state.pos === start || len != null && this.state.pos - start !== len || invalid) { + return null; + } + + return total; + } + + readRadixNumber(radix) { + const start = this.state.pos; + let isBigInt = false; + this.state.pos += 2; + const val = this.readInt(radix); + + if (val == null) { + this.raise(this.state.start + 2, ErrorMessages$1.InvalidDigit, radix); + } + + const next = this.input.charCodeAt(this.state.pos); + + if (next === 95) { + this.expectPlugin("numericSeparator", this.state.pos); + } + + if (next === 110) { + ++this.state.pos; + isBigInt = true; + } + + if (isIdentifierStart$1(this.input.codePointAt(this.state.pos))) { + throw this.raise(this.state.pos, ErrorMessages$1.NumberIdentifier); + } + + if (isBigInt) { + const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); + this.finishToken(types$4.bigint, str); + return; + } + + this.finishToken(types$4.num, val); + } + + readNumber(startsWithDot) { + const start = this.state.pos; + let isFloat = false; + let isBigInt = false; + let isNonOctalDecimalInt = false; + + if (!startsWithDot && this.readInt(10) === null) { + this.raise(start, ErrorMessages$1.InvalidNumber); + } + + let octal = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48; + + if (octal) { + if (this.state.strict) { + this.raise(start, ErrorMessages$1.StrictOctalLiteral); + } + + if (/[89]/.test(this.input.slice(start, this.state.pos))) { + octal = false; + isNonOctalDecimalInt = true; + } + } + + let next = this.input.charCodeAt(this.state.pos); + + if (next === 46 && !octal) { + ++this.state.pos; + this.readInt(10); + isFloat = true; + next = this.input.charCodeAt(this.state.pos); + } + + if ((next === 69 || next === 101) && !octal) { + next = this.input.charCodeAt(++this.state.pos); + + if (next === 43 || next === 45) { + ++this.state.pos; + } + + if (this.readInt(10) === null) this.raise(start, ErrorMessages$1.InvalidNumber); + isFloat = true; + next = this.input.charCodeAt(this.state.pos); + } + + if (this.hasPlugin("numericSeparator") && (octal || isNonOctalDecimalInt)) { + const underscorePos = this.input.slice(start, this.state.pos).indexOf("_"); + + if (underscorePos > 0) { + this.raise(underscorePos + start, ErrorMessages$1.ZeroDigitNumericSeparator); + } + } + + if (next === 95) { + this.expectPlugin("numericSeparator", this.state.pos); + } + + if (next === 110) { + if (isFloat || octal || isNonOctalDecimalInt) { + this.raise(start, ErrorMessages$1.InvalidBigIntLiteral); + } + + ++this.state.pos; + isBigInt = true; + } + + if (isIdentifierStart$1(this.input.codePointAt(this.state.pos))) { + throw this.raise(this.state.pos, ErrorMessages$1.NumberIdentifier); + } + + const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); + + if (isBigInt) { + this.finishToken(types$4.bigint, str); + return; + } + + const val = octal ? parseInt(str, 8) : parseFloat(str); + this.finishToken(types$4.num, val); + } + + readCodePoint(throwOnInvalid) { + const ch = this.input.charCodeAt(this.state.pos); + let code; + + if (ch === 123) { + const codePos = ++this.state.pos; + code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, true, throwOnInvalid); + ++this.state.pos; + + if (code !== null && code > 0x10ffff) { + if (throwOnInvalid) { + this.raise(codePos, ErrorMessages$1.InvalidCodePoint); + } else { + return null; + } + } + } else { + code = this.readHexChar(4, false, throwOnInvalid); + } + + return code; + } + + readString(quote) { + let out = "", + chunkStart = ++this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages$1.UnterminatedString); + } + + const ch = this.input.charCodeAt(this.state.pos); + if (ch === quote) break; + + if (ch === 92) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.readEscapedChar(false); + chunkStart = this.state.pos; + } else if (ch === 8232 || ch === 8233) { + ++this.state.pos; + ++this.state.curLine; + this.state.lineStart = this.state.pos; + } else if (isNewLine$1(ch)) { + throw this.raise(this.state.start, ErrorMessages$1.UnterminatedString); + } else { + ++this.state.pos; + } + } + + out += this.input.slice(chunkStart, this.state.pos++); + this.finishToken(types$4.string, out); + } + + readTmplToken() { + let out = "", + chunkStart = this.state.pos, + containsInvalid = false; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages$1.UnterminatedTemplate); + } + + const ch = this.input.charCodeAt(this.state.pos); + + if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { + if (this.state.pos === this.state.start && this.match(types$4.template)) { + if (ch === 36) { + this.state.pos += 2; + this.finishToken(types$4.dollarBraceL); + return; + } else { + ++this.state.pos; + this.finishToken(types$4.backQuote); + return; + } + } + + out += this.input.slice(chunkStart, this.state.pos); + this.finishToken(types$4.template, containsInvalid ? null : out); + return; + } + + if (ch === 92) { + out += this.input.slice(chunkStart, this.state.pos); + const escaped = this.readEscapedChar(true); + + if (escaped === null) { + containsInvalid = true; + } else { + out += escaped; + } + + chunkStart = this.state.pos; + } else if (isNewLine$1(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + ++this.state.pos; + + switch (ch) { + case 13: + if (this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + } + + case 10: + out += "\n"; + break; + + default: + out += String.fromCharCode(ch); + break; + } + + ++this.state.curLine; + this.state.lineStart = this.state.pos; + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + } + + readEscapedChar(inTemplate) { + const throwOnInvalid = !inTemplate; + const ch = this.input.charCodeAt(++this.state.pos); + ++this.state.pos; + + switch (ch) { + case 110: + return "\n"; + + case 114: + return "\r"; + + case 120: + { + const code = this.readHexChar(2, false, throwOnInvalid); + return code === null ? null : String.fromCharCode(code); + } + + case 117: + { + const code = this.readCodePoint(throwOnInvalid); + return code === null ? null : String.fromCodePoint(code); + } + + case 116: + return "\t"; + + case 98: + return "\b"; + + case 118: + return "\u000b"; + + case 102: + return "\f"; + + case 13: + if (this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + } + + case 10: + this.state.lineStart = this.state.pos; + ++this.state.curLine; + + case 8232: + case 8233: + return ""; + + case 56: + case 57: + if (inTemplate) { + return null; + } + + default: + if (ch >= 48 && ch <= 55) { + const codePos = this.state.pos - 1; + const match = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/); + let octalStr = match[0]; + let octal = parseInt(octalStr, 8); + + if (octal > 255) { + octalStr = octalStr.slice(0, -1); + octal = parseInt(octalStr, 8); + } + + this.state.pos += octalStr.length - 1; + const next = this.input.charCodeAt(this.state.pos); + + if (octalStr !== "0" || next === 56 || next === 57) { + if (inTemplate) { + return null; + } else if (this.state.strict) { + this.raise(codePos, ErrorMessages$1.StrictOctalLiteral); + } else { + this.state.octalPositions.push(codePos); + } + } + + return String.fromCharCode(octal); + } + + return String.fromCharCode(ch); + } + } + + readHexChar(len, forceLen, throwOnInvalid) { + const codePos = this.state.pos; + const n = this.readInt(16, len, forceLen, false); + + if (n === null) { + if (throwOnInvalid) { + this.raise(codePos, ErrorMessages$1.InvalidEscapeSequence); + } else { + this.state.pos = codePos - 1; + } + } + + return n; + } + + readWord1() { + let word = ""; + this.state.containsEsc = false; + const start = this.state.pos; + let chunkStart = this.state.pos; + + while (this.state.pos < this.length) { + const ch = this.input.codePointAt(this.state.pos); + + if (isIdentifierChar$1(ch)) { + this.state.pos += ch <= 0xffff ? 1 : 2; + } else if (this.state.isIterator && ch === 64) { + ++this.state.pos; + } else if (ch === 92) { + this.state.containsEsc = true; + word += this.input.slice(chunkStart, this.state.pos); + const escStart = this.state.pos; + const identifierCheck = this.state.pos === start ? isIdentifierStart$1 : isIdentifierChar$1; + + if (this.input.charCodeAt(++this.state.pos) !== 117) { + this.raise(this.state.pos, ErrorMessages$1.MissingUnicodeEscape); + continue; + } + + ++this.state.pos; + const esc = this.readCodePoint(true); + + if (esc !== null) { + if (!identifierCheck(esc)) { + this.raise(escStart, ErrorMessages$1.EscapedCharNotAnIdentifier); + } + + word += String.fromCodePoint(esc); + } + + chunkStart = this.state.pos; + } else { + break; + } + } + + return word + this.input.slice(chunkStart, this.state.pos); + } + + isIterator(word) { + return word === "@@iterator" || word === "@@asyncIterator"; + } + + readWord() { + const word = this.readWord1(); + const type = keywords$2.get(word) || types$4.name; + + if (this.state.isIterator && (!this.isIterator(word) || !this.state.inType)) { + this.raise(this.state.pos, ErrorMessages$1.InvalidIdentifier, word); + } + + this.finishToken(type, word); + } + + checkKeywordEscapes() { + const kw = this.state.type.keyword; + + if (kw && this.state.containsEsc) { + this.raise(this.state.start, ErrorMessages$1.InvalidEscapedReservedWord, kw); + } + } + + braceIsBlock(prevType) { + const parent = this.curContext(); + + if (parent === types$1$1.functionExpression || parent === types$1$1.functionStatement) { + return true; + } + + if (prevType === types$4.colon && (parent === types$1$1.braceStatement || parent === types$1$1.braceExpression)) { + return !parent.isExpr; + } + + if (prevType === types$4._return || prevType === types$4.name && this.state.exprAllowed) { + return lineBreak$1.test(this.input.slice(this.state.lastTokEnd, this.state.start)); + } + + if (prevType === types$4._else || prevType === types$4.semi || prevType === types$4.eof || prevType === types$4.parenR || prevType === types$4.arrow) { + return true; + } + + if (prevType === types$4.braceL) { + return parent === types$1$1.braceStatement; + } + + if (prevType === types$4._var || prevType === types$4._const || prevType === types$4.name) { + return false; + } + + if (prevType === types$4.relational) { + return true; + } + + return !this.state.exprAllowed; + } + + updateContext(prevType) { + const type = this.state.type; + let update; + + if (type.keyword && (prevType === types$4.dot || prevType === types$4.questionDot)) { + this.state.exprAllowed = false; + } else if (update = type.updateContext) { + update.call(this, prevType); + } else { + this.state.exprAllowed = type.beforeExpr; + } + } + + }; + + let UtilParser$1 = class UtilParser extends Tokenizer$1 { + addExtra(node, key, val) { + if (!node) return; + const extra = node.extra = node.extra || {}; + extra[key] = val; + } + + isRelational(op) { + return this.match(types$4.relational) && this.state.value === op; + } + + isLookaheadRelational(op) { + const next = this.nextTokenStart(); + + if (this.input.charAt(next) === op) { + if (next + 1 === this.input.length) { + return true; + } + + const afterNext = this.input.charCodeAt(next + 1); + return afterNext !== op.charCodeAt(0) && afterNext !== 61; + } + + return false; + } + + expectRelational(op) { + if (this.isRelational(op)) { + this.next(); + } else { + this.unexpected(null, types$4.relational); + } + } + + isContextual(name) { + return this.match(types$4.name) && this.state.value === name && !this.state.containsEsc; + } + + isUnparsedContextual(nameStart, name) { + const nameEnd = nameStart + name.length; + return this.input.slice(nameStart, nameEnd) === name && (nameEnd === this.input.length || !isIdentifierChar$1(this.input.charCodeAt(nameEnd))); + } + + isLookaheadContextual(name) { + const next = this.nextTokenStart(); + return this.isUnparsedContextual(next, name); + } + + eatContextual(name) { + return this.isContextual(name) && this.eat(types$4.name); + } + + expectContextual(name, message) { + if (!this.eatContextual(name)) this.unexpected(null, message); + } + + canInsertSemicolon() { + return this.match(types$4.eof) || this.match(types$4.braceR) || this.hasPrecedingLineBreak(); + } + + hasPrecedingLineBreak() { + return lineBreak$1.test(this.input.slice(this.state.lastTokEnd, this.state.start)); + } + + isLineTerminator() { + return this.eat(types$4.semi) || this.canInsertSemicolon(); + } + + semicolon() { + if (!this.isLineTerminator()) this.unexpected(null, types$4.semi); + } + + expect(type, pos) { + this.eat(type) || this.unexpected(pos, type); + } + + assertNoSpace(message = "Unexpected space.") { + if (this.state.start > this.state.lastTokEnd) { + this.raise(this.state.lastTokEnd, message); + } + } + + unexpected(pos, messageOrType = "Unexpected token") { + if (typeof messageOrType !== "string") { + messageOrType = `Unexpected token, expected "${messageOrType.label}"`; + } + + throw this.raise(pos != null ? pos : this.state.start, messageOrType); + } + + expectPlugin(name, pos) { + if (!this.hasPlugin(name)) { + throw this.raiseWithData(pos != null ? pos : this.state.start, { + missingPlugin: [name] + }, `This experimental syntax requires enabling the parser plugin: '${name}'`); + } + + return true; + } + + expectOnePlugin(names, pos) { + if (!names.some(n => this.hasPlugin(n))) { + throw this.raiseWithData(pos != null ? pos : this.state.start, { + missingPlugin: names + }, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`); + } + } + + checkYieldAwaitInDefaultParams() { + if (this.state.yieldPos !== -1 && (this.state.awaitPos === -1 || this.state.yieldPos < this.state.awaitPos)) { + this.raise(this.state.yieldPos, ErrorMessages$1.YieldBindingIdentifier); + } + + if (this.state.awaitPos !== -1) { + this.raise(this.state.awaitPos, ErrorMessages$1.AwaitBindingIdentifier); + } + } + + tryParse(fn, oldState = this.state.clone()) { + const abortSignal = { + node: null + }; + + try { + const node = fn((node = null) => { + abortSignal.node = node; + throw abortSignal; + }); + + if (this.state.errors.length > oldState.errors.length) { + const failState = this.state; + this.state = oldState; + return { + node, + error: failState.errors[oldState.errors.length], + thrown: false, + aborted: false, + failState + }; + } + + return { + node, + error: null, + thrown: false, + aborted: false, + failState: null + }; + } catch (error) { + const failState = this.state; + this.state = oldState; + + if (error instanceof SyntaxError) { + return { + node: null, + error, + thrown: true, + aborted: false, + failState + }; + } + + if (error === abortSignal) { + return { + node: abortSignal.node, + error: null, + thrown: false, + aborted: true, + failState + }; + } + + throw error; + } + } + + checkExpressionErrors(refExpressionErrors, andThrow) { + if (!refExpressionErrors) return false; + const { + shorthandAssign, + doubleProto + } = refExpressionErrors; + if (!andThrow) return shorthandAssign >= 0 || doubleProto >= 0; + + if (shorthandAssign >= 0) { + this.unexpected(shorthandAssign); + } + + if (doubleProto >= 0) { + this.raise(doubleProto, ErrorMessages$1.DuplicateProto); + } + } + + isLiteralPropertyName() { + return this.match(types$4.name) || !!this.state.type.keyword || this.match(types$4.string) || this.match(types$4.num) || this.match(types$4.bigint); + } + + }; + let ExpressionErrors$1 = class ExpressionErrors { + constructor() { + this.shorthandAssign = -1; + this.doubleProto = -1; + } + + }; + + let Node$1 = class Node { + constructor(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + this.loc = new SourceLocation$1(loc); + if (parser == null ? void 0 : parser.options.ranges) this.range = [pos, 0]; + if (parser == null ? void 0 : parser.filename) this.loc.filename = parser.filename; + } + + __clone() { + const newNode = new Node(); + const keys = Object.keys(this); + + for (let i = 0, length = keys.length; i < length; i++) { + const key = keys[i]; + + if (key !== "leadingComments" && key !== "trailingComments" && key !== "innerComments") { + newNode[key] = this[key]; + } + } + + return newNode; + } + + }; + + let NodeUtils$1 = class NodeUtils extends UtilParser$1 { + startNode() { + return new Node$1(this, this.state.start, this.state.startLoc); + } + + startNodeAt(pos, loc) { + return new Node$1(this, pos, loc); + } + + startNodeAtNode(type) { + return this.startNodeAt(type.start, type.loc.start); + } + + finishNode(node, type) { + return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); + } + + finishNodeAt(node, type, pos, loc) { + + node.type = type; + node.end = pos; + node.loc.end = loc; + if (this.options.ranges) node.range[1] = pos; + this.processComment(node); + return node; + } + + resetStartLocation(node, start, startLoc) { + node.start = start; + node.loc.start = startLoc; + if (this.options.ranges) node.range[0] = start; + } + + resetEndLocation(node, end = this.state.lastTokEnd, endLoc = this.state.lastTokEndLoc) { + node.end = end; + node.loc.end = endLoc; + if (this.options.ranges) node.range[1] = end; + } + + resetStartLocationFromNode(node, locationNode) { + this.resetStartLocation(node, locationNode.start, locationNode.loc.start); + } + + }; + + const unwrapParenthesizedExpression$1 = node => { + return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression$1(node.expression) : node; + }; + + let LValParser$1 = class LValParser extends NodeUtils$1 { + toAssignable(node) { + var _node$extra, _node$extra3; + + let parenthesized = undefined; + + if (node.type === "ParenthesizedExpression" || ((_node$extra = node.extra) == null ? void 0 : _node$extra.parenthesized)) { + parenthesized = unwrapParenthesizedExpression$1(node); + + if (parenthesized.type !== "Identifier" && parenthesized.type !== "MemberExpression") { + this.raise(node.start, ErrorMessages$1.InvalidParenthesizedAssignment); + } + } + + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + break; + + case "ObjectExpression": + node.type = "ObjectPattern"; + + for (let i = 0, length = node.properties.length, last = length - 1; i < length; i++) { + var _node$extra2; + + const prop = node.properties[i]; + const isLast = i === last; + this.toAssignableObjectExpressionProp(prop, isLast); + + if (isLast && prop.type === "RestElement" && ((_node$extra2 = node.extra) == null ? void 0 : _node$extra2.trailingComma)) { + this.raiseRestNotLast(node.extra.trailingComma); + } + } + + break; + + case "ObjectProperty": + this.toAssignable(node.value); + break; + + case "SpreadElement": + { + this.checkToRestConversion(node); + node.type = "RestElement"; + const arg = node.argument; + this.toAssignable(arg); + break; + } + + case "ArrayExpression": + node.type = "ArrayPattern"; + this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingComma); + break; + + case "AssignmentExpression": + if (node.operator !== "=") { + this.raise(node.left.end, ErrorMessages$1.MissingEqInAssignment); + } + + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left); + break; + + case "ParenthesizedExpression": + this.toAssignable(parenthesized); + break; + } + + return node; + } + + toAssignableObjectExpressionProp(prop, isLast) { + if (prop.type === "ObjectMethod") { + const error = prop.kind === "get" || prop.kind === "set" ? ErrorMessages$1.PatternHasAccessor : ErrorMessages$1.PatternHasMethod; + this.raise(prop.key.start, error); + } else if (prop.type === "SpreadElement" && !isLast) { + this.raiseRestNotLast(prop.start); + } else { + this.toAssignable(prop); + } + } + + toAssignableList(exprList, trailingCommaPos) { + let end = exprList.length; + + if (end) { + const last = exprList[end - 1]; + + if ((last == null ? void 0 : last.type) === "RestElement") { + --end; + } else if ((last == null ? void 0 : last.type) === "SpreadElement") { + last.type = "RestElement"; + const arg = last.argument; + this.toAssignable(arg); + + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern" && arg.type !== "ObjectPattern") { + this.unexpected(arg.start); + } + + if (trailingCommaPos) { + this.raiseTrailingCommaAfterRest(trailingCommaPos); + } + + --end; + } + } + + for (let i = 0; i < end; i++) { + const elt = exprList[i]; + + if (elt) { + this.toAssignable(elt); + + if (elt.type === "RestElement") { + this.raiseRestNotLast(elt.start); + } + } + } + + return exprList; + } + + toReferencedList(exprList, isParenthesizedExpr) { + return exprList; + } + + toReferencedListDeep(exprList, isParenthesizedExpr) { + this.toReferencedList(exprList, isParenthesizedExpr); + + for (let _i = 0; _i < exprList.length; _i++) { + const expr = exprList[_i]; + + if ((expr == null ? void 0 : expr.type) === "ArrayExpression") { + this.toReferencedListDeep(expr.elements); + } + } + } + + parseSpread(refExpressionErrors, refNeedsArrowPos) { + const node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refExpressionErrors, undefined, refNeedsArrowPos); + return this.finishNode(node, "SpreadElement"); + } + + parseRestBinding() { + const node = this.startNode(); + this.next(); + node.argument = this.parseBindingAtom(); + return this.finishNode(node, "RestElement"); + } + + parseBindingAtom() { + switch (this.state.type) { + case types$4.bracketL: + { + const node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types$4.bracketR, 93, true); + return this.finishNode(node, "ArrayPattern"); + } + + case types$4.braceL: + return this.parseObj(types$4.braceR, true); + } + + return this.parseIdentifier(); + } + + parseBindingList(close, closeCharCode, allowEmpty, allowModifiers) { + const elts = []; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma); + } + + if (allowEmpty && this.match(types$4.comma)) { + elts.push(null); + } else if (this.eat(close)) { + break; + } else if (this.match(types$4.ellipsis)) { + elts.push(this.parseAssignableListItemTypes(this.parseRestBinding())); + this.checkCommaAfterRest(closeCharCode); + this.expect(close); + break; + } else { + const decorators = []; + + if (this.match(types$4.at) && this.hasPlugin("decorators")) { + this.raise(this.state.start, ErrorMessages$1.UnsupportedParameterDecorator); + } + + while (this.match(types$4.at)) { + decorators.push(this.parseDecorator()); + } + + elts.push(this.parseAssignableListItem(allowModifiers, decorators)); + } + } + + return elts; + } + + parseAssignableListItem(allowModifiers, decorators) { + const left = this.parseMaybeDefault(); + this.parseAssignableListItemTypes(left); + const elt = this.parseMaybeDefault(left.start, left.loc.start, left); + + if (decorators.length) { + left.decorators = decorators; + } + + return elt; + } + + parseAssignableListItemTypes(param) { + return param; + } + + parseMaybeDefault(startPos, startLoc, left) { + startLoc = startLoc || this.state.startLoc; + startPos = startPos || this.state.start; + left = left || this.parseBindingAtom(); + if (!this.eat(types$4.eq)) return left; + const node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern"); + } + + checkLVal(expr, bindingType = BIND_NONE$1, checkClashes, contextDescription, disallowLetBinding, strictModeChanged = false) { + switch (expr.type) { + case "Identifier": + if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord$1(expr.name, this.inModule) : isStrictBindOnlyReservedWord$1(expr.name))) { + this.raise(expr.start, bindingType === BIND_NONE$1 ? ErrorMessages$1.StrictEvalArguments : ErrorMessages$1.StrictEvalArgumentsBinding, expr.name); + } + + if (checkClashes) { + const key = `_${expr.name}`; + + if (checkClashes[key]) { + this.raise(expr.start, ErrorMessages$1.ParamDupe); + } else { + checkClashes[key] = true; + } + } + + if (disallowLetBinding && expr.name === "let") { + this.raise(expr.start, ErrorMessages$1.LetInLexicalBinding); + } + + if (!(bindingType & BIND_NONE$1)) { + this.scope.declareName(expr.name, bindingType, expr.start); + } + + break; + + case "MemberExpression": + if (bindingType !== BIND_NONE$1) { + this.raise(expr.start, ErrorMessages$1.InvalidPropertyBindingPattern); + } + + break; + + case "ObjectPattern": + for (let _i2 = 0, _expr$properties = expr.properties; _i2 < _expr$properties.length; _i2++) { + let prop = _expr$properties[_i2]; + if (prop.type === "ObjectProperty") prop = prop.value;else if (prop.type === "ObjectMethod") continue; + this.checkLVal(prop, bindingType, checkClashes, "object destructuring pattern", disallowLetBinding); + } + + break; + + case "ArrayPattern": + for (let _i3 = 0, _expr$elements = expr.elements; _i3 < _expr$elements.length; _i3++) { + const elem = _expr$elements[_i3]; + + if (elem) { + this.checkLVal(elem, bindingType, checkClashes, "array destructuring pattern", disallowLetBinding); + } + } + + break; + + case "AssignmentPattern": + this.checkLVal(expr.left, bindingType, checkClashes, "assignment pattern"); + break; + + case "RestElement": + this.checkLVal(expr.argument, bindingType, checkClashes, "rest element"); + break; + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, bindingType, checkClashes, "parenthesized expression"); + break; + + default: + { + this.raise(expr.start, bindingType === BIND_NONE$1 ? ErrorMessages$1.InvalidLhs : ErrorMessages$1.InvalidLhsBinding, contextDescription); + } + } + } + + checkToRestConversion(node) { + if (node.argument.type !== "Identifier" && node.argument.type !== "MemberExpression") { + this.raise(node.argument.start, ErrorMessages$1.InvalidRestAssignmentPattern); + } + } + + checkCommaAfterRest(close) { + if (this.match(types$4.comma)) { + if (this.lookaheadCharCode() === close) { + this.raiseTrailingCommaAfterRest(this.state.start); + } else { + this.raiseRestNotLast(this.state.start); + } + } + } + + raiseRestNotLast(pos) { + throw this.raise(pos, ErrorMessages$1.ElementAfterRest); + } + + raiseTrailingCommaAfterRest(pos) { + this.raise(pos, ErrorMessages$1.RestTrailingComma); + } + + }; + + let ExpressionParser$1 = class ExpressionParser extends LValParser$1 { + checkProto(prop, isRecord, protoRef, refExpressionErrors) { + if (prop.type === "SpreadElement" || prop.type === "ObjectMethod" || prop.computed || prop.shorthand) { + return; + } + + const key = prop.key; + const name = key.type === "Identifier" ? key.name : key.value; + + if (name === "__proto__") { + if (isRecord) { + this.raise(key.start, ErrorMessages$1.RecordNoProto); + return; + } + + if (protoRef.used) { + if (refExpressionErrors) { + if (refExpressionErrors.doubleProto === -1) { + refExpressionErrors.doubleProto = key.start; + } + } else { + this.raise(key.start, ErrorMessages$1.DuplicateProto); + } + } + + protoRef.used = true; + } + } + + getExpression() { + let paramFlags = PARAM$1; + + if (this.hasPlugin("topLevelAwait") && this.inModule) { + paramFlags |= PARAM_AWAIT$1; + } + + this.scope.enter(SCOPE_PROGRAM$1); + this.prodParam.enter(paramFlags); + this.nextToken(); + const expr = this.parseExpression(); + + if (!this.match(types$4.eof)) { + this.unexpected(); + } + + expr.comments = this.state.comments; + expr.errors = this.state.errors; + return expr; + } + + parseExpression(noIn, refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const expr = this.parseMaybeAssign(noIn, refExpressionErrors); + + if (this.match(types$4.comma)) { + const node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + + while (this.eat(types$4.comma)) { + node.expressions.push(this.parseMaybeAssign(noIn, refExpressionErrors)); + } + + this.toReferencedList(node.expressions); + return this.finishNode(node, "SequenceExpression"); + } + + return expr; + } + + parseMaybeAssign(noIn, refExpressionErrors, afterLeftParse, refNeedsArrowPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + + if (this.isContextual("yield")) { + if (this.prodParam.hasYield) { + let left = this.parseYield(noIn); + + if (afterLeftParse) { + left = afterLeftParse.call(this, left, startPos, startLoc); + } + + return left; + } else { + this.state.exprAllowed = false; + } + } + + let ownExpressionErrors; + + if (refExpressionErrors) { + ownExpressionErrors = false; + } else { + refExpressionErrors = new ExpressionErrors$1(); + ownExpressionErrors = true; + } + + if (this.match(types$4.parenL) || this.match(types$4.name)) { + this.state.potentialArrowAt = this.state.start; + } + + let left = this.parseMaybeConditional(noIn, refExpressionErrors, refNeedsArrowPos); + + if (afterLeftParse) { + left = afterLeftParse.call(this, left, startPos, startLoc); + } + + if (this.state.type.isAssign) { + const node = this.startNodeAt(startPos, startLoc); + const operator = this.state.value; + node.operator = operator; + + if (operator === "??=") { + this.expectPlugin("logicalAssignment"); + } + + if (operator === "||=" || operator === "&&=") { + this.expectPlugin("logicalAssignment"); + } + + if (this.match(types$4.eq)) { + node.left = this.toAssignable(left); + refExpressionErrors.doubleProto = -1; + } else { + node.left = left; + } + + if (refExpressionErrors.shorthandAssign >= node.left.start) { + refExpressionErrors.shorthandAssign = -1; + } + + this.checkLVal(left, undefined, undefined, "assignment expression"); + this.next(); + node.right = this.parseMaybeAssign(noIn); + return this.finishNode(node, "AssignmentExpression"); + } else if (ownExpressionErrors) { + this.checkExpressionErrors(refExpressionErrors, true); + } + + return left; + } + + parseMaybeConditional(noIn, refExpressionErrors, refNeedsArrowPos) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseExprOps(noIn, refExpressionErrors); + + if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { + return expr; + } + + if (this.checkExpressionErrors(refExpressionErrors, false)) return expr; + return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos); + } + + parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos) { + if (this.eat(types$4.question)) { + const node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types$4.colon); + node.alternate = this.parseMaybeAssign(noIn); + return this.finishNode(node, "ConditionalExpression"); + } + + return expr; + } + + parseExprOps(noIn, refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseMaybeUnary(refExpressionErrors); + + if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { + return expr; + } + + if (this.checkExpressionErrors(refExpressionErrors, false)) { + return expr; + } + + return this.parseExprOp(expr, startPos, startLoc, -1, noIn); + } + + parseExprOp(left, leftStartPos, leftStartLoc, minPrec, noIn) { + let prec = this.state.type.binop; + + if (prec != null && (!noIn || !this.match(types$4._in))) { + if (prec > minPrec) { + const operator = this.state.value; + + if (operator === "|>" && this.state.inFSharpPipelineDirectBody) { + return left; + } + + const node = this.startNodeAt(leftStartPos, leftStartLoc); + node.left = left; + node.operator = operator; + + if (operator === "**" && left.type === "UnaryExpression" && (this.options.createParenthesizedExpressions || !(left.extra && left.extra.parenthesized))) { + this.raise(left.argument.start, ErrorMessages$1.UnexpectedTokenUnaryExponentiation); + } + + const op = this.state.type; + const logical = op === types$4.logicalOR || op === types$4.logicalAND; + const coalesce = op === types$4.nullishCoalescing; + + if (op === types$4.pipeline) { + this.expectPlugin("pipelineOperator"); + this.state.inPipeline = true; + this.checkPipelineAtInfixOperator(left, leftStartPos); + } else if (coalesce) { + prec = types$4.logicalAND.binop; + } + + this.next(); + + if (op === types$4.pipeline && this.getPluginOption("pipelineOperator", "proposal") === "minimal") { + if (this.match(types$4.name) && this.state.value === "await" && this.prodParam.hasAwait) { + throw this.raise(this.state.start, ErrorMessages$1.UnexpectedAwaitAfterPipelineBody); + } + } + + node.right = this.parseExprOpRightExpr(op, prec, noIn); + this.finishNode(node, logical || coalesce ? "LogicalExpression" : "BinaryExpression"); + const nextOp = this.state.type; + + if (coalesce && (nextOp === types$4.logicalOR || nextOp === types$4.logicalAND) || logical && nextOp === types$4.nullishCoalescing) { + throw this.raise(this.state.start, ErrorMessages$1.MixingCoalesceWithLogical); + } + + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn); + } + } + + return left; + } + + parseExprOpRightExpr(op, prec, noIn) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + + switch (op) { + case types$4.pipeline: + switch (this.getPluginOption("pipelineOperator", "proposal")) { + case "smart": + return this.withTopicPermittingContext(() => { + return this.parseSmartPipelineBody(this.parseExprOpBaseRightExpr(op, prec, noIn), startPos, startLoc); + }); + + case "fsharp": + return this.withSoloAwaitPermittingContext(() => { + return this.parseFSharpPipelineBody(prec, noIn); + }); + } + + default: + return this.parseExprOpBaseRightExpr(op, prec, noIn); + } + } + + parseExprOpBaseRightExpr(op, prec, noIn) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + return this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, op.rightAssociative ? prec - 1 : prec, noIn); + } + + parseMaybeUnary(refExpressionErrors) { + if (this.isContextual("await") && this.isAwaitAllowed()) { + return this.parseAwait(); + } else if (this.state.type.prefix) { + const node = this.startNode(); + const update = this.match(types$4.incDec); + node.operator = this.state.value; + node.prefix = true; + + if (node.operator === "throw") { + this.expectPlugin("throwExpressions"); + } + + this.next(); + node.argument = this.parseMaybeUnary(); + this.checkExpressionErrors(refExpressionErrors, true); + + if (update) { + this.checkLVal(node.argument, undefined, undefined, "prefix operation"); + } else if (this.state.strict && node.operator === "delete") { + const arg = node.argument; + + if (arg.type === "Identifier") { + this.raise(node.start, ErrorMessages$1.StrictDelete); + } else if ((arg.type === "MemberExpression" || arg.type === "OptionalMemberExpression") && arg.property.type === "PrivateName") { + this.raise(node.start, ErrorMessages$1.DeletePrivateField); + } + } + + return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); + } + + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let expr = this.parseExprSubscripts(refExpressionErrors); + if (this.checkExpressionErrors(refExpressionErrors, false)) return expr; + + while (this.state.type.postfix && !this.canInsertSemicolon()) { + const node = this.startNodeAt(startPos, startLoc); + node.operator = this.state.value; + node.prefix = false; + node.argument = expr; + this.checkLVal(expr, undefined, undefined, "postfix operation"); + this.next(); + expr = this.finishNode(node, "UpdateExpression"); + } + + return expr; + } + + parseExprSubscripts(refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseExprAtom(refExpressionErrors); + + if (expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt) { + return expr; + } + + return this.parseSubscripts(expr, startPos, startLoc); + } + + parseSubscripts(base, startPos, startLoc, noCalls) { + const state = { + optionalChainMember: false, + maybeAsyncArrow: this.atPossibleAsyncArrow(base), + stop: false + }; + + do { + const oldMaybeInAsyncArrowHead = this.state.maybeInAsyncArrowHead; + + if (state.maybeAsyncArrow) { + this.state.maybeInAsyncArrowHead = true; + } + + base = this.parseSubscript(base, startPos, startLoc, noCalls, state); + state.maybeAsyncArrow = false; + this.state.maybeInAsyncArrowHead = oldMaybeInAsyncArrowHead; + } while (!state.stop); + + return base; + } + + parseSubscript(base, startPos, startLoc, noCalls, state) { + if (!noCalls && this.eat(types$4.doubleColon)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.callee = this.parseNoCallExpr(); + state.stop = true; + return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); + } + + let optional = false; + + if (this.match(types$4.questionDot)) { + state.optionalChainMember = optional = true; + + if (noCalls && this.lookaheadCharCode() === 40) { + state.stop = true; + return base; + } + + this.next(); + } + + const computed = this.eat(types$4.bracketL); + + if (optional && !this.match(types$4.parenL) && !this.match(types$4.backQuote) || computed || this.eat(types$4.dot)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this.parseExpression() : this.parseMaybePrivateName(true); + node.computed = computed; + + if (node.property.type === "PrivateName") { + if (node.object.type === "Super") { + this.raise(startPos, ErrorMessages$1.SuperPrivateField); + } + + this.classScope.usePrivateName(node.property.id.name, node.property.start); + } + + if (computed) { + this.expect(types$4.bracketR); + } + + if (state.optionalChainMember) { + node.optional = optional; + return this.finishNode(node, "OptionalMemberExpression"); + } else { + return this.finishNode(node, "MemberExpression"); + } + } else if (!noCalls && this.match(types$4.parenL)) { + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + this.state.maybeInArrowParameters = true; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + this.next(); + let node = this.startNodeAt(startPos, startLoc); + node.callee = base; + + if (optional) { + node.optional = true; + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + } else { + node.arguments = this.parseCallExpressionArguments(types$4.parenR, state.maybeAsyncArrow, base.type === "Import", base.type !== "Super", node); + } + + this.finishCallExpression(node, state.optionalChainMember); + + if (state.maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) { + state.stop = true; + node = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); + this.checkYieldAwaitInDefaultParams(); + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + } else { + this.toReferencedListDeep(node.arguments); + if (oldYieldPos !== -1) this.state.yieldPos = oldYieldPos; + + if (!this.isAwaitAllowed() && !oldMaybeInArrowParameters || oldAwaitPos !== -1) { + this.state.awaitPos = oldAwaitPos; + } + } + + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + return node; + } else if (this.match(types$4.backQuote)) { + return this.parseTaggedTemplateExpression(startPos, startLoc, base, state); + } else { + state.stop = true; + return base; + } + } + + parseTaggedTemplateExpression(startPos, startLoc, base, state, typeArguments) { + const node = this.startNodeAt(startPos, startLoc); + node.tag = base; + node.quasi = this.parseTemplate(true); + if (typeArguments) node.typeParameters = typeArguments; + + if (state.optionalChainMember) { + this.raise(startPos, ErrorMessages$1.OptionalChainingNoTemplate); + } + + return this.finishNode(node, "TaggedTemplateExpression"); + } + + atPossibleAsyncArrow(base) { + return base.type === "Identifier" && base.name === "async" && this.state.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && base.start === this.state.potentialArrowAt; + } + + finishCallExpression(node, optional) { + if (node.callee.type === "Import") { + if (node.arguments.length === 2) { + this.expectPlugin("moduleAttributes"); + } + + if (node.arguments.length === 0 || node.arguments.length > 2) { + this.raise(node.start, ErrorMessages$1.ImportCallArity, this.hasPlugin("moduleAttributes") ? "one or two arguments" : "one argument"); + } else { + for (let _i = 0, _node$arguments = node.arguments; _i < _node$arguments.length; _i++) { + const arg = _node$arguments[_i]; + + if (arg.type === "SpreadElement") { + this.raise(arg.start, ErrorMessages$1.ImportCallSpreadArgument); + } + } + } + } + + return this.finishNode(node, optional ? "OptionalCallExpression" : "CallExpression"); + } + + parseCallExpressionArguments(close, possibleAsyncArrow, dynamicImport, allowPlaceholder, nodeForExtra) { + const elts = []; + let innerParenStart; + let first = true; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma); + + if (this.match(close)) { + if (dynamicImport && !this.hasPlugin("moduleAttributes")) { + this.raise(this.state.lastTokStart, ErrorMessages$1.ImportCallArgumentTrailingComma); + } + + if (nodeForExtra) { + this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + } + + this.next(); + break; + } + } + + if (this.match(types$4.parenL) && !innerParenStart) { + innerParenStart = this.state.start; + } + + elts.push(this.parseExprListItem(false, possibleAsyncArrow ? new ExpressionErrors$1() : undefined, possibleAsyncArrow ? { + start: 0 + } : undefined, allowPlaceholder)); + } + + if (possibleAsyncArrow && innerParenStart && this.shouldParseAsyncArrow()) { + this.unexpected(); + } + + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return elts; + } + + shouldParseAsyncArrow() { + return this.match(types$4.arrow) && !this.canInsertSemicolon(); + } + + parseAsyncArrowFromCallExpression(node, call) { + var _call$extra; + + this.expect(types$4.arrow); + this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingComma); + return node; + } + + parseNoCallExpr() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + } + + parseExprAtom(refExpressionErrors) { + if (this.state.type === types$4.slash) this.readRegexp(); + const canBeArrow = this.state.potentialArrowAt === this.state.start; + let node; + + switch (this.state.type) { + case types$4._super: + node = this.startNode(); + this.next(); + + if (this.match(types$4.parenL) && !this.scope.allowDirectSuper && !this.options.allowSuperOutsideMethod) { + this.raise(node.start, ErrorMessages$1.SuperNotAllowed); + } else if (!this.scope.allowSuper && !this.options.allowSuperOutsideMethod) { + this.raise(node.start, ErrorMessages$1.UnexpectedSuper); + } + + if (!this.match(types$4.parenL) && !this.match(types$4.bracketL) && !this.match(types$4.dot)) { + this.raise(node.start, ErrorMessages$1.UnsupportedSuper); + } + + return this.finishNode(node, "Super"); + + case types$4._import: + node = this.startNode(); + this.next(); + + if (this.match(types$4.dot)) { + return this.parseImportMetaProperty(node); + } + + if (!this.match(types$4.parenL)) { + this.raise(this.state.lastTokStart, ErrorMessages$1.UnsupportedImport); + } + + return this.finishNode(node, "Import"); + + case types$4._this: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression"); + + case types$4.name: + { + node = this.startNode(); + const containsEsc = this.state.containsEsc; + const id = this.parseIdentifier(); + + if (!containsEsc && id.name === "async" && this.match(types$4._function) && !this.canInsertSemicolon()) { + const last = this.state.context.length - 1; + + if (this.state.context[last] !== types$1$1.functionStatement) { + throw new Error("Internal error"); + } + + this.state.context[last] = types$1$1.functionExpression; + this.next(); + return this.parseFunction(node, undefined, true); + } else if (canBeArrow && !containsEsc && id.name === "async" && this.match(types$4.name) && !this.canInsertSemicolon()) { + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldMaybeInAsyncArrowHead = this.state.maybeInAsyncArrowHead; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + this.state.maybeInArrowParameters = true; + this.state.maybeInAsyncArrowHead = true; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + const params = [this.parseIdentifier()]; + this.expect(types$4.arrow); + this.checkYieldAwaitInDefaultParams(); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.maybeInAsyncArrowHead = oldMaybeInAsyncArrowHead; + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + this.parseArrowExpression(node, params, true); + return node; + } + + if (canBeArrow && this.match(types$4.arrow) && !this.canInsertSemicolon()) { + this.next(); + this.parseArrowExpression(node, [id], false); + return node; + } + + return id; + } + + case types$4._do: + { + this.expectPlugin("doExpressions"); + const node = this.startNode(); + this.next(); + const oldLabels = this.state.labels; + this.state.labels = []; + node.body = this.parseBlock(); + this.state.labels = oldLabels; + return this.finishNode(node, "DoExpression"); + } + + case types$4.regexp: + { + const value = this.state.value; + node = this.parseLiteral(value.value, "RegExpLiteral"); + node.pattern = value.pattern; + node.flags = value.flags; + return node; + } + + case types$4.num: + return this.parseLiteral(this.state.value, "NumericLiteral"); + + case types$4.bigint: + return this.parseLiteral(this.state.value, "BigIntLiteral"); + + case types$4.string: + return this.parseLiteral(this.state.value, "StringLiteral"); + + case types$4._null: + node = this.startNode(); + this.next(); + return this.finishNode(node, "NullLiteral"); + + case types$4._true: + case types$4._false: + return this.parseBooleanLiteral(); + + case types$4.parenL: + return this.parseParenAndDistinguishExpression(canBeArrow); + + case types$4.bracketBarL: + case types$4.bracketHashL: + { + this.expectPlugin("recordAndTuple"); + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + const close = this.state.type === types$4.bracketBarL ? types$4.bracketBarR : types$4.bracketR; + this.state.inFSharpPipelineDirectBody = false; + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(close, false, refExpressionErrors, node); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return this.finishNode(node, "TupleExpression"); + } + + case types$4.bracketL: + { + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types$4.bracketR, true, refExpressionErrors, node); + + if (!this.state.maybeInArrowParameters) { + this.toReferencedList(node.elements); + } + + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return this.finishNode(node, "ArrayExpression"); + } + + case types$4.braceBarL: + case types$4.braceHashL: + { + this.expectPlugin("recordAndTuple"); + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + const close = this.state.type === types$4.braceBarL ? types$4.braceBarR : types$4.braceR; + this.state.inFSharpPipelineDirectBody = false; + const ret = this.parseObj(close, false, true, refExpressionErrors); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return ret; + } + + case types$4.braceL: + { + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + const ret = this.parseObj(types$4.braceR, false, false, refExpressionErrors); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return ret; + } + + case types$4._function: + return this.parseFunctionExpression(); + + case types$4.at: + this.parseDecorators(); + + case types$4._class: + node = this.startNode(); + this.takeDecorators(node); + return this.parseClass(node, false); + + case types$4._new: + return this.parseNew(); + + case types$4.backQuote: + return this.parseTemplate(false); + + case types$4.doubleColon: + { + node = this.startNode(); + this.next(); + node.object = null; + const callee = node.callee = this.parseNoCallExpr(); + + if (callee.type === "MemberExpression") { + return this.finishNode(node, "BindExpression"); + } else { + throw this.raise(callee.start, ErrorMessages$1.UnsupportedBind); + } + } + + case types$4.hash: + { + if (this.state.inPipeline) { + node = this.startNode(); + + if (this.getPluginOption("pipelineOperator", "proposal") !== "smart") { + this.raise(node.start, ErrorMessages$1.PrimaryTopicRequiresSmartPipeline); + } + + this.next(); + + if (!this.primaryTopicReferenceIsAllowedInCurrentTopicContext()) { + this.raise(node.start, ErrorMessages$1.PrimaryTopicNotAllowed); + } + + this.registerTopicReference(); + return this.finishNode(node, "PipelinePrimaryTopicReference"); + } + + const nextCh = this.input.codePointAt(this.state.end); + + if (isIdentifierStart$1(nextCh) || nextCh === 92) { + const start = this.state.start; + node = this.parseMaybePrivateName(true); + + if (this.match(types$4._in)) { + this.expectPlugin("privateIn"); + this.classScope.usePrivateName(node.id.name, node.start); + } else if (this.hasPlugin("privateIn")) { + this.raise(this.state.start, ErrorMessages$1.PrivateInExpectedIn, node.id.name); + } else { + throw this.unexpected(start); + } + + return node; + } + } + + case types$4.relational: + { + if (this.state.value === "<") { + throw this.expectOnePlugin(["jsx", "flow", "typescript"]); + } + } + + default: + throw this.unexpected(); + } + } + + parseBooleanLiteral() { + const node = this.startNode(); + node.value = this.match(types$4._true); + this.next(); + return this.finishNode(node, "BooleanLiteral"); + } + + parseMaybePrivateName(isPrivateNameAllowed) { + const isPrivate = this.match(types$4.hash); + + if (isPrivate) { + this.expectOnePlugin(["classPrivateProperties", "classPrivateMethods"]); + + if (!isPrivateNameAllowed) { + this.raise(this.state.pos, ErrorMessages$1.UnexpectedPrivateField); + } + + const node = this.startNode(); + this.next(); + this.assertNoSpace("Unexpected space between # and identifier"); + node.id = this.parseIdentifier(true); + return this.finishNode(node, "PrivateName"); + } else { + return this.parseIdentifier(true); + } + } + + parseFunctionExpression() { + const node = this.startNode(); + let meta = this.startNode(); + this.next(); + meta = this.createIdentifier(meta, "function"); + + if (this.prodParam.hasYield && this.eat(types$4.dot)) { + return this.parseMetaProperty(node, meta, "sent"); + } + + return this.parseFunction(node); + } + + parseMetaProperty(node, meta, propertyName) { + node.meta = meta; + + if (meta.name === "function" && propertyName === "sent") { + if (this.isContextual(propertyName)) { + this.expectPlugin("functionSent"); + } else if (!this.hasPlugin("functionSent")) { + this.unexpected(); + } + } + + const containsEsc = this.state.containsEsc; + node.property = this.parseIdentifier(true); + + if (node.property.name !== propertyName || containsEsc) { + this.raise(node.property.start, ErrorMessages$1.UnsupportedMetaProperty, meta.name, propertyName); + } + + return this.finishNode(node, "MetaProperty"); + } + + parseImportMetaProperty(node) { + const id = this.createIdentifier(this.startNodeAtNode(node), "import"); + this.expect(types$4.dot); + + if (this.isContextual("meta")) { + if (!this.inModule) { + this.raiseWithData(id.start, { + code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" + }, ErrorMessages$1.ImportMetaOutsideModule); + } + + this.sawUnambiguousESM = true; + } + + return this.parseMetaProperty(node, id, "meta"); + } + + parseLiteral(value, type, startPos, startLoc) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + const node = this.startNodeAt(startPos, startLoc); + this.addExtra(node, "rawValue", value); + this.addExtra(node, "raw", this.input.slice(startPos, this.state.end)); + node.value = value; + this.next(); + return this.finishNode(node, type); + } + + parseParenAndDistinguishExpression(canBeArrow) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let val; + this.expect(types$4.parenL); + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.maybeInArrowParameters = true; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + this.state.inFSharpPipelineDirectBody = false; + const innerStartPos = this.state.start; + const innerStartLoc = this.state.startLoc; + const exprList = []; + const refExpressionErrors = new ExpressionErrors$1(); + const refNeedsArrowPos = { + start: 0 + }; + let first = true; + let spreadStart; + let optionalCommaStart; + + while (!this.match(types$4.parenR)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma, refNeedsArrowPos.start || null); + + if (this.match(types$4.parenR)) { + optionalCommaStart = this.state.start; + break; + } + } + + if (this.match(types$4.ellipsis)) { + const spreadNodeStartPos = this.state.start; + const spreadNodeStartLoc = this.state.startLoc; + spreadStart = this.state.start; + exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartPos, spreadNodeStartLoc)); + this.checkCommaAfterRest(41); + break; + } else { + exprList.push(this.parseMaybeAssign(false, refExpressionErrors, this.parseParenItem, refNeedsArrowPos)); + } + } + + const innerEndPos = this.state.start; + const innerEndLoc = this.state.startLoc; + this.expect(types$4.parenR); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + let arrowNode = this.startNodeAt(startPos, startLoc); + + if (canBeArrow && this.shouldParseArrow() && (arrowNode = this.parseArrow(arrowNode))) { + if (!this.isAwaitAllowed() && !this.state.maybeInAsyncArrowHead) { + this.state.awaitPos = oldAwaitPos; + } + + this.checkYieldAwaitInDefaultParams(); + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + + for (let _i2 = 0; _i2 < exprList.length; _i2++) { + const param = exprList[_i2]; + + if (param.extra && param.extra.parenthesized) { + this.unexpected(param.extra.parenStart); + } + } + + this.parseArrowExpression(arrowNode, exprList, false); + return arrowNode; + } + + if (oldYieldPos !== -1) this.state.yieldPos = oldYieldPos; + if (oldAwaitPos !== -1) this.state.awaitPos = oldAwaitPos; + + if (!exprList.length) { + this.unexpected(this.state.lastTokStart); + } + + if (optionalCommaStart) this.unexpected(optionalCommaStart); + if (spreadStart) this.unexpected(spreadStart); + this.checkExpressionErrors(refExpressionErrors, true); + if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start); + this.toReferencedListDeep(exprList, true); + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + + if (!this.options.createParenthesizedExpressions) { + this.addExtra(val, "parenthesized", true); + this.addExtra(val, "parenStart", startPos); + return val; + } + + const parenExpression = this.startNodeAt(startPos, startLoc); + parenExpression.expression = val; + this.finishNode(parenExpression, "ParenthesizedExpression"); + return parenExpression; + } + + shouldParseArrow() { + return !this.canInsertSemicolon(); + } + + parseArrow(node) { + if (this.eat(types$4.arrow)) { + return node; + } + } + + parseParenItem(node, startPos, startLoc) { + return node; + } + + parseNew() { + const node = this.startNode(); + let meta = this.startNode(); + this.next(); + meta = this.createIdentifier(meta, "new"); + + if (this.eat(types$4.dot)) { + const metaProp = this.parseMetaProperty(node, meta, "target"); + + if (!this.scope.inNonArrowFunction && !this.scope.inClass) { + let error = ErrorMessages$1.UnexpectedNewTarget; + + if (this.hasPlugin("classProperties")) { + error += " or class properties"; + } + + this.raise(metaProp.start, error); + } + + return metaProp; + } + + node.callee = this.parseNoCallExpr(); + + if (node.callee.type === "Import") { + this.raise(node.callee.start, ErrorMessages$1.ImportCallNotNewExpression); + } else if (node.callee.type === "OptionalMemberExpression" || node.callee.type === "OptionalCallExpression") { + this.raise(this.state.lastTokEnd, ErrorMessages$1.OptionalChainingNoNew); + } else if (this.eat(types$4.questionDot)) { + this.raise(this.state.start, ErrorMessages$1.OptionalChainingNoNew); + } + + this.parseNewArguments(node); + return this.finishNode(node, "NewExpression"); + } + + parseNewArguments(node) { + if (this.eat(types$4.parenL)) { + const args = this.parseExprList(types$4.parenR); + this.toReferencedList(args); + node.arguments = args; + } else { + node.arguments = []; + } + } + + parseTemplateElement(isTagged) { + const elem = this.startNode(); + + if (this.state.value === null) { + if (!isTagged) { + this.raise(this.state.start + 1, ErrorMessages$1.InvalidEscapeSequenceTemplate); + } + } + + elem.value = { + raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), + cooked: this.state.value + }; + this.next(); + elem.tail = this.match(types$4.backQuote); + return this.finishNode(elem, "TemplateElement"); + } + + parseTemplate(isTagged) { + const node = this.startNode(); + this.next(); + node.expressions = []; + let curElt = this.parseTemplateElement(isTagged); + node.quasis = [curElt]; + + while (!curElt.tail) { + this.expect(types$4.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types$4.braceR); + node.quasis.push(curElt = this.parseTemplateElement(isTagged)); + } + + this.next(); + return this.finishNode(node, "TemplateLiteral"); + } + + parseObj(close, isPattern, isRecord, refExpressionErrors) { + const propHash = Object.create(null); + let first = true; + const node = this.startNode(); + node.properties = []; + this.next(); + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma); + + if (this.match(close)) { + this.addExtra(node, "trailingComma", this.state.lastTokStart); + this.next(); + break; + } + } + + const prop = this.parseObjectMember(isPattern, refExpressionErrors); + + if (!isPattern) { + this.checkProto(prop, isRecord, propHash, refExpressionErrors); + } + + if (isRecord && prop.type !== "ObjectProperty" && prop.type !== "SpreadElement") { + this.raise(prop.start, ErrorMessages$1.InvalidRecordProperty); + } + + if (prop.shorthand) { + this.addExtra(prop, "shorthand", true); + } + + node.properties.push(prop); + } + + let type = "ObjectExpression"; + + if (isPattern) { + type = "ObjectPattern"; + } else if (isRecord) { + type = "RecordExpression"; + } + + return this.finishNode(node, type); + } + + isAsyncProp(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && (this.isLiteralPropertyName() || this.match(types$4.bracketL) || this.match(types$4.star)) && !this.hasPrecedingLineBreak(); + } + + parseObjectMember(isPattern, refExpressionErrors) { + let decorators = []; + + if (this.match(types$4.at)) { + if (this.hasPlugin("decorators")) { + this.raise(this.state.start, ErrorMessages$1.UnsupportedPropertyDecorator); + } + + while (this.match(types$4.at)) { + decorators.push(this.parseDecorator()); + } + } + + const prop = this.startNode(); + let isGenerator = false; + let isAsync = false; + let startPos; + let startLoc; + + if (this.match(types$4.ellipsis)) { + if (decorators.length) this.unexpected(); + + if (isPattern) { + this.next(); + prop.argument = this.parseIdentifier(); + this.checkCommaAfterRest(125); + return this.finishNode(prop, "RestElement"); + } + + return this.parseSpread(); + } + + if (decorators.length) { + prop.decorators = decorators; + decorators = []; + } + + prop.method = false; + + if (isPattern || refExpressionErrors) { + startPos = this.state.start; + startLoc = this.state.startLoc; + } + + if (!isPattern) { + isGenerator = this.eat(types$4.star); + } + + const containsEsc = this.state.containsEsc; + this.parsePropertyName(prop, false); + + if (!isPattern && !containsEsc && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.eat(types$4.star); + this.parsePropertyName(prop, false); + } else { + isAsync = false; + } + + this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refExpressionErrors, containsEsc); + return prop; + } + + isGetterOrSetterMethod(prop, isPattern) { + return !isPattern && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.isLiteralPropertyName() || this.match(types$4.bracketL)); + } + + getGetterSetterExpectedParamCount(method) { + return method.kind === "get" ? 0 : 1; + } + + checkGetterSetterParams(method) { + const paramCount = this.getGetterSetterExpectedParamCount(method); + const start = method.start; + + if (method.params.length !== paramCount) { + if (method.kind === "get") { + this.raise(start, ErrorMessages$1.BadGetterArity); + } else { + this.raise(start, ErrorMessages$1.BadSetterArity); + } + } + + if (method.kind === "set" && method.params[method.params.length - 1].type === "RestElement") { + this.raise(start, ErrorMessages$1.BadSetterRestParameter); + } + } + + parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) { + if (isAsync || isGenerator || this.match(types$4.parenL)) { + if (isPattern) this.unexpected(); + prop.kind = "method"; + prop.method = true; + return this.parseMethod(prop, isGenerator, isAsync, false, false, "ObjectMethod"); + } + + if (!containsEsc && this.isGetterOrSetterMethod(prop, isPattern)) { + if (isGenerator || isAsync) this.unexpected(); + prop.kind = prop.key.name; + this.parsePropertyName(prop, false); + this.parseMethod(prop, false, false, false, false, "ObjectMethod"); + this.checkGetterSetterParams(prop); + return prop; + } + } + + parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) { + prop.shorthand = false; + + if (this.eat(types$4.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssign(false, refExpressionErrors); + return this.finishNode(prop, "ObjectProperty"); + } + + if (!prop.computed && prop.key.type === "Identifier") { + this.checkReservedWord(prop.key.name, prop.key.start, true, true); + + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); + } else if (this.match(types$4.eq) && refExpressionErrors) { + if (refExpressionErrors.shorthandAssign === -1) { + refExpressionErrors.shorthandAssign = this.state.start; + } + + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key.__clone()); + } else { + prop.value = prop.key.__clone(); + } + + prop.shorthand = true; + return this.finishNode(prop, "ObjectProperty"); + } + } + + parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, refExpressionErrors, containsEsc) { + const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern, containsEsc) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors); + if (!node) this.unexpected(); + return node; + } + + parsePropertyName(prop, isPrivateNameAllowed) { + if (this.eat(types$4.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types$4.bracketR); + } else { + const oldInPropertyName = this.state.inPropertyName; + this.state.inPropertyName = true; + prop.key = this.match(types$4.num) || this.match(types$4.string) || this.match(types$4.bigint) ? this.parseExprAtom() : this.parseMaybePrivateName(isPrivateNameAllowed); + + if (prop.key.type !== "PrivateName") { + prop.computed = false; + } + + this.state.inPropertyName = oldInPropertyName; + } + + return prop.key; + } + + initFunction(node, isAsync) { + node.id = null; + node.generator = false; + node.async = !!isAsync; + } + + parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + this.initFunction(node, isAsync); + node.generator = !!isGenerator; + const allowModifiers = isConstructor; + this.scope.enter(SCOPE_FUNCTION$1 | SCOPE_SUPER$1 | (inClassScope ? SCOPE_CLASS$1 : 0) | (allowDirectSuper ? SCOPE_DIRECT_SUPER$1 : 0)); + this.prodParam.enter(functionFlags$1(isAsync, node.generator)); + this.parseFunctionParams(node, allowModifiers); + this.parseFunctionBodyAndFinish(node, type, true); + this.prodParam.exit(); + this.scope.exit(); + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + return node; + } + + parseArrowExpression(node, params, isAsync, trailingCommaPos) { + this.scope.enter(SCOPE_FUNCTION$1 | SCOPE_ARROW$1); + this.prodParam.enter(functionFlags$1(isAsync, false)); + this.initFunction(node, isAsync); + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + + if (params) { + this.state.maybeInArrowParameters = true; + this.setArrowFunctionParameters(node, params, trailingCommaPos); + } + + this.state.maybeInArrowParameters = false; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + this.parseFunctionBody(node, true); + this.prodParam.exit(); + this.scope.exit(); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + return this.finishNode(node, "ArrowFunctionExpression"); + } + + setArrowFunctionParameters(node, params, trailingCommaPos) { + node.params = this.toAssignableList(params, trailingCommaPos); + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + this.parseFunctionBody(node, false, isMethod); + this.finishNode(node, type); + } + + parseFunctionBody(node, allowExpression, isMethod = false) { + const isExpression = allowExpression && !this.match(types$4.braceL); + const oldInParameters = this.state.inParameters; + this.state.inParameters = false; + + if (isExpression) { + node.body = this.parseMaybeAssign(); + this.checkParams(node, false, allowExpression, false); + } else { + const oldStrict = this.state.strict; + const oldLabels = this.state.labels; + this.state.labels = []; + this.prodParam.enter(this.prodParam.currentFlags() | PARAM_RETURN$1); + node.body = this.parseBlock(true, false, hasStrictModeDirective => { + const nonSimple = !this.isSimpleParamList(node.params); + + if (hasStrictModeDirective && nonSimple) { + const errorPos = (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.end : node.start; + this.raise(errorPos, ErrorMessages$1.IllegalLanguageModeDirective); + } + + const strictModeChanged = !oldStrict && this.state.strict; + this.checkParams(node, !this.state.strict && !allowExpression && !isMethod && !nonSimple, allowExpression, strictModeChanged); + + if (this.state.strict && node.id) { + this.checkLVal(node.id, BIND_OUTSIDE$1, undefined, "function name", undefined, strictModeChanged); + } + }); + this.prodParam.exit(); + this.state.labels = oldLabels; + } + + this.state.inParameters = oldInParameters; + } + + isSimpleParamList(params) { + for (let i = 0, len = params.length; i < len; i++) { + if (params[i].type !== "Identifier") return false; + } + + return true; + } + + checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) { + const nameHash = Object.create(null); + + for (let i = 0; i < node.params.length; i++) { + this.checkLVal(node.params[i], BIND_VAR$1, allowDuplicates ? null : nameHash, "function parameter list", undefined, strictModeChanged); + } + } + + parseExprList(close, allowEmpty, refExpressionErrors, nodeForExtra) { + const elts = []; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma); + + if (this.match(close)) { + if (nodeForExtra) { + this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + } + + this.next(); + break; + } + } + + elts.push(this.parseExprListItem(allowEmpty, refExpressionErrors)); + } + + return elts; + } + + parseExprListItem(allowEmpty, refExpressionErrors, refNeedsArrowPos, allowPlaceholder) { + let elt; + + if (this.match(types$4.comma)) { + if (!allowEmpty) { + this.raise(this.state.pos, ErrorMessages$1.UnexpectedToken, ","); + } + + elt = null; + } else if (this.match(types$4.ellipsis)) { + const spreadNodeStartPos = this.state.start; + const spreadNodeStartLoc = this.state.startLoc; + elt = this.parseParenItem(this.parseSpread(refExpressionErrors, refNeedsArrowPos), spreadNodeStartPos, spreadNodeStartLoc); + } else if (this.match(types$4.question)) { + this.expectPlugin("partialApplication"); + + if (!allowPlaceholder) { + this.raise(this.state.start, ErrorMessages$1.UnexpectedArgumentPlaceholder); + } + + const node = this.startNode(); + this.next(); + elt = this.finishNode(node, "ArgumentPlaceholder"); + } else { + elt = this.parseMaybeAssign(false, refExpressionErrors, this.parseParenItem, refNeedsArrowPos); + } + + return elt; + } + + parseIdentifier(liberal) { + const node = this.startNode(); + const name = this.parseIdentifierName(node.start, liberal); + return this.createIdentifier(node, name); + } + + createIdentifier(node, name) { + node.name = name; + node.loc.identifierName = name; + return this.finishNode(node, "Identifier"); + } + + parseIdentifierName(pos, liberal) { + let name; + + if (this.match(types$4.name)) { + name = this.state.value; + } else if (this.state.type.keyword) { + name = this.state.type.keyword; + const context = this.state.context; + + if ((name === "class" || name === "function") && context[context.length - 1].token === "function") { + context.pop(); + } + } else { + throw this.unexpected(); + } + + if (liberal) { + this.state.type = types$4.name; + } else { + this.checkReservedWord(name, this.state.start, !!this.state.type.keyword, false); + } + + this.next(); + return name; + } + + checkReservedWord(word, startLoc, checkKeywords, isBinding) { + if (this.prodParam.hasYield && word === "yield") { + this.raise(startLoc, ErrorMessages$1.YieldBindingIdentifier); + return; + } + + if (word === "await") { + if (this.prodParam.hasAwait) { + this.raise(startLoc, ErrorMessages$1.AwaitBindingIdentifier); + return; + } + + if (this.state.awaitPos === -1 && (this.state.maybeInAsyncArrowHead || this.isAwaitAllowed())) { + this.state.awaitPos = this.state.start; + } + } + + if (this.scope.inClass && !this.scope.inNonArrowFunction && word === "arguments") { + this.raise(startLoc, ErrorMessages$1.ArgumentsDisallowedInInitializer); + return; + } + + if (checkKeywords && isKeyword$1(word)) { + this.raise(startLoc, ErrorMessages$1.UnexpectedKeyword, word); + return; + } + + const reservedTest = !this.state.strict ? isReservedWord$1 : isBinding ? isStrictBindReservedWord$1 : isStrictReservedWord$1; + + if (reservedTest(word, this.inModule)) { + if (!this.prodParam.hasAwait && word === "await") { + this.raise(startLoc, ErrorMessages$1.AwaitNotInAsyncFunction); + } else { + this.raise(startLoc, ErrorMessages$1.UnexpectedReservedWord, word); + } + } + } + + isAwaitAllowed() { + if (this.scope.inFunction) return this.prodParam.hasAwait; + if (this.options.allowAwaitOutsideFunction) return true; + + if (this.hasPlugin("topLevelAwait")) { + return this.inModule && this.prodParam.hasAwait; + } + + return false; + } + + parseAwait() { + const node = this.startNode(); + this.next(); + + if (this.state.inParameters) { + this.raise(node.start, ErrorMessages$1.AwaitExpressionFormalParameter); + } else if (this.state.awaitPos === -1) { + this.state.awaitPos = node.start; + } + + if (this.eat(types$4.star)) { + this.raise(node.start, ErrorMessages$1.ObsoleteAwaitStar); + } + + if (!this.scope.inFunction && !this.options.allowAwaitOutsideFunction) { + if (this.hasPrecedingLineBreak() || this.match(types$4.plusMin) || this.match(types$4.parenL) || this.match(types$4.bracketL) || this.match(types$4.backQuote) || this.match(types$4.regexp) || this.match(types$4.slash) || this.hasPlugin("v8intrinsic") && this.match(types$4.modulo)) { + this.ambiguousScriptDifferentAst = true; + } else { + this.sawUnambiguousESM = true; + } + } + + if (!this.state.soloAwait) { + node.argument = this.parseMaybeUnary(); + } + + return this.finishNode(node, "AwaitExpression"); + } + + parseYield(noIn) { + const node = this.startNode(); + + if (this.state.inParameters) { + this.raise(node.start, ErrorMessages$1.YieldInParameter); + } else if (this.state.yieldPos === -1) { + this.state.yieldPos = node.start; + } + + this.next(); + + if (this.match(types$4.semi) || !this.match(types$4.star) && !this.state.type.startsExpr || this.hasPrecedingLineBreak()) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types$4.star); + node.argument = this.parseMaybeAssign(noIn); + } + + return this.finishNode(node, "YieldExpression"); + } + + checkPipelineAtInfixOperator(left, leftStartPos) { + if (this.getPluginOption("pipelineOperator", "proposal") === "smart") { + if (left.type === "SequenceExpression") { + this.raise(leftStartPos, ErrorMessages$1.PipelineHeadSequenceExpression); + } + } + } + + parseSmartPipelineBody(childExpression, startPos, startLoc) { + const pipelineStyle = this.checkSmartPipelineBodyStyle(childExpression); + this.checkSmartPipelineBodyEarlyErrors(childExpression, pipelineStyle, startPos); + return this.parseSmartPipelineBodyInStyle(childExpression, pipelineStyle, startPos, startLoc); + } + + checkSmartPipelineBodyEarlyErrors(childExpression, pipelineStyle, startPos) { + if (this.match(types$4.arrow)) { + throw this.raise(this.state.start, ErrorMessages$1.PipelineBodyNoArrow); + } else if (pipelineStyle === "PipelineTopicExpression" && childExpression.type === "SequenceExpression") { + this.raise(startPos, ErrorMessages$1.PipelineBodySequenceExpression); + } + } + + parseSmartPipelineBodyInStyle(childExpression, pipelineStyle, startPos, startLoc) { + const bodyNode = this.startNodeAt(startPos, startLoc); + + switch (pipelineStyle) { + case "PipelineBareFunction": + bodyNode.callee = childExpression; + break; + + case "PipelineBareConstructor": + bodyNode.callee = childExpression.callee; + break; + + case "PipelineBareAwaitedFunction": + bodyNode.callee = childExpression.argument; + break; + + case "PipelineTopicExpression": + if (!this.topicReferenceWasUsedInCurrentTopicContext()) { + this.raise(startPos, ErrorMessages$1.PipelineTopicUnused); + } + + bodyNode.expression = childExpression; + break; + + default: + throw new Error(`Internal @babel/parser error: Unknown pipeline style (${pipelineStyle})`); + } + + return this.finishNode(bodyNode, pipelineStyle); + } + + checkSmartPipelineBodyStyle(expression) { + switch (expression.type) { + default: + return this.isSimpleReference(expression) ? "PipelineBareFunction" : "PipelineTopicExpression"; + } + } + + isSimpleReference(expression) { + switch (expression.type) { + case "MemberExpression": + return !expression.computed && this.isSimpleReference(expression.object); + + case "Identifier": + return true; + + default: + return false; + } + } + + withTopicPermittingContext(callback) { + const outerContextTopicState = this.state.topicContext; + this.state.topicContext = { + maxNumOfResolvableTopics: 1, + maxTopicIndex: null + }; + + try { + return callback(); + } finally { + this.state.topicContext = outerContextTopicState; + } + } + + withTopicForbiddingContext(callback) { + const outerContextTopicState = this.state.topicContext; + this.state.topicContext = { + maxNumOfResolvableTopics: 0, + maxTopicIndex: null + }; + + try { + return callback(); + } finally { + this.state.topicContext = outerContextTopicState; + } + } + + withSoloAwaitPermittingContext(callback) { + const outerContextSoloAwaitState = this.state.soloAwait; + this.state.soloAwait = true; + + try { + return callback(); + } finally { + this.state.soloAwait = outerContextSoloAwaitState; + } + } + + registerTopicReference() { + this.state.topicContext.maxTopicIndex = 0; + } + + primaryTopicReferenceIsAllowedInCurrentTopicContext() { + return this.state.topicContext.maxNumOfResolvableTopics >= 1; + } + + topicReferenceWasUsedInCurrentTopicContext() { + return this.state.topicContext.maxTopicIndex != null && this.state.topicContext.maxTopicIndex >= 0; + } + + parseFSharpPipelineBody(prec, noIn) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.state.potentialArrowAt = this.state.start; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = true; + const ret = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return ret; + } + + }; + + const loopLabel$1 = { + kind: "loop" + }, + switchLabel$1 = { + kind: "switch" + }; + const FUNC_NO_FLAGS$1 = 0b000, + FUNC_STATEMENT$1 = 0b001, + FUNC_HANGING_STATEMENT$1 = 0b010, + FUNC_NULLABLE_ID$1 = 0b100; + let StatementParser$1 = class StatementParser extends ExpressionParser$1 { + parseTopLevel(file, program) { + program.sourceType = this.options.sourceType; + program.interpreter = this.parseInterpreterDirective(); + this.parseBlockBody(program, true, true, types$4.eof); + + if (this.inModule && !this.options.allowUndeclaredExports && this.scope.undefinedExports.size > 0) { + for (let _i = 0, _Array$from = Array.from(this.scope.undefinedExports); _i < _Array$from.length; _i++) { + const [name] = _Array$from[_i]; + const pos = this.scope.undefinedExports.get(name); + this.raise(pos, ErrorMessages$1.ModuleExportUndefined, name); + } + } + + file.program = this.finishNode(program, "Program"); + file.comments = this.state.comments; + if (this.options.tokens) file.tokens = this.tokens; + return this.finishNode(file, "File"); + } + + stmtToDirective(stmt) { + const expr = stmt.expression; + const directiveLiteral = this.startNodeAt(expr.start, expr.loc.start); + const directive = this.startNodeAt(stmt.start, stmt.loc.start); + const raw = this.input.slice(expr.start, expr.end); + const val = directiveLiteral.value = raw.slice(1, -1); + this.addExtra(directiveLiteral, "raw", raw); + this.addExtra(directiveLiteral, "rawValue", val); + directive.value = this.finishNodeAt(directiveLiteral, "DirectiveLiteral", expr.end, expr.loc.end); + return this.finishNodeAt(directive, "Directive", stmt.end, stmt.loc.end); + } + + parseInterpreterDirective() { + if (!this.match(types$4.interpreterDirective)) { + return null; + } + + const node = this.startNode(); + node.value = this.state.value; + this.next(); + return this.finishNode(node, "InterpreterDirective"); + } + + isLet(context) { + if (!this.isContextual("let")) { + return false; + } + + const next = this.nextTokenStart(); + const nextCh = this.input.charCodeAt(next); + if (nextCh === 91) return true; + if (context) return false; + if (nextCh === 123) return true; + + if (isIdentifierStart$1(nextCh)) { + let pos = next + 1; + + while (isIdentifierChar$1(this.input.charCodeAt(pos))) { + ++pos; + } + + const ident = this.input.slice(next, pos); + if (!keywordRelationalOperator$1.test(ident)) return true; + } + + return false; + } + + parseStatement(context, topLevel) { + if (this.match(types$4.at)) { + this.parseDecorators(true); + } + + return this.parseStatementContent(context, topLevel); + } + + parseStatementContent(context, topLevel) { + let starttype = this.state.type; + const node = this.startNode(); + let kind; + + if (this.isLet(context)) { + starttype = types$4._var; + kind = "let"; + } + + switch (starttype) { + case types$4._break: + case types$4._continue: + return this.parseBreakContinueStatement(node, starttype.keyword); + + case types$4._debugger: + return this.parseDebuggerStatement(node); + + case types$4._do: + return this.parseDoStatement(node); + + case types$4._for: + return this.parseForStatement(node); + + case types$4._function: + if (this.lookaheadCharCode() === 46) break; + + if (context) { + if (this.state.strict) { + this.raise(this.state.start, ErrorMessages$1.StrictFunction); + } else if (context !== "if" && context !== "label") { + this.raise(this.state.start, ErrorMessages$1.SloppyFunction); + } + } + + return this.parseFunctionStatement(node, false, !context); + + case types$4._class: + if (context) this.unexpected(); + return this.parseClass(node, true); + + case types$4._if: + return this.parseIfStatement(node); + + case types$4._return: + return this.parseReturnStatement(node); + + case types$4._switch: + return this.parseSwitchStatement(node); + + case types$4._throw: + return this.parseThrowStatement(node); + + case types$4._try: + return this.parseTryStatement(node); + + case types$4._const: + case types$4._var: + kind = kind || this.state.value; + + if (context && kind !== "var") { + this.raise(this.state.start, ErrorMessages$1.UnexpectedLexicalDeclaration); + } + + return this.parseVarStatement(node, kind); + + case types$4._while: + return this.parseWhileStatement(node); + + case types$4._with: + return this.parseWithStatement(node); + + case types$4.braceL: + return this.parseBlock(); + + case types$4.semi: + return this.parseEmptyStatement(node); + + case types$4._export: + case types$4._import: + { + const nextTokenCharCode = this.lookaheadCharCode(); + + if (nextTokenCharCode === 40 || nextTokenCharCode === 46) { + break; + } + + if (!this.options.allowImportExportEverywhere && !topLevel) { + this.raise(this.state.start, ErrorMessages$1.UnexpectedImportExport); + } + + this.next(); + let result; + + if (starttype === types$4._import) { + result = this.parseImport(node); + + if (result.type === "ImportDeclaration" && (!result.importKind || result.importKind === "value")) { + this.sawUnambiguousESM = true; + } + } else { + result = this.parseExport(node); + + if (result.type === "ExportNamedDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportAllDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportDefaultDeclaration") { + this.sawUnambiguousESM = true; + } + } + + this.assertModuleNodeAllowed(node); + return result; + } + + default: + { + if (this.isAsyncFunction()) { + if (context) { + this.raise(this.state.start, ErrorMessages$1.AsyncFunctionInSingleStatementContext); + } + + this.next(); + return this.parseFunctionStatement(node, true, !context); + } + } + } + + const maybeName = this.state.value; + const expr = this.parseExpression(); + + if (starttype === types$4.name && expr.type === "Identifier" && this.eat(types$4.colon)) { + return this.parseLabeledStatement(node, maybeName, expr, context); + } else { + return this.parseExpressionStatement(node, expr); + } + } + + assertModuleNodeAllowed(node) { + if (!this.options.allowImportExportEverywhere && !this.inModule) { + this.raiseWithData(node.start, { + code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" + }, ErrorMessages$1.ImportOutsideModule); + } + } + + takeDecorators(node) { + const decorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + if (decorators.length) { + node.decorators = decorators; + this.resetStartLocationFromNode(node, decorators[0]); + this.state.decoratorStack[this.state.decoratorStack.length - 1] = []; + } + } + + canHaveLeadingDecorator() { + return this.match(types$4._class); + } + + parseDecorators(allowExport) { + const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + while (this.match(types$4.at)) { + const decorator = this.parseDecorator(); + currentContextDecorators.push(decorator); + } + + if (this.match(types$4._export)) { + if (!allowExport) { + this.unexpected(); + } + + if (this.hasPlugin("decorators") && !this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.raise(this.state.start, ErrorMessages$1.DecoratorExportClass); + } + } else if (!this.canHaveLeadingDecorator()) { + throw this.raise(this.state.start, ErrorMessages$1.UnexpectedLeadingDecorator); + } + } + + parseDecorator() { + this.expectOnePlugin(["decorators-legacy", "decorators"]); + const node = this.startNode(); + this.next(); + + if (this.hasPlugin("decorators")) { + this.state.decoratorStack.push([]); + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let expr; + + if (this.eat(types$4.parenL)) { + expr = this.parseExpression(); + this.expect(types$4.parenR); + } else { + expr = this.parseIdentifier(false); + + while (this.eat(types$4.dot)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = expr; + node.property = this.parseIdentifier(true); + node.computed = false; + expr = this.finishNode(node, "MemberExpression"); + } + } + + node.expression = this.parseMaybeDecoratorArguments(expr); + this.state.decoratorStack.pop(); + } else { + node.expression = this.parseExprSubscripts(); + } + + return this.finishNode(node, "Decorator"); + } + + parseMaybeDecoratorArguments(expr) { + if (this.eat(types$4.parenL)) { + const node = this.startNodeAtNode(expr); + node.callee = expr; + node.arguments = this.parseCallExpressionArguments(types$4.parenR, false); + this.toReferencedList(node.arguments); + return this.finishNode(node, "CallExpression"); + } + + return expr; + } + + parseBreakContinueStatement(node, keyword) { + const isBreak = keyword === "break"; + this.next(); + + if (this.isLineTerminator()) { + node.label = null; + } else { + node.label = this.parseIdentifier(); + this.semicolon(); + } + + this.verifyBreakContinue(node, keyword); + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); + } + + verifyBreakContinue(node, keyword) { + const isBreak = keyword === "break"; + let i; + + for (i = 0; i < this.state.labels.length; ++i) { + const lab = this.state.labels[i]; + + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break; + if (node.label && isBreak) break; + } + } + + if (i === this.state.labels.length) { + this.raise(node.start, ErrorMessages$1.IllegalBreakContinue, keyword); + } + } + + parseDebuggerStatement(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement"); + } + + parseHeaderExpression() { + this.expect(types$4.parenL); + const val = this.parseExpression(); + this.expect(types$4.parenR); + return val; + } + + parseDoStatement(node) { + this.next(); + this.state.labels.push(loopLabel$1); + node.body = this.withTopicForbiddingContext(() => this.parseStatement("do")); + this.state.labels.pop(); + this.expect(types$4._while); + node.test = this.parseHeaderExpression(); + this.eat(types$4.semi); + return this.finishNode(node, "DoWhileStatement"); + } + + parseForStatement(node) { + this.next(); + this.state.labels.push(loopLabel$1); + let awaitAt = -1; + + if (this.isAwaitAllowed() && this.eatContextual("await")) { + awaitAt = this.state.lastTokStart; + } + + this.scope.enter(SCOPE_OTHER$1); + this.expect(types$4.parenL); + + if (this.match(types$4.semi)) { + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, null); + } + + const isLet = this.isLet(); + + if (this.match(types$4._var) || this.match(types$4._const) || isLet) { + const init = this.startNode(); + const kind = isLet ? "let" : this.state.value; + this.next(); + this.parseVar(init, true, kind); + this.finishNode(init, "VariableDeclaration"); + + if ((this.match(types$4._in) || this.isContextual("of")) && init.declarations.length === 1) { + return this.parseForIn(node, init, awaitAt); + } + + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, init); + } + + const refExpressionErrors = new ExpressionErrors$1(); + const init = this.parseExpression(true, refExpressionErrors); + + if (this.match(types$4._in) || this.isContextual("of")) { + this.toAssignable(init); + const description = this.isContextual("of") ? "for-of statement" : "for-in statement"; + this.checkLVal(init, undefined, undefined, description); + return this.parseForIn(node, init, awaitAt); + } else { + this.checkExpressionErrors(refExpressionErrors, true); + } + + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, init); + } + + parseFunctionStatement(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT$1 | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT$1), isAsync); + } + + parseIfStatement(node) { + this.next(); + node.test = this.parseHeaderExpression(); + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types$4._else) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement"); + } + + parseReturnStatement(node) { + if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) { + this.raise(this.state.start, ErrorMessages$1.IllegalReturn); + } + + this.next(); + + if (this.isLineTerminator()) { + node.argument = null; + } else { + node.argument = this.parseExpression(); + this.semicolon(); + } + + return this.finishNode(node, "ReturnStatement"); + } + + parseSwitchStatement(node) { + this.next(); + node.discriminant = this.parseHeaderExpression(); + const cases = node.cases = []; + this.expect(types$4.braceL); + this.state.labels.push(switchLabel$1); + this.scope.enter(SCOPE_OTHER$1); + let cur; + + for (let sawDefault; !this.match(types$4.braceR);) { + if (this.match(types$4._case) || this.match(types$4._default)) { + const isCase = this.match(types$4._case); + if (cur) this.finishNode(cur, "SwitchCase"); + cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { + this.raise(this.state.lastTokStart, ErrorMessages$1.MultipleDefaultsInSwitch); + } + + sawDefault = true; + cur.test = null; + } + + this.expect(types$4.colon); + } else { + if (cur) { + cur.consequent.push(this.parseStatement(null)); + } else { + this.unexpected(); + } + } + } + + this.scope.exit(); + if (cur) this.finishNode(cur, "SwitchCase"); + this.next(); + this.state.labels.pop(); + return this.finishNode(node, "SwitchStatement"); + } + + parseThrowStatement(node) { + this.next(); + + if (lineBreak$1.test(this.input.slice(this.state.lastTokEnd, this.state.start))) { + this.raise(this.state.lastTokEnd, ErrorMessages$1.NewlineAfterThrow); + } + + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement"); + } + + parseTryStatement(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + + if (this.match(types$4._catch)) { + const clause = this.startNode(); + this.next(); + + if (this.match(types$4.parenL)) { + this.expect(types$4.parenL); + clause.param = this.parseBindingAtom(); + const simple = clause.param.type === "Identifier"; + this.scope.enter(simple ? SCOPE_SIMPLE_CATCH$1 : 0); + this.checkLVal(clause.param, BIND_LEXICAL$1, null, "catch clause"); + this.expect(types$4.parenR); + } else { + clause.param = null; + this.scope.enter(SCOPE_OTHER$1); + } + + clause.body = this.withTopicForbiddingContext(() => this.parseBlock(false, false)); + this.scope.exit(); + node.handler = this.finishNode(clause, "CatchClause"); + } + + node.finalizer = this.eat(types$4._finally) ? this.parseBlock() : null; + + if (!node.handler && !node.finalizer) { + this.raise(node.start, ErrorMessages$1.NoCatchOrFinally); + } + + return this.finishNode(node, "TryStatement"); + } + + parseVarStatement(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration"); + } + + parseWhileStatement(node) { + this.next(); + node.test = this.parseHeaderExpression(); + this.state.labels.push(loopLabel$1); + node.body = this.withTopicForbiddingContext(() => this.parseStatement("while")); + this.state.labels.pop(); + return this.finishNode(node, "WhileStatement"); + } + + parseWithStatement(node) { + if (this.state.strict) { + this.raise(this.state.start, ErrorMessages$1.StrictWith); + } + + this.next(); + node.object = this.parseHeaderExpression(); + node.body = this.withTopicForbiddingContext(() => this.parseStatement("with")); + return this.finishNode(node, "WithStatement"); + } + + parseEmptyStatement(node) { + this.next(); + return this.finishNode(node, "EmptyStatement"); + } + + parseLabeledStatement(node, maybeName, expr, context) { + for (let _i2 = 0, _this$state$labels = this.state.labels; _i2 < _this$state$labels.length; _i2++) { + const label = _this$state$labels[_i2]; + + if (label.name === maybeName) { + this.raise(expr.start, ErrorMessages$1.LabelRedeclaration, maybeName); + } + } + + const kind = this.state.type.isLoop ? "loop" : this.match(types$4._switch) ? "switch" : null; + + for (let i = this.state.labels.length - 1; i >= 0; i--) { + const label = this.state.labels[i]; + + if (label.statementStart === node.start) { + label.statementStart = this.state.start; + label.kind = kind; + } else { + break; + } + } + + this.state.labels.push({ + name: maybeName, + kind: kind, + statementStart: this.state.start + }); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.state.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement"); + } + + parseExpressionStatement(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement"); + } + + parseBlock(allowDirectives = false, createNewLexicalScope = true, afterBlockParse) { + const node = this.startNode(); + this.expect(types$4.braceL); + + if (createNewLexicalScope) { + this.scope.enter(SCOPE_OTHER$1); + } + + this.parseBlockBody(node, allowDirectives, false, types$4.braceR, afterBlockParse); + + if (createNewLexicalScope) { + this.scope.exit(); + } + + return this.finishNode(node, "BlockStatement"); + } + + isValidDirective(stmt) { + return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized; + } + + parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) { + const body = node.body = []; + const directives = node.directives = []; + this.parseBlockOrModuleBlockBody(body, allowDirectives ? directives : undefined, topLevel, end, afterBlockParse); + } + + parseBlockOrModuleBlockBody(body, directives, topLevel, end, afterBlockParse) { + const octalPositions = []; + const oldStrict = this.state.strict; + let hasStrictModeDirective = false; + let parsedNonDirective = false; + + while (!this.match(end)) { + if (!parsedNonDirective && this.state.octalPositions.length) { + octalPositions.push(...this.state.octalPositions); + } + + const stmt = this.parseStatement(null, topLevel); + + if (directives && !parsedNonDirective && this.isValidDirective(stmt)) { + const directive = this.stmtToDirective(stmt); + directives.push(directive); + + if (!hasStrictModeDirective && directive.value.value === "use strict") { + hasStrictModeDirective = true; + this.setStrict(true); + } + + continue; + } + + parsedNonDirective = true; + body.push(stmt); + } + + if (this.state.strict && octalPositions.length) { + for (let _i3 = 0; _i3 < octalPositions.length; _i3++) { + const pos = octalPositions[_i3]; + this.raise(pos, ErrorMessages$1.StrictOctalLiteral); + } + } + + if (afterBlockParse) { + afterBlockParse.call(this, hasStrictModeDirective); + } + + if (!oldStrict) { + this.setStrict(false); + } + + this.next(); + } + + parseFor(node, init) { + node.init = init; + this.expect(types$4.semi); + node.test = this.match(types$4.semi) ? null : this.parseExpression(); + this.expect(types$4.semi); + node.update = this.match(types$4.parenR) ? null : this.parseExpression(); + this.expect(types$4.parenR); + node.body = this.withTopicForbiddingContext(() => this.parseStatement("for")); + this.scope.exit(); + this.state.labels.pop(); + return this.finishNode(node, "ForStatement"); + } + + parseForIn(node, init, awaitAt) { + const isForIn = this.match(types$4._in); + this.next(); + + if (isForIn) { + if (awaitAt > -1) this.unexpected(awaitAt); + } else { + node.await = awaitAt > -1; + } + + if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) { + this.raise(init.start, ErrorMessages$1.ForInOfLoopInitializer, isForIn ? "for-in" : "for-of"); + } else if (init.type === "AssignmentPattern") { + this.raise(init.start, ErrorMessages$1.InvalidLhs, "for-loop"); + } + + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types$4.parenR); + node.body = this.withTopicForbiddingContext(() => this.parseStatement("for")); + this.scope.exit(); + this.state.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement"); + } + + parseVar(node, isFor, kind) { + const declarations = node.declarations = []; + const isTypescript = this.hasPlugin("typescript"); + node.kind = kind; + + for (;;) { + const decl = this.startNode(); + this.parseVarId(decl, kind); + + if (this.eat(types$4.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else { + if (kind === "const" && !(this.match(types$4._in) || this.isContextual("of"))) { + if (!isTypescript) { + this.unexpected(); + } + } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(types$4._in) || this.isContextual("of")))) { + this.raise(this.state.lastTokEnd, ErrorMessages$1.DeclarationMissingInitializer, "Complex binding patterns"); + } + + decl.init = null; + } + + declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types$4.comma)) break; + } + + return node; + } + + parseVarId(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLVal(decl.id, kind === "var" ? BIND_VAR$1 : BIND_LEXICAL$1, undefined, "variable declaration", kind !== "var"); + } + + parseFunction(node, statement = FUNC_NO_FLAGS$1, isAsync = false) { + const isStatement = statement & FUNC_STATEMENT$1; + const isHangingStatement = statement & FUNC_HANGING_STATEMENT$1; + const requireId = !!isStatement && !(statement & FUNC_NULLABLE_ID$1); + this.initFunction(node, isAsync); + + if (this.match(types$4.star) && isHangingStatement) { + this.raise(this.state.start, ErrorMessages$1.GeneratorInSingleStatementContext); + } + + node.generator = this.eat(types$4.star); + + if (isStatement) { + node.id = this.parseFunctionId(requireId); + } + + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldYieldPos = this.state.yieldPos; + const oldAwaitPos = this.state.awaitPos; + this.state.maybeInArrowParameters = false; + this.state.yieldPos = -1; + this.state.awaitPos = -1; + this.scope.enter(SCOPE_FUNCTION$1); + this.prodParam.enter(functionFlags$1(isAsync, node.generator)); + + if (!isStatement) { + node.id = this.parseFunctionId(); + } + + this.parseFunctionParams(node); + this.withTopicForbiddingContext(() => { + this.parseFunctionBodyAndFinish(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); + }); + this.prodParam.exit(); + this.scope.exit(); + + if (isStatement && !isHangingStatement) { + this.registerFunctionStatementId(node); + } + + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.yieldPos = oldYieldPos; + this.state.awaitPos = oldAwaitPos; + return node; + } + + parseFunctionId(requireId) { + return requireId || this.match(types$4.name) ? this.parseIdentifier() : null; + } + + parseFunctionParams(node, allowModifiers) { + const oldInParameters = this.state.inParameters; + this.state.inParameters = true; + this.expect(types$4.parenL); + node.params = this.parseBindingList(types$4.parenR, 41, false, allowModifiers); + this.state.inParameters = oldInParameters; + this.checkYieldAwaitInDefaultParams(); + } + + registerFunctionStatementId(node) { + if (!node.id) return; + this.scope.declareName(node.id.name, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR$1 : BIND_LEXICAL$1 : BIND_FUNCTION$1, node.id.start); + } + + parseClass(node, isStatement, optionalId) { + this.next(); + this.takeDecorators(node); + const oldStrict = this.state.strict; + this.state.strict = true; + this.parseClassId(node, isStatement, optionalId); + this.parseClassSuper(node); + node.body = this.parseClassBody(!!node.superClass, oldStrict); + this.state.strict = oldStrict; + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); + } + + isClassProperty() { + return this.match(types$4.eq) || this.match(types$4.semi) || this.match(types$4.braceR); + } + + isClassMethod() { + return this.match(types$4.parenL); + } + + isNonstaticConstructor(method) { + return !method.computed && !method.static && (method.key.name === "constructor" || method.key.value === "constructor"); + } + + parseClassBody(constructorAllowsSuper, oldStrict) { + this.classScope.enter(); + const state = { + hadConstructor: false + }; + let decorators = []; + const classBody = this.startNode(); + classBody.body = []; + this.expect(types$4.braceL); + this.withTopicForbiddingContext(() => { + while (!this.match(types$4.braceR)) { + if (this.eat(types$4.semi)) { + if (decorators.length > 0) { + throw this.raise(this.state.lastTokEnd, ErrorMessages$1.DecoratorSemicolon); + } + + continue; + } + + if (this.match(types$4.at)) { + decorators.push(this.parseDecorator()); + continue; + } + + const member = this.startNode(); + + if (decorators.length) { + member.decorators = decorators; + this.resetStartLocationFromNode(member, decorators[0]); + decorators = []; + } + + this.parseClassMember(classBody, member, state, constructorAllowsSuper); + + if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) { + this.raise(member.start, ErrorMessages$1.DecoratorConstructor); + } + } + }); + + if (!oldStrict) { + this.state.strict = false; + } + + this.next(); + + if (decorators.length) { + throw this.raise(this.state.start, ErrorMessages$1.TrailingDecorator); + } + + this.classScope.exit(); + return this.finishNode(classBody, "ClassBody"); + } + + parseClassMemberFromModifier(classBody, member) { + const containsEsc = this.state.containsEsc; + const key = this.parseIdentifier(true); + + if (this.isClassMethod()) { + const method = member; + method.kind = "method"; + method.computed = false; + method.key = key; + method.static = false; + this.pushClassMethod(classBody, method, false, false, false, false); + return true; + } else if (this.isClassProperty()) { + const prop = member; + prop.computed = false; + prop.key = key; + prop.static = false; + classBody.body.push(this.parseClassProperty(prop)); + return true; + } else if (containsEsc) { + throw this.unexpected(); + } + + return false; + } + + parseClassMember(classBody, member, state, constructorAllowsSuper) { + const isStatic = this.isContextual("static"); + + if (isStatic && this.parseClassMemberFromModifier(classBody, member)) { + return; + } + + this.parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper); + } + + parseClassMemberWithIsStatic(classBody, member, state, isStatic, constructorAllowsSuper) { + const publicMethod = member; + const privateMethod = member; + const publicProp = member; + const privateProp = member; + const method = publicMethod; + const publicMember = publicMethod; + member.static = isStatic; + + if (this.eat(types$4.star)) { + method.kind = "method"; + this.parseClassPropertyName(method); + + if (method.key.type === "PrivateName") { + this.pushClassPrivateMethod(classBody, privateMethod, true, false); + return; + } + + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages$1.ConstructorIsGenerator); + } + + this.pushClassMethod(classBody, publicMethod, true, false, false, false); + return; + } + + const containsEsc = this.state.containsEsc; + const key = this.parseClassPropertyName(member); + const isPrivate = key.type === "PrivateName"; + const isSimple = key.type === "Identifier"; + const maybeQuestionTokenStart = this.state.start; + this.parsePostMemberNameModifiers(publicMember); + + if (this.isClassMethod()) { + method.kind = "method"; + + if (isPrivate) { + this.pushClassPrivateMethod(classBody, privateMethod, false, false); + return; + } + + const isConstructor = this.isNonstaticConstructor(publicMethod); + let allowsDirectSuper = false; + + if (isConstructor) { + publicMethod.kind = "constructor"; + + if (state.hadConstructor && !this.hasPlugin("typescript")) { + this.raise(key.start, ErrorMessages$1.DuplicateConstructor); + } + + state.hadConstructor = true; + allowsDirectSuper = constructorAllowsSuper; + } + + this.pushClassMethod(classBody, publicMethod, false, false, isConstructor, allowsDirectSuper); + } else if (this.isClassProperty()) { + if (isPrivate) { + this.pushClassPrivateProperty(classBody, privateProp); + } else { + this.pushClassProperty(classBody, publicProp); + } + } else if (isSimple && key.name === "async" && !containsEsc && !this.isLineTerminator()) { + const isGenerator = this.eat(types$4.star); + + if (publicMember.optional) { + this.unexpected(maybeQuestionTokenStart); + } + + method.kind = "method"; + this.parseClassPropertyName(method); + this.parsePostMemberNameModifiers(publicMember); + + if (method.key.type === "PrivateName") { + this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true); + } else { + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages$1.ConstructorIsAsync); + } + + this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false); + } + } else if (isSimple && (key.name === "get" || key.name === "set") && !containsEsc && !(this.match(types$4.star) && this.isLineTerminator())) { + method.kind = key.name; + this.parseClassPropertyName(publicMethod); + + if (method.key.type === "PrivateName") { + this.pushClassPrivateMethod(classBody, privateMethod, false, false); + } else { + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages$1.ConstructorIsAccessor); + } + + this.pushClassMethod(classBody, publicMethod, false, false, false, false); + } + + this.checkGetterSetterParams(publicMethod); + } else if (this.isLineTerminator()) { + if (isPrivate) { + this.pushClassPrivateProperty(classBody, privateProp); + } else { + this.pushClassProperty(classBody, publicProp); + } + } else { + this.unexpected(); + } + } + + parseClassPropertyName(member) { + const key = this.parsePropertyName(member, true); + + if (!member.computed && member.static && (key.name === "prototype" || key.value === "prototype")) { + this.raise(key.start, ErrorMessages$1.StaticPrototype); + } + + if (key.type === "PrivateName" && key.id.name === "constructor") { + this.raise(key.start, ErrorMessages$1.ConstructorClassPrivateField); + } + + return key; + } + + pushClassProperty(classBody, prop) { + if (!prop.computed && (prop.key.name === "constructor" || prop.key.value === "constructor")) { + this.raise(prop.key.start, ErrorMessages$1.ConstructorClassField); + } + + classBody.body.push(this.parseClassProperty(prop)); + } + + pushClassPrivateProperty(classBody, prop) { + this.expectPlugin("classPrivateProperties", prop.key.start); + const node = this.parseClassPrivateProperty(prop); + classBody.body.push(node); + this.classScope.declarePrivateName(node.key.id.name, CLASS_ELEMENT_OTHER$1, node.key.start); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + classBody.body.push(this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true)); + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + this.expectPlugin("classPrivateMethods", method.key.start); + const node = this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true); + classBody.body.push(node); + const kind = node.kind === "get" ? node.static ? CLASS_ELEMENT_STATIC_GETTER$1 : CLASS_ELEMENT_INSTANCE_GETTER$1 : node.kind === "set" ? node.static ? CLASS_ELEMENT_STATIC_SETTER$1 : CLASS_ELEMENT_INSTANCE_SETTER$1 : CLASS_ELEMENT_OTHER$1; + this.classScope.declarePrivateName(node.key.id.name, kind, node.key.start); + } + + parsePostMemberNameModifiers(methodOrProp) {} + + parseAccessModifier() { + return undefined; + } + + parseClassPrivateProperty(node) { + this.scope.enter(SCOPE_CLASS$1 | SCOPE_SUPER$1); + this.prodParam.enter(PARAM$1); + node.value = this.eat(types$4.eq) ? this.parseMaybeAssign() : null; + this.semicolon(); + this.prodParam.exit(); + this.scope.exit(); + return this.finishNode(node, "ClassPrivateProperty"); + } + + parseClassProperty(node) { + if (!node.typeAnnotation) { + this.expectPlugin("classProperties"); + } + + this.scope.enter(SCOPE_CLASS$1 | SCOPE_SUPER$1); + this.prodParam.enter(PARAM$1); + + if (this.match(types$4.eq)) { + this.expectPlugin("classProperties"); + this.next(); + node.value = this.parseMaybeAssign(); + } else { + node.value = null; + } + + this.semicolon(); + this.prodParam.exit(); + this.scope.exit(); + return this.finishNode(node, "ClassProperty"); + } + + parseClassId(node, isStatement, optionalId, bindingType = BIND_CLASS$1) { + if (this.match(types$4.name)) { + node.id = this.parseIdentifier(); + + if (isStatement) { + this.checkLVal(node.id, bindingType, undefined, "class name"); + } + } else { + if (optionalId || !isStatement) { + node.id = null; + } else { + this.unexpected(null, ErrorMessages$1.MissingClassName); + } + } + } + + parseClassSuper(node) { + node.superClass = this.eat(types$4._extends) ? this.parseExprSubscripts() : null; + } + + parseExport(node) { + const hasDefault = this.maybeParseExportDefaultSpecifier(node); + const parseAfterDefault = !hasDefault || this.eat(types$4.comma); + const hasStar = parseAfterDefault && this.eatExportStar(node); + const hasNamespace = hasStar && this.maybeParseExportNamespaceSpecifier(node); + const parseAfterNamespace = parseAfterDefault && (!hasNamespace || this.eat(types$4.comma)); + const isFromRequired = hasDefault || hasStar; + + if (hasStar && !hasNamespace) { + if (hasDefault) this.unexpected(); + this.parseExportFrom(node, true); + return this.finishNode(node, "ExportAllDeclaration"); + } + + const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node); + + if (hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers || hasNamespace && parseAfterNamespace && !hasSpecifiers) { + throw this.unexpected(null, types$4.braceL); + } + + let hasDeclaration; + + if (isFromRequired || hasSpecifiers) { + hasDeclaration = false; + this.parseExportFrom(node, isFromRequired); + } else { + hasDeclaration = this.maybeParseExportDeclaration(node); + } + + if (isFromRequired || hasSpecifiers || hasDeclaration) { + this.checkExport(node, true, false, !!node.source); + return this.finishNode(node, "ExportNamedDeclaration"); + } + + if (this.eat(types$4._default)) { + node.declaration = this.parseExportDefaultExpression(); + this.checkExport(node, true, true); + return this.finishNode(node, "ExportDefaultDeclaration"); + } + + throw this.unexpected(null, types$4.braceL); + } + + eatExportStar(node) { + return this.eat(types$4.star); + } + + maybeParseExportDefaultSpecifier(node) { + if (this.isExportDefaultSpecifier()) { + this.expectPlugin("exportDefaultFrom"); + const specifier = this.startNode(); + specifier.exported = this.parseIdentifier(true); + node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + return true; + } + + return false; + } + + maybeParseExportNamespaceSpecifier(node) { + if (this.isContextual("as")) { + if (!node.specifiers) node.specifiers = []; + const specifier = this.startNodeAt(this.state.lastTokStart, this.state.lastTokStartLoc); + this.next(); + specifier.exported = this.parseIdentifier(true); + node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); + return true; + } + + return false; + } + + maybeParseExportNamedSpecifiers(node) { + if (this.match(types$4.braceL)) { + if (!node.specifiers) node.specifiers = []; + node.specifiers.push(...this.parseExportSpecifiers()); + node.source = null; + node.declaration = null; + return true; + } + + return false; + } + + maybeParseExportDeclaration(node) { + if (this.shouldParseExportDeclaration()) { + if (this.isContextual("async")) { + const next = this.nextTokenStart(); + + if (!this.isUnparsedContextual(next, "function")) { + this.unexpected(next, types$4._function); + } + } + + node.specifiers = []; + node.source = null; + node.declaration = this.parseExportDeclaration(node); + return true; + } + + return false; + } + + isAsyncFunction() { + if (!this.isContextual("async")) return false; + const next = this.nextTokenStart(); + return !lineBreak$1.test(this.input.slice(this.state.pos, next)) && this.isUnparsedContextual(next, "function"); + } + + parseExportDefaultExpression() { + const expr = this.startNode(); + const isAsync = this.isAsyncFunction(); + + if (this.match(types$4._function) || isAsync) { + this.next(); + + if (isAsync) { + this.next(); + } + + return this.parseFunction(expr, FUNC_STATEMENT$1 | FUNC_NULLABLE_ID$1, isAsync); + } else if (this.match(types$4._class)) { + return this.parseClass(expr, true, true); + } else if (this.match(types$4.at)) { + if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.raise(this.state.start, ErrorMessages$1.DecoratorBeforeExport); + } + + this.parseDecorators(false); + return this.parseClass(expr, true, true); + } else if (this.match(types$4._const) || this.match(types$4._var) || this.isLet()) { + throw this.raise(this.state.start, ErrorMessages$1.UnsupportedDefaultExport); + } else { + const res = this.parseMaybeAssign(); + this.semicolon(); + return res; + } + } + + parseExportDeclaration(node) { + return this.parseStatement(null); + } + + isExportDefaultSpecifier() { + if (this.match(types$4.name)) { + const value = this.state.value; + + if (value === "async" || value === "let") { + return false; + } + + if ((value === "type" || value === "interface") && !this.state.containsEsc) { + const l = this.lookahead(); + + if (l.type === types$4.name && l.value !== "from" || l.type === types$4.braceL) { + this.expectOnePlugin(["flow", "typescript"]); + return false; + } + } + } else if (!this.match(types$4._default)) { + return false; + } + + const next = this.nextTokenStart(); + const hasFrom = this.isUnparsedContextual(next, "from"); + + if (this.input.charCodeAt(next) === 44 || this.match(types$4.name) && hasFrom) { + return true; + } + + if (this.match(types$4._default) && hasFrom) { + const nextAfterFrom = this.input.charCodeAt(this.nextTokenStartSince(next + 4)); + return nextAfterFrom === 34 || nextAfterFrom === 39; + } + + return false; + } + + parseExportFrom(node, expect) { + if (this.eatContextual("from")) { + node.source = this.parseImportSource(); + this.checkExport(node); + } else { + if (expect) { + this.unexpected(); + } else { + node.source = null; + } + } + + this.semicolon(); + } + + shouldParseExportDeclaration() { + if (this.match(types$4.at)) { + this.expectOnePlugin(["decorators", "decorators-legacy"]); + + if (this.hasPlugin("decorators")) { + if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.unexpected(this.state.start, ErrorMessages$1.DecoratorBeforeExport); + } else { + return true; + } + } + } + + return this.state.type.keyword === "var" || this.state.type.keyword === "const" || this.state.type.keyword === "function" || this.state.type.keyword === "class" || this.isLet() || this.isAsyncFunction(); + } + + checkExport(node, checkNames, isDefault, isFrom) { + if (checkNames) { + if (isDefault) { + this.checkDuplicateExports(node, "default"); + + if (this.hasPlugin("exportDefaultFrom")) { + var _declaration$extra; + + const declaration = node.declaration; + + if (declaration.type === "Identifier" && declaration.name === "from" && declaration.end - declaration.start === 4 && !((_declaration$extra = declaration.extra) == null ? void 0 : _declaration$extra.parenthesized)) { + this.raise(declaration.start, ErrorMessages$1.ExportDefaultFromAsIdentifier); + } + } + } else if (node.specifiers && node.specifiers.length) { + for (let _i4 = 0, _node$specifiers = node.specifiers; _i4 < _node$specifiers.length; _i4++) { + const specifier = _node$specifiers[_i4]; + this.checkDuplicateExports(specifier, specifier.exported.name); + + if (!isFrom && specifier.local) { + this.checkReservedWord(specifier.local.name, specifier.local.start, true, false); + this.scope.checkLocalExport(specifier.local); + } + } + } else if (node.declaration) { + if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { + const id = node.declaration.id; + if (!id) throw new Error("Assertion failure"); + this.checkDuplicateExports(node, id.name); + } else if (node.declaration.type === "VariableDeclaration") { + for (let _i5 = 0, _node$declaration$dec = node.declaration.declarations; _i5 < _node$declaration$dec.length; _i5++) { + const declaration = _node$declaration$dec[_i5]; + this.checkDeclaration(declaration.id); + } + } + } + } + + const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + if (currentContextDecorators.length) { + const isClass = node.declaration && (node.declaration.type === "ClassDeclaration" || node.declaration.type === "ClassExpression"); + + if (!node.declaration || !isClass) { + throw this.raise(node.start, ErrorMessages$1.UnsupportedDecoratorExport); + } + + this.takeDecorators(node.declaration); + } + } + + checkDeclaration(node) { + if (node.type === "Identifier") { + this.checkDuplicateExports(node, node.name); + } else if (node.type === "ObjectPattern") { + for (let _i6 = 0, _node$properties = node.properties; _i6 < _node$properties.length; _i6++) { + const prop = _node$properties[_i6]; + this.checkDeclaration(prop); + } + } else if (node.type === "ArrayPattern") { + for (let _i7 = 0, _node$elements = node.elements; _i7 < _node$elements.length; _i7++) { + const elem = _node$elements[_i7]; + + if (elem) { + this.checkDeclaration(elem); + } + } + } else if (node.type === "ObjectProperty") { + this.checkDeclaration(node.value); + } else if (node.type === "RestElement") { + this.checkDeclaration(node.argument); + } else if (node.type === "AssignmentPattern") { + this.checkDeclaration(node.left); + } + } + + checkDuplicateExports(node, name) { + if (this.state.exportedIdentifiers.indexOf(name) > -1) { + this.raise(node.start, name === "default" ? ErrorMessages$1.DuplicateDefaultExport : ErrorMessages$1.DuplicateExport, name); + } + + this.state.exportedIdentifiers.push(name); + } + + parseExportSpecifiers() { + const nodes = []; + let first = true; + this.expect(types$4.braceL); + + while (!this.eat(types$4.braceR)) { + if (first) { + first = false; + } else { + this.expect(types$4.comma); + if (this.eat(types$4.braceR)) break; + } + + const node = this.startNode(); + node.local = this.parseIdentifier(true); + node.exported = this.eatContextual("as") ? this.parseIdentifier(true) : node.local.__clone(); + nodes.push(this.finishNode(node, "ExportSpecifier")); + } + + return nodes; + } + + parseImport(node) { + node.specifiers = []; + + if (!this.match(types$4.string)) { + const hasDefault = this.maybeParseDefaultImportSpecifier(node); + const parseNext = !hasDefault || this.eat(types$4.comma); + const hasStar = parseNext && this.maybeParseStarImportSpecifier(node); + if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node); + this.expectContextual("from"); + } + + node.source = this.parseImportSource(); + const attributes = this.maybeParseModuleAttributes(); + + if (attributes) { + node.attributes = attributes; + } + + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportSource() { + if (!this.match(types$4.string)) this.unexpected(); + return this.parseExprAtom(); + } + + shouldParseDefaultImport(node) { + return this.match(types$4.name); + } + + parseImportSpecifierLocal(node, specifier, type, contextDescription) { + specifier.local = this.parseIdentifier(); + this.checkLVal(specifier.local, BIND_LEXICAL$1, undefined, contextDescription); + node.specifiers.push(this.finishNode(specifier, type)); + } + + maybeParseModuleAttributes() { + if (this.match(types$4._with) && !this.hasPrecedingLineBreak()) { + this.expectPlugin("moduleAttributes"); + this.next(); + } else { + if (this.hasPlugin("moduleAttributes")) return []; + return null; + } + + const attrs = []; + const attributes = new Set(); + + do { + const node = this.startNode(); + node.key = this.parseIdentifier(true); + + if (node.key.name !== "type") { + this.raise(node.key.start, ErrorMessages$1.ModuleAttributeDifferentFromType, node.key.name); + } + + if (attributes.has(node.key.name)) { + this.raise(node.key.start, ErrorMessages$1.ModuleAttributesWithDuplicateKeys, node.key.name); + } + + attributes.add(node.key.name); + this.expect(types$4.colon); + + if (!this.match(types$4.string)) { + throw this.unexpected(this.state.start, ErrorMessages$1.ModuleAttributeInvalidValue); + } + + node.value = this.parseLiteral(this.state.value, "StringLiteral"); + this.finishNode(node, "ImportAttribute"); + attrs.push(node); + } while (this.eat(types$4.comma)); + + return attrs; + } + + maybeParseDefaultImportSpecifier(node) { + if (this.shouldParseDefaultImport(node)) { + this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier", "default import specifier"); + return true; + } + + return false; + } + + maybeParseStarImportSpecifier(node) { + if (this.match(types$4.star)) { + const specifier = this.startNode(); + this.next(); + this.expectContextual("as"); + this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier", "import namespace specifier"); + return true; + } + + return false; + } + + parseNamedImportSpecifiers(node) { + let first = true; + this.expect(types$4.braceL); + + while (!this.eat(types$4.braceR)) { + if (first) { + first = false; + } else { + if (this.eat(types$4.colon)) { + throw this.raise(this.state.start, ErrorMessages$1.DestructureNamedImport); + } + + this.expect(types$4.comma); + if (this.eat(types$4.braceR)) break; + } + + this.parseImportSpecifier(node); + } + } + + parseImportSpecifier(node) { + const specifier = this.startNode(); + specifier.imported = this.parseIdentifier(true); + + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + this.checkReservedWord(specifier.imported.name, specifier.start, true, true); + specifier.local = specifier.imported.__clone(); + } + + this.checkLVal(specifier.local, BIND_LEXICAL$1, undefined, "import specifier"); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + } + + }; + + let ClassScope$1 = class ClassScope { + constructor() { + this.privateNames = new Set(); + this.loneAccessors = new Map(); + this.undefinedPrivateNames = new Map(); + } + + }; + let ClassScopeHandler$1 = class ClassScopeHandler { + constructor(raise) { + this.stack = []; + this.undefinedPrivateNames = new Map(); + this.raise = raise; + } + + current() { + return this.stack[this.stack.length - 1]; + } + + enter() { + this.stack.push(new ClassScope$1()); + } + + exit() { + const oldClassScope = this.stack.pop(); + const current = this.current(); + + for (let _i = 0, _Array$from = Array.from(oldClassScope.undefinedPrivateNames); _i < _Array$from.length; _i++) { + const [name, pos] = _Array$from[_i]; + + if (current) { + if (!current.undefinedPrivateNames.has(name)) { + current.undefinedPrivateNames.set(name, pos); + } + } else { + this.raise(pos, ErrorMessages$1.InvalidPrivateFieldResolution, name); + } + } + } + + declarePrivateName(name, elementType, pos) { + const classScope = this.current(); + let redefined = classScope.privateNames.has(name); + + if (elementType & CLASS_ELEMENT_KIND_ACCESSOR$1) { + const accessor = redefined && classScope.loneAccessors.get(name); + + if (accessor) { + const oldStatic = accessor & CLASS_ELEMENT_FLAG_STATIC$1; + const newStatic = elementType & CLASS_ELEMENT_FLAG_STATIC$1; + const oldKind = accessor & CLASS_ELEMENT_KIND_ACCESSOR$1; + const newKind = elementType & CLASS_ELEMENT_KIND_ACCESSOR$1; + redefined = oldKind === newKind || oldStatic !== newStatic; + if (!redefined) classScope.loneAccessors.delete(name); + } else if (!redefined) { + classScope.loneAccessors.set(name, elementType); + } + } + + if (redefined) { + this.raise(pos, ErrorMessages$1.PrivateNameRedeclaration, name); + } + + classScope.privateNames.add(name); + classScope.undefinedPrivateNames.delete(name); + } + + usePrivateName(name, pos) { + let classScope; + + for (let _i2 = 0, _this$stack = this.stack; _i2 < _this$stack.length; _i2++) { + classScope = _this$stack[_i2]; + if (classScope.privateNames.has(name)) return; + } + + if (classScope) { + classScope.undefinedPrivateNames.set(name, pos); + } else { + this.raise(pos, ErrorMessages$1.InvalidPrivateFieldResolution, name); + } + } + + }; + + let Parser$1 = class Parser extends StatementParser$1 { + constructor(options, input) { + options = getOptions$1(options); + super(options, input); + const ScopeHandler = this.getScopeHandler(); + this.options = options; + this.inModule = this.options.sourceType === "module"; + this.scope = new ScopeHandler(this.raise.bind(this), this.inModule); + this.prodParam = new ProductionParameterHandler$1(); + this.classScope = new ClassScopeHandler$1(this.raise.bind(this)); + this.plugins = pluginsMap$1(this.options.plugins); + this.filename = options.sourceFilename; + } + + getScopeHandler() { + return ScopeHandler$1; + } + + parse() { + let paramFlags = PARAM$1; + + if (this.hasPlugin("topLevelAwait") && this.inModule) { + paramFlags |= PARAM_AWAIT$1; + } + + this.scope.enter(SCOPE_PROGRAM$1); + this.prodParam.enter(paramFlags); + const file = this.startNode(); + const program = this.startNode(); + this.nextToken(); + file.errors = null; + this.parseTopLevel(file, program); + file.errors = this.state.errors; + return file; + } + + }; + + function pluginsMap$1(plugins) { + const pluginMap = new Map(); + + for (let _i = 0; _i < plugins.length; _i++) { + const plugin = plugins[_i]; + const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}]; + if (!pluginMap.has(name)) pluginMap.set(name, options || {}); + } + + return pluginMap; + } + + function parse$2(input, options) { + var _options; + + if (((_options = options) == null ? void 0 : _options.sourceType) === "unambiguous") { + options = Object.assign({}, options); + + try { + options.sourceType = "module"; + const parser = getParser$1(options, input); + const ast = parser.parse(); + + if (parser.sawUnambiguousESM) { + return ast; + } + + if (parser.ambiguousScriptDifferentAst) { + try { + options.sourceType = "script"; + return getParser$1(options, input).parse(); + } catch (_unused) {} + } else { + ast.program.sourceType = "script"; + } + + return ast; + } catch (moduleError) { + try { + options.sourceType = "script"; + return getParser$1(options, input).parse(); + } catch (_unused2) {} + + throw moduleError; + } + } else { + return getParser$1(options, input).parse(); + } + } + function parseExpression$1(input, options) { + const parser = getParser$1(options, input); + + if (parser.options.strictMode) { + parser.state.strict = true; + } + + return parser.getExpression(); + } + + function getParser$1(options, input) { + let cls = Parser$1; + + if (options == null ? void 0 : options.plugins) { + validatePlugins$1(options.plugins); + cls = getParserClass$1(options.plugins); + } + + return new cls(options, input); + } + + const parserClassCache$1 = {}; + + function getParserClass$1(pluginsFromOptions) { + const pluginList = mixinPluginNames$1.filter(name => hasPlugin$1(pluginsFromOptions, name)); + const key = pluginList.join("/"); + let cls = parserClassCache$1[key]; + + if (!cls) { + cls = Parser$1; + + for (let _i = 0; _i < pluginList.length; _i++) { + const plugin = pluginList[_i]; + cls = mixinPlugins$1[plugin](cls); + } + + parserClassCache$1[key] = cls; + } + + return cls; + } + + lib$2.parse = parse$2; + lib$2.parseExpression = parseExpression$1; + lib$2.tokTypes = types$4; + + var customParse = {}; + + var parseScriptFragment = {}; + + Object.defineProperty(parseScriptFragment, "__esModule", { + value: true + }); + + var alphanum = /[a-z0-9\-]/i; + + function parseToken(str, start) { + var i = start; + while (i < str.length && alphanum.test(str.charAt(i++))) { + continue; + } + + if (i !== start) { + return { + token: str.substring(start, i - 1), + index: i + }; + } + + return null; + } + + function parseAttributes(str, start) { + var i = start; + var attributes = {}; + var attribute = null; + + while (i < str.length) { + var c = str.charAt(i); + + if (attribute === null && c == ">") { + break; + } else if (attribute === null && alphanum.test(c)) { + attribute = { + name: null, + value: true, + bool: true, + terminator: null + }; + + var attributeNameNode = parseToken(str, i); + if (attributeNameNode) { + attribute.name = attributeNameNode.token; + i = attributeNameNode.index - 2; + } + } else if (attribute !== null) { + if (c === "=") { + // once we've started an attribute, look for = to indicate + // it's a non-boolean attribute + attribute.bool = false; + if (attribute.value === true) { + attribute.value = ""; + } + } else if (!attribute.bool && attribute.terminator === null && (c === '"' || c === "'")) { + // once we've determined it's non-boolean, look for a + // value terminator (", ') + attribute.terminator = c; + } else if (attribute.terminator) { + if (c === attribute.terminator) { + // if we had a terminator and found another, we've + // reach the end of the attribute + attributes[attribute.name] = attribute.value; + attribute = null; + } else { + // otherwise, append the character to the attribute value + attribute.value += c; + + // check for an escaped terminator and push it as well + // to avoid terminating prematurely + if (c === "\\") { + var next = str.charAt(i + 1); + if (next === attribute.terminator) { + attribute.value += next; + i += 1; + } + } + } + } else if (!/\s/.test(c)) { + // if we've hit a non-space character and aren't processing a value, + // we're starting a new attribute so push the attribute and clear the + // local variable + attributes[attribute.name] = attribute.value; + attribute = null; + + // move the cursor back to re-find the start of the attribute + i -= 1; + } + } + + i++; + } + + if (i !== start) { + return { + attributes: attributes, + index: i + }; + } + + return null; + } + + function parseFragment(str) { + var start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + + var tag = null; + var open = false; + var attributes = {}; + + var i = start; + while (i < str.length) { + var c = str.charAt(i++); + + if (!open && !tag && c === "<") { + // Open Start Tag + open = true; + + var tagNode = parseToken(str, i); + if (!tagNode) { + return null; + } + + i = tagNode.index - 1; + tag = tagNode.token; + } else if (open && c === ">") { + // Close Start Tag + break; + } else if (open) { + // Attributes + var attributeNode = parseAttributes(str, i - 1); + + if (attributeNode) { + i = attributeNode.index; + attributes = attributeNode.attributes || attributes; + } + } + } + + if (tag) { + return { + tag: tag, + attributes: attributes + }; + } + + return null; + } + + parseScriptFragment.default = parseFragment; + parseScriptFragment.parseFragment = parseFragment; + + Object.defineProperty(customParse, "__esModule", { + value: true + }); + customParse.parseScriptTags = customParse.parseScripts = customParse.getCandidateScriptLocations = customParse.generateWhitespace = undefined; + + var _types$1 = lib$4; + + var types$3 = _interopRequireWildcard$1(_types$1); + + var _parseScriptFragment = parseScriptFragment; + + var _parseScriptFragment2 = _interopRequireDefault(_parseScriptFragment); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function _interopRequireWildcard$1(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + + var startScript = /]*>/im; + var endScript = /<\/script\s*>/im; + // https://stackoverflow.com/questions/5034781/js-regex-to-split-by-line#comment5633979_5035005 + var newLines = /\r\n|[\n\v\f\r\x85\u2028\u2029]/; + + function getType(tag) { + var fragment = (0, _parseScriptFragment2.default)(tag); + + if (fragment) { + var type = fragment.attributes.type; + + return type ? type.toLowerCase() : null; + } + + return null; + } + + function getCandidateScriptLocations(source, index) { + var i = index || 0; + var str = source.substring(i); + + var startMatch = startScript.exec(str); + if (startMatch) { + var startsAt = startMatch.index + startMatch[0].length; + var afterStart = str.substring(startsAt); + var endMatch = endScript.exec(afterStart); + if (endMatch) { + var locLength = endMatch.index; + var locIndex = i + startsAt; + var endIndex = locIndex + locLength + endMatch[0].length; + + // extract the complete tag (incl start and end tags and content). if the + // type is invalid (= not JS), skip this tag and continue + var tag = source.substring(i + startMatch.index, endIndex); + var type = getType(tag); + if (type && type !== "javascript" && type !== "text/javascript") { + return getCandidateScriptLocations(source, endIndex); + } + + return [adjustForLineAndColumn(source, { + index: locIndex, + length: locLength, + source: source.substring(locIndex, locIndex + locLength) + })].concat(_toConsumableArray(getCandidateScriptLocations(source, endIndex))); + } + } + + return []; + } + + function parseScripts$1(locations, parser) { + return locations.map(parser); + } + + function generateWhitespace(length) { + return Array.from(new Array(length + 1)).join(" "); + } + + function calcLineAndColumn(source, index) { + var lines = source.substring(0, index).split(newLines); + var line = lines.length; + var column = lines.pop().length + 1; + + return { + column: column, + line: line + }; + } + + function adjustForLineAndColumn(fullSource, location) { + var _calcLineAndColumn = calcLineAndColumn(fullSource, location.index), + column = _calcLineAndColumn.column, + line = _calcLineAndColumn.line; + + return Object.assign({}, location, { + line: line, + column: column, + // prepend whitespace for scripts that do not start on the first column + source: generateWhitespace(column) + location.source + }); + } + + function parseScriptTags$1(source, parser) { + var scripts = parseScripts$1(getCandidateScriptLocations(source), parser).filter(types$3.isFile).reduce(function (main, script) { + return { + statements: main.statements.concat(script.program.body), + comments: main.comments.concat(script.comments), + tokens: main.tokens.concat(script.tokens) + }; + }, { + statements: [], + comments: [], + tokens: [] + }); + + var program = types$3.program(scripts.statements); + var file = types$3.file(program, scripts.comments, scripts.tokens); + + var end = calcLineAndColumn(source, source.length); + file.start = program.start = 0; + file.end = program.end = source.length; + file.loc = program.loc = { + start: { + line: 1, + column: 0 + }, + end: end + }; + + return file; + } + + customParse.default = parseScriptTags$1; + customParse.generateWhitespace = generateWhitespace; + customParse.getCandidateScriptLocations = getCandidateScriptLocations; + customParse.parseScripts = parseScripts$1; + customParse.parseScriptTags = parseScriptTags$1; + + Object.defineProperty(dist, "__esModule", { + value: true + }); + dist.parseScriptTags = dist.parseScripts = dist.parseScript = dist.getCandidateScriptLocations = dist.generateWhitespace = dist.extractScriptTags = undefined; + + var _types = lib$4; + + var types$2 = _interopRequireWildcard(_types); + + var _parser = lib$2; + + var parser = _interopRequireWildcard(_parser); + + var _customParse = customParse; + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } + + function parseScript$1(_ref) { + var source = _ref.source, + line = _ref.line; + + // remove empty or only whitespace scripts + if (source.length === 0 || /^\s+$/.test(source)) { + return null; + } + + try { + return parser.parse(source, { + sourceType: "script", + startLine: line + }); + } catch (e) { + return null; + } + } + + function parseScripts(locations) { + var parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : parseScript$1; + + return (0, _customParse.parseScripts)(locations, parser); + } + + function extractScriptTags(source) { + return parseScripts((0, _customParse.getCandidateScriptLocations)(source), function (loc) { + var ast = parseScript$1(loc); + + if (ast) { + return loc; + } + + return null; + }).filter(types$2.isFile); + } + + function parseScriptTags(source) { + var parser = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : parseScript$1; + + return (0, _customParse.parseScriptTags)(source, parser); + } + + var _default$2 = dist.default = parseScriptTags; + dist.extractScriptTags = extractScriptTags; + dist.generateWhitespace = _customParse.generateWhitespace; + dist.getCandidateScriptLocations = _customParse.getCandidateScriptLocations; + dist.parseScript = parseScript$1; + dist.parseScripts = parseScripts; + dist.parseScriptTags = parseScriptTags; + + var lib$1 = {}; + + Object.defineProperty(lib$1, '__esModule', { value: true }); + + const lineBreak = /\r\n?|[\n\u2028\u2029]/; + const lineBreakG = new RegExp(lineBreak.source, "g"); + function isNewLine(code) { + switch (code) { + case 10: + case 13: + case 8232: + case 8233: + return true; + + default: + return false; + } + } + const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + const skipWhiteSpaceInLine = /(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/y; + const skipWhiteSpaceToLineBreak = new RegExp("(?=(" + skipWhiteSpaceInLine.source + "))\\1" + /(?=[\n\r\u2028\u2029]|\/\*(?!.*?\*\/)|$)/.source, "y"); + function isWhitespace(code) { + switch (code) { + case 0x0009: + case 0x000b: + case 0x000c: + case 32: + case 160: + case 5760: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200a: + case 0x202f: + case 0x205f: + case 0x3000: + case 0xfeff: + return true; + + default: + return false; + } + } + + class Position { + constructor(line, col) { + this.line = void 0; + this.column = void 0; + this.line = line; + this.column = col; + } + + } + class SourceLocation { + constructor(start, end) { + this.start = void 0; + this.end = void 0; + this.filename = void 0; + this.identifierName = void 0; + this.start = start; + this.end = end; + } + + } + function getLineInfo(input, offset) { + let line = 1; + let lineStart = 0; + let match; + lineBreakG.lastIndex = 0; + + while ((match = lineBreakG.exec(input)) && match.index < offset) { + line++; + lineStart = lineBreakG.lastIndex; + } + + return new Position(line, offset - lineStart); + } + + class BaseParser { + constructor() { + this.sawUnambiguousESM = false; + this.ambiguousScriptDifferentAst = false; + } + + hasPlugin(name) { + return this.plugins.has(name); + } + + getPluginOption(plugin, name) { + if (this.hasPlugin(plugin)) return this.plugins.get(plugin)[name]; + } + + } + + function setTrailingComments(node, comments) { + if (node.trailingComments === undefined) { + node.trailingComments = comments; + } else { + node.trailingComments.unshift(...comments); + } + } + + function setInnerComments(node, comments) { + if (node.innerComments === undefined) { + node.innerComments = comments; + } else if (comments !== undefined) { + node.innerComments.unshift(...comments); + } + } + + function adjustInnerComments(node, elements, commentWS) { + let lastElement = null; + let i = elements.length; + + while (lastElement === null && i > 0) { + lastElement = elements[--i]; + } + + if (lastElement === null || lastElement.start > commentWS.start) { + setInnerComments(node, commentWS.comments); + } else { + setTrailingComments(lastElement, commentWS.comments); + } + } + + class CommentsParser extends BaseParser { + addComment(comment) { + if (this.filename) comment.loc.filename = this.filename; + this.state.comments.push(comment); + } + + processComment(node) { + const { + commentStack + } = this.state; + const commentStackLength = commentStack.length; + if (commentStackLength === 0) return; + let i = commentStackLength - 1; + const lastCommentWS = commentStack[i]; + + if (lastCommentWS.start === node.end) { + lastCommentWS.leadingNode = node; + i--; + } + + const { + start: nodeStart + } = node; + + for (; i >= 0; i--) { + const commentWS = commentStack[i]; + const commentEnd = commentWS.end; + + if (commentEnd > nodeStart) { + commentWS.containingNode = node; + this.finalizeComment(commentWS); + commentStack.splice(i, 1); + } else { + if (commentEnd === nodeStart) { + commentWS.trailingNode = node; + } + + break; + } + } + } + + finalizeComment(commentWS) { + const { + comments + } = commentWS; + + if (commentWS.leadingNode !== null || commentWS.trailingNode !== null) { + if (commentWS.leadingNode !== null) { + setTrailingComments(commentWS.leadingNode, comments); + } + + if (commentWS.trailingNode !== null) { + commentWS.trailingNode.leadingComments = comments; + } + } else { + const { + containingNode: node, + start: commentStart + } = commentWS; + + if (this.input.charCodeAt(commentStart - 1) === 44) { + switch (node.type) { + case "ObjectExpression": + case "ObjectPattern": + case "RecordExpression": + adjustInnerComments(node, node.properties, commentWS); + break; + + case "CallExpression": + case "OptionalCallExpression": + adjustInnerComments(node, node.arguments, commentWS); + break; + + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + case "ObjectMethod": + case "ClassMethod": + case "ClassPrivateMethod": + adjustInnerComments(node, node.params, commentWS); + break; + + case "ArrayExpression": + case "ArrayPattern": + case "TupleExpression": + adjustInnerComments(node, node.elements, commentWS); + break; + + case "ExportNamedDeclaration": + case "ImportDeclaration": + adjustInnerComments(node, node.specifiers, commentWS); + break; + + default: + { + setInnerComments(node, comments); + } + } + } else { + setInnerComments(node, comments); + } + } + } + + finalizeRemainingComments() { + const { + commentStack + } = this.state; + + for (let i = commentStack.length - 1; i >= 0; i--) { + this.finalizeComment(commentStack[i]); + } + + this.state.commentStack = []; + } + + resetPreviousNodeTrailingComments(node) { + const { + commentStack + } = this.state; + const { + length + } = commentStack; + if (length === 0) return; + const commentWS = commentStack[length - 1]; + + if (commentWS.leadingNode === node) { + commentWS.leadingNode = null; + } + } + + } + + const ErrorCodes = Object.freeze({ + SyntaxError: "BABEL_PARSER_SYNTAX_ERROR", + SourceTypeModuleError: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" + }); + + const ErrorMessages = makeErrorTemplates({ + AccessorIsGenerator: "A %0ter cannot be a generator.", + ArgumentsInClass: "'arguments' is only allowed in functions and class methods.", + AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block.", + AwaitBindingIdentifier: "Can not use 'await' as identifier inside an async function.", + AwaitBindingIdentifierInStaticBlock: "Can not use 'await' as identifier inside a static block.", + AwaitExpressionFormalParameter: "'await' is not allowed in async function parameters.", + AwaitNotInAsyncContext: "'await' is only allowed within async functions and at the top levels of modules.", + AwaitNotInAsyncFunction: "'await' is only allowed within async functions.", + BadGetterArity: "A 'get' accesor must not have any formal parameters.", + BadSetterArity: "A 'set' accesor must have exactly one formal parameter.", + BadSetterRestParameter: "A 'set' accesor function argument must not be a rest parameter.", + ConstructorClassField: "Classes may not have a field named 'constructor'.", + ConstructorClassPrivateField: "Classes may not have a private field named '#constructor'.", + ConstructorIsAccessor: "Class constructor may not be an accessor.", + ConstructorIsAsync: "Constructor can't be an async function.", + ConstructorIsGenerator: "Constructor can't be a generator.", + DeclarationMissingInitializer: "'%0' require an initialization value.", + DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax.", + DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?", + DecoratorExportClass: "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.", + DecoratorSemicolon: "Decorators must not be followed by a semicolon.", + DecoratorStaticBlock: "Decorators can't be used with a static block.", + DeletePrivateField: "Deleting a private field is not allowed.", + DestructureNamedImport: "ES2015 named imports do not destructure. Use another statement for destructuring after the import.", + DuplicateConstructor: "Duplicate constructor in the same class.", + DuplicateDefaultExport: "Only one default export allowed per module.", + DuplicateExport: "`%0` has already been exported. Exported identifiers must be unique.", + DuplicateProto: "Redefinition of __proto__ property.", + DuplicateRegExpFlags: "Duplicate regular expression flag.", + ElementAfterRest: "Rest element must be last element.", + EscapedCharNotAnIdentifier: "Invalid Unicode escape.", + ExportBindingIsString: "A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { '%0' as '%1' } from 'some-module'`?", + ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'.", + ForInOfLoopInitializer: "'%0' loop variable declaration may not have an initializer.", + ForOfAsync: "The left-hand side of a for-of loop may not be 'async'.", + ForOfLet: "The left-hand side of a for-of loop may not start with 'let'.", + GeneratorInSingleStatementContext: "Generators can only be declared at the top level or inside a block.", + IllegalBreakContinue: "Unsyntactic %0.", + IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list.", + IllegalReturn: "'return' outside of function.", + ImportBindingIsString: 'A string literal cannot be used as an imported binding.\n- Did you mean `import { "%0" as foo }`?', + ImportCallArgumentTrailingComma: "Trailing comma is disallowed inside import(...) arguments.", + ImportCallArity: "`import()` requires exactly %0.", + ImportCallNotNewExpression: "Cannot use new with import(...).", + ImportCallSpreadArgument: "`...` is not allowed in `import()`.", + InvalidBigIntLiteral: "Invalid BigIntLiteral.", + InvalidCodePoint: "Code point out of bounds.", + InvalidDecimal: "Invalid decimal.", + InvalidDigit: "Expected number in radix %0.", + InvalidEscapeSequence: "Bad character escape sequence.", + InvalidEscapeSequenceTemplate: "Invalid escape sequence in template.", + InvalidEscapedReservedWord: "Escape sequence in keyword %0.", + InvalidIdentifier: "Invalid identifier %0.", + InvalidLhs: "Invalid left-hand side in %0.", + InvalidLhsBinding: "Binding invalid left-hand side in %0.", + InvalidNumber: "Invalid number.", + InvalidOrMissingExponent: "Floating-point numbers require a valid exponent after the 'e'.", + InvalidOrUnexpectedToken: "Unexpected character '%0'.", + InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern.", + InvalidPrivateFieldResolution: "Private name #%0 is not defined.", + InvalidPropertyBindingPattern: "Binding member expression.", + InvalidRecordProperty: "Only properties and spread elements are allowed in record definitions.", + InvalidRestAssignmentPattern: "Invalid rest operator's argument.", + LabelRedeclaration: "Label '%0' is already declared.", + LetInLexicalBinding: "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", + LineTerminatorBeforeArrow: "No line break is allowed before '=>'.", + MalformedRegExpFlags: "Invalid regular expression flag.", + MissingClassName: "A class name is required.", + MissingEqInAssignment: "Only '=' operator can be used for specifying default value.", + MissingSemicolon: "Missing semicolon.", + MissingUnicodeEscape: "Expecting Unicode escape sequence \\uXXXX.", + MixingCoalesceWithLogical: "Nullish coalescing operator(??) requires parens when mixing with logical operators.", + ModuleAttributeDifferentFromType: "The only accepted module attribute is `type`.", + ModuleAttributeInvalidValue: "Only string literals are allowed as module attribute values.", + ModuleAttributesWithDuplicateKeys: 'Duplicate key "%0" is not allowed in module attributes.', + ModuleExportNameHasLoneSurrogate: "An export name cannot include a lone surrogate, found '\\u%0'.", + ModuleExportUndefined: "Export '%0' is not defined.", + MultipleDefaultsInSwitch: "Multiple default clauses.", + NewlineAfterThrow: "Illegal newline after throw.", + NoCatchOrFinally: "Missing catch or finally clause.", + NumberIdentifier: "Identifier directly after number.", + NumericSeparatorInEscapeSequence: "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences.", + ObsoleteAwaitStar: "'await*' has been removed from the async functions proposal. Use Promise.all() instead.", + OptionalChainingNoNew: "Constructors in/after an Optional Chain are not allowed.", + OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain.", + OverrideOnConstructor: "'override' modifier cannot appear on a constructor declaration.", + ParamDupe: "Argument name clash.", + PatternHasAccessor: "Object pattern can't contain getter or setter.", + PatternHasMethod: "Object pattern can't contain methods.", + PipeBodyIsTighter: "Unexpected %0 after pipeline body; any %0 expression acting as Hack-style pipe body must be parenthesized due to its loose operator precedence.", + PipeTopicRequiresHackPipes: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.', + PipeTopicUnbound: "Topic reference is unbound; it must be inside a pipe body.", + PipeTopicUnconfiguredToken: 'Invalid topic token %0. In order to use %0 as a topic reference, the pipelineOperator plugin must be configured with { "proposal": "hack", "topicToken": "%0" }.', + PipeTopicUnused: "Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once.", + PipeUnparenthesizedBody: "Hack-style pipe body cannot be an unparenthesized %0 expression; please wrap it in parentheses.", + PipelineBodyNoArrow: 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized.', + PipelineBodySequenceExpression: "Pipeline body may not be a comma-separated sequence expression.", + PipelineHeadSequenceExpression: "Pipeline head should not be a comma-separated sequence expression.", + PipelineTopicUnused: "Pipeline is in topic style but does not use topic reference.", + PrimaryTopicNotAllowed: "Topic reference was used in a lexical context without topic binding.", + PrimaryTopicRequiresSmartPipeline: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.', + PrivateInExpectedIn: "Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`).", + PrivateNameRedeclaration: "Duplicate private name #%0.", + RecordExpressionBarIncorrectEndSyntaxType: "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", + RecordExpressionBarIncorrectStartSyntaxType: "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", + RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.", + RecordNoProto: "'__proto__' is not allowed in Record expressions.", + RestTrailingComma: "Unexpected trailing comma after rest element.", + SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement.", + StaticPrototype: "Classes may not have static property named prototype.", + StrictDelete: "Deleting local variable in strict mode.", + StrictEvalArguments: "Assigning to '%0' in strict mode.", + StrictEvalArgumentsBinding: "Binding '%0' in strict mode.", + StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block.", + StrictNumericEscape: "The only valid numeric escape in strict mode is '\\0'.", + StrictOctalLiteral: "Legacy octal literals are not allowed in strict mode.", + StrictWith: "'with' in strict mode.", + SuperNotAllowed: "`super()` is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?", + SuperPrivateField: "Private fields can't be accessed on super.", + TrailingDecorator: "Decorators must be attached to a class element.", + TupleExpressionBarIncorrectEndSyntaxType: "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", + TupleExpressionBarIncorrectStartSyntaxType: "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", + TupleExpressionHashIncorrectStartSyntaxType: "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.", + UnexpectedArgumentPlaceholder: "Unexpected argument placeholder.", + UnexpectedAwaitAfterPipelineBody: 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal.', + UnexpectedDigitAfterHash: "Unexpected digit after hash token.", + UnexpectedImportExport: "'import' and 'export' may only appear at the top level.", + UnexpectedKeyword: "Unexpected keyword '%0'.", + UnexpectedLeadingDecorator: "Leading decorators must be attached to a class declaration.", + UnexpectedLexicalDeclaration: "Lexical declaration cannot appear in a single-statement context.", + UnexpectedNewTarget: "`new.target` can only be used in functions or class properties.", + UnexpectedNumericSeparator: "A numeric separator is only allowed between two digits.", + UnexpectedPrivateField: "Private names can only be used as the name of a class element (i.e. class C { #p = 42; #m() {} } )\n or a property of member expression (i.e. this.#p).", + UnexpectedReservedWord: "Unexpected reserved word '%0'.", + UnexpectedSuper: "'super' is only allowed in object methods and classes.", + UnexpectedToken: "Unexpected token '%0'.", + UnexpectedTokenUnaryExponentiation: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.", + UnsupportedBind: "Binding should be performed on object property.", + UnsupportedDecoratorExport: "A decorated export must export a class declaration.", + UnsupportedDefaultExport: "Only expressions, functions or classes are allowed as the `default` export.", + UnsupportedImport: "`import` can only be used in `import()` or `import.meta`.", + UnsupportedMetaProperty: "The only valid meta property for %0 is %0.%1.", + UnsupportedParameterDecorator: "Decorators cannot be used to decorate parameters.", + UnsupportedPropertyDecorator: "Decorators cannot be used to decorate object literal properties.", + UnsupportedSuper: "'super' can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop]).", + UnterminatedComment: "Unterminated comment.", + UnterminatedRegExp: "Unterminated regular expression.", + UnterminatedString: "Unterminated string constant.", + UnterminatedTemplate: "Unterminated template.", + VarRedeclaration: "Identifier '%0' has already been declared.", + YieldBindingIdentifier: "Can not use 'yield' as identifier inside a generator.", + YieldInParameter: "Yield expression is not allowed in formal parameters.", + ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0." + }, ErrorCodes.SyntaxError); + const SourceTypeModuleErrorMessages = makeErrorTemplates({ + ImportMetaOutsideModule: `import.meta may appear only with 'sourceType: "module"'`, + ImportOutsideModule: `'import' and 'export' may appear only with 'sourceType: "module"'` + }, ErrorCodes.SourceTypeModuleError); + + function keepReasonCodeCompat(reasonCode, syntaxPlugin) { + { + if (syntaxPlugin === "flow" && reasonCode === "PatternIsOptional") { + return "OptionalBindingPattern"; + } + } + return reasonCode; + } + + function makeErrorTemplates(messages, code, syntaxPlugin) { + const templates = {}; + Object.keys(messages).forEach(reasonCode => { + templates[reasonCode] = Object.freeze({ + code, + reasonCode: keepReasonCodeCompat(reasonCode, syntaxPlugin), + template: messages[reasonCode] + }); + }); + return Object.freeze(templates); + } + class ParserError extends CommentsParser { + getLocationForPosition(pos) { + let loc; + if (pos === this.state.start) loc = this.state.startLoc;else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc;else if (pos === this.state.end) loc = this.state.endLoc;else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc;else loc = getLineInfo(this.input, pos); + return loc; + } + + raise(pos, { + code, + reasonCode, + template + }, ...params) { + return this.raiseWithData(pos, { + code, + reasonCode + }, template, ...params); + } + + raiseOverwrite(pos, { + code, + template + }, ...params) { + const loc = this.getLocationForPosition(pos); + const message = template.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`; + + if (this.options.errorRecovery) { + const errors = this.state.errors; + + for (let i = errors.length - 1; i >= 0; i--) { + const error = errors[i]; + + if (error.pos === pos) { + return Object.assign(error, { + message + }); + } else if (error.pos < pos) { + break; + } + } + } + + return this._raise({ + code, + loc, + pos + }, message); + } + + raiseWithData(pos, data, errorTemplate, ...params) { + const loc = this.getLocationForPosition(pos); + const message = errorTemplate.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`; + return this._raise(Object.assign({ + loc, + pos + }, data), message); + } + + _raise(errorContext, message) { + const err = new SyntaxError(message); + Object.assign(err, errorContext); + + if (this.options.errorRecovery) { + if (!this.isLookahead) this.state.errors.push(err); + return err; + } else { + throw err; + } + } + + } + + var estree = (superClass => class extends superClass { + parseRegExpLiteral({ + pattern, + flags + }) { + let regex = null; + + try { + regex = new RegExp(pattern, flags); + } catch (e) {} + + const node = this.estreeParseLiteral(regex); + node.regex = { + pattern, + flags + }; + return node; + } + + parseBigIntLiteral(value) { + let bigInt; + + try { + bigInt = BigInt(value); + } catch (_unused) { + bigInt = null; + } + + const node = this.estreeParseLiteral(bigInt); + node.bigint = String(node.value || value); + return node; + } + + parseDecimalLiteral(value) { + const decimal = null; + const node = this.estreeParseLiteral(decimal); + node.decimal = String(node.value || value); + return node; + } + + estreeParseLiteral(value) { + return this.parseLiteral(value, "Literal"); + } + + parseStringLiteral(value) { + return this.estreeParseLiteral(value); + } + + parseNumericLiteral(value) { + return this.estreeParseLiteral(value); + } + + parseNullLiteral() { + return this.estreeParseLiteral(null); + } + + parseBooleanLiteral(value) { + return this.estreeParseLiteral(value); + } + + directiveToStmt(directive) { + const directiveLiteral = directive.value; + const stmt = this.startNodeAt(directive.start, directive.loc.start); + const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); + expression.value = directiveLiteral.extra.expressionValue; + expression.raw = directiveLiteral.extra.raw; + stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); + stmt.directive = directiveLiteral.extra.raw.slice(1, -1); + return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); + } + + initFunction(node, isAsync) { + super.initFunction(node, isAsync); + node.expression = false; + } + + checkDeclaration(node) { + if (node != null && this.isObjectProperty(node)) { + this.checkDeclaration(node.value); + } else { + super.checkDeclaration(node); + } + } + + getObjectOrClassMethodParams(method) { + return method.value.params; + } + + isValidDirective(stmt) { + var _stmt$expression$extr; + + return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && !((_stmt$expression$extr = stmt.expression.extra) != null && _stmt$expression$extr.parenthesized); + } + + stmtToDirective(stmt) { + const value = stmt.expression.value; + const directive = super.stmtToDirective(stmt); + this.addExtra(directive.value, "expressionValue", value); + return directive; + } + + parseBlockBody(node, ...args) { + super.parseBlockBody(node, ...args); + const directiveStatements = node.directives.map(d => this.directiveToStmt(d)); + node.body = directiveStatements.concat(node.body); + delete node.directives; + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true); + + if (method.typeParameters) { + method.value.typeParameters = method.typeParameters; + delete method.typeParameters; + } + + classBody.body.push(method); + } + + parsePrivateName() { + const node = super.parsePrivateName(); + + if (!this.getPluginOption("estree", "classFeatures")) { + return node; + } + + return this.convertPrivateNameToPrivateIdentifier(node); + } + + convertPrivateNameToPrivateIdentifier(node) { + const name = super.getPrivateNameSV(node); + node = node; + delete node.id; + node.name = name; + node.type = "PrivateIdentifier"; + return node; + } + + isPrivateName(node) { + if (!this.getPluginOption("estree", "classFeatures")) { + return super.isPrivateName(node); + } + + return node.type === "PrivateIdentifier"; + } + + getPrivateNameSV(node) { + if (!this.getPluginOption("estree", "classFeatures")) { + return super.getPrivateNameSV(node); + } + + return node.name; + } + + parseLiteral(value, type) { + const node = super.parseLiteral(value, type); + node.raw = node.extra.raw; + delete node.extra; + return node; + } + + parseFunctionBody(node, allowExpression, isMethod = false) { + super.parseFunctionBody(node, allowExpression, isMethod); + node.expression = node.body.type !== "BlockStatement"; + } + + parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { + let funcNode = this.startNode(); + funcNode.kind = node.kind; + funcNode = super.parseMethod(funcNode, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope); + funcNode.type = "FunctionExpression"; + delete funcNode.kind; + node.value = funcNode; + + if (type === "ClassPrivateMethod") { + node.computed = false; + } + + type = "MethodDefinition"; + return this.finishNode(node, type); + } + + parseClassProperty(...args) { + const propertyNode = super.parseClassProperty(...args); + + if (this.getPluginOption("estree", "classFeatures")) { + propertyNode.type = "PropertyDefinition"; + } + + return propertyNode; + } + + parseClassPrivateProperty(...args) { + const propertyNode = super.parseClassPrivateProperty(...args); + + if (this.getPluginOption("estree", "classFeatures")) { + propertyNode.type = "PropertyDefinition"; + propertyNode.computed = false; + } + + return propertyNode; + } + + parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) { + const node = super.parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor); + + if (node) { + node.type = "Property"; + if (node.kind === "method") node.kind = "init"; + node.shorthand = false; + } + + return node; + } + + parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) { + const node = super.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors); + + if (node) { + node.kind = "init"; + node.type = "Property"; + } + + return node; + } + + isAssignable(node, isBinding) { + if (node != null && this.isObjectProperty(node)) { + return this.isAssignable(node.value, isBinding); + } + + return super.isAssignable(node, isBinding); + } + + toAssignable(node, isLHS = false) { + if (node != null && this.isObjectProperty(node)) { + this.toAssignable(node.value, isLHS); + return node; + } + + return super.toAssignable(node, isLHS); + } + + toAssignableObjectExpressionProp(prop, ...args) { + if (prop.kind === "get" || prop.kind === "set") { + this.raise(prop.key.start, ErrorMessages.PatternHasAccessor); + } else if (prop.method) { + this.raise(prop.key.start, ErrorMessages.PatternHasMethod); + } else { + super.toAssignableObjectExpressionProp(prop, ...args); + } + } + + finishCallExpression(node, optional) { + super.finishCallExpression(node, optional); + + if (node.callee.type === "Import") { + node.type = "ImportExpression"; + node.source = node.arguments[0]; + + if (this.hasPlugin("importAssertions")) { + var _node$arguments$; + + node.attributes = (_node$arguments$ = node.arguments[1]) != null ? _node$arguments$ : null; + } + + delete node.arguments; + delete node.callee; + } + + return node; + } + + toReferencedArguments(node) { + if (node.type === "ImportExpression") { + return; + } + + super.toReferencedArguments(node); + } + + parseExport(node) { + super.parseExport(node); + + switch (node.type) { + case "ExportAllDeclaration": + node.exported = null; + break; + + case "ExportNamedDeclaration": + if (node.specifiers.length === 1 && node.specifiers[0].type === "ExportNamespaceSpecifier") { + node.type = "ExportAllDeclaration"; + node.exported = node.specifiers[0].exported; + delete node.specifiers; + } + + break; + } + + return node; + } + + parseSubscript(base, startPos, startLoc, noCalls, state) { + const node = super.parseSubscript(base, startPos, startLoc, noCalls, state); + + if (state.optionalChainMember) { + if (node.type === "OptionalMemberExpression" || node.type === "OptionalCallExpression") { + node.type = node.type.substring(8); + } + + if (state.stop) { + const chain = this.startNodeAtNode(node); + chain.expression = node; + return this.finishNode(chain, "ChainExpression"); + } + } else if (node.type === "MemberExpression" || node.type === "CallExpression") { + node.optional = false; + } + + return node; + } + + hasPropertyAsPrivateName(node) { + if (node.type === "ChainExpression") { + node = node.expression; + } + + return super.hasPropertyAsPrivateName(node); + } + + isOptionalChain(node) { + return node.type === "ChainExpression"; + } + + isObjectProperty(node) { + return node.type === "Property" && node.kind === "init" && !node.method; + } + + isObjectMethod(node) { + return node.method || node.kind === "get" || node.kind === "set"; + } + + }); + + class TokContext { + constructor(token, preserveSpace) { + this.token = void 0; + this.preserveSpace = void 0; + this.token = token; + this.preserveSpace = !!preserveSpace; + } + + } + const types$1 = { + brace: new TokContext("{"), + template: new TokContext("`", true) + }; + + const beforeExpr = true; + const startsExpr = true; + const isLoop = true; + const isAssign = true; + const prefix = true; + const postfix = true; + class ExportedTokenType { + constructor(label, conf = {}) { + this.label = void 0; + this.keyword = void 0; + this.beforeExpr = void 0; + this.startsExpr = void 0; + this.rightAssociative = void 0; + this.isLoop = void 0; + this.isAssign = void 0; + this.prefix = void 0; + this.postfix = void 0; + this.binop = void 0; + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.rightAssociative = !!conf.rightAssociative; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop != null ? conf.binop : null; + { + this.updateContext = null; + } + } + + } + const keywords$1 = new Map(); + + function createKeyword(name, options = {}) { + options.keyword = name; + const token = createToken(name, options); + keywords$1.set(name, token); + return token; + } + + function createBinop(name, binop) { + return createToken(name, { + beforeExpr, + binop + }); + } + + let tokenTypeCounter = -1; + const tokenTypes = []; + const tokenLabels = []; + const tokenBinops = []; + const tokenBeforeExprs = []; + const tokenStartsExprs = []; + const tokenPrefixes = []; + + function createToken(name, options = {}) { + var _options$binop, _options$beforeExpr, _options$startsExpr, _options$prefix; + + ++tokenTypeCounter; + tokenLabels.push(name); + tokenBinops.push((_options$binop = options.binop) != null ? _options$binop : -1); + tokenBeforeExprs.push((_options$beforeExpr = options.beforeExpr) != null ? _options$beforeExpr : false); + tokenStartsExprs.push((_options$startsExpr = options.startsExpr) != null ? _options$startsExpr : false); + tokenPrefixes.push((_options$prefix = options.prefix) != null ? _options$prefix : false); + tokenTypes.push(new ExportedTokenType(name, options)); + return tokenTypeCounter; + } + + const tt = { + num: createToken("num", { + startsExpr + }), + bigint: createToken("bigint", { + startsExpr + }), + decimal: createToken("decimal", { + startsExpr + }), + regexp: createToken("regexp", { + startsExpr + }), + string: createToken("string", { + startsExpr + }), + name: createToken("name", { + startsExpr + }), + privateName: createToken("#name", { + startsExpr + }), + eof: createToken("eof"), + bracketL: createToken("[", { + beforeExpr, + startsExpr + }), + bracketHashL: createToken("#[", { + beforeExpr, + startsExpr + }), + bracketBarL: createToken("[|", { + beforeExpr, + startsExpr + }), + bracketR: createToken("]"), + bracketBarR: createToken("|]"), + braceL: createToken("{", { + beforeExpr, + startsExpr + }), + braceBarL: createToken("{|", { + beforeExpr, + startsExpr + }), + braceHashL: createToken("#{", { + beforeExpr, + startsExpr + }), + braceR: createToken("}", { + beforeExpr + }), + braceBarR: createToken("|}"), + parenL: createToken("(", { + beforeExpr, + startsExpr + }), + parenR: createToken(")"), + comma: createToken(",", { + beforeExpr + }), + semi: createToken(";", { + beforeExpr + }), + colon: createToken(":", { + beforeExpr + }), + doubleColon: createToken("::", { + beforeExpr + }), + dot: createToken("."), + question: createToken("?", { + beforeExpr + }), + questionDot: createToken("?."), + arrow: createToken("=>", { + beforeExpr + }), + template: createToken("template"), + ellipsis: createToken("...", { + beforeExpr + }), + backQuote: createToken("`", { + startsExpr + }), + dollarBraceL: createToken("${", { + beforeExpr, + startsExpr + }), + at: createToken("@"), + hash: createToken("#", { + startsExpr + }), + interpreterDirective: createToken("#!..."), + eq: createToken("=", { + beforeExpr, + isAssign + }), + assign: createToken("_=", { + beforeExpr, + isAssign + }), + slashAssign: createToken("_=", { + beforeExpr, + isAssign + }), + moduloAssign: createToken("_=", { + beforeExpr, + isAssign + }), + incDec: createToken("++/--", { + prefix, + postfix, + startsExpr + }), + bang: createToken("!", { + beforeExpr, + prefix, + startsExpr + }), + tilde: createToken("~", { + beforeExpr, + prefix, + startsExpr + }), + pipeline: createBinop("|>", 0), + nullishCoalescing: createBinop("??", 1), + logicalOR: createBinop("||", 1), + logicalAND: createBinop("&&", 2), + bitwiseOR: createBinop("|", 3), + bitwiseXOR: createBinop("^", 4), + bitwiseAND: createBinop("&", 5), + equality: createBinop("==/!=/===/!==", 6), + relational: createBinop("/<=/>=", 7), + bitShift: createBinop("<>/>>>", 8), + plusMin: createToken("+/-", { + beforeExpr, + binop: 9, + prefix, + startsExpr + }), + modulo: createToken("%", { + binop: 10, + startsExpr + }), + star: createToken("*", { + binop: 10 + }), + slash: createBinop("/", 10), + exponent: createToken("**", { + beforeExpr, + binop: 11, + rightAssociative: true + }), + _in: createKeyword("in", { + beforeExpr, + binop: 7 + }), + _instanceof: createKeyword("instanceof", { + beforeExpr, + binop: 7 + }), + _break: createKeyword("break"), + _case: createKeyword("case", { + beforeExpr + }), + _catch: createKeyword("catch"), + _continue: createKeyword("continue"), + _debugger: createKeyword("debugger"), + _default: createKeyword("default", { + beforeExpr + }), + _else: createKeyword("else", { + beforeExpr + }), + _finally: createKeyword("finally"), + _function: createKeyword("function", { + startsExpr + }), + _if: createKeyword("if"), + _return: createKeyword("return", { + beforeExpr + }), + _switch: createKeyword("switch"), + _throw: createKeyword("throw", { + beforeExpr, + prefix, + startsExpr + }), + _try: createKeyword("try"), + _var: createKeyword("var"), + _const: createKeyword("const"), + _with: createKeyword("with"), + _new: createKeyword("new", { + beforeExpr, + startsExpr + }), + _this: createKeyword("this", { + startsExpr + }), + _super: createKeyword("super", { + startsExpr + }), + _class: createKeyword("class", { + startsExpr + }), + _extends: createKeyword("extends", { + beforeExpr + }), + _export: createKeyword("export"), + _import: createKeyword("import", { + startsExpr + }), + _null: createKeyword("null", { + startsExpr + }), + _true: createKeyword("true", { + startsExpr + }), + _false: createKeyword("false", { + startsExpr + }), + _typeof: createKeyword("typeof", { + beforeExpr, + prefix, + startsExpr + }), + _void: createKeyword("void", { + beforeExpr, + prefix, + startsExpr + }), + _delete: createKeyword("delete", { + beforeExpr, + prefix, + startsExpr + }), + _do: createKeyword("do", { + isLoop, + beforeExpr + }), + _for: createKeyword("for", { + isLoop + }), + _while: createKeyword("while", { + isLoop + }), + jsxName: createToken("jsxName"), + jsxText: createToken("jsxText", { + beforeExpr: true + }), + jsxTagStart: createToken("jsxTagStart", { + startsExpr: true + }), + jsxTagEnd: createToken("jsxTagEnd"), + placeholder: createToken("%%", { + startsExpr: true + }) + }; + function tokenComesBeforeExpression(token) { + return tokenBeforeExprs[token]; + } + function tokenCanStartExpression(token) { + return tokenStartsExprs[token]; + } + function tokenIsAssignment(token) { + return token >= 35 && token <= 38; + } + function tokenIsLoop(token) { + return token >= 89 && token <= 91; + } + function tokenIsKeyword(token) { + return token >= 57 && token <= 91; + } + function tokenIsOperator(token) { + return token >= 42 && token <= 58; + } + function tokenIsPostfix(token) { + return token === 39; + } + function tokenIsPrefix(token) { + return tokenPrefixes[token]; + } + function tokenLabelName(token) { + return tokenLabels[token]; + } + function tokenOperatorPrecedence(token) { + return tokenBinops[token]; + } + function tokenIsRightAssociative(token) { + return token === 56; + } + function getExportedToken(token) { + return tokenTypes[token]; + } + function isTokenType(obj) { + return typeof obj === "number"; + } + { + tokenTypes[16].updateContext = context => { + context.pop(); + }; + + tokenTypes[13].updateContext = tokenTypes[15].updateContext = tokenTypes[31].updateContext = context => { + context.push(types$1.brace); + }; + + tokenTypes[30].updateContext = context => { + if (context[context.length - 1] === types$1.template) { + context.pop(); + } else { + context.push(types$1.template); + } + }; + + tokenTypes[94].updateContext = context => { + context.push(types$1.j_expr, types$1.j_oTag); + }; + } + + let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u1711\u171f-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4c\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u0898-\u089f\u08ca-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; + const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1070, 4050, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 46, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 482, 44, 11, 6, 17, 0, 322, 29, 19, 43, 1269, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4152, 8, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; + const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 357, 0, 62, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; + + function isInAstralSet(code, set) { + let pos = 0x10000; + + for (let i = 0, length = set.length; i < length; i += 2) { + pos += set[i]; + if (pos > code) return false; + pos += set[i + 1]; + if (pos >= code) return true; + } + + return false; + } + + function isIdentifierStart(code) { + if (code < 65) return code === 36; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); + } + + return isInAstralSet(code, astralIdentifierStartCodes); + } + function isIdentifierChar(code) { + if (code < 48) return code === 36; + if (code < 58) return true; + if (code < 65) return false; + if (code <= 90) return true; + if (code < 97) return code === 95; + if (code <= 122) return true; + + if (code <= 0xffff) { + return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); + } + + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); + } + + const reservedWords = { + keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], + strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], + strictBind: ["eval", "arguments"] + }; + const keywords = new Set(reservedWords.keyword); + const reservedWordsStrictSet = new Set(reservedWords.strict); + const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); + function isReservedWord(word, inModule) { + return inModule && word === "await" || word === "enum"; + } + function isStrictReservedWord(word, inModule) { + return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); + } + function isStrictBindOnlyReservedWord(word) { + return reservedWordsStrictBindSet.has(word); + } + function isStrictBindReservedWord(word, inModule) { + return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); + } + function isKeyword(word) { + return keywords.has(word); + } + + function isIteratorStart(current, next) { + return current === 64 && next === 64; + } + const reservedWordLikeSet = new Set(["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "eval", "arguments", "enum", "await"]); + function canBeReservedWord(word) { + return reservedWordLikeSet.has(word); + } + + const SCOPE_OTHER = 0b000000000, + SCOPE_PROGRAM = 0b000000001, + SCOPE_FUNCTION = 0b000000010, + SCOPE_ARROW = 0b000000100, + SCOPE_SIMPLE_CATCH = 0b000001000, + SCOPE_SUPER = 0b000010000, + SCOPE_DIRECT_SUPER = 0b000100000, + SCOPE_CLASS = 0b001000000, + SCOPE_STATIC_BLOCK = 0b010000000, + SCOPE_TS_MODULE = 0b100000000, + SCOPE_VAR = SCOPE_PROGRAM | SCOPE_FUNCTION | SCOPE_TS_MODULE; + const BIND_KIND_VALUE = 0b000000000001, + BIND_KIND_TYPE = 0b000000000010, + BIND_SCOPE_VAR = 0b000000000100, + BIND_SCOPE_LEXICAL = 0b000000001000, + BIND_SCOPE_FUNCTION = 0b000000010000, + BIND_FLAGS_NONE = 0b000001000000, + BIND_FLAGS_CLASS = 0b000010000000, + BIND_FLAGS_TS_ENUM = 0b000100000000, + BIND_FLAGS_TS_CONST_ENUM = 0b001000000000, + BIND_FLAGS_TS_EXPORT_ONLY = 0b010000000000, + BIND_FLAGS_FLOW_DECLARE_FN = 0b100000000000; + const BIND_CLASS = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_CLASS, + BIND_LEXICAL = BIND_KIND_VALUE | 0 | BIND_SCOPE_LEXICAL | 0, + BIND_VAR = BIND_KIND_VALUE | 0 | BIND_SCOPE_VAR | 0, + BIND_FUNCTION = BIND_KIND_VALUE | 0 | BIND_SCOPE_FUNCTION | 0, + BIND_TS_INTERFACE = 0 | BIND_KIND_TYPE | 0 | BIND_FLAGS_CLASS, + BIND_TS_TYPE = 0 | BIND_KIND_TYPE | 0 | 0, + BIND_TS_ENUM = BIND_KIND_VALUE | BIND_KIND_TYPE | BIND_SCOPE_LEXICAL | BIND_FLAGS_TS_ENUM, + BIND_TS_AMBIENT = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY, + BIND_NONE = 0 | 0 | 0 | BIND_FLAGS_NONE, + BIND_OUTSIDE = BIND_KIND_VALUE | 0 | 0 | BIND_FLAGS_NONE, + BIND_TS_CONST_ENUM = BIND_TS_ENUM | BIND_FLAGS_TS_CONST_ENUM, + BIND_TS_NAMESPACE = 0 | 0 | 0 | BIND_FLAGS_TS_EXPORT_ONLY, + BIND_FLOW_DECLARE_FN = BIND_FLAGS_FLOW_DECLARE_FN; + const CLASS_ELEMENT_FLAG_STATIC = 0b100, + CLASS_ELEMENT_KIND_GETTER = 0b010, + CLASS_ELEMENT_KIND_SETTER = 0b001, + CLASS_ELEMENT_KIND_ACCESSOR = CLASS_ELEMENT_KIND_GETTER | CLASS_ELEMENT_KIND_SETTER; + const CLASS_ELEMENT_STATIC_GETTER = CLASS_ELEMENT_KIND_GETTER | CLASS_ELEMENT_FLAG_STATIC, + CLASS_ELEMENT_STATIC_SETTER = CLASS_ELEMENT_KIND_SETTER | CLASS_ELEMENT_FLAG_STATIC, + CLASS_ELEMENT_INSTANCE_GETTER = CLASS_ELEMENT_KIND_GETTER, + CLASS_ELEMENT_INSTANCE_SETTER = CLASS_ELEMENT_KIND_SETTER, + CLASS_ELEMENT_OTHER = 0; + + class Scope { + constructor(flags) { + this.var = new Set(); + this.lexical = new Set(); + this.functions = new Set(); + this.flags = flags; + } + + } + class ScopeHandler { + constructor(raise, inModule) { + this.scopeStack = []; + this.undefinedExports = new Map(); + this.undefinedPrivateNames = new Map(); + this.raise = raise; + this.inModule = inModule; + } + + get inFunction() { + return (this.currentVarScopeFlags() & SCOPE_FUNCTION) > 0; + } + + get allowSuper() { + return (this.currentThisScopeFlags() & SCOPE_SUPER) > 0; + } + + get allowDirectSuper() { + return (this.currentThisScopeFlags() & SCOPE_DIRECT_SUPER) > 0; + } + + get inClass() { + return (this.currentThisScopeFlags() & SCOPE_CLASS) > 0; + } + + get inClassAndNotInNonArrowFunction() { + const flags = this.currentThisScopeFlags(); + return (flags & SCOPE_CLASS) > 0 && (flags & SCOPE_FUNCTION) === 0; + } + + get inStaticBlock() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & SCOPE_STATIC_BLOCK) { + return true; + } + + if (flags & (SCOPE_VAR | SCOPE_CLASS)) { + return false; + } + } + } + + get inNonArrowFunction() { + return (this.currentThisScopeFlags() & SCOPE_FUNCTION) > 0; + } + + get treatFunctionsAsVar() { + return this.treatFunctionsAsVarInScope(this.currentScope()); + } + + createScope(flags) { + return new Scope(flags); + } + + enter(flags) { + this.scopeStack.push(this.createScope(flags)); + } + + exit() { + this.scopeStack.pop(); + } + + treatFunctionsAsVarInScope(scope) { + return !!(scope.flags & SCOPE_FUNCTION || !this.inModule && scope.flags & SCOPE_PROGRAM); + } + + declareName(name, bindingType, pos) { + let scope = this.currentScope(); + + if (bindingType & BIND_SCOPE_LEXICAL || bindingType & BIND_SCOPE_FUNCTION) { + this.checkRedeclarationInScope(scope, name, bindingType, pos); + + if (bindingType & BIND_SCOPE_FUNCTION) { + scope.functions.add(name); + } else { + scope.lexical.add(name); + } + + if (bindingType & BIND_SCOPE_LEXICAL) { + this.maybeExportDefined(scope, name); + } + } else if (bindingType & BIND_SCOPE_VAR) { + for (let i = this.scopeStack.length - 1; i >= 0; --i) { + scope = this.scopeStack[i]; + this.checkRedeclarationInScope(scope, name, bindingType, pos); + scope.var.add(name); + this.maybeExportDefined(scope, name); + if (scope.flags & SCOPE_VAR) break; + } + } + + if (this.inModule && scope.flags & SCOPE_PROGRAM) { + this.undefinedExports.delete(name); + } + } + + maybeExportDefined(scope, name) { + if (this.inModule && scope.flags & SCOPE_PROGRAM) { + this.undefinedExports.delete(name); + } + } + + checkRedeclarationInScope(scope, name, bindingType, pos) { + if (this.isRedeclaredInScope(scope, name, bindingType)) { + this.raise(pos, ErrorMessages.VarRedeclaration, name); + } + } + + isRedeclaredInScope(scope, name, bindingType) { + if (!(bindingType & BIND_KIND_VALUE)) return false; + + if (bindingType & BIND_SCOPE_LEXICAL) { + return scope.lexical.has(name) || scope.functions.has(name) || scope.var.has(name); + } + + if (bindingType & BIND_SCOPE_FUNCTION) { + return scope.lexical.has(name) || !this.treatFunctionsAsVarInScope(scope) && scope.var.has(name); + } + + return scope.lexical.has(name) && !(scope.flags & SCOPE_SIMPLE_CATCH && scope.lexical.values().next().value === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.has(name); + } + + checkLocalExport(id) { + const { + name + } = id; + const topLevelScope = this.scopeStack[0]; + + if (!topLevelScope.lexical.has(name) && !topLevelScope.var.has(name) && !topLevelScope.functions.has(name)) { + this.undefinedExports.set(name, id.start); + } + } + + currentScope() { + return this.scopeStack[this.scopeStack.length - 1]; + } + + currentVarScopeFlags() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & SCOPE_VAR) { + return flags; + } + } + } + + currentThisScopeFlags() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & (SCOPE_VAR | SCOPE_CLASS) && !(flags & SCOPE_ARROW)) { + return flags; + } + } + } + + } + + class FlowScope extends Scope { + constructor(...args) { + super(...args); + this.declareFunctions = new Set(); + } + + } + + class FlowScopeHandler extends ScopeHandler { + createScope(flags) { + return new FlowScope(flags); + } + + declareName(name, bindingType, pos) { + const scope = this.currentScope(); + + if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { + this.checkRedeclarationInScope(scope, name, bindingType, pos); + this.maybeExportDefined(scope, name); + scope.declareFunctions.add(name); + return; + } + + super.declareName(...arguments); + } + + isRedeclaredInScope(scope, name, bindingType) { + if (super.isRedeclaredInScope(...arguments)) return true; + + if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { + return !scope.declareFunctions.has(name) && (scope.lexical.has(name) || scope.functions.has(name)); + } + + return false; + } + + checkLocalExport(id) { + if (!this.scopeStack[0].declareFunctions.has(id.name)) { + super.checkLocalExport(id); + } + } + + } + + class State { + constructor() { + this.strict = void 0; + this.curLine = void 0; + this.startLoc = void 0; + this.endLoc = void 0; + this.errors = []; + this.potentialArrowAt = -1; + this.noArrowAt = []; + this.noArrowParamsConversionAt = []; + this.maybeInArrowParameters = false; + this.inType = false; + this.noAnonFunctionType = false; + this.inPropertyName = false; + this.hasFlowComment = false; + this.isAmbientContext = false; + this.inAbstractClass = false; + this.topicContext = { + maxNumOfResolvableTopics: 0, + maxTopicIndex: null + }; + this.soloAwait = false; + this.inFSharpPipelineDirectBody = false; + this.labels = []; + this.decoratorStack = [[]]; + this.comments = []; + this.commentStack = []; + this.pos = 0; + this.lineStart = 0; + this.type = 7; + this.value = null; + this.start = 0; + this.end = 0; + this.lastTokEndLoc = null; + this.lastTokStartLoc = null; + this.lastTokStart = 0; + this.lastTokEnd = 0; + this.context = [types$1.brace]; + this.exprAllowed = true; + this.containsEsc = false; + this.strictErrors = new Map(); + this.tokensLength = 0; + } + + init(options) { + this.strict = options.strictMode === false ? false : options.strictMode === true ? true : options.sourceType === "module"; + this.curLine = options.startLine; + this.startLoc = this.endLoc = this.curPosition(); + } + + curPosition() { + return new Position(this.curLine, this.pos - this.lineStart); + } + + clone(skipArrays) { + const state = new State(); + const keys = Object.keys(this); + + for (let i = 0, length = keys.length; i < length; i++) { + const key = keys[i]; + let val = this[key]; + + if (!skipArrays && Array.isArray(val)) { + val = val.slice(); + } + + state[key] = val; + } + + return state; + } + + } + + var _isDigit = function isDigit(code) { + return code >= 48 && code <= 57; + }; + const VALID_REGEX_FLAGS = new Set([103, 109, 115, 105, 121, 117, 100]); + const forbiddenNumericSeparatorSiblings = { + decBinOct: [46, 66, 69, 79, 95, 98, 101, 111], + hex: [46, 88, 95, 120] + }; + const allowedNumericSeparatorSiblings = {}; + allowedNumericSeparatorSiblings.bin = [48, 49]; + allowedNumericSeparatorSiblings.oct = [...allowedNumericSeparatorSiblings.bin, 50, 51, 52, 53, 54, 55]; + allowedNumericSeparatorSiblings.dec = [...allowedNumericSeparatorSiblings.oct, 56, 57]; + allowedNumericSeparatorSiblings.hex = [...allowedNumericSeparatorSiblings.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102]; + class Token { + constructor(state) { + this.type = state.type; + this.value = state.value; + this.start = state.start; + this.end = state.end; + this.loc = new SourceLocation(state.startLoc, state.endLoc); + } + + } + class Tokenizer extends ParserError { + constructor(options, input) { + super(); + this.isLookahead = void 0; + this.tokens = []; + this.state = new State(); + this.state.init(options); + this.input = input; + this.length = input.length; + this.isLookahead = false; + } + + pushToken(token) { + this.tokens.length = this.state.tokensLength; + this.tokens.push(token); + ++this.state.tokensLength; + } + + next() { + this.checkKeywordEscapes(); + + if (this.options.tokens) { + this.pushToken(new Token(this.state)); + } + + this.state.lastTokEnd = this.state.end; + this.state.lastTokStart = this.state.start; + this.state.lastTokEndLoc = this.state.endLoc; + this.state.lastTokStartLoc = this.state.startLoc; + this.nextToken(); + } + + eat(type) { + if (this.match(type)) { + this.next(); + return true; + } else { + return false; + } + } + + match(type) { + return this.state.type === type; + } + + createLookaheadState(state) { + return { + pos: state.pos, + value: null, + type: state.type, + start: state.start, + end: state.end, + lastTokEnd: state.end, + context: [this.curContext()], + inType: state.inType + }; + } + + lookahead() { + const old = this.state; + this.state = this.createLookaheadState(old); + this.isLookahead = true; + this.nextToken(); + this.isLookahead = false; + const curr = this.state; + this.state = old; + return curr; + } + + nextTokenStart() { + return this.nextTokenStartSince(this.state.pos); + } + + nextTokenStartSince(pos) { + skipWhiteSpace.lastIndex = pos; + return skipWhiteSpace.test(this.input) ? skipWhiteSpace.lastIndex : pos; + } + + lookaheadCharCode() { + return this.input.charCodeAt(this.nextTokenStart()); + } + + codePointAtPos(pos) { + let cp = this.input.charCodeAt(pos); + + if ((cp & 0xfc00) === 0xd800 && ++pos < this.input.length) { + const trail = this.input.charCodeAt(pos); + + if ((trail & 0xfc00) === 0xdc00) { + cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff); + } + } + + return cp; + } + + setStrict(strict) { + this.state.strict = strict; + + if (strict) { + this.state.strictErrors.forEach((message, pos) => this.raise(pos, message)); + this.state.strictErrors.clear(); + } + } + + curContext() { + return this.state.context[this.state.context.length - 1]; + } + + nextToken() { + const curContext = this.curContext(); + if (!curContext.preserveSpace) this.skipSpace(); + this.state.start = this.state.pos; + if (!this.isLookahead) this.state.startLoc = this.state.curPosition(); + + if (this.state.pos >= this.length) { + this.finishToken(7); + return; + } + + if (curContext === types$1.template) { + this.readTmplToken(); + } else { + this.getTokenFromCode(this.codePointAtPos(this.state.pos)); + } + } + + skipBlockComment() { + let startLoc; + if (!this.isLookahead) startLoc = this.state.curPosition(); + const start = this.state.pos; + const end = this.input.indexOf("*/", start + 2); + if (end === -1) throw this.raise(start, ErrorMessages.UnterminatedComment); + this.state.pos = end + 2; + lineBreakG.lastIndex = start + 2; + + while (lineBreakG.test(this.input) && lineBreakG.lastIndex <= end) { + ++this.state.curLine; + this.state.lineStart = lineBreakG.lastIndex; + } + + if (this.isLookahead) return; + const comment = { + type: "CommentBlock", + value: this.input.slice(start + 2, end), + start, + end: end + 2, + loc: new SourceLocation(startLoc, this.state.curPosition()) + }; + if (this.options.tokens) this.pushToken(comment); + return comment; + } + + skipLineComment(startSkip) { + const start = this.state.pos; + let startLoc; + if (!this.isLookahead) startLoc = this.state.curPosition(); + let ch = this.input.charCodeAt(this.state.pos += startSkip); + + if (this.state.pos < this.length) { + while (!isNewLine(ch) && ++this.state.pos < this.length) { + ch = this.input.charCodeAt(this.state.pos); + } + } + + if (this.isLookahead) return; + const end = this.state.pos; + const value = this.input.slice(start + startSkip, end); + const comment = { + type: "CommentLine", + value, + start, + end, + loc: new SourceLocation(startLoc, this.state.curPosition()) + }; + if (this.options.tokens) this.pushToken(comment); + return comment; + } + + skipSpace() { + const spaceStart = this.state.pos; + const comments = []; + + loop: while (this.state.pos < this.length) { + const ch = this.input.charCodeAt(this.state.pos); + + switch (ch) { + case 32: + case 160: + case 9: + ++this.state.pos; + break; + + case 13: + if (this.input.charCodeAt(this.state.pos + 1) === 10) { + ++this.state.pos; + } + + case 10: + case 8232: + case 8233: + ++this.state.pos; + ++this.state.curLine; + this.state.lineStart = this.state.pos; + break; + + case 47: + switch (this.input.charCodeAt(this.state.pos + 1)) { + case 42: + { + const comment = this.skipBlockComment(); + + if (comment !== undefined) { + this.addComment(comment); + if (this.options.attachComment) comments.push(comment); + } + + break; + } + + case 47: + { + const comment = this.skipLineComment(2); + + if (comment !== undefined) { + this.addComment(comment); + if (this.options.attachComment) comments.push(comment); + } + + break; + } + + default: + break loop; + } + + break; + + default: + if (isWhitespace(ch)) { + ++this.state.pos; + } else if (ch === 45 && !this.inModule) { + const pos = this.state.pos; + + if (this.input.charCodeAt(pos + 1) === 45 && this.input.charCodeAt(pos + 2) === 62 && (spaceStart === 0 || this.state.lineStart > spaceStart)) { + const comment = this.skipLineComment(3); + + if (comment !== undefined) { + this.addComment(comment); + if (this.options.attachComment) comments.push(comment); + } + } else { + break loop; + } + } else if (ch === 60 && !this.inModule) { + const pos = this.state.pos; + + if (this.input.charCodeAt(pos + 1) === 33 && this.input.charCodeAt(pos + 2) === 45 && this.input.charCodeAt(pos + 3) === 45) { + const comment = this.skipLineComment(4); + + if (comment !== undefined) { + this.addComment(comment); + if (this.options.attachComment) comments.push(comment); + } + } else { + break loop; + } + } else { + break loop; + } + + } + } + + if (comments.length > 0) { + const end = this.state.pos; + const CommentWhitespace = { + start: spaceStart, + end, + comments, + leadingNode: null, + trailingNode: null, + containingNode: null + }; + this.state.commentStack.push(CommentWhitespace); + } + } + + finishToken(type, val) { + this.state.end = this.state.pos; + const prevType = this.state.type; + this.state.type = type; + this.state.value = val; + + if (!this.isLookahead) { + this.state.endLoc = this.state.curPosition(); + this.updateContext(prevType); + } + } + + readToken_numberSign() { + if (this.state.pos === 0 && this.readToken_interpreter()) { + return; + } + + const nextPos = this.state.pos + 1; + const next = this.codePointAtPos(nextPos); + + if (next >= 48 && next <= 57) { + throw this.raise(this.state.pos, ErrorMessages.UnexpectedDigitAfterHash); + } + + if (next === 123 || next === 91 && this.hasPlugin("recordAndTuple")) { + this.expectPlugin("recordAndTuple"); + + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "hash") { + throw this.raise(this.state.pos, next === 123 ? ErrorMessages.RecordExpressionHashIncorrectStartSyntaxType : ErrorMessages.TupleExpressionHashIncorrectStartSyntaxType); + } + + this.state.pos += 2; + + if (next === 123) { + this.finishToken(15); + } else { + this.finishToken(9); + } + } else if (isIdentifierStart(next)) { + ++this.state.pos; + this.finishToken(6, this.readWord1(next)); + } else if (next === 92) { + ++this.state.pos; + this.finishToken(6, this.readWord1()); + } else { + this.finishOp(33, 1); + } + } + + readToken_dot() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next >= 48 && next <= 57) { + this.readNumber(true); + return; + } + + if (next === 46 && this.input.charCodeAt(this.state.pos + 2) === 46) { + this.state.pos += 3; + this.finishToken(29); + } else { + ++this.state.pos; + this.finishToken(24); + } + } + + readToken_slash() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(37, 2); + } else { + this.finishOp(55, 1); + } + } + + readToken_interpreter() { + if (this.state.pos !== 0 || this.length < 2) return false; + let ch = this.input.charCodeAt(this.state.pos + 1); + if (ch !== 33) return false; + const start = this.state.pos; + this.state.pos += 1; + + while (!isNewLine(ch) && ++this.state.pos < this.length) { + ch = this.input.charCodeAt(this.state.pos); + } + + const value = this.input.slice(start + 2, this.state.pos); + this.finishToken(34, value); + return true; + } + + readToken_mult_modulo(code) { + let type = code === 42 ? 54 : 53; + let width = 1; + let next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 42 && next === 42) { + width++; + next = this.input.charCodeAt(this.state.pos + 2); + type = 56; + } + + if (next === 61 && !this.state.inType) { + width++; + type = code === 37 ? 38 : 36; + } + + this.finishOp(type, width); + } + + readToken_pipe_amp(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === code) { + if (this.input.charCodeAt(this.state.pos + 2) === 61) { + this.finishOp(36, 3); + } else { + this.finishOp(code === 124 ? 44 : 45, 2); + } + + return; + } + + if (code === 124) { + if (next === 62) { + this.finishOp(42, 2); + return; + } + + if (this.hasPlugin("recordAndTuple") && next === 125) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectEndSyntaxType); + } + + this.state.pos += 2; + this.finishToken(17); + return; + } + + if (this.hasPlugin("recordAndTuple") && next === 93) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectEndSyntaxType); + } + + this.state.pos += 2; + this.finishToken(12); + return; + } + } + + if (next === 61) { + this.finishOp(36, 2); + return; + } + + this.finishOp(code === 124 ? 46 : 48, 1); + } + + readToken_caret() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(36, 2); + } else { + this.finishOp(47, 1); + } + } + + readToken_plus_min(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === code) { + this.finishOp(39, 2); + return; + } + + if (next === 61) { + this.finishOp(36, 2); + } else { + this.finishOp(52, 1); + } + } + + readToken_lt_gt(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + let size = 1; + + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; + + if (this.input.charCodeAt(this.state.pos + size) === 61) { + this.finishOp(36, size + 1); + return; + } + + this.finishOp(51, size); + return; + } + + if (next === 61) { + size = 2; + } + + this.finishOp(50, size); + } + + readToken_eq_excl(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 61) { + this.finishOp(49, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); + return; + } + + if (code === 61 && next === 62) { + this.state.pos += 2; + this.finishToken(27); + return; + } + + this.finishOp(code === 61 ? 35 : 40, 1); + } + + readToken_question() { + const next = this.input.charCodeAt(this.state.pos + 1); + const next2 = this.input.charCodeAt(this.state.pos + 2); + + if (next === 63) { + if (next2 === 61) { + this.finishOp(36, 3); + } else { + this.finishOp(43, 2); + } + } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) { + this.state.pos += 2; + this.finishToken(26); + } else { + ++this.state.pos; + this.finishToken(25); + } + } + + getTokenFromCode(code) { + switch (code) { + case 46: + this.readToken_dot(); + return; + + case 40: + ++this.state.pos; + this.finishToken(18); + return; + + case 41: + ++this.state.pos; + this.finishToken(19); + return; + + case 59: + ++this.state.pos; + this.finishToken(21); + return; + + case 44: + ++this.state.pos; + this.finishToken(20); + return; + + case 91: + if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectStartSyntaxType); + } + + this.state.pos += 2; + this.finishToken(10); + } else { + ++this.state.pos; + this.finishToken(8); + } + + return; + + case 93: + ++this.state.pos; + this.finishToken(11); + return; + + case 123: + if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { + if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { + throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectStartSyntaxType); + } + + this.state.pos += 2; + this.finishToken(14); + } else { + ++this.state.pos; + this.finishToken(13); + } + + return; + + case 125: + ++this.state.pos; + this.finishToken(16); + return; + + case 58: + if (this.hasPlugin("functionBind") && this.input.charCodeAt(this.state.pos + 1) === 58) { + this.finishOp(23, 2); + } else { + ++this.state.pos; + this.finishToken(22); + } + + return; + + case 63: + this.readToken_question(); + return; + + case 96: + ++this.state.pos; + this.finishToken(30); + return; + + case 48: + { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 120 || next === 88) { + this.readRadixNumber(16); + return; + } + + if (next === 111 || next === 79) { + this.readRadixNumber(8); + return; + } + + if (next === 98 || next === 66) { + this.readRadixNumber(2); + return; + } + } + + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + this.readNumber(false); + return; + + case 34: + case 39: + this.readString(code); + return; + + case 47: + this.readToken_slash(); + return; + + case 37: + case 42: + this.readToken_mult_modulo(code); + return; + + case 124: + case 38: + this.readToken_pipe_amp(code); + return; + + case 94: + this.readToken_caret(); + return; + + case 43: + case 45: + this.readToken_plus_min(code); + return; + + case 60: + case 62: + this.readToken_lt_gt(code); + return; + + case 61: + case 33: + this.readToken_eq_excl(code); + return; + + case 126: + this.finishOp(41, 1); + return; + + case 64: + ++this.state.pos; + this.finishToken(32); + return; + + case 35: + this.readToken_numberSign(); + return; + + case 92: + this.readWord(); + return; + + default: + if (isIdentifierStart(code)) { + this.readWord(code); + return; + } + + } + + throw this.raise(this.state.pos, ErrorMessages.InvalidOrUnexpectedToken, String.fromCodePoint(code)); + } + + finishOp(type, size) { + const str = this.input.slice(this.state.pos, this.state.pos + size); + this.state.pos += size; + this.finishToken(type, str); + } + + readRegexp() { + const start = this.state.start + 1; + let escaped, inClass; + let { + pos + } = this.state; + + for (;; ++pos) { + if (pos >= this.length) { + throw this.raise(start, ErrorMessages.UnterminatedRegExp); + } + + const ch = this.input.charCodeAt(pos); + + if (isNewLine(ch)) { + throw this.raise(start, ErrorMessages.UnterminatedRegExp); + } + + if (escaped) { + escaped = false; + } else { + if (ch === 91) { + inClass = true; + } else if (ch === 93 && inClass) { + inClass = false; + } else if (ch === 47 && !inClass) { + break; + } + + escaped = ch === 92; + } + } + + const content = this.input.slice(start, pos); + ++pos; + let mods = ""; + + while (pos < this.length) { + const cp = this.codePointAtPos(pos); + const char = String.fromCharCode(cp); + + if (VALID_REGEX_FLAGS.has(cp)) { + if (mods.includes(char)) { + this.raise(pos + 1, ErrorMessages.DuplicateRegExpFlags); + } + } else if (isIdentifierChar(cp) || cp === 92) { + this.raise(pos + 1, ErrorMessages.MalformedRegExpFlags); + } else { + break; + } + + ++pos; + mods += char; + } + + this.state.pos = pos; + this.finishToken(3, { + pattern: content, + flags: mods + }); + } + + readInt(radix, len, forceLen, allowNumSeparator = true) { + const start = this.state.pos; + const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct; + const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings.hex : radix === 10 ? allowedNumericSeparatorSiblings.dec : radix === 8 ? allowedNumericSeparatorSiblings.oct : allowedNumericSeparatorSiblings.bin; + let invalid = false; + let total = 0; + + for (let i = 0, e = len == null ? Infinity : len; i < e; ++i) { + const code = this.input.charCodeAt(this.state.pos); + let val; + + if (code === 95) { + const prev = this.input.charCodeAt(this.state.pos - 1); + const next = this.input.charCodeAt(this.state.pos + 1); + + if (allowedSiblings.indexOf(next) === -1) { + this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator); + } else if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) { + this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator); + } + + if (!allowNumSeparator) { + this.raise(this.state.pos, ErrorMessages.NumericSeparatorInEscapeSequence); + } + + ++this.state.pos; + continue; + } + + if (code >= 97) { + val = code - 97 + 10; + } else if (code >= 65) { + val = code - 65 + 10; + } else if (_isDigit(code)) { + val = code - 48; + } else { + val = Infinity; + } + + if (val >= radix) { + if (this.options.errorRecovery && val <= 9) { + val = 0; + this.raise(this.state.start + i + 2, ErrorMessages.InvalidDigit, radix); + } else if (forceLen) { + val = 0; + invalid = true; + } else { + break; + } + } + + ++this.state.pos; + total = total * radix + val; + } + + if (this.state.pos === start || len != null && this.state.pos - start !== len || invalid) { + return null; + } + + return total; + } + + readRadixNumber(radix) { + const start = this.state.pos; + let isBigInt = false; + this.state.pos += 2; + const val = this.readInt(radix); + + if (val == null) { + this.raise(this.state.start + 2, ErrorMessages.InvalidDigit, radix); + } + + const next = this.input.charCodeAt(this.state.pos); + + if (next === 110) { + ++this.state.pos; + isBigInt = true; + } else if (next === 109) { + throw this.raise(start, ErrorMessages.InvalidDecimal); + } + + if (isIdentifierStart(this.codePointAtPos(this.state.pos))) { + throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier); + } + + if (isBigInt) { + const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); + this.finishToken(1, str); + return; + } + + this.finishToken(0, val); + } + + readNumber(startsWithDot) { + const start = this.state.pos; + let isFloat = false; + let isBigInt = false; + let isDecimal = false; + let hasExponent = false; + let isOctal = false; + + if (!startsWithDot && this.readInt(10) === null) { + this.raise(start, ErrorMessages.InvalidNumber); + } + + const hasLeadingZero = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48; + + if (hasLeadingZero) { + const integer = this.input.slice(start, this.state.pos); + this.recordStrictModeErrors(start, ErrorMessages.StrictOctalLiteral); + + if (!this.state.strict) { + const underscorePos = integer.indexOf("_"); + + if (underscorePos > 0) { + this.raise(underscorePos + start, ErrorMessages.ZeroDigitNumericSeparator); + } + } + + isOctal = hasLeadingZero && !/[89]/.test(integer); + } + + let next = this.input.charCodeAt(this.state.pos); + + if (next === 46 && !isOctal) { + ++this.state.pos; + this.readInt(10); + isFloat = true; + next = this.input.charCodeAt(this.state.pos); + } + + if ((next === 69 || next === 101) && !isOctal) { + next = this.input.charCodeAt(++this.state.pos); + + if (next === 43 || next === 45) { + ++this.state.pos; + } + + if (this.readInt(10) === null) { + this.raise(start, ErrorMessages.InvalidOrMissingExponent); + } + + isFloat = true; + hasExponent = true; + next = this.input.charCodeAt(this.state.pos); + } + + if (next === 110) { + if (isFloat || hasLeadingZero) { + this.raise(start, ErrorMessages.InvalidBigIntLiteral); + } + + ++this.state.pos; + isBigInt = true; + } + + if (next === 109) { + this.expectPlugin("decimal", this.state.pos); + + if (hasExponent || hasLeadingZero) { + this.raise(start, ErrorMessages.InvalidDecimal); + } + + ++this.state.pos; + isDecimal = true; + } + + if (isIdentifierStart(this.codePointAtPos(this.state.pos))) { + throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier); + } + + const str = this.input.slice(start, this.state.pos).replace(/[_mn]/g, ""); + + if (isBigInt) { + this.finishToken(1, str); + return; + } + + if (isDecimal) { + this.finishToken(2, str); + return; + } + + const val = isOctal ? parseInt(str, 8) : parseFloat(str); + this.finishToken(0, val); + } + + readCodePoint(throwOnInvalid) { + const ch = this.input.charCodeAt(this.state.pos); + let code; + + if (ch === 123) { + const codePos = ++this.state.pos; + code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, true, throwOnInvalid); + ++this.state.pos; + + if (code !== null && code > 0x10ffff) { + if (throwOnInvalid) { + this.raise(codePos, ErrorMessages.InvalidCodePoint); + } else { + return null; + } + } + } else { + code = this.readHexChar(4, false, throwOnInvalid); + } + + return code; + } + + readString(quote) { + let out = "", + chunkStart = ++this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + } + + const ch = this.input.charCodeAt(this.state.pos); + if (ch === quote) break; + + if (ch === 92) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.readEscapedChar(false); + chunkStart = this.state.pos; + } else if (ch === 8232 || ch === 8233) { + ++this.state.pos; + ++this.state.curLine; + this.state.lineStart = this.state.pos; + } else if (isNewLine(ch)) { + throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + } else { + ++this.state.pos; + } + } + + out += this.input.slice(chunkStart, this.state.pos++); + this.finishToken(4, out); + } + + readTmplToken() { + let out = "", + chunkStart = this.state.pos, + containsInvalid = false; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages.UnterminatedTemplate); + } + + const ch = this.input.charCodeAt(this.state.pos); + + if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { + if (this.state.pos === this.state.start && this.match(28)) { + if (ch === 36) { + this.state.pos += 2; + this.finishToken(31); + return; + } else { + ++this.state.pos; + this.finishToken(30); + return; + } + } + + out += this.input.slice(chunkStart, this.state.pos); + this.finishToken(28, containsInvalid ? null : out); + return; + } + + if (ch === 92) { + out += this.input.slice(chunkStart, this.state.pos); + const escaped = this.readEscapedChar(true); + + if (escaped === null) { + containsInvalid = true; + } else { + out += escaped; + } + + chunkStart = this.state.pos; + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + ++this.state.pos; + + switch (ch) { + case 13: + if (this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + } + + case 10: + out += "\n"; + break; + + default: + out += String.fromCharCode(ch); + break; + } + + ++this.state.curLine; + this.state.lineStart = this.state.pos; + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + } + + recordStrictModeErrors(pos, message) { + if (this.state.strict && !this.state.strictErrors.has(pos)) { + this.raise(pos, message); + } else { + this.state.strictErrors.set(pos, message); + } + } + + readEscapedChar(inTemplate) { + const throwOnInvalid = !inTemplate; + const ch = this.input.charCodeAt(++this.state.pos); + ++this.state.pos; + + switch (ch) { + case 110: + return "\n"; + + case 114: + return "\r"; + + case 120: + { + const code = this.readHexChar(2, false, throwOnInvalid); + return code === null ? null : String.fromCharCode(code); + } + + case 117: + { + const code = this.readCodePoint(throwOnInvalid); + return code === null ? null : String.fromCodePoint(code); + } + + case 116: + return "\t"; + + case 98: + return "\b"; + + case 118: + return "\u000b"; + + case 102: + return "\f"; + + case 13: + if (this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + } + + case 10: + this.state.lineStart = this.state.pos; + ++this.state.curLine; + + case 8232: + case 8233: + return ""; + + case 56: + case 57: + if (inTemplate) { + return null; + } else { + this.recordStrictModeErrors(this.state.pos - 1, ErrorMessages.StrictNumericEscape); + } + + default: + if (ch >= 48 && ch <= 55) { + const codePos = this.state.pos - 1; + const match = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/); + let octalStr = match[0]; + let octal = parseInt(octalStr, 8); + + if (octal > 255) { + octalStr = octalStr.slice(0, -1); + octal = parseInt(octalStr, 8); + } + + this.state.pos += octalStr.length - 1; + const next = this.input.charCodeAt(this.state.pos); + + if (octalStr !== "0" || next === 56 || next === 57) { + if (inTemplate) { + return null; + } else { + this.recordStrictModeErrors(codePos, ErrorMessages.StrictNumericEscape); + } + } + + return String.fromCharCode(octal); + } + + return String.fromCharCode(ch); + } + } + + readHexChar(len, forceLen, throwOnInvalid) { + const codePos = this.state.pos; + const n = this.readInt(16, len, forceLen, false); + + if (n === null) { + if (throwOnInvalid) { + this.raise(codePos, ErrorMessages.InvalidEscapeSequence); + } else { + this.state.pos = codePos - 1; + } + } + + return n; + } + + readWord1(firstCode) { + this.state.containsEsc = false; + let word = ""; + const start = this.state.pos; + let chunkStart = this.state.pos; + + if (firstCode !== undefined) { + this.state.pos += firstCode <= 0xffff ? 1 : 2; + } + + while (this.state.pos < this.length) { + const ch = this.codePointAtPos(this.state.pos); + + if (isIdentifierChar(ch)) { + this.state.pos += ch <= 0xffff ? 1 : 2; + } else if (ch === 92) { + this.state.containsEsc = true; + word += this.input.slice(chunkStart, this.state.pos); + const escStart = this.state.pos; + const identifierCheck = this.state.pos === start ? isIdentifierStart : isIdentifierChar; + + if (this.input.charCodeAt(++this.state.pos) !== 117) { + this.raise(this.state.pos, ErrorMessages.MissingUnicodeEscape); + chunkStart = this.state.pos - 1; + continue; + } + + ++this.state.pos; + const esc = this.readCodePoint(true); + + if (esc !== null) { + if (!identifierCheck(esc)) { + this.raise(escStart, ErrorMessages.EscapedCharNotAnIdentifier); + } + + word += String.fromCodePoint(esc); + } + + chunkStart = this.state.pos; + } else { + break; + } + } + + return word + this.input.slice(chunkStart, this.state.pos); + } + + readWord(firstCode) { + const word = this.readWord1(firstCode); + const type = keywords$1.get(word) || 5; + this.finishToken(type, word); + } + + checkKeywordEscapes() { + const { + type + } = this.state; + + if (tokenIsKeyword(type) && this.state.containsEsc) { + this.raise(this.state.start, ErrorMessages.InvalidEscapedReservedWord, tokenLabelName(type)); + } + } + + updateContext(prevType) { + const { + context, + type + } = this.state; + + switch (type) { + case 16: + context.pop(); + break; + + case 13: + case 15: + case 31: + context.push(types$1.brace); + break; + + case 30: + if (context[context.length - 1] === types$1.template) { + context.pop(); + } else { + context.push(types$1.template); + } + + break; + } + } + + } + + class ClassScope { + constructor() { + this.privateNames = new Set(); + this.loneAccessors = new Map(); + this.undefinedPrivateNames = new Map(); + } + + } + class ClassScopeHandler { + constructor(raise) { + this.stack = []; + this.undefinedPrivateNames = new Map(); + this.raise = raise; + } + + current() { + return this.stack[this.stack.length - 1]; + } + + enter() { + this.stack.push(new ClassScope()); + } + + exit() { + const oldClassScope = this.stack.pop(); + const current = this.current(); + + for (const [name, pos] of Array.from(oldClassScope.undefinedPrivateNames)) { + if (current) { + if (!current.undefinedPrivateNames.has(name)) { + current.undefinedPrivateNames.set(name, pos); + } + } else { + this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name); + } + } + } + + declarePrivateName(name, elementType, pos) { + const classScope = this.current(); + let redefined = classScope.privateNames.has(name); + + if (elementType & CLASS_ELEMENT_KIND_ACCESSOR) { + const accessor = redefined && classScope.loneAccessors.get(name); + + if (accessor) { + const oldStatic = accessor & CLASS_ELEMENT_FLAG_STATIC; + const newStatic = elementType & CLASS_ELEMENT_FLAG_STATIC; + const oldKind = accessor & CLASS_ELEMENT_KIND_ACCESSOR; + const newKind = elementType & CLASS_ELEMENT_KIND_ACCESSOR; + redefined = oldKind === newKind || oldStatic !== newStatic; + if (!redefined) classScope.loneAccessors.delete(name); + } else if (!redefined) { + classScope.loneAccessors.set(name, elementType); + } + } + + if (redefined) { + this.raise(pos, ErrorMessages.PrivateNameRedeclaration, name); + } + + classScope.privateNames.add(name); + classScope.undefinedPrivateNames.delete(name); + } + + usePrivateName(name, pos) { + let classScope; + + for (classScope of this.stack) { + if (classScope.privateNames.has(name)) return; + } + + if (classScope) { + classScope.undefinedPrivateNames.set(name, pos); + } else { + this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name); + } + } + + } + + const kExpression = 0, + kMaybeArrowParameterDeclaration = 1, + kMaybeAsyncArrowParameterDeclaration = 2, + kParameterDeclaration = 3; + + class ExpressionScope { + constructor(type = kExpression) { + this.type = void 0; + this.type = type; + } + + canBeArrowParameterDeclaration() { + return this.type === kMaybeAsyncArrowParameterDeclaration || this.type === kMaybeArrowParameterDeclaration; + } + + isCertainlyParameterDeclaration() { + return this.type === kParameterDeclaration; + } + + } + + class ArrowHeadParsingScope extends ExpressionScope { + constructor(type) { + super(type); + this.errors = new Map(); + } + + recordDeclarationError(pos, template) { + this.errors.set(pos, template); + } + + clearDeclarationError(pos) { + this.errors.delete(pos); + } + + iterateErrors(iterator) { + this.errors.forEach(iterator); + } + + } + + class ExpressionScopeHandler { + constructor(raise) { + this.stack = [new ExpressionScope()]; + this.raise = raise; + } + + enter(scope) { + this.stack.push(scope); + } + + exit() { + this.stack.pop(); + } + + recordParameterInitializerError(pos, template) { + const { + stack + } = this; + let i = stack.length - 1; + let scope = stack[i]; + + while (!scope.isCertainlyParameterDeclaration()) { + if (scope.canBeArrowParameterDeclaration()) { + scope.recordDeclarationError(pos, template); + } else { + return; + } + + scope = stack[--i]; + } + + this.raise(pos, template); + } + + recordParenthesizedIdentifierError(pos, template) { + const { + stack + } = this; + const scope = stack[stack.length - 1]; + + if (scope.isCertainlyParameterDeclaration()) { + this.raise(pos, template); + } else if (scope.canBeArrowParameterDeclaration()) { + scope.recordDeclarationError(pos, template); + } else { + return; + } + } + + recordAsyncArrowParametersError(pos, template) { + const { + stack + } = this; + let i = stack.length - 1; + let scope = stack[i]; + + while (scope.canBeArrowParameterDeclaration()) { + if (scope.type === kMaybeAsyncArrowParameterDeclaration) { + scope.recordDeclarationError(pos, template); + } + + scope = stack[--i]; + } + } + + validateAsPattern() { + const { + stack + } = this; + const currentScope = stack[stack.length - 1]; + if (!currentScope.canBeArrowParameterDeclaration()) return; + currentScope.iterateErrors((template, pos) => { + this.raise(pos, template); + let i = stack.length - 2; + let scope = stack[i]; + + while (scope.canBeArrowParameterDeclaration()) { + scope.clearDeclarationError(pos); + scope = stack[--i]; + } + }); + } + + } + function newParameterDeclarationScope() { + return new ExpressionScope(kParameterDeclaration); + } + function newArrowHeadScope() { + return new ArrowHeadParsingScope(kMaybeArrowParameterDeclaration); + } + function newAsyncArrowScope() { + return new ArrowHeadParsingScope(kMaybeAsyncArrowParameterDeclaration); + } + function newExpressionScope() { + return new ExpressionScope(); + } + + const PARAM = 0b0000, + PARAM_YIELD = 0b0001, + PARAM_AWAIT = 0b0010, + PARAM_RETURN = 0b0100, + PARAM_IN = 0b1000; + class ProductionParameterHandler { + constructor() { + this.stacks = []; + } + + enter(flags) { + this.stacks.push(flags); + } + + exit() { + this.stacks.pop(); + } + + currentFlags() { + return this.stacks[this.stacks.length - 1]; + } + + get hasAwait() { + return (this.currentFlags() & PARAM_AWAIT) > 0; + } + + get hasYield() { + return (this.currentFlags() & PARAM_YIELD) > 0; + } + + get hasReturn() { + return (this.currentFlags() & PARAM_RETURN) > 0; + } + + get hasIn() { + return (this.currentFlags() & PARAM_IN) > 0; + } + + } + function functionFlags(isAsync, isGenerator) { + return (isAsync ? PARAM_AWAIT : 0) | (isGenerator ? PARAM_YIELD : 0); + } + + class UtilParser extends Tokenizer { + addExtra(node, key, val) { + if (!node) return; + const extra = node.extra = node.extra || {}; + extra[key] = val; + } + + isRelational(op) { + return this.match(50) && this.state.value === op; + } + + expectRelational(op) { + if (this.isRelational(op)) { + this.next(); + } else { + this.unexpected(null, 50); + } + } + + isContextual(name) { + return this.match(5) && this.state.value === name && !this.state.containsEsc; + } + + isUnparsedContextual(nameStart, name) { + const nameEnd = nameStart + name.length; + + if (this.input.slice(nameStart, nameEnd) === name) { + const nextCh = this.input.charCodeAt(nameEnd); + return !(isIdentifierChar(nextCh) || (nextCh & 0xfc00) === 0xd800); + } + + return false; + } + + isLookaheadContextual(name) { + const next = this.nextTokenStart(); + return this.isUnparsedContextual(next, name); + } + + eatContextual(name) { + return this.isContextual(name) && this.eat(5); + } + + expectContextual(name, template) { + if (!this.eatContextual(name)) this.unexpected(null, template); + } + + canInsertSemicolon() { + return this.match(7) || this.match(16) || this.hasPrecedingLineBreak(); + } + + hasPrecedingLineBreak() { + return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); + } + + hasFollowingLineBreak() { + skipWhiteSpaceToLineBreak.lastIndex = this.state.end; + return skipWhiteSpaceToLineBreak.test(this.input); + } + + isLineTerminator() { + return this.eat(21) || this.canInsertSemicolon(); + } + + semicolon(allowAsi = true) { + if (allowAsi ? this.isLineTerminator() : this.eat(21)) return; + this.raise(this.state.lastTokEnd, ErrorMessages.MissingSemicolon); + } + + expect(type, pos) { + this.eat(type) || this.unexpected(pos, type); + } + + assertNoSpace(message = "Unexpected space.") { + if (this.state.start > this.state.lastTokEnd) { + this.raise(this.state.lastTokEnd, { + code: ErrorCodes.SyntaxError, + reasonCode: "UnexpectedSpace", + template: message + }); + } + } + + unexpected(pos, messageOrType = { + code: ErrorCodes.SyntaxError, + reasonCode: "UnexpectedToken", + template: "Unexpected token" + }) { + if (isTokenType(messageOrType)) { + messageOrType = { + code: ErrorCodes.SyntaxError, + reasonCode: "UnexpectedToken", + template: `Unexpected token, expected "${tokenLabelName(messageOrType)}"` + }; + } + + throw this.raise(pos != null ? pos : this.state.start, messageOrType); + } + + expectPlugin(name, pos) { + if (!this.hasPlugin(name)) { + throw this.raiseWithData(pos != null ? pos : this.state.start, { + missingPlugin: [name] + }, `This experimental syntax requires enabling the parser plugin: '${name}'`); + } + + return true; + } + + expectOnePlugin(names, pos) { + if (!names.some(n => this.hasPlugin(n))) { + throw this.raiseWithData(pos != null ? pos : this.state.start, { + missingPlugin: names + }, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`); + } + } + + tryParse(fn, oldState = this.state.clone()) { + const abortSignal = { + node: null + }; + + try { + const node = fn((node = null) => { + abortSignal.node = node; + throw abortSignal; + }); + + if (this.state.errors.length > oldState.errors.length) { + const failState = this.state; + this.state = oldState; + this.state.tokensLength = failState.tokensLength; + return { + node, + error: failState.errors[oldState.errors.length], + thrown: false, + aborted: false, + failState + }; + } + + return { + node, + error: null, + thrown: false, + aborted: false, + failState: null + }; + } catch (error) { + const failState = this.state; + this.state = oldState; + + if (error instanceof SyntaxError) { + return { + node: null, + error, + thrown: true, + aborted: false, + failState + }; + } + + if (error === abortSignal) { + return { + node: abortSignal.node, + error: null, + thrown: false, + aborted: true, + failState + }; + } + + throw error; + } + } + + checkExpressionErrors(refExpressionErrors, andThrow) { + if (!refExpressionErrors) return false; + const { + shorthandAssign, + doubleProto, + optionalParameters + } = refExpressionErrors; + + if (!andThrow) { + return shorthandAssign >= 0 || doubleProto >= 0 || optionalParameters >= 0; + } + + if (shorthandAssign >= 0) { + this.unexpected(shorthandAssign); + } + + if (doubleProto >= 0) { + this.raise(doubleProto, ErrorMessages.DuplicateProto); + } + + if (optionalParameters >= 0) { + this.unexpected(optionalParameters); + } + } + + isLiteralPropertyName() { + return this.match(5) || tokenIsKeyword(this.state.type) || this.match(4) || this.match(0) || this.match(1) || this.match(2); + } + + isPrivateName(node) { + return node.type === "PrivateName"; + } + + getPrivateNameSV(node) { + return node.id.name; + } + + hasPropertyAsPrivateName(node) { + return (node.type === "MemberExpression" || node.type === "OptionalMemberExpression") && this.isPrivateName(node.property); + } + + isOptionalChain(node) { + return node.type === "OptionalMemberExpression" || node.type === "OptionalCallExpression"; + } + + isObjectProperty(node) { + return node.type === "ObjectProperty"; + } + + isObjectMethod(node) { + return node.type === "ObjectMethod"; + } + + initializeScopes(inModule = this.options.sourceType === "module") { + const oldLabels = this.state.labels; + this.state.labels = []; + const oldExportedIdentifiers = this.exportedIdentifiers; + this.exportedIdentifiers = new Set(); + const oldInModule = this.inModule; + this.inModule = inModule; + const oldScope = this.scope; + const ScopeHandler = this.getScopeHandler(); + this.scope = new ScopeHandler(this.raise.bind(this), this.inModule); + const oldProdParam = this.prodParam; + this.prodParam = new ProductionParameterHandler(); + const oldClassScope = this.classScope; + this.classScope = new ClassScopeHandler(this.raise.bind(this)); + const oldExpressionScope = this.expressionScope; + this.expressionScope = new ExpressionScopeHandler(this.raise.bind(this)); + return () => { + this.state.labels = oldLabels; + this.exportedIdentifiers = oldExportedIdentifiers; + this.inModule = oldInModule; + this.scope = oldScope; + this.prodParam = oldProdParam; + this.classScope = oldClassScope; + this.expressionScope = oldExpressionScope; + }; + } + + enterInitialScopes() { + let paramFlags = PARAM; + + if (this.inModule) { + paramFlags |= PARAM_AWAIT; + } + + this.scope.enter(SCOPE_PROGRAM); + this.prodParam.enter(paramFlags); + } + + } + class ExpressionErrors { + constructor() { + this.shorthandAssign = -1; + this.doubleProto = -1; + this.optionalParameters = -1; + } + + } + + class Node { + constructor(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + this.loc = new SourceLocation(loc); + if (parser != null && parser.options.ranges) this.range = [pos, 0]; + if (parser != null && parser.filename) this.loc.filename = parser.filename; + } + + } + + const NodePrototype = Node.prototype; + { + NodePrototype.__clone = function () { + const newNode = new Node(); + const keys = Object.keys(this); + + for (let i = 0, length = keys.length; i < length; i++) { + const key = keys[i]; + + if (key !== "leadingComments" && key !== "trailingComments" && key !== "innerComments") { + newNode[key] = this[key]; + } + } + + return newNode; + }; + } + + function clonePlaceholder(node) { + return cloneIdentifier(node); + } + + function cloneIdentifier(node) { + const { + type, + start, + end, + loc, + range, + extra, + name + } = node; + const cloned = Object.create(NodePrototype); + cloned.type = type; + cloned.start = start; + cloned.end = end; + cloned.loc = loc; + cloned.range = range; + cloned.extra = extra; + cloned.name = name; + + if (type === "Placeholder") { + cloned.expectedNode = node.expectedNode; + } + + return cloned; + } + function cloneStringLiteral(node) { + const { + type, + start, + end, + loc, + range, + extra + } = node; + + if (type === "Placeholder") { + return clonePlaceholder(node); + } + + const cloned = Object.create(NodePrototype); + cloned.type = "StringLiteral"; + cloned.start = start; + cloned.end = end; + cloned.loc = loc; + cloned.range = range; + cloned.extra = extra; + cloned.value = node.value; + return cloned; + } + class NodeUtils extends UtilParser { + startNode() { + return new Node(this, this.state.start, this.state.startLoc); + } + + startNodeAt(pos, loc) { + return new Node(this, pos, loc); + } + + startNodeAtNode(type) { + return this.startNodeAt(type.start, type.loc.start); + } + + finishNode(node, type) { + return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); + } + + finishNodeAt(node, type, pos, loc) { + + node.type = type; + node.end = pos; + node.loc.end = loc; + if (this.options.ranges) node.range[1] = pos; + if (this.options.attachComment) this.processComment(node); + return node; + } + + resetStartLocation(node, start, startLoc) { + node.start = start; + node.loc.start = startLoc; + if (this.options.ranges) node.range[0] = start; + } + + resetEndLocation(node, end = this.state.lastTokEnd, endLoc = this.state.lastTokEndLoc) { + node.end = end; + node.loc.end = endLoc; + if (this.options.ranges) node.range[1] = end; + } + + resetStartLocationFromNode(node, locationNode) { + this.resetStartLocation(node, locationNode.start, locationNode.loc.start); + } + + } + + const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]); + const FlowErrors = makeErrorTemplates({ + AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.", + AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module.", + AssignReservedType: "Cannot overwrite reserved type %0.", + DeclareClassElement: "The `declare` modifier can only appear on class fields.", + DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.", + DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement.", + EnumBooleanMemberNotInitialized: "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.", + EnumDuplicateMemberName: "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.", + EnumInconsistentMemberValues: "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.", + EnumInvalidExplicitType: "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + EnumInvalidExplicitTypeUnknownSupplied: "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + EnumInvalidMemberInitializerPrimaryType: "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.", + EnumInvalidMemberInitializerSymbolType: "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.", + EnumInvalidMemberInitializerUnknownType: "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.", + EnumInvalidMemberName: "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.", + EnumNumberMemberNotInitialized: "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.", + EnumStringMemberInconsistentlyInitailized: "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.", + GetterMayNotHaveThisParam: "A getter cannot have a `this` parameter.", + ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements.", + InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type.", + InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions.", + InexactVariance: "Explicit inexact syntax cannot have variance.", + InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`.", + MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.", + NestedDeclareModule: "`declare module` cannot be used inside another `declare module`.", + NestedFlowComment: "Cannot have a flow comment inside another flow comment.", + PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.", + SetterMayNotHaveThisParam: "A setter cannot have a `this` parameter.", + SpreadVariance: "Spread properties cannot have variance.", + ThisParamAnnotationRequired: "A type annotation is required for the `this` parameter.", + ThisParamBannedInConstructor: "Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions.", + ThisParamMayNotBeOptional: "The `this` parameter cannot be optional.", + ThisParamMustBeFirst: "The `this` parameter must be the first function parameter.", + ThisParamNoDefault: "The `this` parameter may not have a default value.", + TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.", + TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis.", + UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object.", + UnexpectedReservedType: "Unexpected reserved type %0.", + UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new.", + UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.", + UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions.", + UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint".', + UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration.", + UnexpectedTypeParameterBeforeAsyncArrowFunction: "Type parameters must come after the async keyword, e.g. instead of ` async () => {}`, use `async () => {}`.", + UnsupportedDeclareExportKind: "`declare export %0` is not supported. Use `%1` instead.", + UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module.", + UnterminatedFlowComment: "Unterminated flow-comment." + }, ErrorCodes.SyntaxError, "flow"); + + function isEsModuleType(bodyElement) { + return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration"); + } + + function hasTypeImportKind(node) { + return node.importKind === "type" || node.importKind === "typeof"; + } + + function isMaybeDefaultImport(state) { + return (state.type === 5 || tokenIsKeyword(state.type)) && state.value !== "from"; + } + + const exportSuggestions = { + const: "declare export var", + let: "declare export var", + type: "export type", + interface: "export interface" + }; + + function partition(list, test) { + const list1 = []; + const list2 = []; + + for (let i = 0; i < list.length; i++) { + (test(list[i], i, list) ? list1 : list2).push(list[i]); + } + + return [list1, list2]; + } + + const FLOW_PRAGMA_REGEX = /\*?\s*@((?:no)?flow)\b/; + var flow$1 = (superClass => class extends superClass { + constructor(...args) { + super(...args); + this.flowPragma = undefined; + } + + getScopeHandler() { + return FlowScopeHandler; + } + + shouldParseTypes() { + return this.getPluginOption("flow", "all") || this.flowPragma === "flow"; + } + + shouldParseEnums() { + return !!this.getPluginOption("flow", "enums"); + } + + finishToken(type, val) { + if (type !== 4 && type !== 21 && type !== 34) { + if (this.flowPragma === undefined) { + this.flowPragma = null; + } + } + + return super.finishToken(type, val); + } + + addComment(comment) { + if (this.flowPragma === undefined) { + const matches = FLOW_PRAGMA_REGEX.exec(comment.value); + + if (!matches) ; else if (matches[1] === "flow") { + this.flowPragma = "flow"; + } else if (matches[1] === "noflow") { + this.flowPragma = "noflow"; + } else { + throw new Error("Unexpected flow pragma"); + } + } + + return super.addComment(comment); + } + + flowParseTypeInitialiser(tok) { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(tok || 22); + const type = this.flowParseType(); + this.state.inType = oldInType; + return type; + } + + flowParsePredicate() { + const node = this.startNode(); + const moduloPos = this.state.start; + this.next(); + this.expectContextual("checks"); + + if (this.state.lastTokStart > moduloPos + 1) { + this.raise(moduloPos, FlowErrors.UnexpectedSpaceBetweenModuloChecks); + } + + if (this.eat(18)) { + node.value = this.parseExpression(); + this.expect(19); + return this.finishNode(node, "DeclaredPredicate"); + } else { + return this.finishNode(node, "InferredPredicate"); + } + } + + flowParseTypeAndPredicateInitialiser() { + const oldInType = this.state.inType; + this.state.inType = true; + this.expect(22); + let type = null; + let predicate = null; + + if (this.match(53)) { + this.state.inType = oldInType; + predicate = this.flowParsePredicate(); + } else { + type = this.flowParseType(); + this.state.inType = oldInType; + + if (this.match(53)) { + predicate = this.flowParsePredicate(); + } + } + + return [type, predicate]; + } + + flowParseDeclareClass(node) { + this.next(); + this.flowParseInterfaceish(node, true); + return this.finishNode(node, "DeclareClass"); + } + + flowParseDeclareFunction(node) { + this.next(); + const id = node.id = this.parseIdentifier(); + const typeNode = this.startNode(); + const typeContainer = this.startNode(); + + if (this.isRelational("<")) { + typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + typeNode.typeParameters = null; + } + + this.expect(18); + const tmp = this.flowParseFunctionTypeParams(); + typeNode.params = tmp.params; + typeNode.rest = tmp.rest; + typeNode.this = tmp._this; + this.expect(19); + [typeNode.returnType, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation"); + id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); + this.resetEndLocation(id); + this.semicolon(); + this.scope.declareName(node.id.name, BIND_FLOW_DECLARE_FN, node.id.start); + return this.finishNode(node, "DeclareFunction"); + } + + flowParseDeclare(node, insideModule) { + if (this.match(79)) { + return this.flowParseDeclareClass(node); + } else if (this.match(67)) { + return this.flowParseDeclareFunction(node); + } else if (this.match(73)) { + return this.flowParseDeclareVariable(node); + } else if (this.eatContextual("module")) { + if (this.match(24)) { + return this.flowParseDeclareModuleExports(node); + } else { + if (insideModule) { + this.raise(this.state.lastTokStart, FlowErrors.NestedDeclareModule); + } + + return this.flowParseDeclareModule(node); + } + } else if (this.isContextual("type")) { + return this.flowParseDeclareTypeAlias(node); + } else if (this.isContextual("opaque")) { + return this.flowParseDeclareOpaqueType(node); + } else if (this.isContextual("interface")) { + return this.flowParseDeclareInterface(node); + } else if (this.match(81)) { + return this.flowParseDeclareExportDeclaration(node, insideModule); + } else { + throw this.unexpected(); + } + } + + flowParseDeclareVariable(node) { + this.next(); + node.id = this.flowParseTypeAnnotatableIdentifier(true); + this.scope.declareName(node.id.name, BIND_VAR, node.id.start); + this.semicolon(); + return this.finishNode(node, "DeclareVariable"); + } + + flowParseDeclareModule(node) { + this.scope.enter(SCOPE_OTHER); + + if (this.match(4)) { + node.id = this.parseExprAtom(); + } else { + node.id = this.parseIdentifier(); + } + + const bodyNode = node.body = this.startNode(); + const body = bodyNode.body = []; + this.expect(13); + + while (!this.match(16)) { + let bodyNode = this.startNode(); + + if (this.match(82)) { + this.next(); + + if (!this.isContextual("type") && !this.match(86)) { + this.raise(this.state.lastTokStart, FlowErrors.InvalidNonTypeImportInDeclareModule); + } + + this.parseImport(bodyNode); + } else { + this.expectContextual("declare", FlowErrors.UnsupportedStatementInDeclareModule); + bodyNode = this.flowParseDeclare(bodyNode, true); + } + + body.push(bodyNode); + } + + this.scope.exit(); + this.expect(16); + this.finishNode(bodyNode, "BlockStatement"); + let kind = null; + let hasModuleExport = false; + body.forEach(bodyElement => { + if (isEsModuleType(bodyElement)) { + if (kind === "CommonJS") { + this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind); + } + + kind = "ES"; + } else if (bodyElement.type === "DeclareModuleExports") { + if (hasModuleExport) { + this.raise(bodyElement.start, FlowErrors.DuplicateDeclareModuleExports); + } + + if (kind === "ES") { + this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind); + } + + kind = "CommonJS"; + hasModuleExport = true; + } + }); + node.kind = kind || "CommonJS"; + return this.finishNode(node, "DeclareModule"); + } + + flowParseDeclareExportDeclaration(node, insideModule) { + this.expect(81); + + if (this.eat(64)) { + if (this.match(67) || this.match(79)) { + node.declaration = this.flowParseDeclare(this.startNode()); + } else { + node.declaration = this.flowParseType(); + this.semicolon(); + } + + node.default = true; + return this.finishNode(node, "DeclareExportDeclaration"); + } else { + if (this.match(74) || this.isLet() || (this.isContextual("type") || this.isContextual("interface")) && !insideModule) { + const label = this.state.value; + const suggestion = exportSuggestions[label]; + throw this.raise(this.state.start, FlowErrors.UnsupportedDeclareExportKind, label, suggestion); + } + + if (this.match(73) || this.match(67) || this.match(79) || this.isContextual("opaque")) { + node.declaration = this.flowParseDeclare(this.startNode()); + node.default = false; + return this.finishNode(node, "DeclareExportDeclaration"); + } else if (this.match(54) || this.match(13) || this.isContextual("interface") || this.isContextual("type") || this.isContextual("opaque")) { + node = this.parseExport(node); + + if (node.type === "ExportNamedDeclaration") { + node.type = "ExportDeclaration"; + node.default = false; + delete node.exportKind; + } + + node.type = "Declare" + node.type; + return node; + } + } + + throw this.unexpected(); + } + + flowParseDeclareModuleExports(node) { + this.next(); + this.expectContextual("exports"); + node.typeAnnotation = this.flowParseTypeAnnotation(); + this.semicolon(); + return this.finishNode(node, "DeclareModuleExports"); + } + + flowParseDeclareTypeAlias(node) { + this.next(); + this.flowParseTypeAlias(node); + node.type = "DeclareTypeAlias"; + return node; + } + + flowParseDeclareOpaqueType(node) { + this.next(); + this.flowParseOpaqueType(node, true); + node.type = "DeclareOpaqueType"; + return node; + } + + flowParseDeclareInterface(node) { + this.next(); + this.flowParseInterfaceish(node); + return this.finishNode(node, "DeclareInterface"); + } + + flowParseInterfaceish(node, isClass = false) { + node.id = this.flowParseRestrictedIdentifier(!isClass, true); + this.scope.declareName(node.id.name, isClass ? BIND_FUNCTION : BIND_LEXICAL, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.extends = []; + node.implements = []; + node.mixins = []; + + if (this.eat(80)) { + do { + node.extends.push(this.flowParseInterfaceExtends()); + } while (!isClass && this.eat(20)); + } + + if (this.isContextual("mixins")) { + this.next(); + + do { + node.mixins.push(this.flowParseInterfaceExtends()); + } while (this.eat(20)); + } + + if (this.isContextual("implements")) { + this.next(); + + do { + node.implements.push(this.flowParseInterfaceExtends()); + } while (this.eat(20)); + } + + node.body = this.flowParseObjectType({ + allowStatic: isClass, + allowExact: false, + allowSpread: false, + allowProto: isClass, + allowInexact: false + }); + } + + flowParseInterfaceExtends() { + const node = this.startNode(); + node.id = this.flowParseQualifiedTypeIdentifier(); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + + return this.finishNode(node, "InterfaceExtends"); + } + + flowParseInterface(node) { + this.flowParseInterfaceish(node); + return this.finishNode(node, "InterfaceDeclaration"); + } + + checkNotUnderscore(word) { + if (word === "_") { + this.raise(this.state.start, FlowErrors.UnexpectedReservedUnderscore); + } + } + + checkReservedType(word, startLoc, declaration) { + if (!reservedTypes.has(word)) return; + this.raise(startLoc, declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, word); + } + + flowParseRestrictedIdentifier(liberal, declaration) { + this.checkReservedType(this.state.value, this.state.start, declaration); + return this.parseIdentifier(liberal); + } + + flowParseTypeAlias(node) { + node.id = this.flowParseRestrictedIdentifier(false, true); + this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.right = this.flowParseTypeInitialiser(35); + this.semicolon(); + return this.finishNode(node, "TypeAlias"); + } + + flowParseOpaqueType(node, declare) { + this.expectContextual("type"); + node.id = this.flowParseRestrictedIdentifier(true, true); + this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } else { + node.typeParameters = null; + } + + node.supertype = null; + + if (this.match(22)) { + node.supertype = this.flowParseTypeInitialiser(22); + } + + node.impltype = null; + + if (!declare) { + node.impltype = this.flowParseTypeInitialiser(35); + } + + this.semicolon(); + return this.finishNode(node, "OpaqueType"); + } + + flowParseTypeParameter(requireDefault = false) { + const nodeStart = this.state.start; + const node = this.startNode(); + const variance = this.flowParseVariance(); + const ident = this.flowParseTypeAnnotatableIdentifier(); + node.name = ident.name; + node.variance = variance; + node.bound = ident.typeAnnotation; + + if (this.match(35)) { + this.eat(35); + node.default = this.flowParseType(); + } else { + if (requireDefault) { + this.raise(nodeStart, FlowErrors.MissingTypeParamDefault); + } + } + + return this.finishNode(node, "TypeParameter"); + } + + flowParseTypeParameterDeclaration() { + const oldInType = this.state.inType; + const node = this.startNode(); + node.params = []; + this.state.inType = true; + + if (this.isRelational("<") || this.match(94)) { + this.next(); + } else { + this.unexpected(); + } + + let defaultRequired = false; + + do { + const typeParameter = this.flowParseTypeParameter(defaultRequired); + node.params.push(typeParameter); + + if (typeParameter.default) { + defaultRequired = true; + } + + if (!this.isRelational(">")) { + this.expect(20); + } + } while (!this.isRelational(">")); + + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterDeclaration"); + } + + flowParseTypeParameterInstantiation() { + const node = this.startNode(); + const oldInType = this.state.inType; + node.params = []; + this.state.inType = true; + this.expectRelational("<"); + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = false; + + while (!this.isRelational(">")) { + node.params.push(this.flowParseType()); + + if (!this.isRelational(">")) { + this.expect(20); + } + } + + this.state.noAnonFunctionType = oldNoAnonFunctionType; + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterInstantiation"); + } + + flowParseTypeParameterInstantiationCallOrNew() { + const node = this.startNode(); + const oldInType = this.state.inType; + node.params = []; + this.state.inType = true; + this.expectRelational("<"); + + while (!this.isRelational(">")) { + node.params.push(this.flowParseTypeOrImplicitInstantiation()); + + if (!this.isRelational(">")) { + this.expect(20); + } + } + + this.expectRelational(">"); + this.state.inType = oldInType; + return this.finishNode(node, "TypeParameterInstantiation"); + } + + flowParseInterfaceType() { + const node = this.startNode(); + this.expectContextual("interface"); + node.extends = []; + + if (this.eat(80)) { + do { + node.extends.push(this.flowParseInterfaceExtends()); + } while (this.eat(20)); + } + + node.body = this.flowParseObjectType({ + allowStatic: false, + allowExact: false, + allowSpread: false, + allowProto: false, + allowInexact: false + }); + return this.finishNode(node, "InterfaceTypeAnnotation"); + } + + flowParseObjectPropertyKey() { + return this.match(0) || this.match(4) ? this.parseExprAtom() : this.parseIdentifier(true); + } + + flowParseObjectTypeIndexer(node, isStatic, variance) { + node.static = isStatic; + + if (this.lookahead().type === 22) { + node.id = this.flowParseObjectPropertyKey(); + node.key = this.flowParseTypeInitialiser(); + } else { + node.id = null; + node.key = this.flowParseType(); + } + + this.expect(11); + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + return this.finishNode(node, "ObjectTypeIndexer"); + } + + flowParseObjectTypeInternalSlot(node, isStatic) { + node.static = isStatic; + node.id = this.flowParseObjectPropertyKey(); + this.expect(11); + this.expect(11); + + if (this.isRelational("<") || this.match(18)) { + node.method = true; + node.optional = false; + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + } else { + node.method = false; + + if (this.eat(25)) { + node.optional = true; + } + + node.value = this.flowParseTypeInitialiser(); + } + + return this.finishNode(node, "ObjectTypeInternalSlot"); + } + + flowParseObjectTypeMethodish(node) { + node.params = []; + node.rest = null; + node.typeParameters = null; + node.this = null; + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + this.expect(18); + + if (this.match(77)) { + node.this = this.flowParseFunctionTypeParam(true); + node.this.name = null; + + if (!this.match(19)) { + this.expect(20); + } + } + + while (!this.match(19) && !this.match(29)) { + node.params.push(this.flowParseFunctionTypeParam(false)); + + if (!this.match(19)) { + this.expect(20); + } + } + + if (this.eat(29)) { + node.rest = this.flowParseFunctionTypeParam(false); + } + + this.expect(19); + node.returnType = this.flowParseTypeInitialiser(); + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + flowParseObjectTypeCallProperty(node, isStatic) { + const valueNode = this.startNode(); + node.static = isStatic; + node.value = this.flowParseObjectTypeMethodish(valueNode); + return this.finishNode(node, "ObjectTypeCallProperty"); + } + + flowParseObjectType({ + allowStatic, + allowExact, + allowSpread, + allowProto, + allowInexact + }) { + const oldInType = this.state.inType; + this.state.inType = true; + const nodeStart = this.startNode(); + nodeStart.callProperties = []; + nodeStart.properties = []; + nodeStart.indexers = []; + nodeStart.internalSlots = []; + let endDelim; + let exact; + let inexact = false; + + if (allowExact && this.match(14)) { + this.expect(14); + endDelim = 17; + exact = true; + } else { + this.expect(13); + endDelim = 16; + exact = false; + } + + nodeStart.exact = exact; + + while (!this.match(endDelim)) { + let isStatic = false; + let protoStart = null; + let inexactStart = null; + const node = this.startNode(); + + if (allowProto && this.isContextual("proto")) { + const lookahead = this.lookahead(); + + if (lookahead.type !== 22 && lookahead.type !== 25) { + this.next(); + protoStart = this.state.start; + allowStatic = false; + } + } + + if (allowStatic && this.isContextual("static")) { + const lookahead = this.lookahead(); + + if (lookahead.type !== 22 && lookahead.type !== 25) { + this.next(); + isStatic = true; + } + } + + const variance = this.flowParseVariance(); + + if (this.eat(8)) { + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (this.eat(8)) { + if (variance) { + this.unexpected(variance.start); + } + + nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic)); + } else { + nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); + } + } else if (this.match(18) || this.isRelational("<")) { + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.unexpected(variance.start); + } + + nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); + } else { + let kind = "init"; + + if (this.isContextual("get") || this.isContextual("set")) { + const lookahead = this.lookahead(); + + if (lookahead.type === 5 || lookahead.type === 4 || lookahead.type === 0) { + kind = this.state.value; + this.next(); + } + } + + const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact); + + if (propOrInexact === null) { + inexact = true; + inexactStart = this.state.lastTokStart; + } else { + nodeStart.properties.push(propOrInexact); + } + } + + this.flowObjectTypeSemicolon(); + + if (inexactStart && !this.match(16) && !this.match(17)) { + this.raise(inexactStart, FlowErrors.UnexpectedExplicitInexactInObject); + } + } + + this.expect(endDelim); + + if (allowSpread) { + nodeStart.inexact = inexact; + } + + const out = this.finishNode(nodeStart, "ObjectTypeAnnotation"); + this.state.inType = oldInType; + return out; + } + + flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) { + if (this.eat(29)) { + const isInexactToken = this.match(20) || this.match(21) || this.match(16) || this.match(17); + + if (isInexactToken) { + if (!allowSpread) { + this.raise(this.state.lastTokStart, FlowErrors.InexactInsideNonObject); + } else if (!allowInexact) { + this.raise(this.state.lastTokStart, FlowErrors.InexactInsideExact); + } + + if (variance) { + this.raise(variance.start, FlowErrors.InexactVariance); + } + + return null; + } + + if (!allowSpread) { + this.raise(this.state.lastTokStart, FlowErrors.UnexpectedSpreadType); + } + + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.raise(variance.start, FlowErrors.SpreadVariance); + } + + node.argument = this.flowParseType(); + return this.finishNode(node, "ObjectTypeSpreadProperty"); + } else { + node.key = this.flowParseObjectPropertyKey(); + node.static = isStatic; + node.proto = protoStart != null; + node.kind = kind; + let optional = false; + + if (this.isRelational("<") || this.match(18)) { + node.method = true; + + if (protoStart != null) { + this.unexpected(protoStart); + } + + if (variance) { + this.unexpected(variance.start); + } + + node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); + + if (kind === "get" || kind === "set") { + this.flowCheckGetterSetterParams(node); + } + + if (!allowSpread && node.key.name === "constructor" && node.value.this) { + this.raise(node.value.this.start, FlowErrors.ThisParamBannedInConstructor); + } + } else { + if (kind !== "init") this.unexpected(); + node.method = false; + + if (this.eat(25)) { + optional = true; + } + + node.value = this.flowParseTypeInitialiser(); + node.variance = variance; + } + + node.optional = optional; + return this.finishNode(node, "ObjectTypeProperty"); + } + } + + flowCheckGetterSetterParams(property) { + const paramCount = property.kind === "get" ? 0 : 1; + const start = property.start; + const length = property.value.params.length + (property.value.rest ? 1 : 0); + + if (property.value.this) { + this.raise(property.value.this.start, property.kind === "get" ? FlowErrors.GetterMayNotHaveThisParam : FlowErrors.SetterMayNotHaveThisParam); + } + + if (length !== paramCount) { + if (property.kind === "get") { + this.raise(start, ErrorMessages.BadGetterArity); + } else { + this.raise(start, ErrorMessages.BadSetterArity); + } + } + + if (property.kind === "set" && property.value.rest) { + this.raise(start, ErrorMessages.BadSetterRestParameter); + } + } + + flowObjectTypeSemicolon() { + if (!this.eat(21) && !this.eat(20) && !this.match(16) && !this.match(17)) { + this.unexpected(); + } + } + + flowParseQualifiedTypeIdentifier(startPos, startLoc, id) { + startPos = startPos || this.state.start; + startLoc = startLoc || this.state.startLoc; + let node = id || this.flowParseRestrictedIdentifier(true); + + while (this.eat(24)) { + const node2 = this.startNodeAt(startPos, startLoc); + node2.qualification = node; + node2.id = this.flowParseRestrictedIdentifier(true); + node = this.finishNode(node2, "QualifiedTypeIdentifier"); + } + + return node; + } + + flowParseGenericType(startPos, startLoc, id) { + const node = this.startNodeAt(startPos, startLoc); + node.typeParameters = null; + node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } + + return this.finishNode(node, "GenericTypeAnnotation"); + } + + flowParseTypeofType() { + const node = this.startNode(); + this.expect(86); + node.argument = this.flowParsePrimaryType(); + return this.finishNode(node, "TypeofTypeAnnotation"); + } + + flowParseTupleType() { + const node = this.startNode(); + node.types = []; + this.expect(8); + + while (this.state.pos < this.length && !this.match(11)) { + node.types.push(this.flowParseType()); + if (this.match(11)) break; + this.expect(20); + } + + this.expect(11); + return this.finishNode(node, "TupleTypeAnnotation"); + } + + flowParseFunctionTypeParam(first) { + let name = null; + let optional = false; + let typeAnnotation = null; + const node = this.startNode(); + const lh = this.lookahead(); + const isThis = this.state.type === 77; + + if (lh.type === 22 || lh.type === 25) { + if (isThis && !first) { + this.raise(node.start, FlowErrors.ThisParamMustBeFirst); + } + + name = this.parseIdentifier(isThis); + + if (this.eat(25)) { + optional = true; + + if (isThis) { + this.raise(node.start, FlowErrors.ThisParamMayNotBeOptional); + } + } + + typeAnnotation = this.flowParseTypeInitialiser(); + } else { + typeAnnotation = this.flowParseType(); + } + + node.name = name; + node.optional = optional; + node.typeAnnotation = typeAnnotation; + return this.finishNode(node, "FunctionTypeParam"); + } + + reinterpretTypeAsFunctionTypeParam(type) { + const node = this.startNodeAt(type.start, type.loc.start); + node.name = null; + node.optional = false; + node.typeAnnotation = type; + return this.finishNode(node, "FunctionTypeParam"); + } + + flowParseFunctionTypeParams(params = []) { + let rest = null; + let _this = null; + + if (this.match(77)) { + _this = this.flowParseFunctionTypeParam(true); + _this.name = null; + + if (!this.match(19)) { + this.expect(20); + } + } + + while (!this.match(19) && !this.match(29)) { + params.push(this.flowParseFunctionTypeParam(false)); + + if (!this.match(19)) { + this.expect(20); + } + } + + if (this.eat(29)) { + rest = this.flowParseFunctionTypeParam(false); + } + + return { + params, + rest, + _this + }; + } + + flowIdentToTypeAnnotation(startPos, startLoc, node, id) { + switch (id.name) { + case "any": + return this.finishNode(node, "AnyTypeAnnotation"); + + case "bool": + case "boolean": + return this.finishNode(node, "BooleanTypeAnnotation"); + + case "mixed": + return this.finishNode(node, "MixedTypeAnnotation"); + + case "empty": + return this.finishNode(node, "EmptyTypeAnnotation"); + + case "number": + return this.finishNode(node, "NumberTypeAnnotation"); + + case "string": + return this.finishNode(node, "StringTypeAnnotation"); + + case "symbol": + return this.finishNode(node, "SymbolTypeAnnotation"); + + default: + this.checkNotUnderscore(id.name); + return this.flowParseGenericType(startPos, startLoc, id); + } + } + + flowParsePrimaryType() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const node = this.startNode(); + let tmp; + let type; + let isGroupedType = false; + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + + switch (this.state.type) { + case 5: + if (this.isContextual("interface")) { + return this.flowParseInterfaceType(); + } + + return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier()); + + case 13: + return this.flowParseObjectType({ + allowStatic: false, + allowExact: false, + allowSpread: true, + allowProto: false, + allowInexact: true + }); + + case 14: + return this.flowParseObjectType({ + allowStatic: false, + allowExact: true, + allowSpread: true, + allowProto: false, + allowInexact: false + }); + + case 8: + this.state.noAnonFunctionType = false; + type = this.flowParseTupleType(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + return type; + + case 50: + if (this.state.value === "<") { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + this.expect(18); + tmp = this.flowParseFunctionTypeParams(); + node.params = tmp.params; + node.rest = tmp.rest; + node.this = tmp._this; + this.expect(19); + this.expect(27); + node.returnType = this.flowParseType(); + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + break; + + case 18: + this.next(); + + if (!this.match(19) && !this.match(29)) { + if (this.match(5) || this.match(77)) { + const token = this.lookahead().type; + isGroupedType = token !== 25 && token !== 22; + } else { + isGroupedType = true; + } + } + + if (isGroupedType) { + this.state.noAnonFunctionType = false; + type = this.flowParseType(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + + if (this.state.noAnonFunctionType || !(this.match(20) || this.match(19) && this.lookahead().type === 27)) { + this.expect(19); + return type; + } else { + this.eat(20); + } + } + + if (type) { + tmp = this.flowParseFunctionTypeParams([this.reinterpretTypeAsFunctionTypeParam(type)]); + } else { + tmp = this.flowParseFunctionTypeParams(); + } + + node.params = tmp.params; + node.rest = tmp.rest; + node.this = tmp._this; + this.expect(19); + this.expect(27); + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + + case 4: + return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); + + case 84: + case 85: + node.value = this.match(84); + this.next(); + return this.finishNode(node, "BooleanLiteralTypeAnnotation"); + + case 52: + if (this.state.value === "-") { + this.next(); + + if (this.match(0)) { + return this.parseLiteralAtNode(-this.state.value, "NumberLiteralTypeAnnotation", node); + } + + if (this.match(1)) { + return this.parseLiteralAtNode(-this.state.value, "BigIntLiteralTypeAnnotation", node); + } + + throw this.raise(this.state.start, FlowErrors.UnexpectedSubtractionOperand); + } + + throw this.unexpected(); + + case 0: + return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); + + case 1: + return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation"); + + case 87: + this.next(); + return this.finishNode(node, "VoidTypeAnnotation"); + + case 83: + this.next(); + return this.finishNode(node, "NullLiteralTypeAnnotation"); + + case 77: + this.next(); + return this.finishNode(node, "ThisTypeAnnotation"); + + case 54: + this.next(); + return this.finishNode(node, "ExistsTypeAnnotation"); + + case 86: + return this.flowParseTypeofType(); + + default: + if (tokenIsKeyword(this.state.type)) { + const label = tokenLabelName(this.state.type); + this.next(); + return super.createIdentifier(node, label); + } + + } + + throw this.unexpected(); + } + + flowParsePostfixType() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let type = this.flowParsePrimaryType(); + let seenOptionalIndexedAccess = false; + + while ((this.match(8) || this.match(26)) && !this.canInsertSemicolon()) { + const node = this.startNodeAt(startPos, startLoc); + const optional = this.eat(26); + seenOptionalIndexedAccess = seenOptionalIndexedAccess || optional; + this.expect(8); + + if (!optional && this.match(11)) { + node.elementType = type; + this.next(); + type = this.finishNode(node, "ArrayTypeAnnotation"); + } else { + node.objectType = type; + node.indexType = this.flowParseType(); + this.expect(11); + + if (seenOptionalIndexedAccess) { + node.optional = optional; + type = this.finishNode(node, "OptionalIndexedAccessType"); + } else { + type = this.finishNode(node, "IndexedAccessType"); + } + } + } + + return type; + } + + flowParsePrefixType() { + const node = this.startNode(); + + if (this.eat(25)) { + node.typeAnnotation = this.flowParsePrefixType(); + return this.finishNode(node, "NullableTypeAnnotation"); + } else { + return this.flowParsePostfixType(); + } + } + + flowParseAnonFunctionWithoutParens() { + const param = this.flowParsePrefixType(); + + if (!this.state.noAnonFunctionType && this.eat(27)) { + const node = this.startNodeAt(param.start, param.loc.start); + node.params = [this.reinterpretTypeAsFunctionTypeParam(param)]; + node.rest = null; + node.this = null; + node.returnType = this.flowParseType(); + node.typeParameters = null; + return this.finishNode(node, "FunctionTypeAnnotation"); + } + + return param; + } + + flowParseIntersectionType() { + const node = this.startNode(); + this.eat(48); + const type = this.flowParseAnonFunctionWithoutParens(); + node.types = [type]; + + while (this.eat(48)) { + node.types.push(this.flowParseAnonFunctionWithoutParens()); + } + + return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation"); + } + + flowParseUnionType() { + const node = this.startNode(); + this.eat(46); + const type = this.flowParseIntersectionType(); + node.types = [type]; + + while (this.eat(46)) { + node.types.push(this.flowParseIntersectionType()); + } + + return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation"); + } + + flowParseType() { + const oldInType = this.state.inType; + this.state.inType = true; + const type = this.flowParseUnionType(); + this.state.inType = oldInType; + return type; + } + + flowParseTypeOrImplicitInstantiation() { + if (this.state.type === 5 && this.state.value === "_") { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const node = this.parseIdentifier(); + return this.flowParseGenericType(startPos, startLoc, node); + } else { + return this.flowParseType(); + } + } + + flowParseTypeAnnotation() { + const node = this.startNode(); + node.typeAnnotation = this.flowParseTypeInitialiser(); + return this.finishNode(node, "TypeAnnotation"); + } + + flowParseTypeAnnotatableIdentifier(allowPrimitiveOverride) { + const ident = allowPrimitiveOverride ? this.parseIdentifier() : this.flowParseRestrictedIdentifier(); + + if (this.match(22)) { + ident.typeAnnotation = this.flowParseTypeAnnotation(); + this.resetEndLocation(ident); + } + + return ident; + } + + typeCastToParameter(node) { + node.expression.typeAnnotation = node.typeAnnotation; + this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + return node.expression; + } + + flowParseVariance() { + let variance = null; + + if (this.match(52)) { + variance = this.startNode(); + + if (this.state.value === "+") { + variance.kind = "plus"; + } else { + variance.kind = "minus"; + } + + this.next(); + this.finishNode(variance, "Variance"); + } + + return variance; + } + + parseFunctionBody(node, allowExpressionBody, isMethod = false) { + if (allowExpressionBody) { + return this.forwardNoArrowParamsConversionAt(node, () => super.parseFunctionBody(node, true, isMethod)); + } + + return super.parseFunctionBody(node, false, isMethod); + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + if (this.match(22)) { + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + node.returnType = typeNode.typeAnnotation ? this.finishNode(typeNode, "TypeAnnotation") : null; + } + + super.parseFunctionBodyAndFinish(node, type, isMethod); + } + + parseStatement(context, topLevel) { + if (this.state.strict && this.match(5) && this.state.value === "interface") { + const lookahead = this.lookahead(); + + if (lookahead.type === 5 || isKeyword(lookahead.value)) { + const node = this.startNode(); + this.next(); + return this.flowParseInterface(node); + } + } else if (this.shouldParseEnums() && this.isContextual("enum")) { + const node = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(node); + } + + const stmt = super.parseStatement(context, topLevel); + + if (this.flowPragma === undefined && !this.isValidDirective(stmt)) { + this.flowPragma = null; + } + + return stmt; + } + + parseExpressionStatement(node, expr) { + if (expr.type === "Identifier") { + if (expr.name === "declare") { + if (this.match(79) || this.match(5) || this.match(67) || this.match(73) || this.match(81)) { + return this.flowParseDeclare(node); + } + } else if (this.match(5)) { + if (expr.name === "interface") { + return this.flowParseInterface(node); + } else if (expr.name === "type") { + return this.flowParseTypeAlias(node); + } else if (expr.name === "opaque") { + return this.flowParseOpaqueType(node, false); + } + } + } + + return super.parseExpressionStatement(node, expr); + } + + shouldParseExportDeclaration() { + return this.isContextual("type") || this.isContextual("interface") || this.isContextual("opaque") || this.shouldParseEnums() && this.isContextual("enum") || super.shouldParseExportDeclaration(); + } + + isExportDefaultSpecifier() { + if (this.match(5) && (this.state.value === "type" || this.state.value === "interface" || this.state.value === "opaque" || this.shouldParseEnums() && this.state.value === "enum")) { + return false; + } + + return super.isExportDefaultSpecifier(); + } + + parseExportDefaultExpression() { + if (this.shouldParseEnums() && this.isContextual("enum")) { + const node = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(node); + } + + return super.parseExportDefaultExpression(); + } + + parseConditional(expr, startPos, startLoc, refExpressionErrors) { + if (!this.match(25)) return expr; + + if (this.state.maybeInArrowParameters) { + const nextCh = this.lookaheadCharCode(); + + if (nextCh === 44 || nextCh === 61 || nextCh === 58 || nextCh === 41) { + this.setOptionalParametersError(refExpressionErrors); + return expr; + } + } + + this.expect(25); + const state = this.state.clone(); + const originalNoArrowAt = this.state.noArrowAt; + const node = this.startNodeAt(startPos, startLoc); + let { + consequent, + failed + } = this.tryParseConditionalConsequent(); + let [valid, invalid] = this.getArrowLikeExpressions(consequent); + + if (failed || invalid.length > 0) { + const noArrowAt = [...originalNoArrowAt]; + + if (invalid.length > 0) { + this.state = state; + this.state.noArrowAt = noArrowAt; + + for (let i = 0; i < invalid.length; i++) { + noArrowAt.push(invalid[i].start); + } + + ({ + consequent, + failed + } = this.tryParseConditionalConsequent()); + [valid, invalid] = this.getArrowLikeExpressions(consequent); + } + + if (failed && valid.length > 1) { + this.raise(state.start, FlowErrors.AmbiguousConditionalArrow); + } + + if (failed && valid.length === 1) { + this.state = state; + noArrowAt.push(valid[0].start); + this.state.noArrowAt = noArrowAt; + ({ + consequent, + failed + } = this.tryParseConditionalConsequent()); + } + } + + this.getArrowLikeExpressions(consequent, true); + this.state.noArrowAt = originalNoArrowAt; + this.expect(22); + node.test = expr; + node.consequent = consequent; + node.alternate = this.forwardNoArrowParamsConversionAt(node, () => this.parseMaybeAssign(undefined, undefined)); + return this.finishNode(node, "ConditionalExpression"); + } + + tryParseConditionalConsequent() { + this.state.noArrowParamsConversionAt.push(this.state.start); + const consequent = this.parseMaybeAssignAllowIn(); + const failed = !this.match(22); + this.state.noArrowParamsConversionAt.pop(); + return { + consequent, + failed + }; + } + + getArrowLikeExpressions(node, disallowInvalid) { + const stack = [node]; + const arrows = []; + + while (stack.length !== 0) { + const node = stack.pop(); + + if (node.type === "ArrowFunctionExpression") { + if (node.typeParameters || !node.returnType) { + this.finishArrowValidation(node); + } else { + arrows.push(node); + } + + stack.push(node.body); + } else if (node.type === "ConditionalExpression") { + stack.push(node.consequent); + stack.push(node.alternate); + } + } + + if (disallowInvalid) { + arrows.forEach(node => this.finishArrowValidation(node)); + return [arrows, []]; + } + + return partition(arrows, node => node.params.every(param => this.isAssignable(param, true))); + } + + finishArrowValidation(node) { + var _node$extra; + + this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingComma, false); + this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW); + super.checkParams(node, false, true); + this.scope.exit(); + } + + forwardNoArrowParamsConversionAt(node, parse) { + let result; + + if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + this.state.noArrowParamsConversionAt.push(this.state.start); + result = parse(); + this.state.noArrowParamsConversionAt.pop(); + } else { + result = parse(); + } + + return result; + } + + parseParenItem(node, startPos, startLoc) { + node = super.parseParenItem(node, startPos, startLoc); + + if (this.eat(25)) { + node.optional = true; + this.resetEndLocation(node); + } + + if (this.match(22)) { + const typeCastNode = this.startNodeAt(startPos, startLoc); + typeCastNode.expression = node; + typeCastNode.typeAnnotation = this.flowParseTypeAnnotation(); + return this.finishNode(typeCastNode, "TypeCastExpression"); + } + + return node; + } + + assertModuleNodeAllowed(node) { + if (node.type === "ImportDeclaration" && (node.importKind === "type" || node.importKind === "typeof") || node.type === "ExportNamedDeclaration" && node.exportKind === "type" || node.type === "ExportAllDeclaration" && node.exportKind === "type") { + return; + } + + super.assertModuleNodeAllowed(node); + } + + parseExport(node) { + const decl = super.parseExport(node); + + if (decl.type === "ExportNamedDeclaration" || decl.type === "ExportAllDeclaration") { + decl.exportKind = decl.exportKind || "value"; + } + + return decl; + } + + parseExportDeclaration(node) { + if (this.isContextual("type")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + + if (this.match(13)) { + node.specifiers = this.parseExportSpecifiers(); + this.parseExportFrom(node); + return null; + } else { + return this.flowParseTypeAlias(declarationNode); + } + } else if (this.isContextual("opaque")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseOpaqueType(declarationNode, false); + } else if (this.isContextual("interface")) { + node.exportKind = "type"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseInterface(declarationNode); + } else if (this.shouldParseEnums() && this.isContextual("enum")) { + node.exportKind = "value"; + const declarationNode = this.startNode(); + this.next(); + return this.flowParseEnumDeclaration(declarationNode); + } else { + return super.parseExportDeclaration(node); + } + } + + eatExportStar(node) { + if (super.eatExportStar(...arguments)) return true; + + if (this.isContextual("type") && this.lookahead().type === 54) { + node.exportKind = "type"; + this.next(); + this.next(); + return true; + } + + return false; + } + + maybeParseExportNamespaceSpecifier(node) { + const pos = this.state.start; + const hasNamespace = super.maybeParseExportNamespaceSpecifier(node); + + if (hasNamespace && node.exportKind === "type") { + this.unexpected(pos); + } + + return hasNamespace; + } + + parseClassId(node, isStatement, optionalId) { + super.parseClassId(node, isStatement, optionalId); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + } + + parseClassMember(classBody, member, state) { + const pos = this.state.start; + + if (this.isContextual("declare")) { + if (this.parseClassMemberFromModifier(classBody, member)) { + return; + } + + member.declare = true; + } + + super.parseClassMember(classBody, member, state); + + if (member.declare) { + if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty" && member.type !== "PropertyDefinition") { + this.raise(pos, FlowErrors.DeclareClassElement); + } else if (member.value) { + this.raise(member.value.start, FlowErrors.DeclareClassFieldInitializer); + } + } + } + + isIterator(word) { + return word === "iterator" || word === "asyncIterator"; + } + + readIterator() { + const word = super.readWord1(); + const fullWord = "@@" + word; + + if (!this.isIterator(word) || !this.state.inType) { + this.raise(this.state.pos, ErrorMessages.InvalidIdentifier, fullWord); + } + + this.finishToken(5, fullWord); + } + + getTokenFromCode(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 123 && next === 124) { + return this.finishOp(14, 2); + } else if (this.state.inType && (code === 62 || code === 60)) { + return this.finishOp(50, 1); + } else if (this.state.inType && code === 63) { + if (next === 46) { + return this.finishOp(26, 2); + } + + return this.finishOp(25, 1); + } else if (isIteratorStart(code, next)) { + this.state.pos += 2; + return this.readIterator(); + } else { + return super.getTokenFromCode(code); + } + } + + isAssignable(node, isBinding) { + if (node.type === "TypeCastExpression") { + return this.isAssignable(node.expression, isBinding); + } else { + return super.isAssignable(node, isBinding); + } + } + + toAssignable(node, isLHS = false) { + if (node.type === "TypeCastExpression") { + return super.toAssignable(this.typeCastToParameter(node), isLHS); + } else { + return super.toAssignable(node, isLHS); + } + } + + toAssignableList(exprList, trailingCommaPos, isLHS) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + + if ((expr == null ? void 0 : expr.type) === "TypeCastExpression") { + exprList[i] = this.typeCastToParameter(expr); + } + } + + return super.toAssignableList(exprList, trailingCommaPos, isLHS); + } + + toReferencedList(exprList, isParenthesizedExpr) { + for (let i = 0; i < exprList.length; i++) { + var _expr$extra; + + const expr = exprList[i]; + + if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) != null && _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) { + this.raise(expr.typeAnnotation.start, FlowErrors.TypeCastInPattern); + } + } + + return exprList; + } + + parseArrayLike(close, canBePattern, isTuple, refExpressionErrors) { + const node = super.parseArrayLike(close, canBePattern, isTuple, refExpressionErrors); + + if (canBePattern && !this.state.maybeInArrowParameters) { + this.toReferencedList(node.elements); + } + + return node; + } + + checkLVal(expr, ...args) { + if (expr.type !== "TypeCastExpression") { + return super.checkLVal(expr, ...args); + } + } + + parseClassProperty(node) { + if (this.match(22)) { + node.typeAnnotation = this.flowParseTypeAnnotation(); + } + + return super.parseClassProperty(node); + } + + parseClassPrivateProperty(node) { + if (this.match(22)) { + node.typeAnnotation = this.flowParseTypeAnnotation(); + } + + return super.parseClassPrivateProperty(node); + } + + isClassMethod() { + return this.isRelational("<") || super.isClassMethod(); + } + + isClassProperty() { + return this.match(22) || super.isClassProperty(); + } + + isNonstaticConstructor(method) { + return !this.match(22) && super.isNonstaticConstructor(method); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + if (method.variance) { + this.unexpected(method.variance.start); + } + + delete method.variance; + + if (this.isRelational("<")) { + method.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); + + if (method.params && isConstructor) { + const params = method.params; + + if (params.length > 0 && this.isThisParam(params[0])) { + this.raise(method.start, FlowErrors.ThisParamBannedInConstructor); + } + } else if (method.type === "MethodDefinition" && isConstructor && method.value.params) { + const params = method.value.params; + + if (params.length > 0 && this.isThisParam(params[0])) { + this.raise(method.start, FlowErrors.ThisParamBannedInConstructor); + } + } + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + if (method.variance) { + this.unexpected(method.variance.start); + } + + delete method.variance; + + if (this.isRelational("<")) { + method.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); + } + + parseClassSuper(node) { + super.parseClassSuper(node); + + if (node.superClass && this.isRelational("<")) { + node.superTypeParameters = this.flowParseTypeParameterInstantiation(); + } + + if (this.isContextual("implements")) { + this.next(); + const implemented = node.implements = []; + + do { + const node = this.startNode(); + node.id = this.flowParseRestrictedIdentifier(true); + + if (this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterInstantiation(); + } else { + node.typeParameters = null; + } + + implemented.push(this.finishNode(node, "ClassImplements")); + } while (this.eat(20)); + } + } + + checkGetterSetterParams(method) { + super.checkGetterSetterParams(method); + const params = this.getObjectOrClassMethodParams(method); + + if (params.length > 0) { + const param = params[0]; + + if (this.isThisParam(param) && method.kind === "get") { + this.raise(param.start, FlowErrors.GetterMayNotHaveThisParam); + } else if (this.isThisParam(param)) { + this.raise(param.start, FlowErrors.SetterMayNotHaveThisParam); + } + } + } + + parsePropertyName(node, isPrivateNameAllowed) { + const variance = this.flowParseVariance(); + const key = super.parsePropertyName(node, isPrivateNameAllowed); + node.variance = variance; + return key; + } + + parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) { + if (prop.variance) { + this.unexpected(prop.variance.start); + } + + delete prop.variance; + let typeParameters; + + if (this.isRelational("<") && !isAccessor) { + typeParameters = this.flowParseTypeParameterDeclaration(); + if (!this.match(18)) this.unexpected(); + } + + super.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors); + + if (typeParameters) { + (prop.value || prop).typeParameters = typeParameters; + } + } + + parseAssignableListItemTypes(param) { + if (this.eat(25)) { + if (param.type !== "Identifier") { + this.raise(param.start, FlowErrors.PatternIsOptional); + } + + if (this.isThisParam(param)) { + this.raise(param.start, FlowErrors.ThisParamMayNotBeOptional); + } + + param.optional = true; + } + + if (this.match(22)) { + param.typeAnnotation = this.flowParseTypeAnnotation(); + } else if (this.isThisParam(param)) { + this.raise(param.start, FlowErrors.ThisParamAnnotationRequired); + } + + if (this.match(35) && this.isThisParam(param)) { + this.raise(param.start, FlowErrors.ThisParamNoDefault); + } + + this.resetEndLocation(param); + return param; + } + + parseMaybeDefault(startPos, startLoc, left) { + const node = super.parseMaybeDefault(startPos, startLoc, left); + + if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { + this.raise(node.typeAnnotation.start, FlowErrors.TypeBeforeInitializer); + } + + return node; + } + + shouldParseDefaultImport(node) { + if (!hasTypeImportKind(node)) { + return super.shouldParseDefaultImport(node); + } + + return isMaybeDefaultImport(this.state); + } + + parseImportSpecifierLocal(node, specifier, type, contextDescription) { + specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier(); + this.checkLVal(specifier.local, contextDescription, BIND_LEXICAL); + node.specifiers.push(this.finishNode(specifier, type)); + } + + maybeParseDefaultImportSpecifier(node) { + node.importKind = "value"; + let kind = null; + + if (this.match(86)) { + kind = "typeof"; + } else if (this.isContextual("type")) { + kind = "type"; + } + + if (kind) { + const lh = this.lookahead(); + + if (kind === "type" && lh.type === 54) { + this.unexpected(lh.start); + } + + if (isMaybeDefaultImport(lh) || lh.type === 13 || lh.type === 54) { + this.next(); + node.importKind = kind; + } + } + + return super.maybeParseDefaultImportSpecifier(node); + } + + parseImportSpecifier(node) { + const specifier = this.startNode(); + const firstIdentIsString = this.match(4); + const firstIdent = this.parseModuleExportName(); + let specifierTypeKind = null; + + if (firstIdent.type === "Identifier") { + if (firstIdent.name === "type") { + specifierTypeKind = "type"; + } else if (firstIdent.name === "typeof") { + specifierTypeKind = "typeof"; + } + } + + let isBinding = false; + + if (this.isContextual("as") && !this.isLookaheadContextual("as")) { + const as_ident = this.parseIdentifier(true); + + if (specifierTypeKind !== null && !this.match(5) && !tokenIsKeyword(this.state.type)) { + specifier.imported = as_ident; + specifier.importKind = specifierTypeKind; + specifier.local = cloneIdentifier(as_ident); + } else { + specifier.imported = firstIdent; + specifier.importKind = null; + specifier.local = this.parseIdentifier(); + } + } else { + if (specifierTypeKind !== null && (this.match(5) || tokenIsKeyword(this.state.type))) { + specifier.imported = this.parseIdentifier(true); + specifier.importKind = specifierTypeKind; + } else { + if (firstIdentIsString) { + throw this.raise(specifier.start, ErrorMessages.ImportBindingIsString, firstIdent.value); + } + + specifier.imported = firstIdent; + specifier.importKind = null; + } + + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + isBinding = true; + specifier.local = cloneIdentifier(specifier.imported); + } + } + + const nodeIsTypeImport = hasTypeImportKind(node); + const specifierIsTypeImport = hasTypeImportKind(specifier); + + if (nodeIsTypeImport && specifierIsTypeImport) { + this.raise(specifier.start, FlowErrors.ImportTypeShorthandOnlyInPureImport); + } + + if (nodeIsTypeImport || specifierIsTypeImport) { + this.checkReservedType(specifier.local.name, specifier.local.start, true); + } + + if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) { + this.checkReservedWord(specifier.local.name, specifier.start, true, true); + } + + this.checkLVal(specifier.local, "import specifier", BIND_LEXICAL); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + } + + parseBindingAtom() { + switch (this.state.type) { + case 77: + return this.parseIdentifier(true); + + default: + return super.parseBindingAtom(); + } + } + + parseFunctionParams(node, allowModifiers) { + const kind = node.kind; + + if (kind !== "get" && kind !== "set" && this.isRelational("<")) { + node.typeParameters = this.flowParseTypeParameterDeclaration(); + } + + super.parseFunctionParams(node, allowModifiers); + } + + parseVarId(decl, kind) { + super.parseVarId(decl, kind); + + if (this.match(22)) { + decl.id.typeAnnotation = this.flowParseTypeAnnotation(); + this.resetEndLocation(decl.id); + } + } + + parseAsyncArrowFromCallExpression(node, call) { + if (this.match(22)) { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + node.returnType = this.flowParseTypeAnnotation(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + } + + return super.parseAsyncArrowFromCallExpression(node, call); + } + + shouldParseAsyncArrow() { + return this.match(22) || super.shouldParseAsyncArrow(); + } + + parseMaybeAssign(refExpressionErrors, afterLeftParse) { + var _jsx; + + let state = null; + let jsx; + + if (this.hasPlugin("jsx") && (this.match(94) || this.isRelational("<"))) { + state = this.state.clone(); + jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state); + if (!jsx.error) return jsx.node; + const { + context + } = this.state; + const curContext = context[context.length - 1]; + + if (curContext === types$1.j_oTag) { + context.length -= 2; + } else if (curContext === types$1.j_expr) { + context.length -= 1; + } + } + + if ((_jsx = jsx) != null && _jsx.error || this.isRelational("<")) { + var _jsx2, _jsx3; + + state = state || this.state.clone(); + let typeParameters; + const arrow = this.tryParse(abort => { + var _arrowExpression$extr; + + typeParameters = this.flowParseTypeParameterDeclaration(); + const arrowExpression = this.forwardNoArrowParamsConversionAt(typeParameters, () => { + const result = super.parseMaybeAssign(refExpressionErrors, afterLeftParse); + this.resetStartLocationFromNode(result, typeParameters); + return result; + }); + if ((_arrowExpression$extr = arrowExpression.extra) != null && _arrowExpression$extr.parenthesized) abort(); + const expr = this.maybeUnwrapTypeCastExpression(arrowExpression); + if (expr.type !== "ArrowFunctionExpression") abort(); + expr.typeParameters = typeParameters; + this.resetStartLocationFromNode(expr, typeParameters); + return arrowExpression; + }, state); + let arrowExpression = null; + + if (arrow.node && this.maybeUnwrapTypeCastExpression(arrow.node).type === "ArrowFunctionExpression") { + if (!arrow.error && !arrow.aborted) { + if (arrow.node.async) { + this.raise(typeParameters.start, FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction); + } + + return arrow.node; + } + + arrowExpression = arrow.node; + } + + if ((_jsx2 = jsx) != null && _jsx2.node) { + this.state = jsx.failState; + return jsx.node; + } + + if (arrowExpression) { + this.state = arrow.failState; + return arrowExpression; + } + + if ((_jsx3 = jsx) != null && _jsx3.thrown) throw jsx.error; + if (arrow.thrown) throw arrow.error; + throw this.raise(typeParameters.start, FlowErrors.UnexpectedTokenAfterTypeParameter); + } + + return super.parseMaybeAssign(refExpressionErrors, afterLeftParse); + } + + parseArrow(node) { + if (this.match(22)) { + const result = this.tryParse(() => { + const oldNoAnonFunctionType = this.state.noAnonFunctionType; + this.state.noAnonFunctionType = true; + const typeNode = this.startNode(); + [typeNode.typeAnnotation, node.predicate] = this.flowParseTypeAndPredicateInitialiser(); + this.state.noAnonFunctionType = oldNoAnonFunctionType; + if (this.canInsertSemicolon()) this.unexpected(); + if (!this.match(27)) this.unexpected(); + return typeNode; + }); + if (result.thrown) return null; + if (result.error) this.state = result.failState; + node.returnType = result.node.typeAnnotation ? this.finishNode(result.node, "TypeAnnotation") : null; + } + + return super.parseArrow(node); + } + + shouldParseArrow(params) { + return this.match(22) || super.shouldParseArrow(params); + } + + setArrowFunctionParameters(node, params) { + if (this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + node.params = params; + } else { + super.setArrowFunctionParameters(node, params); + } + } + + checkParams(node, allowDuplicates, isArrowFunction) { + if (isArrowFunction && this.state.noArrowParamsConversionAt.indexOf(node.start) !== -1) { + return; + } + + for (let i = 0; i < node.params.length; i++) { + if (this.isThisParam(node.params[i]) && i > 0) { + this.raise(node.params[i].start, FlowErrors.ThisParamMustBeFirst); + } + } + + return super.checkParams(...arguments); + } + + parseParenAndDistinguishExpression(canBeArrow) { + return super.parseParenAndDistinguishExpression(canBeArrow && this.state.noArrowAt.indexOf(this.state.start) === -1); + } + + parseSubscripts(base, startPos, startLoc, noCalls) { + if (base.type === "Identifier" && base.name === "async" && this.state.noArrowAt.indexOf(startPos) !== -1) { + this.next(); + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + node.arguments = this.parseCallExpressionArguments(19, false); + base = this.finishNode(node, "CallExpression"); + } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) { + const state = this.state.clone(); + const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startPos, startLoc) || abort(), state); + if (!arrow.error && !arrow.aborted) return arrow.node; + const result = this.tryParse(() => super.parseSubscripts(base, startPos, startLoc, noCalls), state); + if (result.node && !result.error) return result.node; + + if (arrow.node) { + this.state = arrow.failState; + return arrow.node; + } + + if (result.node) { + this.state = result.failState; + return result.node; + } + + throw arrow.error || result.error; + } + + return super.parseSubscripts(base, startPos, startLoc, noCalls); + } + + parseSubscript(base, startPos, startLoc, noCalls, subscriptState) { + if (this.match(26) && this.isLookaheadToken_lt()) { + subscriptState.optionalChainMember = true; + + if (noCalls) { + subscriptState.stop = true; + return base; + } + + this.next(); + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + node.typeArguments = this.flowParseTypeParameterInstantiation(); + this.expect(18); + node.arguments = this.parseCallExpressionArguments(19, false); + node.optional = true; + return this.finishCallExpression(node, true); + } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) { + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + const result = this.tryParse(() => { + node.typeArguments = this.flowParseTypeParameterInstantiationCallOrNew(); + this.expect(18); + node.arguments = this.parseCallExpressionArguments(19, false); + if (subscriptState.optionalChainMember) node.optional = false; + return this.finishCallExpression(node, subscriptState.optionalChainMember); + }); + + if (result.node) { + if (result.error) this.state = result.failState; + return result.node; + } + } + + return super.parseSubscript(base, startPos, startLoc, noCalls, subscriptState); + } + + parseNewArguments(node) { + let targs = null; + + if (this.shouldParseTypes() && this.isRelational("<")) { + targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node; + } + + node.typeArguments = targs; + super.parseNewArguments(node); + } + + parseAsyncArrowWithTypeParameters(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + this.parseFunctionParams(node); + if (!this.parseArrow(node)) return; + return this.parseArrowExpression(node, undefined, true); + } + + readToken_mult_modulo(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 42 && next === 47 && this.state.hasFlowComment) { + this.state.hasFlowComment = false; + this.state.pos += 2; + this.nextToken(); + return; + } + + super.readToken_mult_modulo(code); + } + + readToken_pipe_amp(code) { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (code === 124 && next === 125) { + this.finishOp(17, 2); + return; + } + + super.readToken_pipe_amp(code); + } + + parseTopLevel(file, program) { + const fileNode = super.parseTopLevel(file, program); + + if (this.state.hasFlowComment) { + this.raise(this.state.pos, FlowErrors.UnterminatedFlowComment); + } + + return fileNode; + } + + skipBlockComment() { + if (this.hasPlugin("flowComments") && this.skipFlowComment()) { + if (this.state.hasFlowComment) { + this.unexpected(null, FlowErrors.NestedFlowComment); + } + + this.hasFlowCommentCompletion(); + this.state.pos += this.skipFlowComment(); + this.state.hasFlowComment = true; + return; + } + + if (this.state.hasFlowComment) { + const end = this.input.indexOf("*-/", this.state.pos += 2); + + if (end === -1) { + throw this.raise(this.state.pos - 2, ErrorMessages.UnterminatedComment); + } + + this.state.pos = end + 3; + return; + } + + return super.skipBlockComment(); + } + + skipFlowComment() { + const { + pos + } = this.state; + let shiftToFirstNonWhiteSpace = 2; + + while ([32, 9].includes(this.input.charCodeAt(pos + shiftToFirstNonWhiteSpace))) { + shiftToFirstNonWhiteSpace++; + } + + const ch2 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos); + const ch3 = this.input.charCodeAt(shiftToFirstNonWhiteSpace + pos + 1); + + if (ch2 === 58 && ch3 === 58) { + return shiftToFirstNonWhiteSpace + 2; + } + + if (this.input.slice(shiftToFirstNonWhiteSpace + pos, shiftToFirstNonWhiteSpace + pos + 12) === "flow-include") { + return shiftToFirstNonWhiteSpace + 12; + } + + if (ch2 === 58 && ch3 !== 58) { + return shiftToFirstNonWhiteSpace; + } + + return false; + } + + hasFlowCommentCompletion() { + const end = this.input.indexOf("*/", this.state.pos); + + if (end === -1) { + throw this.raise(this.state.pos, ErrorMessages.UnterminatedComment); + } + } + + flowEnumErrorBooleanMemberNotInitialized(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors.EnumBooleanMemberNotInitialized, memberName, enumName); + } + + flowEnumErrorInvalidMemberName(pos, { + enumName, + memberName + }) { + const suggestion = memberName[0].toUpperCase() + memberName.slice(1); + this.raise(pos, FlowErrors.EnumInvalidMemberName, memberName, suggestion, enumName); + } + + flowEnumErrorDuplicateMemberName(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors.EnumDuplicateMemberName, memberName, enumName); + } + + flowEnumErrorInconsistentMemberValues(pos, { + enumName + }) { + this.raise(pos, FlowErrors.EnumInconsistentMemberValues, enumName); + } + + flowEnumErrorInvalidExplicitType(pos, { + enumName, + suppliedType + }) { + return this.raise(pos, suppliedType === null ? FlowErrors.EnumInvalidExplicitTypeUnknownSupplied : FlowErrors.EnumInvalidExplicitType, enumName, suppliedType); + } + + flowEnumErrorInvalidMemberInitializer(pos, { + enumName, + explicitType, + memberName + }) { + let message = null; + + switch (explicitType) { + case "boolean": + case "number": + case "string": + message = FlowErrors.EnumInvalidMemberInitializerPrimaryType; + break; + + case "symbol": + message = FlowErrors.EnumInvalidMemberInitializerSymbolType; + break; + + default: + message = FlowErrors.EnumInvalidMemberInitializerUnknownType; + } + + return this.raise(pos, message, enumName, memberName, explicitType); + } + + flowEnumErrorNumberMemberNotInitialized(pos, { + enumName, + memberName + }) { + this.raise(pos, FlowErrors.EnumNumberMemberNotInitialized, enumName, memberName); + } + + flowEnumErrorStringMemberInconsistentlyInitailized(pos, { + enumName + }) { + this.raise(pos, FlowErrors.EnumStringMemberInconsistentlyInitailized, enumName); + } + + flowEnumMemberInit() { + const startPos = this.state.start; + + const endOfInit = () => this.match(20) || this.match(16); + + switch (this.state.type) { + case 0: + { + const literal = this.parseNumericLiteral(this.state.value); + + if (endOfInit()) { + return { + type: "number", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + case 4: + { + const literal = this.parseStringLiteral(this.state.value); + + if (endOfInit()) { + return { + type: "string", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + case 84: + case 85: + { + const literal = this.parseBooleanLiteral(this.match(84)); + + if (endOfInit()) { + return { + type: "boolean", + pos: literal.start, + value: literal + }; + } + + return { + type: "invalid", + pos: startPos + }; + } + + default: + return { + type: "invalid", + pos: startPos + }; + } + } + + flowEnumMemberRaw() { + const pos = this.state.start; + const id = this.parseIdentifier(true); + const init = this.eat(35) ? this.flowEnumMemberInit() : { + type: "none", + pos + }; + return { + id, + init + }; + } + + flowEnumCheckExplicitTypeMismatch(pos, context, expectedType) { + const { + explicitType + } = context; + + if (explicitType === null) { + return; + } + + if (explicitType !== expectedType) { + this.flowEnumErrorInvalidMemberInitializer(pos, context); + } + } + + flowEnumMembers({ + enumName, + explicitType + }) { + const seenNames = new Set(); + const members = { + booleanMembers: [], + numberMembers: [], + stringMembers: [], + defaultedMembers: [] + }; + let hasUnknownMembers = false; + + while (!this.match(16)) { + if (this.eat(29)) { + hasUnknownMembers = true; + break; + } + + const memberNode = this.startNode(); + const { + id, + init + } = this.flowEnumMemberRaw(); + const memberName = id.name; + + if (memberName === "") { + continue; + } + + if (/^[a-z]/.test(memberName)) { + this.flowEnumErrorInvalidMemberName(id.start, { + enumName, + memberName + }); + } + + if (seenNames.has(memberName)) { + this.flowEnumErrorDuplicateMemberName(id.start, { + enumName, + memberName + }); + } + + seenNames.add(memberName); + const context = { + enumName, + explicitType, + memberName + }; + memberNode.id = id; + + switch (init.type) { + case "boolean": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "boolean"); + memberNode.init = init.value; + members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember")); + break; + } + + case "number": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "number"); + memberNode.init = init.value; + members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember")); + break; + } + + case "string": + { + this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "string"); + memberNode.init = init.value; + members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember")); + break; + } + + case "invalid": + { + throw this.flowEnumErrorInvalidMemberInitializer(init.pos, context); + } + + case "none": + { + switch (explicitType) { + case "boolean": + this.flowEnumErrorBooleanMemberNotInitialized(init.pos, context); + break; + + case "number": + this.flowEnumErrorNumberMemberNotInitialized(init.pos, context); + break; + + default: + members.defaultedMembers.push(this.finishNode(memberNode, "EnumDefaultedMember")); + } + } + } + + if (!this.match(16)) { + this.expect(20); + } + } + + return { + members, + hasUnknownMembers + }; + } + + flowEnumStringMembers(initializedMembers, defaultedMembers, { + enumName + }) { + if (initializedMembers.length === 0) { + return defaultedMembers; + } else if (defaultedMembers.length === 0) { + return initializedMembers; + } else if (defaultedMembers.length > initializedMembers.length) { + for (const member of initializedMembers) { + this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + enumName + }); + } + + return defaultedMembers; + } else { + for (const member of defaultedMembers) { + this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + enumName + }); + } + + return initializedMembers; + } + } + + flowEnumParseExplicitType({ + enumName + }) { + if (this.eatContextual("of")) { + if (!this.match(5)) { + throw this.flowEnumErrorInvalidExplicitType(this.state.start, { + enumName, + suppliedType: null + }); + } + + const { + value + } = this.state; + this.next(); + + if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") { + this.flowEnumErrorInvalidExplicitType(this.state.start, { + enumName, + suppliedType: value + }); + } + + return value; + } + + return null; + } + + flowEnumBody(node, { + enumName, + nameLoc + }) { + const explicitType = this.flowEnumParseExplicitType({ + enumName + }); + this.expect(13); + const { + members, + hasUnknownMembers + } = this.flowEnumMembers({ + enumName, + explicitType + }); + node.hasUnknownMembers = hasUnknownMembers; + + switch (explicitType) { + case "boolean": + node.explicitType = true; + node.members = members.booleanMembers; + this.expect(16); + return this.finishNode(node, "EnumBooleanBody"); + + case "number": + node.explicitType = true; + node.members = members.numberMembers; + this.expect(16); + return this.finishNode(node, "EnumNumberBody"); + + case "string": + node.explicitType = true; + node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, { + enumName + }); + this.expect(16); + return this.finishNode(node, "EnumStringBody"); + + case "symbol": + node.members = members.defaultedMembers; + this.expect(16); + return this.finishNode(node, "EnumSymbolBody"); + + default: + { + const empty = () => { + node.members = []; + this.expect(16); + return this.finishNode(node, "EnumStringBody"); + }; + + node.explicitType = false; + const boolsLen = members.booleanMembers.length; + const numsLen = members.numberMembers.length; + const strsLen = members.stringMembers.length; + const defaultedLen = members.defaultedMembers.length; + + if (!boolsLen && !numsLen && !strsLen && !defaultedLen) { + return empty(); + } else if (!boolsLen && !numsLen) { + node.members = this.flowEnumStringMembers(members.stringMembers, members.defaultedMembers, { + enumName + }); + this.expect(16); + return this.finishNode(node, "EnumStringBody"); + } else if (!numsLen && !strsLen && boolsLen >= defaultedLen) { + for (const member of members.defaultedMembers) { + this.flowEnumErrorBooleanMemberNotInitialized(member.start, { + enumName, + memberName: member.id.name + }); + } + + node.members = members.booleanMembers; + this.expect(16); + return this.finishNode(node, "EnumBooleanBody"); + } else if (!boolsLen && !strsLen && numsLen >= defaultedLen) { + for (const member of members.defaultedMembers) { + this.flowEnumErrorNumberMemberNotInitialized(member.start, { + enumName, + memberName: member.id.name + }); + } + + node.members = members.numberMembers; + this.expect(16); + return this.finishNode(node, "EnumNumberBody"); + } else { + this.flowEnumErrorInconsistentMemberValues(nameLoc, { + enumName + }); + return empty(); + } + } + } + } + + flowParseEnumDeclaration(node) { + const id = this.parseIdentifier(); + node.id = id; + node.body = this.flowEnumBody(this.startNode(), { + enumName: id.name, + nameLoc: id.start + }); + return this.finishNode(node, "EnumDeclaration"); + } + + isLookaheadToken_lt() { + const next = this.nextTokenStart(); + + if (this.input.charCodeAt(next) === 60) { + const afterNext = this.input.charCodeAt(next + 1); + return afterNext !== 60 && afterNext !== 61; + } + + return false; + } + + maybeUnwrapTypeCastExpression(node) { + return node.type === "TypeCastExpression" ? node.expression : node; + } + + }); + + const entities = { + quot: "\u0022", + amp: "&", + apos: "\u0027", + lt: "<", + gt: ">", + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + fnof: "\u0192", + circ: "\u02C6", + tilde: "\u02DC", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + bull: "\u2022", + hellip: "\u2026", + permil: "\u2030", + prime: "\u2032", + Prime: "\u2033", + lsaquo: "\u2039", + rsaquo: "\u203A", + oline: "\u203E", + frasl: "\u2044", + euro: "\u20AC", + image: "\u2111", + weierp: "\u2118", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666" + }; + + const HEX_NUMBER = /^[\da-fA-F]+$/; + const DECIMAL_NUMBER = /^\d+$/; + const JsxErrors = makeErrorTemplates({ + AttributeIsEmpty: "JSX attributes must only be assigned a non-empty expression.", + MissingClosingTagElement: "Expected corresponding JSX closing tag for <%0>.", + MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>.", + UnexpectedSequenceExpression: "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?", + UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text.", + UnterminatedJsxContent: "Unterminated JSX contents.", + UnwrappedAdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...?" + }, ErrorCodes.SyntaxError, "jsx"); + types$1.j_oTag = new TokContext("...", true); + + function isFragment(object) { + return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false; + } + + function getQualifiedJSXName(object) { + if (object.type === "JSXIdentifier") { + return object.name; + } + + if (object.type === "JSXNamespacedName") { + return object.namespace.name + ":" + object.name.name; + } + + if (object.type === "JSXMemberExpression") { + return getQualifiedJSXName(object.object) + "." + getQualifiedJSXName(object.property); + } + + throw new Error("Node had unexpected type: " + object.type); + } + + var jsx$1 = (superClass => class extends superClass { + jsxReadToken() { + let out = ""; + let chunkStart = this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, JsxErrors.UnterminatedJsxContent); + } + + const ch = this.input.charCodeAt(this.state.pos); + + switch (ch) { + case 60: + case 123: + if (this.state.pos === this.state.start) { + if (ch === 60 && this.state.exprAllowed) { + ++this.state.pos; + return this.finishToken(94); + } + + return super.getTokenFromCode(ch); + } + + out += this.input.slice(chunkStart, this.state.pos); + return this.finishToken(93, out); + + case 38: + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + break; + + case 62: + case 125: + + default: + if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(true); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + + } + } + } + + jsxReadNewLine(normalizeCRLF) { + const ch = this.input.charCodeAt(this.state.pos); + let out; + ++this.state.pos; + + if (ch === 13 && this.input.charCodeAt(this.state.pos) === 10) { + ++this.state.pos; + out = normalizeCRLF ? "\n" : "\r\n"; + } else { + out = String.fromCharCode(ch); + } + + ++this.state.curLine; + this.state.lineStart = this.state.pos; + return out; + } + + jsxReadString(quote) { + let out = ""; + let chunkStart = ++this.state.pos; + + for (;;) { + if (this.state.pos >= this.length) { + throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + } + + const ch = this.input.charCodeAt(this.state.pos); + if (ch === quote) break; + + if (ch === 38) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadEntity(); + chunkStart = this.state.pos; + } else if (isNewLine(ch)) { + out += this.input.slice(chunkStart, this.state.pos); + out += this.jsxReadNewLine(false); + chunkStart = this.state.pos; + } else { + ++this.state.pos; + } + } + + out += this.input.slice(chunkStart, this.state.pos++); + return this.finishToken(4, out); + } + + jsxReadEntity() { + let str = ""; + let count = 0; + let entity; + let ch = this.input[this.state.pos]; + const startPos = ++this.state.pos; + + while (this.state.pos < this.length && count++ < 10) { + ch = this.input[this.state.pos++]; + + if (ch === ";") { + if (str[0] === "#") { + if (str[1] === "x") { + str = str.substr(2); + + if (HEX_NUMBER.test(str)) { + entity = String.fromCodePoint(parseInt(str, 16)); + } + } else { + str = str.substr(1); + + if (DECIMAL_NUMBER.test(str)) { + entity = String.fromCodePoint(parseInt(str, 10)); + } + } + } else { + entity = entities[str]; + } + + break; + } + + str += ch; + } + + if (!entity) { + this.state.pos = startPos; + return "&"; + } + + return entity; + } + + jsxReadWord() { + let ch; + const start = this.state.pos; + + do { + ch = this.input.charCodeAt(++this.state.pos); + } while (isIdentifierChar(ch) || ch === 45); + + return this.finishToken(92, this.input.slice(start, this.state.pos)); + } + + jsxParseIdentifier() { + const node = this.startNode(); + + if (this.match(92)) { + node.name = this.state.value; + } else if (tokenIsKeyword(this.state.type)) { + node.name = tokenLabelName(this.state.type); + } else { + this.unexpected(); + } + + this.next(); + return this.finishNode(node, "JSXIdentifier"); + } + + jsxParseNamespacedName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const name = this.jsxParseIdentifier(); + if (!this.eat(22)) return name; + const node = this.startNodeAt(startPos, startLoc); + node.namespace = name; + node.name = this.jsxParseIdentifier(); + return this.finishNode(node, "JSXNamespacedName"); + } + + jsxParseElementName() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let node = this.jsxParseNamespacedName(); + + if (node.type === "JSXNamespacedName") { + return node; + } + + while (this.eat(24)) { + const newNode = this.startNodeAt(startPos, startLoc); + newNode.object = node; + newNode.property = this.jsxParseIdentifier(); + node = this.finishNode(newNode, "JSXMemberExpression"); + } + + return node; + } + + jsxParseAttributeValue() { + let node; + + switch (this.state.type) { + case 13: + node = this.startNode(); + this.next(); + node = this.jsxParseExpressionContainer(node); + + if (node.expression.type === "JSXEmptyExpression") { + this.raise(node.start, JsxErrors.AttributeIsEmpty); + } + + return node; + + case 94: + case 4: + return this.parseExprAtom(); + + default: + throw this.raise(this.state.start, JsxErrors.UnsupportedJsxValue); + } + } + + jsxParseEmptyExpression() { + const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); + return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); + } + + jsxParseSpreadChild(node) { + this.next(); + node.expression = this.parseExpression(); + this.expect(16); + return this.finishNode(node, "JSXSpreadChild"); + } + + jsxParseExpressionContainer(node) { + if (this.match(16)) { + node.expression = this.jsxParseEmptyExpression(); + } else { + const expression = this.parseExpression(); + node.expression = expression; + } + + this.expect(16); + return this.finishNode(node, "JSXExpressionContainer"); + } + + jsxParseAttribute() { + const node = this.startNode(); + + if (this.eat(13)) { + this.expect(29); + node.argument = this.parseMaybeAssignAllowIn(); + this.expect(16); + return this.finishNode(node, "JSXSpreadAttribute"); + } + + node.name = this.jsxParseNamespacedName(); + node.value = this.eat(35) ? this.jsxParseAttributeValue() : null; + return this.finishNode(node, "JSXAttribute"); + } + + jsxParseOpeningElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + + if (this.match(95)) { + this.expect(95); + return this.finishNode(node, "JSXOpeningFragment"); + } + + node.name = this.jsxParseElementName(); + return this.jsxParseOpeningElementAfterName(node); + } + + jsxParseOpeningElementAfterName(node) { + const attributes = []; + + while (!this.match(55) && !this.match(95)) { + attributes.push(this.jsxParseAttribute()); + } + + node.attributes = attributes; + node.selfClosing = this.eat(55); + this.expect(95); + return this.finishNode(node, "JSXOpeningElement"); + } + + jsxParseClosingElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + + if (this.match(95)) { + this.expect(95); + return this.finishNode(node, "JSXClosingFragment"); + } + + node.name = this.jsxParseElementName(); + this.expect(95); + return this.finishNode(node, "JSXClosingElement"); + } + + jsxParseElementAt(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + const children = []; + const openingElement = this.jsxParseOpeningElementAt(startPos, startLoc); + let closingElement = null; + + if (!openingElement.selfClosing) { + contents: for (;;) { + switch (this.state.type) { + case 94: + startPos = this.state.start; + startLoc = this.state.startLoc; + this.next(); + + if (this.eat(55)) { + closingElement = this.jsxParseClosingElementAt(startPos, startLoc); + break contents; + } + + children.push(this.jsxParseElementAt(startPos, startLoc)); + break; + + case 93: + children.push(this.parseExprAtom()); + break; + + case 13: + { + const node = this.startNode(); + this.next(); + + if (this.match(29)) { + children.push(this.jsxParseSpreadChild(node)); + } else { + children.push(this.jsxParseExpressionContainer(node)); + } + + break; + } + + default: + throw this.unexpected(); + } + } + + if (isFragment(openingElement) && !isFragment(closingElement)) { + this.raise(closingElement.start, JsxErrors.MissingClosingTagFragment); + } else if (!isFragment(openingElement) && isFragment(closingElement)) { + this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name)); + } else if (!isFragment(openingElement) && !isFragment(closingElement)) { + if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { + this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name)); + } + } + } + + if (isFragment(openingElement)) { + node.openingFragment = openingElement; + node.closingFragment = closingElement; + } else { + node.openingElement = openingElement; + node.closingElement = closingElement; + } + + node.children = children; + + if (this.isRelational("<")) { + throw this.raise(this.state.start, JsxErrors.UnwrappedAdjacentJSXElements); + } + + return isFragment(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement"); + } + + jsxParseElement() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.next(); + return this.jsxParseElementAt(startPos, startLoc); + } + + parseExprAtom(refExpressionErrors) { + if (this.match(93)) { + return this.parseLiteral(this.state.value, "JSXText"); + } else if (this.match(94)) { + return this.jsxParseElement(); + } else if (this.isRelational("<") && this.input.charCodeAt(this.state.pos) !== 33) { + this.finishToken(94); + return this.jsxParseElement(); + } else { + return super.parseExprAtom(refExpressionErrors); + } + } + + createLookaheadState(state) { + const lookaheadState = super.createLookaheadState(state); + lookaheadState.inPropertyName = state.inPropertyName; + return lookaheadState; + } + + getTokenFromCode(code) { + if (this.state.inPropertyName) return super.getTokenFromCode(code); + const context = this.curContext(); + + if (context === types$1.j_expr) { + return this.jsxReadToken(); + } + + if (context === types$1.j_oTag || context === types$1.j_cTag) { + if (isIdentifierStart(code)) { + return this.jsxReadWord(); + } + + if (code === 62) { + ++this.state.pos; + return this.finishToken(95); + } + + if ((code === 34 || code === 39) && context === types$1.j_oTag) { + return this.jsxReadString(code); + } + } + + if (code === 60 && this.state.exprAllowed && this.input.charCodeAt(this.state.pos + 1) !== 33) { + ++this.state.pos; + return this.finishToken(94); + } + + return super.getTokenFromCode(code); + } + + updateContext(prevType) { + super.updateContext(prevType); + const { + context, + type + } = this.state; + + if (type === 55 && prevType === 94) { + context.splice(-2, 2, types$1.j_cTag); + this.state.exprAllowed = false; + } else if (type === 94) { + context.push(types$1.j_expr, types$1.j_oTag); + } else if (type === 95) { + const out = context.pop(); + + if (out === types$1.j_oTag && prevType === 55 || out === types$1.j_cTag) { + context.pop(); + this.state.exprAllowed = context[context.length - 1] === types$1.j_expr; + } else { + this.state.exprAllowed = true; + } + } else if (tokenIsKeyword(type) && (prevType === 24 || prevType === 26)) { + this.state.exprAllowed = false; + } else { + this.state.exprAllowed = tokenComesBeforeExpression(type); + } + } + + }); + + class TypeScriptScope extends Scope { + constructor(...args) { + super(...args); + this.types = new Set(); + this.enums = new Set(); + this.constEnums = new Set(); + this.classes = new Set(); + this.exportOnlyBindings = new Set(); + } + + } + + class TypeScriptScopeHandler extends ScopeHandler { + createScope(flags) { + return new TypeScriptScope(flags); + } + + declareName(name, bindingType, pos) { + const scope = this.currentScope(); + + if (bindingType & BIND_FLAGS_TS_EXPORT_ONLY) { + this.maybeExportDefined(scope, name); + scope.exportOnlyBindings.add(name); + return; + } + + super.declareName(...arguments); + + if (bindingType & BIND_KIND_TYPE) { + if (!(bindingType & BIND_KIND_VALUE)) { + this.checkRedeclarationInScope(scope, name, bindingType, pos); + this.maybeExportDefined(scope, name); + } + + scope.types.add(name); + } + + if (bindingType & BIND_FLAGS_TS_ENUM) scope.enums.add(name); + if (bindingType & BIND_FLAGS_TS_CONST_ENUM) scope.constEnums.add(name); + if (bindingType & BIND_FLAGS_CLASS) scope.classes.add(name); + } + + isRedeclaredInScope(scope, name, bindingType) { + if (scope.enums.has(name)) { + if (bindingType & BIND_FLAGS_TS_ENUM) { + const isConst = !!(bindingType & BIND_FLAGS_TS_CONST_ENUM); + const wasConst = scope.constEnums.has(name); + return isConst !== wasConst; + } + + return true; + } + + if (bindingType & BIND_FLAGS_CLASS && scope.classes.has(name)) { + if (scope.lexical.has(name)) { + return !!(bindingType & BIND_KIND_VALUE); + } else { + return false; + } + } + + if (bindingType & BIND_KIND_TYPE && scope.types.has(name)) { + return true; + } + + return super.isRedeclaredInScope(...arguments); + } + + checkLocalExport(id) { + const topLevelScope = this.scopeStack[0]; + const { + name + } = id; + + if (!topLevelScope.types.has(name) && !topLevelScope.exportOnlyBindings.has(name)) { + super.checkLocalExport(id); + } + } + + } + + function nonNull(x) { + if (x == null) { + throw new Error(`Unexpected ${x} value.`); + } + + return x; + } + + function assert(x) { + if (!x) { + throw new Error("Assert fail"); + } + } + + const TSErrors = makeErrorTemplates({ + AbstractMethodHasImplementation: "Method '%0' cannot have an implementation because it is marked abstract.", + AbstractPropertyHasInitializer: "Property '%0' cannot have an initializer because it is marked abstract.", + AccesorCannotDeclareThisParameter: "'get' and 'set' accessors cannot declare 'this' parameters.", + AccesorCannotHaveTypeParameters: "An accessor cannot have type parameters.", + ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.", + ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier.", + ConstructorHasTypeParameters: "Type parameters cannot appear on a constructor declaration.", + DeclareAccessor: "'declare' is not allowed in %0ters.", + DeclareClassFieldHasInitializer: "Initializers are not allowed in ambient contexts.", + DeclareFunctionHasImplementation: "An implementation cannot be declared in ambient contexts.", + DuplicateAccessibilityModifier: "Accessibility modifier already seen.", + DuplicateModifier: "Duplicate modifier: '%0'.", + EmptyHeritageClauseType: "'%0' list cannot be empty.", + EmptyTypeArguments: "Type argument list cannot be empty.", + EmptyTypeParameters: "Type parameter list cannot be empty.", + ExpectedAmbientAfterExportDeclare: "'export declare' must be followed by an ambient declaration.", + ImportAliasHasImportType: "An import alias can not use 'import type'.", + IncompatibleModifiers: "'%0' modifier cannot be used with '%1' modifier.", + IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier.", + IndexSignatureHasAccessibility: "Index signatures cannot have an accessibility modifier ('%0').", + IndexSignatureHasDeclare: "Index signatures cannot have the 'declare' modifier.", + IndexSignatureHasOverride: "'override' modifier cannot appear on an index signature.", + IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier.", + InvalidModifierOnTypeMember: "'%0' modifier cannot appear on a type member.", + InvalidModifiersOrder: "'%0' modifier must precede '%1' modifier.", + InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.", + MissingInterfaceName: "'interface' declarations must be followed by an identifier.", + MixedLabeledAndUnlabeledElements: "Tuple members must all have names or all not have names.", + NonAbstractClassHasAbstractMethod: "Abstract methods can only appear within an abstract class.", + NonClassMethodPropertyHasAbstractModifer: "'abstract' modifier can only appear on a class, method, or property declaration.", + OptionalTypeBeforeRequired: "A required element cannot follow an optional element.", + OverrideNotInSubClass: "This member cannot have an 'override' modifier because its containing class does not extend another class.", + PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.", + PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.", + PrivateElementHasAccessibility: "Private elements cannot have an accessibility modifier ('%0').", + ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.", + SetAccesorCannotHaveOptionalParameter: "A 'set' accessor cannot have an optional parameter.", + SetAccesorCannotHaveRestParameter: "A 'set' accessor cannot have rest parameter.", + SetAccesorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.", + StaticBlockCannotHaveModifier: "Static class blocks cannot have any modifier.", + TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.", + TypeImportCannotSpecifyDefaultAndNamed: "A type-only import can specify a default import or named bindings, but not both.", + UnexpectedParameterModifier: "A parameter property is only allowed in a constructor implementation.", + UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.", + UnexpectedTypeAnnotation: "Did not expect a type annotation here.", + UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.", + UnsupportedImportTypeArgument: "Argument in a type import must be a string literal.", + UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.", + UnsupportedSignatureParameterKind: "Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got %0." + }, ErrorCodes.SyntaxError, "typescript"); + + function keywordTypeFromName(value) { + switch (value) { + case "any": + return "TSAnyKeyword"; + + case "boolean": + return "TSBooleanKeyword"; + + case "bigint": + return "TSBigIntKeyword"; + + case "never": + return "TSNeverKeyword"; + + case "number": + return "TSNumberKeyword"; + + case "object": + return "TSObjectKeyword"; + + case "string": + return "TSStringKeyword"; + + case "symbol": + return "TSSymbolKeyword"; + + case "undefined": + return "TSUndefinedKeyword"; + + case "unknown": + return "TSUnknownKeyword"; + + default: + return undefined; + } + } + + function tsIsAccessModifier(modifier) { + return modifier === "private" || modifier === "public" || modifier === "protected"; + } + + var typescript$1 = (superClass => class extends superClass { + getScopeHandler() { + return TypeScriptScopeHandler; + } + + tsIsIdentifier() { + return this.match(5); + } + + tsTokenCanFollowModifier() { + return (this.match(8) || this.match(13) || this.match(54) || this.match(29) || this.match(6) || this.isLiteralPropertyName()) && !this.hasPrecedingLineBreak(); + } + + tsNextTokenCanFollowModifier() { + this.next(); + return this.tsTokenCanFollowModifier(); + } + + tsParseModifier(allowedModifiers, stopOnStartOfClassStaticBlock) { + if (!this.match(5)) { + return undefined; + } + + const modifier = this.state.value; + + if (allowedModifiers.indexOf(modifier) !== -1) { + if (stopOnStartOfClassStaticBlock && this.tsIsStartOfStaticBlocks()) { + return undefined; + } + + if (this.tsTryParse(this.tsNextTokenCanFollowModifier.bind(this))) { + return modifier; + } + } + + return undefined; + } + + tsParseModifiers(modified, allowedModifiers, disallowedModifiers, errorTemplate, stopOnStartOfClassStaticBlock) { + const enforceOrder = (pos, modifier, before, after) => { + if (modifier === before && modified[after]) { + this.raise(pos, TSErrors.InvalidModifiersOrder, before, after); + } + }; + + const incompatible = (pos, modifier, mod1, mod2) => { + if (modified[mod1] && modifier === mod2 || modified[mod2] && modifier === mod1) { + this.raise(pos, TSErrors.IncompatibleModifiers, mod1, mod2); + } + }; + + for (;;) { + const startPos = this.state.start; + const modifier = this.tsParseModifier(allowedModifiers.concat(disallowedModifiers != null ? disallowedModifiers : []), stopOnStartOfClassStaticBlock); + if (!modifier) break; + + if (tsIsAccessModifier(modifier)) { + if (modified.accessibility) { + this.raise(startPos, TSErrors.DuplicateAccessibilityModifier); + } else { + enforceOrder(startPos, modifier, modifier, "override"); + enforceOrder(startPos, modifier, modifier, "static"); + enforceOrder(startPos, modifier, modifier, "readonly"); + modified.accessibility = modifier; + } + } else { + if (Object.hasOwnProperty.call(modified, modifier)) { + this.raise(startPos, TSErrors.DuplicateModifier, modifier); + } else { + enforceOrder(startPos, modifier, "static", "readonly"); + enforceOrder(startPos, modifier, "static", "override"); + enforceOrder(startPos, modifier, "override", "readonly"); + enforceOrder(startPos, modifier, "abstract", "override"); + incompatible(startPos, modifier, "declare", "override"); + incompatible(startPos, modifier, "static", "abstract"); + } + + modified[modifier] = true; + } + + if (disallowedModifiers != null && disallowedModifiers.includes(modifier)) { + this.raise(startPos, errorTemplate, modifier); + } + } + } + + tsIsListTerminator(kind) { + switch (kind) { + case "EnumMembers": + case "TypeMembers": + return this.match(16); + + case "HeritageClauseElement": + return this.match(13); + + case "TupleElementTypes": + return this.match(11); + + case "TypeParametersOrArguments": + return this.isRelational(">"); + } + + throw new Error("Unreachable"); + } + + tsParseList(kind, parseElement) { + const result = []; + + while (!this.tsIsListTerminator(kind)) { + result.push(parseElement()); + } + + return result; + } + + tsParseDelimitedList(kind, parseElement) { + return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true)); + } + + tsParseDelimitedListWorker(kind, parseElement, expectSuccess) { + const result = []; + + for (;;) { + if (this.tsIsListTerminator(kind)) { + break; + } + + const element = parseElement(); + + if (element == null) { + return undefined; + } + + result.push(element); + + if (this.eat(20)) { + continue; + } + + if (this.tsIsListTerminator(kind)) { + break; + } + + if (expectSuccess) { + this.expect(20); + } + + return undefined; + } + + return result; + } + + tsParseBracketedList(kind, parseElement, bracket, skipFirstToken) { + if (!skipFirstToken) { + if (bracket) { + this.expect(8); + } else { + this.expectRelational("<"); + } + } + + const result = this.tsParseDelimitedList(kind, parseElement); + + if (bracket) { + this.expect(11); + } else { + this.expectRelational(">"); + } + + return result; + } + + tsParseImportType() { + const node = this.startNode(); + this.expect(82); + this.expect(18); + + if (!this.match(4)) { + this.raise(this.state.start, TSErrors.UnsupportedImportTypeArgument); + } + + node.argument = this.parseExprAtom(); + this.expect(19); + + if (this.eat(24)) { + node.qualifier = this.tsParseEntityName(true); + } + + if (this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSImportType"); + } + + tsParseEntityName(allowReservedWords) { + let entity = this.parseIdentifier(); + + while (this.eat(24)) { + const node = this.startNodeAtNode(entity); + node.left = entity; + node.right = this.parseIdentifier(allowReservedWords); + entity = this.finishNode(node, "TSQualifiedName"); + } + + return entity; + } + + tsParseTypeReference() { + const node = this.startNode(); + node.typeName = this.tsParseEntityName(false); + + if (!this.hasPrecedingLineBreak() && this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSTypeReference"); + } + + tsParseThisTypePredicate(lhs) { + this.next(); + const node = this.startNodeAtNode(lhs); + node.parameterName = lhs; + node.typeAnnotation = this.tsParseTypeAnnotation(false); + node.asserts = false; + return this.finishNode(node, "TSTypePredicate"); + } + + tsParseThisTypeNode() { + const node = this.startNode(); + this.next(); + return this.finishNode(node, "TSThisType"); + } + + tsParseTypeQuery() { + const node = this.startNode(); + this.expect(86); + + if (this.match(82)) { + node.exprName = this.tsParseImportType(); + } else { + node.exprName = this.tsParseEntityName(true); + } + + return this.finishNode(node, "TSTypeQuery"); + } + + tsParseTypeParameter() { + const node = this.startNode(); + node.name = this.tsParseTypeParameterName(); + node.constraint = this.tsEatThenParseType(80); + node.default = this.tsEatThenParseType(35); + return this.finishNode(node, "TSTypeParameter"); + } + + tsTryParseTypeParameters() { + if (this.isRelational("<")) { + return this.tsParseTypeParameters(); + } + } + + tsParseTypeParameters() { + const node = this.startNode(); + + if (this.isRelational("<") || this.match(94)) { + this.next(); + } else { + this.unexpected(); + } + + node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true); + + if (node.params.length === 0) { + this.raise(node.start, TSErrors.EmptyTypeParameters); + } + + return this.finishNode(node, "TSTypeParameterDeclaration"); + } + + tsTryNextParseConstantContext() { + if (this.lookahead().type === 74) { + this.next(); + return this.tsParseTypeReference(); + } + + return null; + } + + tsFillSignature(returnToken, signature) { + const returnTokenRequired = returnToken === 27; + signature.typeParameters = this.tsTryParseTypeParameters(); + this.expect(18); + signature.parameters = this.tsParseBindingListForSignature(); + + if (returnTokenRequired) { + signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + } else if (this.match(returnToken)) { + signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + } + } + + tsParseBindingListForSignature() { + return this.parseBindingList(19, 41).map(pattern => { + if (pattern.type !== "Identifier" && pattern.type !== "RestElement" && pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") { + this.raise(pattern.start, TSErrors.UnsupportedSignatureParameterKind, pattern.type); + } + + return pattern; + }); + } + + tsParseTypeMemberSemicolon() { + if (!this.eat(20) && !this.isLineTerminator()) { + this.expect(21); + } + } + + tsParseSignatureMember(kind, node) { + this.tsFillSignature(22, node); + this.tsParseTypeMemberSemicolon(); + return this.finishNode(node, kind); + } + + tsIsUnambiguouslyIndexSignature() { + this.next(); + return this.eat(5) && this.match(22); + } + + tsTryParseIndexSignature(node) { + if (!(this.match(8) && this.tsLookAhead(this.tsIsUnambiguouslyIndexSignature.bind(this)))) { + return undefined; + } + + this.expect(8); + const id = this.parseIdentifier(); + id.typeAnnotation = this.tsParseTypeAnnotation(); + this.resetEndLocation(id); + this.expect(11); + node.parameters = [id]; + const type = this.tsTryParseTypeAnnotation(); + if (type) node.typeAnnotation = type; + this.tsParseTypeMemberSemicolon(); + return this.finishNode(node, "TSIndexSignature"); + } + + tsParsePropertyOrMethodSignature(node, readonly) { + if (this.eat(25)) node.optional = true; + const nodeAny = node; + + if (this.match(18) || this.isRelational("<")) { + if (readonly) { + this.raise(node.start, TSErrors.ReadonlyForMethodSignature); + } + + const method = nodeAny; + + if (method.kind && this.isRelational("<")) { + this.raise(this.state.pos, TSErrors.AccesorCannotHaveTypeParameters); + } + + this.tsFillSignature(22, method); + this.tsParseTypeMemberSemicolon(); + + if (method.kind === "get") { + if (method.parameters.length > 0) { + this.raise(this.state.pos, ErrorMessages.BadGetterArity); + + if (this.isThisParam(method.parameters[0])) { + this.raise(this.state.pos, TSErrors.AccesorCannotDeclareThisParameter); + } + } + } else if (method.kind === "set") { + if (method.parameters.length !== 1) { + this.raise(this.state.pos, ErrorMessages.BadSetterArity); + } else { + const firstParameter = method.parameters[0]; + + if (this.isThisParam(firstParameter)) { + this.raise(this.state.pos, TSErrors.AccesorCannotDeclareThisParameter); + } + + if (firstParameter.type === "Identifier" && firstParameter.optional) { + this.raise(this.state.pos, TSErrors.SetAccesorCannotHaveOptionalParameter); + } + + if (firstParameter.type === "RestElement") { + this.raise(this.state.pos, TSErrors.SetAccesorCannotHaveRestParameter); + } + } + + if (method.typeAnnotation) { + this.raise(method.typeAnnotation.start, TSErrors.SetAccesorCannotHaveReturnType); + } + } else { + method.kind = "method"; + } + + return this.finishNode(method, "TSMethodSignature"); + } else { + const property = nodeAny; + if (readonly) property.readonly = true; + const type = this.tsTryParseTypeAnnotation(); + if (type) property.typeAnnotation = type; + this.tsParseTypeMemberSemicolon(); + return this.finishNode(property, "TSPropertySignature"); + } + } + + tsParseTypeMember() { + const node = this.startNode(); + + if (this.match(18) || this.isRelational("<")) { + return this.tsParseSignatureMember("TSCallSignatureDeclaration", node); + } + + if (this.match(76)) { + const id = this.startNode(); + this.next(); + + if (this.match(18) || this.isRelational("<")) { + return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node); + } else { + node.key = this.createIdentifier(id, "new"); + return this.tsParsePropertyOrMethodSignature(node, false); + } + } + + this.tsParseModifiers(node, ["readonly"], ["declare", "abstract", "private", "protected", "public", "static", "override"], TSErrors.InvalidModifierOnTypeMember); + const idx = this.tsTryParseIndexSignature(node); + + if (idx) { + return idx; + } + + this.parsePropertyName(node, false); + + if (!node.computed && node.key.type === "Identifier" && (node.key.name === "get" || node.key.name === "set") && this.tsTokenCanFollowModifier()) { + node.kind = node.key.name; + this.parsePropertyName(node, false); + } + + return this.tsParsePropertyOrMethodSignature(node, !!node.readonly); + } + + tsParseTypeLiteral() { + const node = this.startNode(); + node.members = this.tsParseObjectTypeMembers(); + return this.finishNode(node, "TSTypeLiteral"); + } + + tsParseObjectTypeMembers() { + this.expect(13); + const members = this.tsParseList("TypeMembers", this.tsParseTypeMember.bind(this)); + this.expect(16); + return members; + } + + tsIsStartOfMappedType() { + this.next(); + + if (this.eat(52)) { + return this.isContextual("readonly"); + } + + if (this.isContextual("readonly")) { + this.next(); + } + + if (!this.match(8)) { + return false; + } + + this.next(); + + if (!this.tsIsIdentifier()) { + return false; + } + + this.next(); + return this.match(57); + } + + tsParseMappedTypeParameter() { + const node = this.startNode(); + node.name = this.tsParseTypeParameterName(); + node.constraint = this.tsExpectThenParseType(57); + return this.finishNode(node, "TSTypeParameter"); + } + + tsParseMappedType() { + const node = this.startNode(); + this.expect(13); + + if (this.match(52)) { + node.readonly = this.state.value; + this.next(); + this.expectContextual("readonly"); + } else if (this.eatContextual("readonly")) { + node.readonly = true; + } + + this.expect(8); + node.typeParameter = this.tsParseMappedTypeParameter(); + node.nameType = this.eatContextual("as") ? this.tsParseType() : null; + this.expect(11); + + if (this.match(52)) { + node.optional = this.state.value; + this.next(); + this.expect(25); + } else if (this.eat(25)) { + node.optional = true; + } + + node.typeAnnotation = this.tsTryParseType(); + this.semicolon(); + this.expect(16); + return this.finishNode(node, "TSMappedType"); + } + + tsParseTupleType() { + const node = this.startNode(); + node.elementTypes = this.tsParseBracketedList("TupleElementTypes", this.tsParseTupleElementType.bind(this), true, false); + let seenOptionalElement = false; + let labeledElements = null; + node.elementTypes.forEach(elementNode => { + var _labeledElements; + + let { + type + } = elementNode; + + if (seenOptionalElement && type !== "TSRestType" && type !== "TSOptionalType" && !(type === "TSNamedTupleMember" && elementNode.optional)) { + this.raise(elementNode.start, TSErrors.OptionalTypeBeforeRequired); + } + + seenOptionalElement = seenOptionalElement || type === "TSNamedTupleMember" && elementNode.optional || type === "TSOptionalType"; + + if (type === "TSRestType") { + elementNode = elementNode.typeAnnotation; + type = elementNode.type; + } + + const isLabeled = type === "TSNamedTupleMember"; + labeledElements = (_labeledElements = labeledElements) != null ? _labeledElements : isLabeled; + + if (labeledElements !== isLabeled) { + this.raise(elementNode.start, TSErrors.MixedLabeledAndUnlabeledElements); + } + }); + return this.finishNode(node, "TSTupleType"); + } + + tsParseTupleElementType() { + const { + start: startPos, + startLoc + } = this.state; + const rest = this.eat(29); + let type = this.tsParseType(); + const optional = this.eat(25); + const labeled = this.eat(22); + + if (labeled) { + const labeledNode = this.startNodeAtNode(type); + labeledNode.optional = optional; + + if (type.type === "TSTypeReference" && !type.typeParameters && type.typeName.type === "Identifier") { + labeledNode.label = type.typeName; + } else { + this.raise(type.start, TSErrors.InvalidTupleMemberLabel); + labeledNode.label = type; + } + + labeledNode.elementType = this.tsParseType(); + type = this.finishNode(labeledNode, "TSNamedTupleMember"); + } else if (optional) { + const optionalTypeNode = this.startNodeAtNode(type); + optionalTypeNode.typeAnnotation = type; + type = this.finishNode(optionalTypeNode, "TSOptionalType"); + } + + if (rest) { + const restNode = this.startNodeAt(startPos, startLoc); + restNode.typeAnnotation = type; + type = this.finishNode(restNode, "TSRestType"); + } + + return type; + } + + tsParseParenthesizedType() { + const node = this.startNode(); + this.expect(18); + node.typeAnnotation = this.tsParseType(); + this.expect(19); + return this.finishNode(node, "TSParenthesizedType"); + } + + tsParseFunctionOrConstructorType(type, abstract) { + const node = this.startNode(); + + if (type === "TSConstructorType") { + node.abstract = !!abstract; + if (abstract) this.next(); + this.next(); + } + + this.tsFillSignature(27, node); + return this.finishNode(node, type); + } + + tsParseLiteralTypeNode() { + const node = this.startNode(); + + node.literal = (() => { + switch (this.state.type) { + case 0: + case 1: + case 4: + case 84: + case 85: + return this.parseExprAtom(); + + default: + throw this.unexpected(); + } + })(); + + return this.finishNode(node, "TSLiteralType"); + } + + tsParseTemplateLiteralType() { + const node = this.startNode(); + node.literal = this.parseTemplate(false); + return this.finishNode(node, "TSLiteralType"); + } + + parseTemplateSubstitution() { + if (this.state.inType) return this.tsParseType(); + return super.parseTemplateSubstitution(); + } + + tsParseThisTypeOrThisTypePredicate() { + const thisKeyword = this.tsParseThisTypeNode(); + + if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { + return this.tsParseThisTypePredicate(thisKeyword); + } else { + return thisKeyword; + } + } + + tsParseNonArrayType() { + switch (this.state.type) { + case 5: + case 87: + case 83: + { + const type = this.match(87) ? "TSVoidKeyword" : this.match(83) ? "TSNullKeyword" : keywordTypeFromName(this.state.value); + + if (type !== undefined && this.lookaheadCharCode() !== 46) { + const node = this.startNode(); + this.next(); + return this.finishNode(node, type); + } + + return this.tsParseTypeReference(); + } + + case 4: + case 0: + case 1: + case 84: + case 85: + return this.tsParseLiteralTypeNode(); + + case 52: + if (this.state.value === "-") { + const node = this.startNode(); + const nextToken = this.lookahead(); + + if (nextToken.type !== 0 && nextToken.type !== 1) { + throw this.unexpected(); + } + + node.literal = this.parseMaybeUnary(); + return this.finishNode(node, "TSLiteralType"); + } + + break; + + case 77: + return this.tsParseThisTypeOrThisTypePredicate(); + + case 86: + return this.tsParseTypeQuery(); + + case 82: + return this.tsParseImportType(); + + case 13: + return this.tsLookAhead(this.tsIsStartOfMappedType.bind(this)) ? this.tsParseMappedType() : this.tsParseTypeLiteral(); + + case 8: + return this.tsParseTupleType(); + + case 18: + return this.tsParseParenthesizedType(); + + case 30: + return this.tsParseTemplateLiteralType(); + } + + throw this.unexpected(); + } + + tsParseArrayTypeOrHigher() { + let type = this.tsParseNonArrayType(); + + while (!this.hasPrecedingLineBreak() && this.eat(8)) { + if (this.match(11)) { + const node = this.startNodeAtNode(type); + node.elementType = type; + this.expect(11); + type = this.finishNode(node, "TSArrayType"); + } else { + const node = this.startNodeAtNode(type); + node.objectType = type; + node.indexType = this.tsParseType(); + this.expect(11); + type = this.finishNode(node, "TSIndexedAccessType"); + } + } + + return type; + } + + tsParseTypeOperator(operator) { + const node = this.startNode(); + this.expectContextual(operator); + node.operator = operator; + node.typeAnnotation = this.tsParseTypeOperatorOrHigher(); + + if (operator === "readonly") { + this.tsCheckTypeAnnotationForReadOnly(node); + } + + return this.finishNode(node, "TSTypeOperator"); + } + + tsCheckTypeAnnotationForReadOnly(node) { + switch (node.typeAnnotation.type) { + case "TSTupleType": + case "TSArrayType": + return; + + default: + this.raise(node.start, TSErrors.UnexpectedReadonly); + } + } + + tsParseInferType() { + const node = this.startNode(); + this.expectContextual("infer"); + const typeParameter = this.startNode(); + typeParameter.name = this.tsParseTypeParameterName(); + node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter"); + return this.finishNode(node, "TSInferType"); + } + + tsParseTypeOperatorOrHigher() { + const operator = ["keyof", "unique", "readonly"].find(kw => this.isContextual(kw)); + return operator ? this.tsParseTypeOperator(operator) : this.isContextual("infer") ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher(); + } + + tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) { + const node = this.startNode(); + const hasLeadingOperator = this.eat(operator); + const types = []; + + do { + types.push(parseConstituentType()); + } while (this.eat(operator)); + + if (types.length === 1 && !hasLeadingOperator) { + return types[0]; + } + + node.types = types; + return this.finishNode(node, kind); + } + + tsParseIntersectionTypeOrHigher() { + return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), 48); + } + + tsParseUnionTypeOrHigher() { + return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), 46); + } + + tsIsStartOfFunctionType() { + if (this.isRelational("<")) { + return true; + } + + return this.match(18) && this.tsLookAhead(this.tsIsUnambiguouslyStartOfFunctionType.bind(this)); + } + + tsSkipParameterStart() { + if (this.match(5) || this.match(77)) { + this.next(); + return true; + } + + if (this.match(13)) { + let braceStackCounter = 1; + this.next(); + + while (braceStackCounter > 0) { + if (this.match(13)) { + ++braceStackCounter; + } else if (this.match(16)) { + --braceStackCounter; + } + + this.next(); + } + + return true; + } + + if (this.match(8)) { + let braceStackCounter = 1; + this.next(); + + while (braceStackCounter > 0) { + if (this.match(8)) { + ++braceStackCounter; + } else if (this.match(11)) { + --braceStackCounter; + } + + this.next(); + } + + return true; + } + + return false; + } + + tsIsUnambiguouslyStartOfFunctionType() { + this.next(); + + if (this.match(19) || this.match(29)) { + return true; + } + + if (this.tsSkipParameterStart()) { + if (this.match(22) || this.match(20) || this.match(25) || this.match(35)) { + return true; + } + + if (this.match(19)) { + this.next(); + + if (this.match(27)) { + return true; + } + } + } + + return false; + } + + tsParseTypeOrTypePredicateAnnotation(returnToken) { + return this.tsInType(() => { + const t = this.startNode(); + this.expect(returnToken); + const node = this.startNode(); + const asserts = !!this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this)); + + if (asserts && this.match(77)) { + let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate(); + + if (thisTypePredicate.type === "TSThisType") { + node.parameterName = thisTypePredicate; + node.asserts = true; + node.typeAnnotation = null; + thisTypePredicate = this.finishNode(node, "TSTypePredicate"); + } else { + this.resetStartLocationFromNode(thisTypePredicate, node); + thisTypePredicate.asserts = true; + } + + t.typeAnnotation = thisTypePredicate; + return this.finishNode(t, "TSTypeAnnotation"); + } + + const typePredicateVariable = this.tsIsIdentifier() && this.tsTryParse(this.tsParseTypePredicatePrefix.bind(this)); + + if (!typePredicateVariable) { + if (!asserts) { + return this.tsParseTypeAnnotation(false, t); + } + + node.parameterName = this.parseIdentifier(); + node.asserts = asserts; + node.typeAnnotation = null; + t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); + return this.finishNode(t, "TSTypeAnnotation"); + } + + const type = this.tsParseTypeAnnotation(false); + node.parameterName = typePredicateVariable; + node.typeAnnotation = type; + node.asserts = asserts; + t.typeAnnotation = this.finishNode(node, "TSTypePredicate"); + return this.finishNode(t, "TSTypeAnnotation"); + }); + } + + tsTryParseTypeOrTypePredicateAnnotation() { + return this.match(22) ? this.tsParseTypeOrTypePredicateAnnotation(22) : undefined; + } + + tsTryParseTypeAnnotation() { + return this.match(22) ? this.tsParseTypeAnnotation() : undefined; + } + + tsTryParseType() { + return this.tsEatThenParseType(22); + } + + tsParseTypePredicatePrefix() { + const id = this.parseIdentifier(); + + if (this.isContextual("is") && !this.hasPrecedingLineBreak()) { + this.next(); + return id; + } + } + + tsParseTypePredicateAsserts() { + if (!this.match(5) || this.state.value !== "asserts") { + return false; + } + + const containsEsc = this.state.containsEsc; + this.next(); + + if (!this.match(5) && !this.match(77)) { + return false; + } + + if (containsEsc) { + this.raise(this.state.lastTokStart, ErrorMessages.InvalidEscapedReservedWord, "asserts"); + } + + return true; + } + + tsParseTypeAnnotation(eatColon = true, t = this.startNode()) { + this.tsInType(() => { + if (eatColon) this.expect(22); + t.typeAnnotation = this.tsParseType(); + }); + return this.finishNode(t, "TSTypeAnnotation"); + } + + tsParseType() { + assert(this.state.inType); + const type = this.tsParseNonConditionalType(); + + if (this.hasPrecedingLineBreak() || !this.eat(80)) { + return type; + } + + const node = this.startNodeAtNode(type); + node.checkType = type; + node.extendsType = this.tsParseNonConditionalType(); + this.expect(25); + node.trueType = this.tsParseType(); + this.expect(22); + node.falseType = this.tsParseType(); + return this.finishNode(node, "TSConditionalType"); + } + + isAbstractConstructorSignature() { + return this.isContextual("abstract") && this.lookahead().type === 76; + } + + tsParseNonConditionalType() { + if (this.tsIsStartOfFunctionType()) { + return this.tsParseFunctionOrConstructorType("TSFunctionType"); + } + + if (this.match(76)) { + return this.tsParseFunctionOrConstructorType("TSConstructorType"); + } else if (this.isAbstractConstructorSignature()) { + return this.tsParseFunctionOrConstructorType("TSConstructorType", true); + } + + return this.tsParseUnionTypeOrHigher(); + } + + tsParseTypeAssertion() { + const node = this.startNode(); + + const _const = this.tsTryNextParseConstantContext(); + + node.typeAnnotation = _const || this.tsNextThenParseType(); + this.expectRelational(">"); + node.expression = this.parseMaybeUnary(); + return this.finishNode(node, "TSTypeAssertion"); + } + + tsParseHeritageClause(descriptor) { + const originalStart = this.state.start; + const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", this.tsParseExpressionWithTypeArguments.bind(this)); + + if (!delimitedList.length) { + this.raise(originalStart, TSErrors.EmptyHeritageClauseType, descriptor); + } + + return delimitedList; + } + + tsParseExpressionWithTypeArguments() { + const node = this.startNode(); + node.expression = this.tsParseEntityName(false); + + if (this.isRelational("<")) { + node.typeParameters = this.tsParseTypeArguments(); + } + + return this.finishNode(node, "TSExpressionWithTypeArguments"); + } + + tsParseInterfaceDeclaration(node) { + if (this.match(5)) { + node.id = this.parseIdentifier(); + this.checkLVal(node.id, "typescript interface declaration", BIND_TS_INTERFACE); + } else { + node.id = null; + this.raise(this.state.start, TSErrors.MissingInterfaceName); + } + + node.typeParameters = this.tsTryParseTypeParameters(); + + if (this.eat(80)) { + node.extends = this.tsParseHeritageClause("extends"); + } + + const body = this.startNode(); + body.body = this.tsInType(this.tsParseObjectTypeMembers.bind(this)); + node.body = this.finishNode(body, "TSInterfaceBody"); + return this.finishNode(node, "TSInterfaceDeclaration"); + } + + tsParseTypeAliasDeclaration(node) { + node.id = this.parseIdentifier(); + this.checkLVal(node.id, "typescript type alias", BIND_TS_TYPE); + node.typeParameters = this.tsTryParseTypeParameters(); + node.typeAnnotation = this.tsInType(() => { + this.expect(35); + + if (this.isContextual("intrinsic") && this.lookahead().type !== 24) { + const node = this.startNode(); + this.next(); + return this.finishNode(node, "TSIntrinsicKeyword"); + } + + return this.tsParseType(); + }); + this.semicolon(); + return this.finishNode(node, "TSTypeAliasDeclaration"); + } + + tsInNoContext(cb) { + const oldContext = this.state.context; + this.state.context = [oldContext[0]]; + + try { + return cb(); + } finally { + this.state.context = oldContext; + } + } + + tsInType(cb) { + const oldInType = this.state.inType; + this.state.inType = true; + + try { + return cb(); + } finally { + this.state.inType = oldInType; + } + } + + tsEatThenParseType(token) { + return !this.match(token) ? undefined : this.tsNextThenParseType(); + } + + tsExpectThenParseType(token) { + return this.tsDoThenParseType(() => this.expect(token)); + } + + tsNextThenParseType() { + return this.tsDoThenParseType(() => this.next()); + } + + tsDoThenParseType(cb) { + return this.tsInType(() => { + cb(); + return this.tsParseType(); + }); + } + + tsParseEnumMember() { + const node = this.startNode(); + node.id = this.match(4) ? this.parseExprAtom() : this.parseIdentifier(true); + + if (this.eat(35)) { + node.initializer = this.parseMaybeAssignAllowIn(); + } + + return this.finishNode(node, "TSEnumMember"); + } + + tsParseEnumDeclaration(node, isConst) { + if (isConst) node.const = true; + node.id = this.parseIdentifier(); + this.checkLVal(node.id, "typescript enum declaration", isConst ? BIND_TS_CONST_ENUM : BIND_TS_ENUM); + this.expect(13); + node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this)); + this.expect(16); + return this.finishNode(node, "TSEnumDeclaration"); + } + + tsParseModuleBlock() { + const node = this.startNode(); + this.scope.enter(SCOPE_OTHER); + this.expect(13); + this.parseBlockOrModuleBlockBody(node.body = [], undefined, true, 16); + this.scope.exit(); + return this.finishNode(node, "TSModuleBlock"); + } + + tsParseModuleOrNamespaceDeclaration(node, nested = false) { + node.id = this.parseIdentifier(); + + if (!nested) { + this.checkLVal(node.id, "module or namespace declaration", BIND_TS_NAMESPACE); + } + + if (this.eat(24)) { + const inner = this.startNode(); + this.tsParseModuleOrNamespaceDeclaration(inner, true); + node.body = inner; + } else { + this.scope.enter(SCOPE_TS_MODULE); + this.prodParam.enter(PARAM); + node.body = this.tsParseModuleBlock(); + this.prodParam.exit(); + this.scope.exit(); + } + + return this.finishNode(node, "TSModuleDeclaration"); + } + + tsParseAmbientExternalModuleDeclaration(node) { + if (this.isContextual("global")) { + node.global = true; + node.id = this.parseIdentifier(); + } else if (this.match(4)) { + node.id = this.parseExprAtom(); + } else { + this.unexpected(); + } + + if (this.match(13)) { + this.scope.enter(SCOPE_TS_MODULE); + this.prodParam.enter(PARAM); + node.body = this.tsParseModuleBlock(); + this.prodParam.exit(); + this.scope.exit(); + } else { + this.semicolon(); + } + + return this.finishNode(node, "TSModuleDeclaration"); + } + + tsParseImportEqualsDeclaration(node, isExport) { + node.isExport = isExport || false; + node.id = this.parseIdentifier(); + this.checkLVal(node.id, "import equals declaration", BIND_LEXICAL); + this.expect(35); + const moduleReference = this.tsParseModuleReference(); + + if (node.importKind === "type" && moduleReference.type !== "TSExternalModuleReference") { + this.raise(moduleReference.start, TSErrors.ImportAliasHasImportType); + } + + node.moduleReference = moduleReference; + this.semicolon(); + return this.finishNode(node, "TSImportEqualsDeclaration"); + } + + tsIsExternalModuleReference() { + return this.isContextual("require") && this.lookaheadCharCode() === 40; + } + + tsParseModuleReference() { + return this.tsIsExternalModuleReference() ? this.tsParseExternalModuleReference() : this.tsParseEntityName(false); + } + + tsParseExternalModuleReference() { + const node = this.startNode(); + this.expectContextual("require"); + this.expect(18); + + if (!this.match(4)) { + throw this.unexpected(); + } + + node.expression = this.parseExprAtom(); + this.expect(19); + return this.finishNode(node, "TSExternalModuleReference"); + } + + tsLookAhead(f) { + const state = this.state.clone(); + const res = f(); + this.state = state; + return res; + } + + tsTryParseAndCatch(f) { + const result = this.tryParse(abort => f() || abort()); + if (result.aborted || !result.node) return undefined; + if (result.error) this.state = result.failState; + return result.node; + } + + tsTryParse(f) { + const state = this.state.clone(); + const result = f(); + + if (result !== undefined && result !== false) { + return result; + } else { + this.state = state; + return undefined; + } + } + + tsTryParseDeclare(nany) { + if (this.isLineTerminator()) { + return; + } + + let starttype = this.state.type; + let kind; + + if (this.isContextual("let")) { + starttype = 73; + kind = "let"; + } + + return this.tsInAmbientContext(() => { + switch (starttype) { + case 67: + nany.declare = true; + return this.parseFunctionStatement(nany, false, true); + + case 79: + nany.declare = true; + return this.parseClass(nany, true, false); + + case 74: + if (this.match(74) && this.isLookaheadContextual("enum")) { + this.expect(74); + this.expectContextual("enum"); + return this.tsParseEnumDeclaration(nany, true); + } + + case 73: + kind = kind || this.state.value; + return this.parseVarStatement(nany, kind); + + case 5: + { + const value = this.state.value; + + if (value === "global") { + return this.tsParseAmbientExternalModuleDeclaration(nany); + } else { + return this.tsParseDeclaration(nany, value, true); + } + } + } + }); + } + + tsTryParseExportDeclaration() { + return this.tsParseDeclaration(this.startNode(), this.state.value, true); + } + + tsParseExpressionStatement(node, expr) { + switch (expr.name) { + case "declare": + { + const declaration = this.tsTryParseDeclare(node); + + if (declaration) { + declaration.declare = true; + return declaration; + } + + break; + } + + case "global": + if (this.match(13)) { + this.scope.enter(SCOPE_TS_MODULE); + this.prodParam.enter(PARAM); + const mod = node; + mod.global = true; + mod.id = expr; + mod.body = this.tsParseModuleBlock(); + this.scope.exit(); + this.prodParam.exit(); + return this.finishNode(mod, "TSModuleDeclaration"); + } + + break; + + default: + return this.tsParseDeclaration(node, expr.name, false); + } + } + + tsParseDeclaration(node, value, next) { + switch (value) { + case "abstract": + if (this.tsCheckLineTerminator(next) && (this.match(79) || this.match(5))) { + return this.tsParseAbstractDeclaration(node); + } + + break; + + case "enum": + if (next || this.match(5)) { + if (next) this.next(); + return this.tsParseEnumDeclaration(node, false); + } + + break; + + case "interface": + if (this.tsCheckLineTerminator(next) && this.match(5)) { + return this.tsParseInterfaceDeclaration(node); + } + + break; + + case "module": + if (this.tsCheckLineTerminator(next)) { + if (this.match(4)) { + return this.tsParseAmbientExternalModuleDeclaration(node); + } else if (this.match(5)) { + return this.tsParseModuleOrNamespaceDeclaration(node); + } + } + + break; + + case "namespace": + if (this.tsCheckLineTerminator(next) && this.match(5)) { + return this.tsParseModuleOrNamespaceDeclaration(node); + } + + break; + + case "type": + if (this.tsCheckLineTerminator(next) && this.match(5)) { + return this.tsParseTypeAliasDeclaration(node); + } + + break; + } + } + + tsCheckLineTerminator(next) { + if (next) { + if (this.hasFollowingLineBreak()) return false; + this.next(); + return true; + } + + return !this.isLineTerminator(); + } + + tsTryParseGenericAsyncArrowFunction(startPos, startLoc) { + if (!this.isRelational("<")) { + return undefined; + } + + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + this.state.maybeInArrowParameters = true; + const res = this.tsTryParseAndCatch(() => { + const node = this.startNodeAt(startPos, startLoc); + node.typeParameters = this.tsParseTypeParameters(); + super.parseFunctionParams(node); + node.returnType = this.tsTryParseTypeOrTypePredicateAnnotation(); + this.expect(27); + return node; + }); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + + if (!res) { + return undefined; + } + + return this.parseArrowExpression(res, null, true); + } + + tsParseTypeArguments() { + const node = this.startNode(); + node.params = this.tsInType(() => this.tsInNoContext(() => { + this.expectRelational("<"); + return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this)); + })); + + if (node.params.length === 0) { + this.raise(node.start, TSErrors.EmptyTypeArguments); + } + + this.expectRelational(">"); + return this.finishNode(node, "TSTypeParameterInstantiation"); + } + + tsIsDeclarationStart() { + if (this.match(5)) { + switch (this.state.value) { + case "abstract": + case "declare": + case "enum": + case "interface": + case "module": + case "namespace": + case "type": + return true; + } + } + + return false; + } + + isExportDefaultSpecifier() { + if (this.tsIsDeclarationStart()) return false; + return super.isExportDefaultSpecifier(); + } + + parseAssignableListItem(allowModifiers, decorators) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let accessibility; + let readonly = false; + let override = false; + + if (allowModifiers !== undefined) { + const modified = {}; + this.tsParseModifiers(modified, ["public", "private", "protected", "override", "readonly"]); + accessibility = modified.accessibility; + override = modified.override; + readonly = modified.readonly; + + if (allowModifiers === false && (accessibility || readonly || override)) { + this.raise(startPos, TSErrors.UnexpectedParameterModifier); + } + } + + const left = this.parseMaybeDefault(); + this.parseAssignableListItemTypes(left); + const elt = this.parseMaybeDefault(left.start, left.loc.start, left); + + if (accessibility || readonly || override) { + const pp = this.startNodeAt(startPos, startLoc); + + if (decorators.length) { + pp.decorators = decorators; + } + + if (accessibility) pp.accessibility = accessibility; + if (readonly) pp.readonly = readonly; + if (override) pp.override = override; + + if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") { + this.raise(pp.start, TSErrors.UnsupportedParameterPropertyKind); + } + + pp.parameter = elt; + return this.finishNode(pp, "TSParameterProperty"); + } + + if (decorators.length) { + left.decorators = decorators; + } + + return elt; + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + if (this.match(22)) { + node.returnType = this.tsParseTypeOrTypePredicateAnnotation(22); + } + + const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" ? "TSDeclareMethod" : undefined; + + if (bodilessType && !this.match(13) && this.isLineTerminator()) { + this.finishNode(node, bodilessType); + return; + } + + if (bodilessType === "TSDeclareFunction" && this.state.isAmbientContext) { + this.raise(node.start, TSErrors.DeclareFunctionHasImplementation); + + if (node.declare) { + super.parseFunctionBodyAndFinish(node, bodilessType, isMethod); + return; + } + } + + super.parseFunctionBodyAndFinish(node, type, isMethod); + } + + registerFunctionStatementId(node) { + if (!node.body && node.id) { + this.checkLVal(node.id, "function name", BIND_TS_AMBIENT); + } else { + super.registerFunctionStatementId(...arguments); + } + } + + tsCheckForInvalidTypeCasts(items) { + items.forEach(node => { + if ((node == null ? void 0 : node.type) === "TSTypeCastExpression") { + this.raise(node.typeAnnotation.start, TSErrors.UnexpectedTypeAnnotation); + } + }); + } + + toReferencedList(exprList, isInParens) { + this.tsCheckForInvalidTypeCasts(exprList); + return exprList; + } + + parseArrayLike(...args) { + const node = super.parseArrayLike(...args); + + if (node.type === "ArrayExpression") { + this.tsCheckForInvalidTypeCasts(node.elements); + } + + return node; + } + + parseSubscript(base, startPos, startLoc, noCalls, state) { + if (!this.hasPrecedingLineBreak() && this.match(40)) { + this.state.exprAllowed = false; + this.next(); + const nonNullExpression = this.startNodeAt(startPos, startLoc); + nonNullExpression.expression = base; + return this.finishNode(nonNullExpression, "TSNonNullExpression"); + } + + let isOptionalCall = false; + + if (this.match(26) && this.lookaheadCharCode() === 60) { + if (noCalls) { + state.stop = true; + return base; + } + + state.optionalChainMember = isOptionalCall = true; + this.next(); + } + + if (this.isRelational("<")) { + let missingParenErrorPos; + const result = this.tsTryParseAndCatch(() => { + if (!noCalls && this.atPossibleAsyncArrow(base)) { + const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startPos, startLoc); + + if (asyncArrowFn) { + return asyncArrowFn; + } + } + + const node = this.startNodeAt(startPos, startLoc); + node.callee = base; + const typeArguments = this.tsParseTypeArguments(); + + if (typeArguments) { + if (isOptionalCall && !this.match(18)) { + missingParenErrorPos = this.state.pos; + this.unexpected(); + } + + if (!noCalls && this.eat(18)) { + node.arguments = this.parseCallExpressionArguments(19, false); + this.tsCheckForInvalidTypeCasts(node.arguments); + node.typeParameters = typeArguments; + + if (state.optionalChainMember) { + node.optional = isOptionalCall; + } + + return this.finishCallExpression(node, state.optionalChainMember); + } else if (this.match(30)) { + const result = this.parseTaggedTemplateExpression(base, startPos, startLoc, state); + result.typeParameters = typeArguments; + return result; + } + } + + this.unexpected(); + }); + + if (missingParenErrorPos) { + this.unexpected(missingParenErrorPos, 18); + } + + if (result) return result; + } + + return super.parseSubscript(base, startPos, startLoc, noCalls, state); + } + + parseNewArguments(node) { + if (this.isRelational("<")) { + const typeParameters = this.tsTryParseAndCatch(() => { + const args = this.tsParseTypeArguments(); + if (!this.match(18)) this.unexpected(); + return args; + }); + + if (typeParameters) { + node.typeParameters = typeParameters; + } + } + + super.parseNewArguments(node); + } + + parseExprOp(left, leftStartPos, leftStartLoc, minPrec) { + if (tokenOperatorPrecedence(57) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual("as")) { + const node = this.startNodeAt(leftStartPos, leftStartLoc); + node.expression = left; + + const _const = this.tsTryNextParseConstantContext(); + + if (_const) { + node.typeAnnotation = _const; + } else { + node.typeAnnotation = this.tsNextThenParseType(); + } + + this.finishNode(node, "TSAsExpression"); + this.reScan_lt_gt(); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec); + } + + return super.parseExprOp(left, leftStartPos, leftStartLoc, minPrec); + } + + checkReservedWord(word, startLoc, checkKeywords, isBinding) {} + + checkDuplicateExports() {} + + parseImport(node) { + node.importKind = "value"; + + if (this.match(5) || this.match(54) || this.match(13)) { + let ahead = this.lookahead(); + + if (this.isContextual("type") && ahead.type !== 20 && !(ahead.type === 5 && ahead.value === "from") && ahead.type !== 35) { + node.importKind = "type"; + this.next(); + ahead = this.lookahead(); + } + + if (this.match(5) && ahead.type === 35) { + return this.tsParseImportEqualsDeclaration(node); + } + } + + const importNode = super.parseImport(node); + + if (importNode.importKind === "type" && importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier") { + this.raise(importNode.start, TSErrors.TypeImportCannotSpecifyDefaultAndNamed); + } + + return importNode; + } + + parseExport(node) { + if (this.match(82)) { + this.next(); + + if (this.isContextual("type") && this.lookaheadCharCode() !== 61) { + node.importKind = "type"; + this.next(); + } else { + node.importKind = "value"; + } + + return this.tsParseImportEqualsDeclaration(node, true); + } else if (this.eat(35)) { + const assign = node; + assign.expression = this.parseExpression(); + this.semicolon(); + return this.finishNode(assign, "TSExportAssignment"); + } else if (this.eatContextual("as")) { + const decl = node; + this.expectContextual("namespace"); + decl.id = this.parseIdentifier(); + this.semicolon(); + return this.finishNode(decl, "TSNamespaceExportDeclaration"); + } else { + if (this.isContextual("type") && this.lookahead().type === 13) { + this.next(); + node.exportKind = "type"; + } else { + node.exportKind = "value"; + } + + return super.parseExport(node); + } + } + + isAbstractClass() { + return this.isContextual("abstract") && this.lookahead().type === 79; + } + + parseExportDefaultExpression() { + if (this.isAbstractClass()) { + const cls = this.startNode(); + this.next(); + cls.abstract = true; + this.parseClass(cls, true, true); + return cls; + } + + if (this.state.value === "interface") { + const interfaceNode = this.startNode(); + this.next(); + const result = this.tsParseInterfaceDeclaration(interfaceNode); + if (result) return result; + } + + return super.parseExportDefaultExpression(); + } + + parseStatementContent(context, topLevel) { + if (this.state.type === 74) { + const ahead = this.lookahead(); + + if (ahead.type === 5 && ahead.value === "enum") { + const node = this.startNode(); + this.expect(74); + this.expectContextual("enum"); + return this.tsParseEnumDeclaration(node, true); + } + } + + return super.parseStatementContent(context, topLevel); + } + + parseAccessModifier() { + return this.tsParseModifier(["public", "protected", "private"]); + } + + tsHasSomeModifiers(member, modifiers) { + return modifiers.some(modifier => { + if (tsIsAccessModifier(modifier)) { + return member.accessibility === modifier; + } + + return !!member[modifier]; + }); + } + + tsIsStartOfStaticBlocks() { + return this.isContextual("static") && this.lookaheadCharCode() === 123; + } + + parseClassMember(classBody, member, state) { + const modifiers = ["declare", "private", "public", "protected", "override", "abstract", "readonly", "static"]; + this.tsParseModifiers(member, modifiers, undefined, undefined, true); + + const callParseClassMemberWithIsStatic = () => { + if (this.tsIsStartOfStaticBlocks()) { + this.next(); + this.next(); + + if (this.tsHasSomeModifiers(member, modifiers)) { + this.raise(this.state.pos, TSErrors.StaticBlockCannotHaveModifier); + } + + this.parseClassStaticBlock(classBody, member); + } else { + this.parseClassMemberWithIsStatic(classBody, member, state, !!member.static); + } + }; + + if (member.declare) { + this.tsInAmbientContext(callParseClassMemberWithIsStatic); + } else { + callParseClassMemberWithIsStatic(); + } + } + + parseClassMemberWithIsStatic(classBody, member, state, isStatic) { + const idx = this.tsTryParseIndexSignature(member); + + if (idx) { + classBody.body.push(idx); + + if (member.abstract) { + this.raise(member.start, TSErrors.IndexSignatureHasAbstract); + } + + if (member.accessibility) { + this.raise(member.start, TSErrors.IndexSignatureHasAccessibility, member.accessibility); + } + + if (member.declare) { + this.raise(member.start, TSErrors.IndexSignatureHasDeclare); + } + + if (member.override) { + this.raise(member.start, TSErrors.IndexSignatureHasOverride); + } + + return; + } + + if (!this.state.inAbstractClass && member.abstract) { + this.raise(member.start, TSErrors.NonAbstractClassHasAbstractMethod); + } + + if (member.override) { + if (!state.hadSuperClass) { + this.raise(member.start, TSErrors.OverrideNotInSubClass); + } + } + + super.parseClassMemberWithIsStatic(classBody, member, state, isStatic); + } + + parsePostMemberNameModifiers(methodOrProp) { + const optional = this.eat(25); + if (optional) methodOrProp.optional = true; + + if (methodOrProp.readonly && this.match(18)) { + this.raise(methodOrProp.start, TSErrors.ClassMethodHasReadonly); + } + + if (methodOrProp.declare && this.match(18)) { + this.raise(methodOrProp.start, TSErrors.ClassMethodHasDeclare); + } + } + + parseExpressionStatement(node, expr) { + const decl = expr.type === "Identifier" ? this.tsParseExpressionStatement(node, expr) : undefined; + return decl || super.parseExpressionStatement(node, expr); + } + + shouldParseExportDeclaration() { + if (this.tsIsDeclarationStart()) return true; + return super.shouldParseExportDeclaration(); + } + + parseConditional(expr, startPos, startLoc, refExpressionErrors) { + if (!this.state.maybeInArrowParameters || !this.match(25)) { + return super.parseConditional(expr, startPos, startLoc, refExpressionErrors); + } + + const result = this.tryParse(() => super.parseConditional(expr, startPos, startLoc)); + + if (!result.node) { + if (result.error) { + super.setOptionalParametersError(refExpressionErrors, result.error); + } + + return expr; + } + + if (result.error) this.state = result.failState; + return result.node; + } + + parseParenItem(node, startPos, startLoc) { + node = super.parseParenItem(node, startPos, startLoc); + + if (this.eat(25)) { + node.optional = true; + this.resetEndLocation(node); + } + + if (this.match(22)) { + const typeCastNode = this.startNodeAt(startPos, startLoc); + typeCastNode.expression = node; + typeCastNode.typeAnnotation = this.tsParseTypeAnnotation(); + return this.finishNode(typeCastNode, "TSTypeCastExpression"); + } + + return node; + } + + parseExportDeclaration(node) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const isDeclare = this.eatContextual("declare"); + + if (isDeclare && (this.isContextual("declare") || !this.shouldParseExportDeclaration())) { + throw this.raise(this.state.start, TSErrors.ExpectedAmbientAfterExportDeclare); + } + + let declaration; + + if (this.match(5)) { + declaration = this.tsTryParseExportDeclaration(); + } + + if (!declaration) { + declaration = super.parseExportDeclaration(node); + } + + if (declaration && (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare)) { + node.exportKind = "type"; + } + + if (declaration && isDeclare) { + this.resetStartLocation(declaration, startPos, startLoc); + declaration.declare = true; + } + + return declaration; + } + + parseClassId(node, isStatement, optionalId) { + if ((!isStatement || optionalId) && this.isContextual("implements")) { + return; + } + + super.parseClassId(node, isStatement, optionalId, node.declare ? BIND_TS_AMBIENT : BIND_CLASS); + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) node.typeParameters = typeParameters; + } + + parseClassPropertyAnnotation(node) { + if (!node.optional && this.eat(40)) { + node.definite = true; + } + + const type = this.tsTryParseTypeAnnotation(); + if (type) node.typeAnnotation = type; + } + + parseClassProperty(node) { + this.parseClassPropertyAnnotation(node); + + if (this.state.isAmbientContext && this.match(35)) { + this.raise(this.state.start, TSErrors.DeclareClassFieldHasInitializer); + } + + if (node.abstract && this.match(35)) { + const { + key + } = node; + this.raise(this.state.start, TSErrors.AbstractPropertyHasInitializer, key.type === "Identifier" && !node.computed ? key.name : `[${this.input.slice(key.start, key.end)}]`); + } + + return super.parseClassProperty(node); + } + + parseClassPrivateProperty(node) { + if (node.abstract) { + this.raise(node.start, TSErrors.PrivateElementHasAbstract); + } + + if (node.accessibility) { + this.raise(node.start, TSErrors.PrivateElementHasAccessibility, node.accessibility); + } + + this.parseClassPropertyAnnotation(node); + return super.parseClassPrivateProperty(node); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + const typeParameters = this.tsTryParseTypeParameters(); + + if (typeParameters && isConstructor) { + this.raise(typeParameters.start, TSErrors.ConstructorHasTypeParameters); + } + + if (method.declare && (method.kind === "get" || method.kind === "set")) { + this.raise(method.start, TSErrors.DeclareAccessor, method.kind); + } + + if (typeParameters) method.typeParameters = typeParameters; + super.pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper); + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) method.typeParameters = typeParameters; + super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); + } + + parseClassSuper(node) { + super.parseClassSuper(node); + + if (node.superClass && this.isRelational("<")) { + node.superTypeParameters = this.tsParseTypeArguments(); + } + + if (this.eatContextual("implements")) { + node.implements = this.tsParseHeritageClause("implements"); + } + } + + parseObjPropValue(prop, ...args) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) prop.typeParameters = typeParameters; + super.parseObjPropValue(prop, ...args); + } + + parseFunctionParams(node, allowModifiers) { + const typeParameters = this.tsTryParseTypeParameters(); + if (typeParameters) node.typeParameters = typeParameters; + super.parseFunctionParams(node, allowModifiers); + } + + parseVarId(decl, kind) { + super.parseVarId(decl, kind); + + if (decl.id.type === "Identifier" && this.eat(40)) { + decl.definite = true; + } + + const type = this.tsTryParseTypeAnnotation(); + + if (type) { + decl.id.typeAnnotation = type; + this.resetEndLocation(decl.id); + } + } + + parseAsyncArrowFromCallExpression(node, call) { + if (this.match(22)) { + node.returnType = this.tsParseTypeAnnotation(); + } + + return super.parseAsyncArrowFromCallExpression(node, call); + } + + parseMaybeAssign(...args) { + var _jsx, _jsx2, _typeCast, _jsx3, _typeCast2, _jsx4, _typeCast3; + + let state; + let jsx; + let typeCast; + + if (this.hasPlugin("jsx") && (this.match(94) || this.isRelational("<"))) { + state = this.state.clone(); + jsx = this.tryParse(() => super.parseMaybeAssign(...args), state); + if (!jsx.error) return jsx.node; + const { + context + } = this.state; + + if (context[context.length - 1] === types$1.j_oTag) { + context.length -= 2; + } else if (context[context.length - 1] === types$1.j_expr) { + context.length -= 1; + } + } + + if (!((_jsx = jsx) != null && _jsx.error) && !this.isRelational("<")) { + return super.parseMaybeAssign(...args); + } + + let typeParameters; + state = state || this.state.clone(); + const arrow = this.tryParse(abort => { + var _expr$extra, _typeParameters; + + typeParameters = this.tsParseTypeParameters(); + const expr = super.parseMaybeAssign(...args); + + if (expr.type !== "ArrowFunctionExpression" || (_expr$extra = expr.extra) != null && _expr$extra.parenthesized) { + abort(); + } + + if (((_typeParameters = typeParameters) == null ? void 0 : _typeParameters.params.length) !== 0) { + this.resetStartLocationFromNode(expr, typeParameters); + } + + expr.typeParameters = typeParameters; + return expr; + }, state); + if (!arrow.error && !arrow.aborted) return arrow.node; + + if (!jsx) { + assert(!this.hasPlugin("jsx")); + typeCast = this.tryParse(() => super.parseMaybeAssign(...args), state); + if (!typeCast.error) return typeCast.node; + } + + if ((_jsx2 = jsx) != null && _jsx2.node) { + this.state = jsx.failState; + return jsx.node; + } + + if (arrow.node) { + this.state = arrow.failState; + return arrow.node; + } + + if ((_typeCast = typeCast) != null && _typeCast.node) { + this.state = typeCast.failState; + return typeCast.node; + } + + if ((_jsx3 = jsx) != null && _jsx3.thrown) throw jsx.error; + if (arrow.thrown) throw arrow.error; + if ((_typeCast2 = typeCast) != null && _typeCast2.thrown) throw typeCast.error; + throw ((_jsx4 = jsx) == null ? void 0 : _jsx4.error) || arrow.error || ((_typeCast3 = typeCast) == null ? void 0 : _typeCast3.error); + } + + parseMaybeUnary(refExpressionErrors) { + if (!this.hasPlugin("jsx") && this.isRelational("<")) { + return this.tsParseTypeAssertion(); + } else { + return super.parseMaybeUnary(refExpressionErrors); + } + } + + parseArrow(node) { + if (this.match(22)) { + const result = this.tryParse(abort => { + const returnType = this.tsParseTypeOrTypePredicateAnnotation(22); + if (this.canInsertSemicolon() || !this.match(27)) abort(); + return returnType; + }); + if (result.aborted) return; + + if (!result.thrown) { + if (result.error) this.state = result.failState; + node.returnType = result.node; + } + } + + return super.parseArrow(node); + } + + parseAssignableListItemTypes(param) { + if (this.eat(25)) { + if (param.type !== "Identifier" && !this.state.isAmbientContext && !this.state.inType) { + this.raise(param.start, TSErrors.PatternIsOptional); + } + + param.optional = true; + } + + const type = this.tsTryParseTypeAnnotation(); + if (type) param.typeAnnotation = type; + this.resetEndLocation(param); + return param; + } + + isAssignable(node, isBinding) { + switch (node.type) { + case "TSTypeCastExpression": + return this.isAssignable(node.expression, isBinding); + + case "TSParameterProperty": + return true; + + default: + return super.isAssignable(node, isBinding); + } + } + + toAssignable(node, isLHS = false) { + switch (node.type) { + case "TSTypeCastExpression": + return super.toAssignable(this.typeCastToParameter(node), isLHS); + + case "TSParameterProperty": + return super.toAssignable(node, isLHS); + + case "ParenthesizedExpression": + return this.toAssignableParenthesizedExpression(node, isLHS); + + case "TSAsExpression": + case "TSNonNullExpression": + case "TSTypeAssertion": + node.expression = this.toAssignable(node.expression, isLHS); + return node; + + default: + return super.toAssignable(node, isLHS); + } + } + + toAssignableParenthesizedExpression(node, isLHS) { + switch (node.expression.type) { + case "TSAsExpression": + case "TSNonNullExpression": + case "TSTypeAssertion": + case "ParenthesizedExpression": + node.expression = this.toAssignable(node.expression, isLHS); + return node; + + default: + return super.toAssignable(node, isLHS); + } + } + + checkLVal(expr, contextDescription, ...args) { + var _expr$extra2; + + switch (expr.type) { + case "TSTypeCastExpression": + return; + + case "TSParameterProperty": + this.checkLVal(expr.parameter, "parameter property", ...args); + return; + + case "TSAsExpression": + case "TSTypeAssertion": + if (!args[0] && contextDescription !== "parenthesized expression" && !((_expr$extra2 = expr.extra) != null && _expr$extra2.parenthesized)) { + this.raise(expr.start, ErrorMessages.InvalidLhs, contextDescription); + break; + } + + this.checkLVal(expr.expression, "parenthesized expression", ...args); + return; + + case "TSNonNullExpression": + this.checkLVal(expr.expression, contextDescription, ...args); + return; + + default: + super.checkLVal(expr, contextDescription, ...args); + return; + } + } + + parseBindingAtom() { + switch (this.state.type) { + case 77: + return this.parseIdentifier(true); + + default: + return super.parseBindingAtom(); + } + } + + parseMaybeDecoratorArguments(expr) { + if (this.isRelational("<")) { + const typeArguments = this.tsParseTypeArguments(); + + if (this.match(18)) { + const call = super.parseMaybeDecoratorArguments(expr); + call.typeParameters = typeArguments; + return call; + } + + this.unexpected(this.state.start, 18); + } + + return super.parseMaybeDecoratorArguments(expr); + } + + checkCommaAfterRest(close) { + if (this.state.isAmbientContext && this.match(20) && this.lookaheadCharCode() === close) { + this.next(); + } else { + super.checkCommaAfterRest(close); + } + } + + isClassMethod() { + return this.isRelational("<") || super.isClassMethod(); + } + + isClassProperty() { + return this.match(40) || this.match(22) || super.isClassProperty(); + } + + parseMaybeDefault(...args) { + const node = super.parseMaybeDefault(...args); + + if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { + this.raise(node.typeAnnotation.start, TSErrors.TypeAnnotationAfterAssign); + } + + return node; + } + + getTokenFromCode(code) { + if (this.state.inType && (code === 62 || code === 60)) { + return this.finishOp(50, 1); + } else { + return super.getTokenFromCode(code); + } + } + + reScan_lt_gt() { + if (this.match(50)) { + const code = this.input.charCodeAt(this.state.start); + + if (code === 60 || code === 62) { + this.state.pos -= 1; + this.readToken_lt_gt(code); + } + } + } + + toAssignableList(exprList) { + for (let i = 0; i < exprList.length; i++) { + const expr = exprList[i]; + if (!expr) continue; + + switch (expr.type) { + case "TSTypeCastExpression": + exprList[i] = this.typeCastToParameter(expr); + break; + + case "TSAsExpression": + case "TSTypeAssertion": + if (!this.state.maybeInArrowParameters) { + exprList[i] = this.typeCastToParameter(expr); + } else { + this.raise(expr.start, TSErrors.UnexpectedTypeCastInParameter); + } + + break; + } + } + + return super.toAssignableList(...arguments); + } + + typeCastToParameter(node) { + node.expression.typeAnnotation = node.typeAnnotation; + this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + return node.expression; + } + + shouldParseArrow(params) { + if (this.match(22)) { + return params.every(expr => this.isAssignable(expr, true)); + } + + return super.shouldParseArrow(params); + } + + shouldParseAsyncArrow() { + return this.match(22) || super.shouldParseAsyncArrow(); + } + + canHaveLeadingDecorator() { + return super.canHaveLeadingDecorator() || this.isAbstractClass(); + } + + jsxParseOpeningElementAfterName(node) { + if (this.isRelational("<")) { + const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArguments()); + if (typeArguments) node.typeParameters = typeArguments; + } + + return super.jsxParseOpeningElementAfterName(node); + } + + getGetterSetterExpectedParamCount(method) { + const baseCount = super.getGetterSetterExpectedParamCount(method); + const params = this.getObjectOrClassMethodParams(method); + const firstParam = params[0]; + const hasContextParam = firstParam && this.isThisParam(firstParam); + return hasContextParam ? baseCount + 1 : baseCount; + } + + parseCatchClauseParam() { + const param = super.parseCatchClauseParam(); + const type = this.tsTryParseTypeAnnotation(); + + if (type) { + param.typeAnnotation = type; + this.resetEndLocation(param); + } + + return param; + } + + tsInAmbientContext(cb) { + const oldIsAmbientContext = this.state.isAmbientContext; + this.state.isAmbientContext = true; + + try { + return cb(); + } finally { + this.state.isAmbientContext = oldIsAmbientContext; + } + } + + parseClass(node, ...args) { + const oldInAbstractClass = this.state.inAbstractClass; + this.state.inAbstractClass = !!node.abstract; + + try { + return super.parseClass(node, ...args); + } finally { + this.state.inAbstractClass = oldInAbstractClass; + } + } + + tsParseAbstractDeclaration(node) { + if (this.match(79)) { + node.abstract = true; + return this.parseClass(node, true, false); + } else if (this.isContextual("interface")) { + if (!this.hasFollowingLineBreak()) { + node.abstract = true; + this.raise(node.start, TSErrors.NonClassMethodPropertyHasAbstractModifer); + this.next(); + return this.tsParseInterfaceDeclaration(node); + } + } else { + this.unexpected(null, 79); + } + } + + parseMethod(...args) { + const method = super.parseMethod(...args); + + if (method.abstract) { + const hasBody = this.hasPlugin("estree") ? !!method.value.body : !!method.body; + + if (hasBody) { + const { + key + } = method; + this.raise(method.start, TSErrors.AbstractMethodHasImplementation, key.type === "Identifier" && !method.computed ? key.name : `[${this.input.slice(key.start, key.end)}]`); + } + } + + return method; + } + + tsParseTypeParameterName() { + const typeName = this.parseIdentifier(); + return typeName.name; + } + + shouldParseAsAmbientContext() { + return !!this.getPluginOption("typescript", "dts"); + } + + parse() { + if (this.shouldParseAsAmbientContext()) { + this.state.isAmbientContext = true; + } + + return super.parse(); + } + + getExpression() { + if (this.shouldParseAsAmbientContext()) { + this.state.isAmbientContext = true; + } + + return super.getExpression(); + } + + }); + + const PlaceHolderErrors = makeErrorTemplates({ + ClassNameIsRequired: "A class name is required." + }, ErrorCodes.SyntaxError); + var placeholders = (superClass => class extends superClass { + parsePlaceholder(expectedNode) { + if (this.match(96)) { + const node = this.startNode(); + this.next(); + this.assertNoSpace("Unexpected space in placeholder."); + node.name = super.parseIdentifier(true); + this.assertNoSpace("Unexpected space in placeholder."); + this.expect(96); + return this.finishPlaceholder(node, expectedNode); + } + } + + finishPlaceholder(node, expectedNode) { + const isFinished = !!(node.expectedNode && node.type === "Placeholder"); + node.expectedNode = expectedNode; + return isFinished ? node : this.finishNode(node, "Placeholder"); + } + + getTokenFromCode(code) { + if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) { + return this.finishOp(96, 2); + } + + return super.getTokenFromCode(...arguments); + } + + parseExprAtom() { + return this.parsePlaceholder("Expression") || super.parseExprAtom(...arguments); + } + + parseIdentifier() { + return this.parsePlaceholder("Identifier") || super.parseIdentifier(...arguments); + } + + checkReservedWord(word) { + if (word !== undefined) super.checkReservedWord(...arguments); + } + + parseBindingAtom() { + return this.parsePlaceholder("Pattern") || super.parseBindingAtom(...arguments); + } + + checkLVal(expr) { + if (expr.type !== "Placeholder") super.checkLVal(...arguments); + } + + toAssignable(node) { + if (node && node.type === "Placeholder" && node.expectedNode === "Expression") { + node.expectedNode = "Pattern"; + return node; + } + + return super.toAssignable(...arguments); + } + + isLet(context) { + if (super.isLet(context)) { + return true; + } + + if (!this.isContextual("let")) { + return false; + } + + if (context) return false; + const nextToken = this.lookahead(); + + if (nextToken.type === 96) { + return true; + } + + return false; + } + + verifyBreakContinue(node) { + if (node.label && node.label.type === "Placeholder") return; + super.verifyBreakContinue(...arguments); + } + + parseExpressionStatement(node, expr) { + if (expr.type !== "Placeholder" || expr.extra && expr.extra.parenthesized) { + return super.parseExpressionStatement(...arguments); + } + + if (this.match(22)) { + const stmt = node; + stmt.label = this.finishPlaceholder(expr, "Identifier"); + this.next(); + stmt.body = this.parseStatement("label"); + return this.finishNode(stmt, "LabeledStatement"); + } + + this.semicolon(); + node.name = expr.name; + return this.finishPlaceholder(node, "Statement"); + } + + parseBlock() { + return this.parsePlaceholder("BlockStatement") || super.parseBlock(...arguments); + } + + parseFunctionId() { + return this.parsePlaceholder("Identifier") || super.parseFunctionId(...arguments); + } + + parseClass(node, isStatement, optionalId) { + const type = isStatement ? "ClassDeclaration" : "ClassExpression"; + this.next(); + this.takeDecorators(node); + const oldStrict = this.state.strict; + const placeholder = this.parsePlaceholder("Identifier"); + + if (placeholder) { + if (this.match(80) || this.match(96) || this.match(13)) { + node.id = placeholder; + } else if (optionalId || !isStatement) { + node.id = null; + node.body = this.finishPlaceholder(placeholder, "ClassBody"); + return this.finishNode(node, type); + } else { + this.unexpected(null, PlaceHolderErrors.ClassNameIsRequired); + } + } else { + this.parseClassId(node, isStatement, optionalId); + } + + this.parseClassSuper(node); + node.body = this.parsePlaceholder("ClassBody") || this.parseClassBody(!!node.superClass, oldStrict); + return this.finishNode(node, type); + } + + parseExport(node) { + const placeholder = this.parsePlaceholder("Identifier"); + if (!placeholder) return super.parseExport(...arguments); + + if (!this.isContextual("from") && !this.match(20)) { + node.specifiers = []; + node.source = null; + node.declaration = this.finishPlaceholder(placeholder, "Declaration"); + return this.finishNode(node, "ExportNamedDeclaration"); + } + + this.expectPlugin("exportDefaultFrom"); + const specifier = this.startNode(); + specifier.exported = placeholder; + node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + return super.parseExport(node); + } + + isExportDefaultSpecifier() { + if (this.match(64)) { + const next = this.nextTokenStart(); + + if (this.isUnparsedContextual(next, "from")) { + if (this.input.startsWith(tokenLabelName(96), this.nextTokenStartSince(next + 4))) { + return true; + } + } + } + + return super.isExportDefaultSpecifier(); + } + + maybeParseExportDefaultSpecifier(node) { + if (node.specifiers && node.specifiers.length > 0) { + return true; + } + + return super.maybeParseExportDefaultSpecifier(...arguments); + } + + checkExport(node) { + const { + specifiers + } = node; + + if (specifiers != null && specifiers.length) { + node.specifiers = specifiers.filter(node => node.exported.type === "Placeholder"); + } + + super.checkExport(node); + node.specifiers = specifiers; + } + + parseImport(node) { + const placeholder = this.parsePlaceholder("Identifier"); + if (!placeholder) return super.parseImport(...arguments); + node.specifiers = []; + + if (!this.isContextual("from") && !this.match(20)) { + node.source = this.finishPlaceholder(placeholder, "StringLiteral"); + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + const specifier = this.startNodeAtNode(placeholder); + specifier.local = placeholder; + this.finishNode(specifier, "ImportDefaultSpecifier"); + node.specifiers.push(specifier); + + if (this.eat(20)) { + const hasStarImport = this.maybeParseStarImportSpecifier(node); + if (!hasStarImport) this.parseNamedImportSpecifiers(node); + } + + this.expectContextual("from"); + node.source = this.parseImportSource(); + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportSource() { + return this.parsePlaceholder("StringLiteral") || super.parseImportSource(...arguments); + } + + }); + + var v8intrinsic = (superClass => class extends superClass { + parseV8Intrinsic() { + if (this.match(53)) { + const v8IntrinsicStart = this.state.start; + const node = this.startNode(); + this.eat(53); + + if (this.match(5)) { + const name = this.parseIdentifierName(this.state.start); + const identifier = this.createIdentifier(node, name); + identifier.type = "V8IntrinsicIdentifier"; + + if (this.match(18)) { + return identifier; + } + } + + this.unexpected(v8IntrinsicStart); + } + } + + parseExprAtom() { + return this.parseV8Intrinsic() || super.parseExprAtom(...arguments); + } + + }); + + function hasPlugin(plugins, name) { + return plugins.some(plugin => { + if (Array.isArray(plugin)) { + return plugin[0] === name; + } else { + return plugin === name; + } + }); + } + function getPluginOption(plugins, name, option) { + const plugin = plugins.find(plugin => { + if (Array.isArray(plugin)) { + return plugin[0] === name; + } else { + return plugin === name; + } + }); + + if (plugin && Array.isArray(plugin)) { + return plugin[1][option]; + } + + return null; + } + const PIPELINE_PROPOSALS = ["minimal", "fsharp", "hack", "smart"]; + const TOPIC_TOKENS = ["%", "#"]; + const RECORD_AND_TUPLE_SYNTAX_TYPES = ["hash", "bar"]; + function validatePlugins(plugins) { + if (hasPlugin(plugins, "decorators")) { + if (hasPlugin(plugins, "decorators-legacy")) { + throw new Error("Cannot use the decorators and decorators-legacy plugin together"); + } + + const decoratorsBeforeExport = getPluginOption(plugins, "decorators", "decoratorsBeforeExport"); + + if (decoratorsBeforeExport == null) { + throw new Error("The 'decorators' plugin requires a 'decoratorsBeforeExport' option," + " whose value must be a boolean. If you are migrating from" + " Babylon/Babel 6 or want to use the old decorators proposal, you" + " should use the 'decorators-legacy' plugin instead of 'decorators'."); + } else if (typeof decoratorsBeforeExport !== "boolean") { + throw new Error("'decoratorsBeforeExport' must be a boolean."); + } + } + + if (hasPlugin(plugins, "flow") && hasPlugin(plugins, "typescript")) { + throw new Error("Cannot combine flow and typescript plugins."); + } + + if (hasPlugin(plugins, "placeholders") && hasPlugin(plugins, "v8intrinsic")) { + throw new Error("Cannot combine placeholders and v8intrinsic plugins."); + } + + if (hasPlugin(plugins, "pipelineOperator")) { + const proposal = getPluginOption(plugins, "pipelineOperator", "proposal"); + + if (!PIPELINE_PROPOSALS.includes(proposal)) { + const proposalList = PIPELINE_PROPOSALS.map(p => `"${p}"`).join(", "); + throw new Error(`"pipelineOperator" requires "proposal" option whose value must be one of: ${proposalList}.`); + } + + const tupleSyntaxIsHash = hasPlugin(plugins, "recordAndTuple") && getPluginOption(plugins, "recordAndTuple", "syntaxType") === "hash"; + + if (proposal === "hack") { + if (hasPlugin(plugins, "placeholders")) { + throw new Error("Cannot combine placeholders plugin and Hack-style pipes."); + } + + if (hasPlugin(plugins, "v8intrinsic")) { + throw new Error("Cannot combine v8intrinsic plugin and Hack-style pipes."); + } + + const topicToken = getPluginOption(plugins, "pipelineOperator", "topicToken"); + + if (!TOPIC_TOKENS.includes(topicToken)) { + const tokenList = TOPIC_TOKENS.map(t => `"${t}"`).join(", "); + throw new Error(`"pipelineOperator" in "proposal": "hack" mode also requires a "topicToken" option whose value must be one of: ${tokenList}.`); + } + + if (topicToken === "#" && tupleSyntaxIsHash) { + throw new Error('Plugin conflict between `["pipelineOperator", { proposal: "hack", topicToken: "#" }]` and `["recordAndtuple", { syntaxType: "hash"}]`.'); + } + } else if (proposal === "smart" && tupleSyntaxIsHash) { + throw new Error('Plugin conflict between `["pipelineOperator", { proposal: "smart" }]` and `["recordAndtuple", { syntaxType: "hash"}]`.'); + } + } + + if (hasPlugin(plugins, "moduleAttributes")) { + { + if (hasPlugin(plugins, "importAssertions")) { + throw new Error("Cannot combine importAssertions and moduleAttributes plugins."); + } + + const moduleAttributesVerionPluginOption = getPluginOption(plugins, "moduleAttributes", "version"); + + if (moduleAttributesVerionPluginOption !== "may-2020") { + throw new Error("The 'moduleAttributes' plugin requires a 'version' option," + " representing the last proposal update. Currently, the" + " only supported value is 'may-2020'."); + } + } + } + + if (hasPlugin(plugins, "recordAndTuple") && !RECORD_AND_TUPLE_SYNTAX_TYPES.includes(getPluginOption(plugins, "recordAndTuple", "syntaxType"))) { + throw new Error("'recordAndTuple' requires 'syntaxType' option whose value should be one of: " + RECORD_AND_TUPLE_SYNTAX_TYPES.map(p => `'${p}'`).join(", ")); + } + + if (hasPlugin(plugins, "asyncDoExpressions") && !hasPlugin(plugins, "doExpressions")) { + const error = new Error("'asyncDoExpressions' requires 'doExpressions', please add 'doExpressions' to parser plugins."); + error.missingPlugins = "doExpressions"; + throw error; + } + } + const mixinPlugins = { + estree, + jsx: jsx$1, + flow: flow$1, + typescript: typescript$1, + v8intrinsic, + placeholders + }; + const mixinPluginNames = Object.keys(mixinPlugins); + + const defaultOptions = { + sourceType: "script", + sourceFilename: undefined, + startLine: 1, + allowAwaitOutsideFunction: false, + allowReturnOutsideFunction: false, + allowImportExportEverywhere: false, + allowSuperOutsideMethod: false, + allowUndeclaredExports: false, + plugins: [], + strictMode: null, + ranges: false, + tokens: false, + createParenthesizedExpressions: false, + errorRecovery: false, + attachComment: true + }; + function getOptions(opts) { + const options = {}; + + for (const key of Object.keys(defaultOptions)) { + options[key] = opts && opts[key] != null ? opts[key] : defaultOptions[key]; + } + + return options; + } + + const unwrapParenthesizedExpression = node => { + return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression(node.expression) : node; + }; + + class LValParser extends NodeUtils { + toAssignable(node, isLHS = false) { + var _node$extra, _node$extra3; + + let parenthesized = undefined; + + if (node.type === "ParenthesizedExpression" || (_node$extra = node.extra) != null && _node$extra.parenthesized) { + parenthesized = unwrapParenthesizedExpression(node); + + if (isLHS) { + if (parenthesized.type === "Identifier") { + this.expressionScope.recordParenthesizedIdentifierError(node.start, ErrorMessages.InvalidParenthesizedAssignment); + } else if (parenthesized.type !== "MemberExpression") { + this.raise(node.start, ErrorMessages.InvalidParenthesizedAssignment); + } + } else { + this.raise(node.start, ErrorMessages.InvalidParenthesizedAssignment); + } + } + + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + break; + + case "ObjectExpression": + node.type = "ObjectPattern"; + + for (let i = 0, length = node.properties.length, last = length - 1; i < length; i++) { + var _node$extra2; + + const prop = node.properties[i]; + const isLast = i === last; + this.toAssignableObjectExpressionProp(prop, isLast, isLHS); + + if (isLast && prop.type === "RestElement" && (_node$extra2 = node.extra) != null && _node$extra2.trailingComma) { + this.raiseRestNotLast(node.extra.trailingComma); + } + } + + break; + + case "ObjectProperty": + this.toAssignable(node.value, isLHS); + break; + + case "SpreadElement": + { + this.checkToRestConversion(node); + node.type = "RestElement"; + const arg = node.argument; + this.toAssignable(arg, isLHS); + break; + } + + case "ArrayExpression": + node.type = "ArrayPattern"; + this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingComma, isLHS); + break; + + case "AssignmentExpression": + if (node.operator !== "=") { + this.raise(node.left.end, ErrorMessages.MissingEqInAssignment); + } + + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isLHS); + break; + + case "ParenthesizedExpression": + this.toAssignable(parenthesized, isLHS); + break; + } + + return node; + } + + toAssignableObjectExpressionProp(prop, isLast, isLHS) { + if (prop.type === "ObjectMethod") { + const error = prop.kind === "get" || prop.kind === "set" ? ErrorMessages.PatternHasAccessor : ErrorMessages.PatternHasMethod; + this.raise(prop.key.start, error); + } else if (prop.type === "SpreadElement" && !isLast) { + this.raiseRestNotLast(prop.start); + } else { + this.toAssignable(prop, isLHS); + } + } + + toAssignableList(exprList, trailingCommaPos, isLHS) { + let end = exprList.length; + + if (end) { + const last = exprList[end - 1]; + + if ((last == null ? void 0 : last.type) === "RestElement") { + --end; + } else if ((last == null ? void 0 : last.type) === "SpreadElement") { + last.type = "RestElement"; + let arg = last.argument; + this.toAssignable(arg, isLHS); + arg = unwrapParenthesizedExpression(arg); + + if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern" && arg.type !== "ObjectPattern") { + this.unexpected(arg.start); + } + + if (trailingCommaPos) { + this.raiseTrailingCommaAfterRest(trailingCommaPos); + } + + --end; + } + } + + for (let i = 0; i < end; i++) { + const elt = exprList[i]; + + if (elt) { + this.toAssignable(elt, isLHS); + + if (elt.type === "RestElement") { + this.raiseRestNotLast(elt.start); + } + } + } + + return exprList; + } + + isAssignable(node, isBinding) { + switch (node.type) { + case "Identifier": + case "ObjectPattern": + case "ArrayPattern": + case "AssignmentPattern": + case "RestElement": + return true; + + case "ObjectExpression": + { + const last = node.properties.length - 1; + return node.properties.every((prop, i) => { + return prop.type !== "ObjectMethod" && (i === last || prop.type !== "SpreadElement") && this.isAssignable(prop); + }); + } + + case "ObjectProperty": + return this.isAssignable(node.value); + + case "SpreadElement": + return this.isAssignable(node.argument); + + case "ArrayExpression": + return node.elements.every(element => element === null || this.isAssignable(element)); + + case "AssignmentExpression": + return node.operator === "="; + + case "ParenthesizedExpression": + return this.isAssignable(node.expression); + + case "MemberExpression": + case "OptionalMemberExpression": + return !isBinding; + + default: + return false; + } + } + + toReferencedList(exprList, isParenthesizedExpr) { + return exprList; + } + + toReferencedListDeep(exprList, isParenthesizedExpr) { + this.toReferencedList(exprList, isParenthesizedExpr); + + for (const expr of exprList) { + if ((expr == null ? void 0 : expr.type) === "ArrayExpression") { + this.toReferencedListDeep(expr.elements); + } + } + } + + parseSpread(refExpressionErrors, refNeedsArrowPos) { + const node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssignAllowIn(refExpressionErrors, undefined, refNeedsArrowPos); + return this.finishNode(node, "SpreadElement"); + } + + parseRestBinding() { + const node = this.startNode(); + this.next(); + node.argument = this.parseBindingAtom(); + return this.finishNode(node, "RestElement"); + } + + parseBindingAtom() { + switch (this.state.type) { + case 8: + { + const node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(11, 93, true); + return this.finishNode(node, "ArrayPattern"); + } + + case 13: + return this.parseObjectLike(16, true); + } + + return this.parseIdentifier(); + } + + parseBindingList(close, closeCharCode, allowEmpty, allowModifiers) { + const elts = []; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(20); + } + + if (allowEmpty && this.match(20)) { + elts.push(null); + } else if (this.eat(close)) { + break; + } else if (this.match(29)) { + elts.push(this.parseAssignableListItemTypes(this.parseRestBinding())); + this.checkCommaAfterRest(closeCharCode); + this.expect(close); + break; + } else { + const decorators = []; + + if (this.match(32) && this.hasPlugin("decorators")) { + this.raise(this.state.start, ErrorMessages.UnsupportedParameterDecorator); + } + + while (this.match(32)) { + decorators.push(this.parseDecorator()); + } + + elts.push(this.parseAssignableListItem(allowModifiers, decorators)); + } + } + + return elts; + } + + parseAssignableListItem(allowModifiers, decorators) { + const left = this.parseMaybeDefault(); + this.parseAssignableListItemTypes(left); + const elt = this.parseMaybeDefault(left.start, left.loc.start, left); + + if (decorators.length) { + left.decorators = decorators; + } + + return elt; + } + + parseAssignableListItemTypes(param) { + return param; + } + + parseMaybeDefault(startPos, startLoc, left) { + var _startLoc, _startPos, _left; + + startLoc = (_startLoc = startLoc) != null ? _startLoc : this.state.startLoc; + startPos = (_startPos = startPos) != null ? _startPos : this.state.start; + left = (_left = left) != null ? _left : this.parseBindingAtom(); + if (!this.eat(35)) return left; + const node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssignAllowIn(); + return this.finishNode(node, "AssignmentPattern"); + } + + checkLVal(expr, contextDescription, bindingType = BIND_NONE, checkClashes, disallowLetBinding, strictModeChanged = false) { + switch (expr.type) { + case "Identifier": + { + const { + name + } = expr; + + if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord(name, this.inModule) : isStrictBindOnlyReservedWord(name))) { + this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.StrictEvalArguments : ErrorMessages.StrictEvalArgumentsBinding, name); + } + + if (checkClashes) { + if (checkClashes.has(name)) { + this.raise(expr.start, ErrorMessages.ParamDupe); + } else { + checkClashes.add(name); + } + } + + if (disallowLetBinding && name === "let") { + this.raise(expr.start, ErrorMessages.LetInLexicalBinding); + } + + if (!(bindingType & BIND_NONE)) { + this.scope.declareName(name, bindingType, expr.start); + } + + break; + } + + case "MemberExpression": + if (bindingType !== BIND_NONE) { + this.raise(expr.start, ErrorMessages.InvalidPropertyBindingPattern); + } + + break; + + case "ObjectPattern": + for (let prop of expr.properties) { + if (this.isObjectProperty(prop)) prop = prop.value;else if (this.isObjectMethod(prop)) continue; + this.checkLVal(prop, "object destructuring pattern", bindingType, checkClashes, disallowLetBinding); + } + + break; + + case "ArrayPattern": + for (const elem of expr.elements) { + if (elem) { + this.checkLVal(elem, "array destructuring pattern", bindingType, checkClashes, disallowLetBinding); + } + } + + break; + + case "AssignmentPattern": + this.checkLVal(expr.left, "assignment pattern", bindingType, checkClashes); + break; + + case "RestElement": + this.checkLVal(expr.argument, "rest element", bindingType, checkClashes); + break; + + case "ParenthesizedExpression": + this.checkLVal(expr.expression, "parenthesized expression", bindingType, checkClashes); + break; + + default: + { + this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.InvalidLhs : ErrorMessages.InvalidLhsBinding, contextDescription); + } + } + } + + checkToRestConversion(node) { + if (node.argument.type !== "Identifier" && node.argument.type !== "MemberExpression") { + this.raise(node.argument.start, ErrorMessages.InvalidRestAssignmentPattern); + } + } + + checkCommaAfterRest(close) { + if (this.match(20)) { + if (this.lookaheadCharCode() === close) { + this.raiseTrailingCommaAfterRest(this.state.start); + } else { + this.raiseRestNotLast(this.state.start); + } + } + } + + raiseRestNotLast(pos) { + throw this.raise(pos, ErrorMessages.ElementAfterRest); + } + + raiseTrailingCommaAfterRest(pos) { + this.raise(pos, ErrorMessages.RestTrailingComma); + } + + } + + const invalidHackPipeBodies = new Map([["ArrowFunctionExpression", "arrow function"], ["AssignmentExpression", "assignment"], ["ConditionalExpression", "conditional"], ["YieldExpression", "yield"]]); + class ExpressionParser extends LValParser { + checkProto(prop, isRecord, protoRef, refExpressionErrors) { + if (prop.type === "SpreadElement" || this.isObjectMethod(prop) || prop.computed || prop.shorthand) { + return; + } + + const key = prop.key; + const name = key.type === "Identifier" ? key.name : key.value; + + if (name === "__proto__") { + if (isRecord) { + this.raise(key.start, ErrorMessages.RecordNoProto); + return; + } + + if (protoRef.used) { + if (refExpressionErrors) { + if (refExpressionErrors.doubleProto === -1) { + refExpressionErrors.doubleProto = key.start; + } + } else { + this.raise(key.start, ErrorMessages.DuplicateProto); + } + } + + protoRef.used = true; + } + } + + shouldExitDescending(expr, potentialArrowAt) { + return expr.type === "ArrowFunctionExpression" && expr.start === potentialArrowAt; + } + + getExpression() { + this.enterInitialScopes(); + this.nextToken(); + const expr = this.parseExpression(); + + if (!this.match(7)) { + this.unexpected(); + } + + this.finalizeRemainingComments(); + expr.comments = this.state.comments; + expr.errors = this.state.errors; + + if (this.options.tokens) { + expr.tokens = this.tokens; + } + + return expr; + } + + parseExpression(disallowIn, refExpressionErrors) { + if (disallowIn) { + return this.disallowInAnd(() => this.parseExpressionBase(refExpressionErrors)); + } + + return this.allowInAnd(() => this.parseExpressionBase(refExpressionErrors)); + } + + parseExpressionBase(refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const expr = this.parseMaybeAssign(refExpressionErrors); + + if (this.match(20)) { + const node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + + while (this.eat(20)) { + node.expressions.push(this.parseMaybeAssign(refExpressionErrors)); + } + + this.toReferencedList(node.expressions); + return this.finishNode(node, "SequenceExpression"); + } + + return expr; + } + + parseMaybeAssignDisallowIn(refExpressionErrors, afterLeftParse) { + return this.disallowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse)); + } + + parseMaybeAssignAllowIn(refExpressionErrors, afterLeftParse) { + return this.allowInAnd(() => this.parseMaybeAssign(refExpressionErrors, afterLeftParse)); + } + + setOptionalParametersError(refExpressionErrors, resultError) { + var _resultError$pos; + + refExpressionErrors.optionalParameters = (_resultError$pos = resultError == null ? void 0 : resultError.pos) != null ? _resultError$pos : this.state.start; + } + + parseMaybeAssign(refExpressionErrors, afterLeftParse) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + + if (this.isContextual("yield")) { + if (this.prodParam.hasYield) { + let left = this.parseYield(); + + if (afterLeftParse) { + left = afterLeftParse.call(this, left, startPos, startLoc); + } + + return left; + } + } + + let ownExpressionErrors; + + if (refExpressionErrors) { + ownExpressionErrors = false; + } else { + refExpressionErrors = new ExpressionErrors(); + ownExpressionErrors = true; + } + + if (this.match(18) || this.match(5)) { + this.state.potentialArrowAt = this.state.start; + } + + let left = this.parseMaybeConditional(refExpressionErrors); + + if (afterLeftParse) { + left = afterLeftParse.call(this, left, startPos, startLoc); + } + + if (tokenIsAssignment(this.state.type)) { + const node = this.startNodeAt(startPos, startLoc); + const operator = this.state.value; + node.operator = operator; + + if (this.match(35)) { + node.left = this.toAssignable(left, true); + refExpressionErrors.doubleProto = -1; + } else { + node.left = left; + } + + if (refExpressionErrors.shorthandAssign >= node.left.start) { + refExpressionErrors.shorthandAssign = -1; + } + + this.checkLVal(left, "assignment expression"); + this.next(); + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentExpression"); + } else if (ownExpressionErrors) { + this.checkExpressionErrors(refExpressionErrors, true); + } + + return left; + } + + parseMaybeConditional(refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseExprOps(refExpressionErrors); + + if (this.shouldExitDescending(expr, potentialArrowAt)) { + return expr; + } + + return this.parseConditional(expr, startPos, startLoc, refExpressionErrors); + } + + parseConditional(expr, startPos, startLoc, refExpressionErrors) { + if (this.eat(25)) { + const node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssignAllowIn(); + this.expect(22); + node.alternate = this.parseMaybeAssign(); + return this.finishNode(node, "ConditionalExpression"); + } + + return expr; + } + + parseMaybeUnaryOrPrivate(refExpressionErrors) { + return this.match(6) ? this.parsePrivateName() : this.parseMaybeUnary(refExpressionErrors); + } + + parseExprOps(refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseMaybeUnaryOrPrivate(refExpressionErrors); + + if (this.shouldExitDescending(expr, potentialArrowAt)) { + return expr; + } + + return this.parseExprOp(expr, startPos, startLoc, -1); + } + + parseExprOp(left, leftStartPos, leftStartLoc, minPrec) { + if (this.isPrivateName(left)) { + const value = this.getPrivateNameSV(left); + const { + start + } = left; + + if (minPrec >= tokenOperatorPrecedence(57) || !this.prodParam.hasIn || !this.match(57)) { + this.raise(start, ErrorMessages.PrivateInExpectedIn, value); + } + + this.classScope.usePrivateName(value, start); + } + + const op = this.state.type; + + if (tokenIsOperator(op) && (this.prodParam.hasIn || !this.match(57))) { + let prec = tokenOperatorPrecedence(op); + + if (prec > minPrec) { + if (op === 42) { + this.expectPlugin("pipelineOperator"); + + if (this.state.inFSharpPipelineDirectBody) { + return left; + } + + this.checkPipelineAtInfixOperator(left, leftStartPos); + } + + const node = this.startNodeAt(leftStartPos, leftStartLoc); + node.left = left; + node.operator = this.state.value; + const logical = op === 44 || op === 45; + const coalesce = op === 43; + + if (coalesce) { + prec = tokenOperatorPrecedence(45); + } + + this.next(); + + if (op === 42 && this.getPluginOption("pipelineOperator", "proposal") === "minimal") { + if (this.match(5) && this.state.value === "await" && this.prodParam.hasAwait) { + throw this.raise(this.state.start, ErrorMessages.UnexpectedAwaitAfterPipelineBody); + } + } + + node.right = this.parseExprOpRightExpr(op, prec); + this.finishNode(node, logical || coalesce ? "LogicalExpression" : "BinaryExpression"); + const nextOp = this.state.type; + + if (coalesce && (nextOp === 44 || nextOp === 45) || logical && nextOp === 43) { + throw this.raise(this.state.start, ErrorMessages.MixingCoalesceWithLogical); + } + + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec); + } + } + + return left; + } + + parseExprOpRightExpr(op, prec) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + + switch (op) { + case 42: + switch (this.getPluginOption("pipelineOperator", "proposal")) { + case "hack": + return this.withTopicBindingContext(() => { + return this.parseHackPipeBody(); + }); + + case "smart": + return this.withTopicBindingContext(() => { + if (this.prodParam.hasYield && this.isContextual("yield")) { + throw this.raise(this.state.start, ErrorMessages.PipeBodyIsTighter, this.state.value); + } + + return this.parseSmartPipelineBodyInStyle(this.parseExprOpBaseRightExpr(op, prec), startPos, startLoc); + }); + + case "fsharp": + return this.withSoloAwaitPermittingContext(() => { + return this.parseFSharpPipelineBody(prec); + }); + } + + default: + return this.parseExprOpBaseRightExpr(op, prec); + } + } + + parseExprOpBaseRightExpr(op, prec) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + return this.parseExprOp(this.parseMaybeUnaryOrPrivate(), startPos, startLoc, tokenIsRightAssociative(op) ? prec - 1 : prec); + } + + parseHackPipeBody() { + var _body$extra; + + const { + start + } = this.state; + const body = this.parseMaybeAssign(); + + if (invalidHackPipeBodies.has(body.type) && !((_body$extra = body.extra) != null && _body$extra.parenthesized)) { + this.raise(start, ErrorMessages.PipeUnparenthesizedBody, invalidHackPipeBodies.get(body.type)); + } + + if (!this.topicReferenceWasUsedInCurrentContext()) { + this.raise(start, ErrorMessages.PipeTopicUnused); + } + + return body; + } + + checkExponentialAfterUnary(node) { + if (this.match(56)) { + this.raise(node.argument.start, ErrorMessages.UnexpectedTokenUnaryExponentiation); + } + } + + parseMaybeUnary(refExpressionErrors, sawUnary) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const isAwait = this.isContextual("await"); + + if (isAwait && this.isAwaitAllowed()) { + this.next(); + const expr = this.parseAwait(startPos, startLoc); + if (!sawUnary) this.checkExponentialAfterUnary(expr); + return expr; + } + + const update = this.match(39); + const node = this.startNode(); + + if (tokenIsPrefix(this.state.type)) { + node.operator = this.state.value; + node.prefix = true; + + if (this.match(71)) { + this.expectPlugin("throwExpressions"); + } + + const isDelete = this.match(88); + this.next(); + node.argument = this.parseMaybeUnary(null, true); + this.checkExpressionErrors(refExpressionErrors, true); + + if (this.state.strict && isDelete) { + const arg = node.argument; + + if (arg.type === "Identifier") { + this.raise(node.start, ErrorMessages.StrictDelete); + } else if (this.hasPropertyAsPrivateName(arg)) { + this.raise(node.start, ErrorMessages.DeletePrivateField); + } + } + + if (!update) { + if (!sawUnary) this.checkExponentialAfterUnary(node); + return this.finishNode(node, "UnaryExpression"); + } + } + + const expr = this.parseUpdate(node, update, refExpressionErrors); + + if (isAwait) { + const { + type + } = this.state; + const startsExpr = this.hasPlugin("v8intrinsic") ? tokenCanStartExpression(type) : tokenCanStartExpression(type) && !this.match(53); + + if (startsExpr && !this.isAmbiguousAwait()) { + this.raiseOverwrite(startPos, ErrorMessages.AwaitNotInAsyncContext); + return this.parseAwait(startPos, startLoc); + } + } + + return expr; + } + + parseUpdate(node, update, refExpressionErrors) { + if (update) { + this.checkLVal(node.argument, "prefix operation"); + return this.finishNode(node, "UpdateExpression"); + } + + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let expr = this.parseExprSubscripts(refExpressionErrors); + if (this.checkExpressionErrors(refExpressionErrors, false)) return expr; + + while (tokenIsPostfix(this.state.type) && !this.canInsertSemicolon()) { + const node = this.startNodeAt(startPos, startLoc); + node.operator = this.state.value; + node.prefix = false; + node.argument = expr; + this.checkLVal(expr, "postfix operation"); + this.next(); + expr = this.finishNode(node, "UpdateExpression"); + } + + return expr; + } + + parseExprSubscripts(refExpressionErrors) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + const potentialArrowAt = this.state.potentialArrowAt; + const expr = this.parseExprAtom(refExpressionErrors); + + if (this.shouldExitDescending(expr, potentialArrowAt)) { + return expr; + } + + return this.parseSubscripts(expr, startPos, startLoc); + } + + parseSubscripts(base, startPos, startLoc, noCalls) { + const state = { + optionalChainMember: false, + maybeAsyncArrow: this.atPossibleAsyncArrow(base), + stop: false + }; + + do { + base = this.parseSubscript(base, startPos, startLoc, noCalls, state); + state.maybeAsyncArrow = false; + } while (!state.stop); + + return base; + } + + parseSubscript(base, startPos, startLoc, noCalls, state) { + if (!noCalls && this.eat(23)) { + return this.parseBind(base, startPos, startLoc, noCalls, state); + } else if (this.match(30)) { + return this.parseTaggedTemplateExpression(base, startPos, startLoc, state); + } + + let optional = false; + + if (this.match(26)) { + if (noCalls && this.lookaheadCharCode() === 40) { + state.stop = true; + return base; + } + + state.optionalChainMember = optional = true; + this.next(); + } + + if (!noCalls && this.match(18)) { + return this.parseCoverCallAndAsyncArrowHead(base, startPos, startLoc, state, optional); + } else { + const computed = this.eat(8); + + if (computed || optional || this.eat(24)) { + return this.parseMember(base, startPos, startLoc, state, computed, optional); + } else { + state.stop = true; + return base; + } + } + } + + parseMember(base, startPos, startLoc, state, computed, optional) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.computed = computed; + const privateName = !computed && this.match(6) && this.state.value; + const property = computed ? this.parseExpression() : privateName ? this.parsePrivateName() : this.parseIdentifier(true); + + if (privateName !== false) { + if (node.object.type === "Super") { + this.raise(startPos, ErrorMessages.SuperPrivateField); + } + + this.classScope.usePrivateName(privateName, property.start); + } + + node.property = property; + + if (computed) { + this.expect(11); + } + + if (state.optionalChainMember) { + node.optional = optional; + return this.finishNode(node, "OptionalMemberExpression"); + } else { + return this.finishNode(node, "MemberExpression"); + } + } + + parseBind(base, startPos, startLoc, noCalls, state) { + const node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.callee = this.parseNoCallExpr(); + state.stop = true; + return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); + } + + parseCoverCallAndAsyncArrowHead(base, startPos, startLoc, state, optional) { + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + let refExpressionErrors = null; + this.state.maybeInArrowParameters = true; + this.next(); + let node = this.startNodeAt(startPos, startLoc); + node.callee = base; + + if (state.maybeAsyncArrow) { + this.expressionScope.enter(newAsyncArrowScope()); + refExpressionErrors = new ExpressionErrors(); + } + + if (state.optionalChainMember) { + node.optional = optional; + } + + if (optional) { + node.arguments = this.parseCallExpressionArguments(19); + } else { + node.arguments = this.parseCallExpressionArguments(19, base.type === "Import", base.type !== "Super", node, refExpressionErrors); + } + + this.finishCallExpression(node, state.optionalChainMember); + + if (state.maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) { + state.stop = true; + this.expressionScope.validateAsPattern(); + this.expressionScope.exit(); + node = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); + } else { + if (state.maybeAsyncArrow) { + this.checkExpressionErrors(refExpressionErrors, true); + this.expressionScope.exit(); + } + + this.toReferencedArguments(node); + } + + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + return node; + } + + toReferencedArguments(node, isParenthesizedExpr) { + this.toReferencedListDeep(node.arguments, isParenthesizedExpr); + } + + parseTaggedTemplateExpression(base, startPos, startLoc, state) { + const node = this.startNodeAt(startPos, startLoc); + node.tag = base; + node.quasi = this.parseTemplate(true); + + if (state.optionalChainMember) { + this.raise(startPos, ErrorMessages.OptionalChainingNoTemplate); + } + + return this.finishNode(node, "TaggedTemplateExpression"); + } + + atPossibleAsyncArrow(base) { + return base.type === "Identifier" && base.name === "async" && this.state.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && base.start === this.state.potentialArrowAt; + } + + finishCallExpression(node, optional) { + if (node.callee.type === "Import") { + if (node.arguments.length === 2) { + { + if (!this.hasPlugin("moduleAttributes")) { + this.expectPlugin("importAssertions"); + } + } + } + + if (node.arguments.length === 0 || node.arguments.length > 2) { + this.raise(node.start, ErrorMessages.ImportCallArity, this.hasPlugin("importAssertions") || this.hasPlugin("moduleAttributes") ? "one or two arguments" : "one argument"); + } else { + for (const arg of node.arguments) { + if (arg.type === "SpreadElement") { + this.raise(arg.start, ErrorMessages.ImportCallSpreadArgument); + } + } + } + } + + return this.finishNode(node, optional ? "OptionalCallExpression" : "CallExpression"); + } + + parseCallExpressionArguments(close, dynamicImport, allowPlaceholder, nodeForExtra, refExpressionErrors) { + const elts = []; + let first = true; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(20); + + if (this.match(close)) { + if (dynamicImport && !this.hasPlugin("importAssertions") && !this.hasPlugin("moduleAttributes")) { + this.raise(this.state.lastTokStart, ErrorMessages.ImportCallArgumentTrailingComma); + } + + if (nodeForExtra) { + this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + } + + this.next(); + break; + } + } + + elts.push(this.parseExprListItem(false, refExpressionErrors, allowPlaceholder)); + } + + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return elts; + } + + shouldParseAsyncArrow() { + return this.match(27) && !this.canInsertSemicolon(); + } + + parseAsyncArrowFromCallExpression(node, call) { + var _call$extra; + + this.resetPreviousNodeTrailingComments(call); + this.expect(27); + this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingComma); + setInnerComments(node, call.innerComments); + setInnerComments(node, call.callee.trailingComments); + return node; + } + + parseNoCallExpr() { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + return this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + } + + parseExprAtom(refExpressionErrors) { + let node; + + switch (this.state.type) { + case 78: + return this.parseSuper(); + + case 82: + node = this.startNode(); + this.next(); + + if (this.match(24)) { + return this.parseImportMetaProperty(node); + } + + if (!this.match(18)) { + this.raise(this.state.lastTokStart, ErrorMessages.UnsupportedImport); + } + + return this.finishNode(node, "Import"); + + case 77: + node = this.startNode(); + this.next(); + return this.finishNode(node, "ThisExpression"); + + case 5: + { + if (this.isContextual("module") && this.lookaheadCharCode() === 123 && !this.hasFollowingLineBreak()) { + return this.parseModuleExpression(); + } + + const canBeArrow = this.state.potentialArrowAt === this.state.start; + const containsEsc = this.state.containsEsc; + const id = this.parseIdentifier(); + + if (!containsEsc && id.name === "async" && !this.canInsertSemicolon()) { + if (this.match(67)) { + this.resetPreviousNodeTrailingComments(id); + this.next(); + return this.parseFunction(this.startNodeAtNode(id), undefined, true); + } else if (this.match(5)) { + if (this.lookaheadCharCode() === 61) { + return this.parseAsyncArrowUnaryFunction(this.startNodeAtNode(id)); + } else { + return id; + } + } else if (this.match(89)) { + this.resetPreviousNodeTrailingComments(id); + return this.parseDo(this.startNodeAtNode(id), true); + } + } + + if (canBeArrow && this.match(27) && !this.canInsertSemicolon()) { + this.next(); + return this.parseArrowExpression(this.startNodeAtNode(id), [id], false); + } + + return id; + } + + case 89: + { + return this.parseDo(this.startNode(), false); + } + + case 55: + case 37: + { + this.readRegexp(); + return this.parseRegExpLiteral(this.state.value); + } + + case 0: + return this.parseNumericLiteral(this.state.value); + + case 1: + return this.parseBigIntLiteral(this.state.value); + + case 2: + return this.parseDecimalLiteral(this.state.value); + + case 4: + return this.parseStringLiteral(this.state.value); + + case 83: + return this.parseNullLiteral(); + + case 84: + return this.parseBooleanLiteral(true); + + case 85: + return this.parseBooleanLiteral(false); + + case 18: + { + const canBeArrow = this.state.potentialArrowAt === this.state.start; + return this.parseParenAndDistinguishExpression(canBeArrow); + } + + case 10: + case 9: + { + return this.parseArrayLike(this.state.type === 10 ? 12 : 11, false, true, refExpressionErrors); + } + + case 8: + { + return this.parseArrayLike(11, true, false, refExpressionErrors); + } + + case 14: + case 15: + { + return this.parseObjectLike(this.state.type === 14 ? 17 : 16, false, true, refExpressionErrors); + } + + case 13: + { + return this.parseObjectLike(16, false, false, refExpressionErrors); + } + + case 67: + return this.parseFunctionOrFunctionSent(); + + case 32: + this.parseDecorators(); + + case 79: + node = this.startNode(); + this.takeDecorators(node); + return this.parseClass(node, false); + + case 76: + return this.parseNewOrNewTarget(); + + case 30: + return this.parseTemplate(false); + + case 23: + { + node = this.startNode(); + this.next(); + node.object = null; + const callee = node.callee = this.parseNoCallExpr(); + + if (callee.type === "MemberExpression") { + return this.finishNode(node, "BindExpression"); + } else { + throw this.raise(callee.start, ErrorMessages.UnsupportedBind); + } + } + + case 6: + { + this.raise(this.state.start, ErrorMessages.PrivateInExpectedIn, this.state.value); + return this.parsePrivateName(); + } + + case 38: + if (this.getPluginOption("pipelineOperator", "proposal") === "hack" && this.getPluginOption("pipelineOperator", "topicToken") === "%") { + this.state.value = "%"; + this.state.type = 53; + this.state.pos--; + this.state.end--; + this.state.endLoc.column--; + } else { + throw this.unexpected(); + } + + case 53: + case 33: + { + const pipeProposal = this.getPluginOption("pipelineOperator", "proposal"); + + if (pipeProposal) { + node = this.startNode(); + const start = this.state.start; + const tokenType = this.state.type; + this.next(); + return this.finishTopicReference(node, start, pipeProposal, tokenType); + } + } + + case 50: + { + if (this.state.value === "<") { + const lookaheadCh = this.input.codePointAt(this.nextTokenStart()); + + if (isIdentifierStart(lookaheadCh) || lookaheadCh === 62) { + this.expectOnePlugin(["jsx", "flow", "typescript"]); + } + } + } + + default: + throw this.unexpected(); + } + } + + finishTopicReference(node, start, pipeProposal, tokenType) { + if (this.testTopicReferenceConfiguration(pipeProposal, start, tokenType)) { + let nodeType; + + if (pipeProposal === "smart") { + nodeType = "PipelinePrimaryTopicReference"; + } else { + nodeType = "TopicReference"; + } + + if (!this.topicReferenceIsAllowedInCurrentContext()) { + if (pipeProposal === "smart") { + this.raise(start, ErrorMessages.PrimaryTopicNotAllowed); + } else { + this.raise(start, ErrorMessages.PipeTopicUnbound); + } + } + + this.registerTopicReference(); + return this.finishNode(node, nodeType); + } else { + throw this.raise(start, ErrorMessages.PipeTopicUnconfiguredToken, tokenLabelName(tokenType)); + } + } + + testTopicReferenceConfiguration(pipeProposal, start, tokenType) { + switch (pipeProposal) { + case "hack": + { + const pluginTopicToken = this.getPluginOption("pipelineOperator", "topicToken"); + return tokenLabelName(tokenType) === pluginTopicToken; + } + + case "smart": + return tokenType === 33; + + default: + throw this.raise(start, ErrorMessages.PipeTopicRequiresHackPipes); + } + } + + parseAsyncArrowUnaryFunction(node) { + this.prodParam.enter(functionFlags(true, this.prodParam.hasYield)); + const params = [this.parseIdentifier()]; + this.prodParam.exit(); + + if (this.hasPrecedingLineBreak()) { + this.raise(this.state.pos, ErrorMessages.LineTerminatorBeforeArrow); + } + + this.expect(27); + this.parseArrowExpression(node, params, true); + return node; + } + + parseDo(node, isAsync) { + this.expectPlugin("doExpressions"); + + if (isAsync) { + this.expectPlugin("asyncDoExpressions"); + } + + node.async = isAsync; + this.next(); + const oldLabels = this.state.labels; + this.state.labels = []; + + if (isAsync) { + this.prodParam.enter(PARAM_AWAIT); + node.body = this.parseBlock(); + this.prodParam.exit(); + } else { + node.body = this.parseBlock(); + } + + this.state.labels = oldLabels; + return this.finishNode(node, "DoExpression"); + } + + parseSuper() { + const node = this.startNode(); + this.next(); + + if (this.match(18) && !this.scope.allowDirectSuper && !this.options.allowSuperOutsideMethod) { + this.raise(node.start, ErrorMessages.SuperNotAllowed); + } else if (!this.scope.allowSuper && !this.options.allowSuperOutsideMethod) { + this.raise(node.start, ErrorMessages.UnexpectedSuper); + } + + if (!this.match(18) && !this.match(8) && !this.match(24)) { + this.raise(node.start, ErrorMessages.UnsupportedSuper); + } + + return this.finishNode(node, "Super"); + } + + parseMaybePrivateName(isPrivateNameAllowed) { + const isPrivate = this.match(6); + + if (isPrivate) { + if (!isPrivateNameAllowed) { + this.raise(this.state.start + 1, ErrorMessages.UnexpectedPrivateField); + } + + return this.parsePrivateName(); + } else { + return this.parseIdentifier(true); + } + } + + parsePrivateName() { + const node = this.startNode(); + const id = this.startNodeAt(this.state.start + 1, new Position(this.state.curLine, this.state.start + 1 - this.state.lineStart)); + const name = this.state.value; + this.next(); + node.id = this.createIdentifier(id, name); + return this.finishNode(node, "PrivateName"); + } + + parseFunctionOrFunctionSent() { + const node = this.startNode(); + this.next(); + + if (this.prodParam.hasYield && this.match(24)) { + const meta = this.createIdentifier(this.startNodeAtNode(node), "function"); + this.next(); + return this.parseMetaProperty(node, meta, "sent"); + } + + return this.parseFunction(node); + } + + parseMetaProperty(node, meta, propertyName) { + node.meta = meta; + + if (meta.name === "function" && propertyName === "sent") { + if (this.isContextual(propertyName)) { + this.expectPlugin("functionSent"); + } else if (!this.hasPlugin("functionSent")) { + this.unexpected(); + } + } + + const containsEsc = this.state.containsEsc; + node.property = this.parseIdentifier(true); + + if (node.property.name !== propertyName || containsEsc) { + this.raise(node.property.start, ErrorMessages.UnsupportedMetaProperty, meta.name, propertyName); + } + + return this.finishNode(node, "MetaProperty"); + } + + parseImportMetaProperty(node) { + const id = this.createIdentifier(this.startNodeAtNode(node), "import"); + this.next(); + + if (this.isContextual("meta")) { + if (!this.inModule) { + this.raise(id.start, SourceTypeModuleErrorMessages.ImportMetaOutsideModule); + } + + this.sawUnambiguousESM = true; + } + + return this.parseMetaProperty(node, id, "meta"); + } + + parseLiteralAtNode(value, type, node) { + this.addExtra(node, "rawValue", value); + this.addExtra(node, "raw", this.input.slice(node.start, this.state.end)); + node.value = value; + this.next(); + return this.finishNode(node, type); + } + + parseLiteral(value, type) { + const node = this.startNode(); + return this.parseLiteralAtNode(value, type, node); + } + + parseStringLiteral(value) { + return this.parseLiteral(value, "StringLiteral"); + } + + parseNumericLiteral(value) { + return this.parseLiteral(value, "NumericLiteral"); + } + + parseBigIntLiteral(value) { + return this.parseLiteral(value, "BigIntLiteral"); + } + + parseDecimalLiteral(value) { + return this.parseLiteral(value, "DecimalLiteral"); + } + + parseRegExpLiteral(value) { + const node = this.parseLiteral(value.value, "RegExpLiteral"); + node.pattern = value.pattern; + node.flags = value.flags; + return node; + } + + parseBooleanLiteral(value) { + const node = this.startNode(); + node.value = value; + this.next(); + return this.finishNode(node, "BooleanLiteral"); + } + + parseNullLiteral() { + const node = this.startNode(); + this.next(); + return this.finishNode(node, "NullLiteral"); + } + + parseParenAndDistinguishExpression(canBeArrow) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let val; + this.next(); + this.expressionScope.enter(newArrowHeadScope()); + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.maybeInArrowParameters = true; + this.state.inFSharpPipelineDirectBody = false; + const innerStartPos = this.state.start; + const innerStartLoc = this.state.startLoc; + const exprList = []; + const refExpressionErrors = new ExpressionErrors(); + let first = true; + let spreadStart; + let optionalCommaStart; + + while (!this.match(19)) { + if (first) { + first = false; + } else { + this.expect(20, refExpressionErrors.optionalParameters === -1 ? null : refExpressionErrors.optionalParameters); + + if (this.match(19)) { + optionalCommaStart = this.state.start; + break; + } + } + + if (this.match(29)) { + const spreadNodeStartPos = this.state.start; + const spreadNodeStartLoc = this.state.startLoc; + spreadStart = this.state.start; + exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartPos, spreadNodeStartLoc)); + this.checkCommaAfterRest(41); + break; + } else { + exprList.push(this.parseMaybeAssignAllowIn(refExpressionErrors, this.parseParenItem)); + } + } + + const innerEndPos = this.state.lastTokEnd; + const innerEndLoc = this.state.lastTokEndLoc; + this.expect(19); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + let arrowNode = this.startNodeAt(startPos, startLoc); + + if (canBeArrow && this.shouldParseArrow(exprList) && (arrowNode = this.parseArrow(arrowNode))) { + this.expressionScope.validateAsPattern(); + this.expressionScope.exit(); + this.parseArrowExpression(arrowNode, exprList, false); + return arrowNode; + } + + this.expressionScope.exit(); + + if (!exprList.length) { + this.unexpected(this.state.lastTokStart); + } + + if (optionalCommaStart) this.unexpected(optionalCommaStart); + if (spreadStart) this.unexpected(spreadStart); + this.checkExpressionErrors(refExpressionErrors, true); + this.toReferencedListDeep(exprList, true); + + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNode(val, "SequenceExpression"); + this.resetEndLocation(val, innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + + if (!this.options.createParenthesizedExpressions) { + this.addExtra(val, "parenthesized", true); + this.addExtra(val, "parenStart", startPos); + return val; + } + + const parenExpression = this.startNodeAt(startPos, startLoc); + parenExpression.expression = val; + this.finishNode(parenExpression, "ParenthesizedExpression"); + return parenExpression; + } + + shouldParseArrow(params) { + return !this.canInsertSemicolon(); + } + + parseArrow(node) { + if (this.eat(27)) { + return node; + } + } + + parseParenItem(node, startPos, startLoc) { + return node; + } + + parseNewOrNewTarget() { + const node = this.startNode(); + this.next(); + + if (this.match(24)) { + const meta = this.createIdentifier(this.startNodeAtNode(node), "new"); + this.next(); + const metaProp = this.parseMetaProperty(node, meta, "target"); + + if (!this.scope.inNonArrowFunction && !this.scope.inClass) { + this.raise(metaProp.start, ErrorMessages.UnexpectedNewTarget); + } + + return metaProp; + } + + return this.parseNew(node); + } + + parseNew(node) { + node.callee = this.parseNoCallExpr(); + + if (node.callee.type === "Import") { + this.raise(node.callee.start, ErrorMessages.ImportCallNotNewExpression); + } else if (this.isOptionalChain(node.callee)) { + this.raise(this.state.lastTokEnd, ErrorMessages.OptionalChainingNoNew); + } else if (this.eat(26)) { + this.raise(this.state.start, ErrorMessages.OptionalChainingNoNew); + } + + this.parseNewArguments(node); + return this.finishNode(node, "NewExpression"); + } + + parseNewArguments(node) { + if (this.eat(18)) { + const args = this.parseExprList(19); + this.toReferencedList(args); + node.arguments = args; + } else { + node.arguments = []; + } + } + + parseTemplateElement(isTagged) { + const elem = this.startNode(); + + if (this.state.value === null) { + if (!isTagged) { + this.raise(this.state.start + 1, ErrorMessages.InvalidEscapeSequenceTemplate); + } + } + + elem.value = { + raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), + cooked: this.state.value + }; + this.next(); + elem.tail = this.match(30); + return this.finishNode(elem, "TemplateElement"); + } + + parseTemplate(isTagged) { + const node = this.startNode(); + this.next(); + node.expressions = []; + let curElt = this.parseTemplateElement(isTagged); + node.quasis = [curElt]; + + while (!curElt.tail) { + this.expect(31); + node.expressions.push(this.parseTemplateSubstitution()); + this.expect(16); + node.quasis.push(curElt = this.parseTemplateElement(isTagged)); + } + + this.next(); + return this.finishNode(node, "TemplateLiteral"); + } + + parseTemplateSubstitution() { + return this.parseExpression(); + } + + parseObjectLike(close, isPattern, isRecord, refExpressionErrors) { + if (isRecord) { + this.expectPlugin("recordAndTuple"); + } + + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + const propHash = Object.create(null); + let first = true; + const node = this.startNode(); + node.properties = []; + this.next(); + + while (!this.match(close)) { + if (first) { + first = false; + } else { + this.expect(20); + + if (this.match(close)) { + this.addExtra(node, "trailingComma", this.state.lastTokStart); + break; + } + } + + const prop = this.parsePropertyDefinition(isPattern, refExpressionErrors); + + if (!isPattern) { + this.checkProto(prop, isRecord, propHash, refExpressionErrors); + } + + if (isRecord && !this.isObjectProperty(prop) && prop.type !== "SpreadElement") { + this.raise(prop.start, ErrorMessages.InvalidRecordProperty); + } + + if (prop.shorthand) { + this.addExtra(prop, "shorthand", true); + } + + node.properties.push(prop); + } + + this.next(); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + let type = "ObjectExpression"; + + if (isPattern) { + type = "ObjectPattern"; + } else if (isRecord) { + type = "RecordExpression"; + } + + return this.finishNode(node, type); + } + + maybeAsyncOrAccessorProp(prop) { + return !prop.computed && prop.key.type === "Identifier" && (this.isLiteralPropertyName() || this.match(8) || this.match(54)); + } + + parsePropertyDefinition(isPattern, refExpressionErrors) { + let decorators = []; + + if (this.match(32)) { + if (this.hasPlugin("decorators")) { + this.raise(this.state.start, ErrorMessages.UnsupportedPropertyDecorator); + } + + while (this.match(32)) { + decorators.push(this.parseDecorator()); + } + } + + const prop = this.startNode(); + let isGenerator = false; + let isAsync = false; + let isAccessor = false; + let startPos; + let startLoc; + + if (this.match(29)) { + if (decorators.length) this.unexpected(); + + if (isPattern) { + this.next(); + prop.argument = this.parseIdentifier(); + this.checkCommaAfterRest(125); + return this.finishNode(prop, "RestElement"); + } + + return this.parseSpread(); + } + + if (decorators.length) { + prop.decorators = decorators; + decorators = []; + } + + prop.method = false; + + if (isPattern || refExpressionErrors) { + startPos = this.state.start; + startLoc = this.state.startLoc; + } + + if (!isPattern) { + isGenerator = this.eat(54); + } + + const containsEsc = this.state.containsEsc; + const key = this.parsePropertyName(prop, false); + + if (!isPattern && !isGenerator && !containsEsc && this.maybeAsyncOrAccessorProp(prop)) { + const keyName = key.name; + + if (keyName === "async" && !this.hasPrecedingLineBreak()) { + isAsync = true; + this.resetPreviousNodeTrailingComments(key); + isGenerator = this.eat(54); + this.parsePropertyName(prop, false); + } + + if (keyName === "get" || keyName === "set") { + isAccessor = true; + this.resetPreviousNodeTrailingComments(key); + prop.kind = keyName; + + if (this.match(54)) { + isGenerator = true; + this.raise(this.state.pos, ErrorMessages.AccessorIsGenerator, keyName); + this.next(); + } + + this.parsePropertyName(prop, false); + } + } + + this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors); + return prop; + } + + getGetterSetterExpectedParamCount(method) { + return method.kind === "get" ? 0 : 1; + } + + getObjectOrClassMethodParams(method) { + return method.params; + } + + checkGetterSetterParams(method) { + var _params; + + const paramCount = this.getGetterSetterExpectedParamCount(method); + const params = this.getObjectOrClassMethodParams(method); + const start = method.start; + + if (params.length !== paramCount) { + if (method.kind === "get") { + this.raise(start, ErrorMessages.BadGetterArity); + } else { + this.raise(start, ErrorMessages.BadSetterArity); + } + } + + if (method.kind === "set" && ((_params = params[params.length - 1]) == null ? void 0 : _params.type) === "RestElement") { + this.raise(start, ErrorMessages.BadSetterRestParameter); + } + } + + parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) { + if (isAccessor) { + this.parseMethod(prop, isGenerator, false, false, false, "ObjectMethod"); + this.checkGetterSetterParams(prop); + return prop; + } + + if (isAsync || isGenerator || this.match(18)) { + if (isPattern) this.unexpected(); + prop.kind = "method"; + prop.method = true; + return this.parseMethod(prop, isGenerator, isAsync, false, false, "ObjectMethod"); + } + } + + parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors) { + prop.shorthand = false; + + if (this.eat(22)) { + prop.value = isPattern ? this.parseMaybeDefault(this.state.start, this.state.startLoc) : this.parseMaybeAssignAllowIn(refExpressionErrors); + return this.finishNode(prop, "ObjectProperty"); + } + + if (!prop.computed && prop.key.type === "Identifier") { + this.checkReservedWord(prop.key.name, prop.key.start, true, false); + + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, cloneIdentifier(prop.key)); + } else if (this.match(35) && refExpressionErrors) { + if (refExpressionErrors.shorthandAssign === -1) { + refExpressionErrors.shorthandAssign = this.state.start; + } + + prop.value = this.parseMaybeDefault(startPos, startLoc, cloneIdentifier(prop.key)); + } else { + prop.value = cloneIdentifier(prop.key); + } + + prop.shorthand = true; + return this.finishNode(prop, "ObjectProperty"); + } + } + + parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) { + const node = this.parseObjectMethod(prop, isGenerator, isAsync, isPattern, isAccessor) || this.parseObjectProperty(prop, startPos, startLoc, isPattern, refExpressionErrors); + if (!node) this.unexpected(); + return node; + } + + parsePropertyName(prop, isPrivateNameAllowed) { + if (this.eat(8)) { + prop.computed = true; + prop.key = this.parseMaybeAssignAllowIn(); + this.expect(11); + } else { + const oldInPropertyName = this.state.inPropertyName; + this.state.inPropertyName = true; + const type = this.state.type; + prop.key = type === 0 || type === 4 || type === 1 || type === 2 ? this.parseExprAtom() : this.parseMaybePrivateName(isPrivateNameAllowed); + + if (type !== 6) { + prop.computed = false; + } + + this.state.inPropertyName = oldInPropertyName; + } + + return prop.key; + } + + initFunction(node, isAsync) { + node.id = null; + node.generator = false; + node.async = !!isAsync; + } + + parseMethod(node, isGenerator, isAsync, isConstructor, allowDirectSuper, type, inClassScope = false) { + this.initFunction(node, isAsync); + node.generator = !!isGenerator; + const allowModifiers = isConstructor; + this.scope.enter(SCOPE_FUNCTION | SCOPE_SUPER | (inClassScope ? SCOPE_CLASS : 0) | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + this.prodParam.enter(functionFlags(isAsync, node.generator)); + this.parseFunctionParams(node, allowModifiers); + this.parseFunctionBodyAndFinish(node, type, true); + this.prodParam.exit(); + this.scope.exit(); + return node; + } + + parseArrayLike(close, canBePattern, isTuple, refExpressionErrors) { + if (isTuple) { + this.expectPlugin("recordAndTuple"); + } + + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = false; + const node = this.startNode(); + this.next(); + node.elements = this.parseExprList(close, !isTuple, refExpressionErrors, node); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return this.finishNode(node, isTuple ? "TupleExpression" : "ArrayExpression"); + } + + parseArrowExpression(node, params, isAsync, trailingCommaPos) { + this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW); + let flags = functionFlags(isAsync, false); + + if (!this.match(8) && this.prodParam.hasIn) { + flags |= PARAM_IN; + } + + this.prodParam.enter(flags); + this.initFunction(node, isAsync); + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + + if (params) { + this.state.maybeInArrowParameters = true; + this.setArrowFunctionParameters(node, params, trailingCommaPos); + } + + this.state.maybeInArrowParameters = false; + this.parseFunctionBody(node, true); + this.prodParam.exit(); + this.scope.exit(); + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + return this.finishNode(node, "ArrowFunctionExpression"); + } + + setArrowFunctionParameters(node, params, trailingCommaPos) { + node.params = this.toAssignableList(params, trailingCommaPos, false); + } + + parseFunctionBodyAndFinish(node, type, isMethod = false) { + this.parseFunctionBody(node, false, isMethod); + this.finishNode(node, type); + } + + parseFunctionBody(node, allowExpression, isMethod = false) { + const isExpression = allowExpression && !this.match(13); + this.expressionScope.enter(newExpressionScope()); + + if (isExpression) { + node.body = this.parseMaybeAssign(); + this.checkParams(node, false, allowExpression, false); + } else { + const oldStrict = this.state.strict; + const oldLabels = this.state.labels; + this.state.labels = []; + this.prodParam.enter(this.prodParam.currentFlags() | PARAM_RETURN); + node.body = this.parseBlock(true, false, hasStrictModeDirective => { + const nonSimple = !this.isSimpleParamList(node.params); + + if (hasStrictModeDirective && nonSimple) { + const errorPos = (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.end : node.start; + this.raise(errorPos, ErrorMessages.IllegalLanguageModeDirective); + } + + const strictModeChanged = !oldStrict && this.state.strict; + this.checkParams(node, !this.state.strict && !allowExpression && !isMethod && !nonSimple, allowExpression, strictModeChanged); + + if (this.state.strict && node.id) { + this.checkLVal(node.id, "function name", BIND_OUTSIDE, undefined, undefined, strictModeChanged); + } + }); + this.prodParam.exit(); + this.expressionScope.exit(); + this.state.labels = oldLabels; + } + } + + isSimpleParamList(params) { + for (let i = 0, len = params.length; i < len; i++) { + if (params[i].type !== "Identifier") return false; + } + + return true; + } + + checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) { + const checkClashes = new Set(); + + for (const param of node.params) { + this.checkLVal(param, "function parameter list", BIND_VAR, allowDuplicates ? null : checkClashes, undefined, strictModeChanged); + } + } + + parseExprList(close, allowEmpty, refExpressionErrors, nodeForExtra) { + const elts = []; + let first = true; + + while (!this.eat(close)) { + if (first) { + first = false; + } else { + this.expect(20); + + if (this.match(close)) { + if (nodeForExtra) { + this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + } + + this.next(); + break; + } + } + + elts.push(this.parseExprListItem(allowEmpty, refExpressionErrors)); + } + + return elts; + } + + parseExprListItem(allowEmpty, refExpressionErrors, allowPlaceholder) { + let elt; + + if (this.match(20)) { + if (!allowEmpty) { + this.raise(this.state.pos, ErrorMessages.UnexpectedToken, ","); + } + + elt = null; + } else if (this.match(29)) { + const spreadNodeStartPos = this.state.start; + const spreadNodeStartLoc = this.state.startLoc; + elt = this.parseParenItem(this.parseSpread(refExpressionErrors), spreadNodeStartPos, spreadNodeStartLoc); + } else if (this.match(25)) { + this.expectPlugin("partialApplication"); + + if (!allowPlaceholder) { + this.raise(this.state.start, ErrorMessages.UnexpectedArgumentPlaceholder); + } + + const node = this.startNode(); + this.next(); + elt = this.finishNode(node, "ArgumentPlaceholder"); + } else { + elt = this.parseMaybeAssignAllowIn(refExpressionErrors, this.parseParenItem); + } + + return elt; + } + + parseIdentifier(liberal) { + const node = this.startNode(); + const name = this.parseIdentifierName(node.start, liberal); + return this.createIdentifier(node, name); + } + + createIdentifier(node, name) { + node.name = name; + node.loc.identifierName = name; + return this.finishNode(node, "Identifier"); + } + + parseIdentifierName(pos, liberal) { + let name; + const { + start, + type + } = this.state; + + if (type === 5) { + name = this.state.value; + } else if (tokenIsKeyword(type)) { + name = tokenLabelName(type); + } else { + throw this.unexpected(); + } + + if (liberal) { + this.state.type = 5; + } else { + this.checkReservedWord(name, start, tokenIsKeyword(type), false); + } + + this.next(); + return name; + } + + checkReservedWord(word, startLoc, checkKeywords, isBinding) { + if (word.length > 10) { + return; + } + + if (!canBeReservedWord(word)) { + return; + } + + if (word === "yield") { + if (this.prodParam.hasYield) { + this.raise(startLoc, ErrorMessages.YieldBindingIdentifier); + return; + } + } else if (word === "await") { + if (this.prodParam.hasAwait) { + this.raise(startLoc, ErrorMessages.AwaitBindingIdentifier); + return; + } else if (this.scope.inStaticBlock) { + this.raise(startLoc, ErrorMessages.AwaitBindingIdentifierInStaticBlock); + return; + } else { + this.expressionScope.recordAsyncArrowParametersError(startLoc, ErrorMessages.AwaitBindingIdentifier); + } + } else if (word === "arguments") { + if (this.scope.inClassAndNotInNonArrowFunction) { + this.raise(startLoc, ErrorMessages.ArgumentsInClass); + return; + } + } + + if (checkKeywords && isKeyword(word)) { + this.raise(startLoc, ErrorMessages.UnexpectedKeyword, word); + return; + } + + const reservedTest = !this.state.strict ? isReservedWord : isBinding ? isStrictBindReservedWord : isStrictReservedWord; + + if (reservedTest(word, this.inModule)) { + this.raise(startLoc, ErrorMessages.UnexpectedReservedWord, word); + } + } + + isAwaitAllowed() { + if (this.prodParam.hasAwait) return true; + + if (this.options.allowAwaitOutsideFunction && !this.scope.inFunction) { + return true; + } + + return false; + } + + parseAwait(startPos, startLoc) { + const node = this.startNodeAt(startPos, startLoc); + this.expressionScope.recordParameterInitializerError(node.start, ErrorMessages.AwaitExpressionFormalParameter); + + if (this.eat(54)) { + this.raise(node.start, ErrorMessages.ObsoleteAwaitStar); + } + + if (!this.scope.inFunction && !this.options.allowAwaitOutsideFunction) { + if (this.isAmbiguousAwait()) { + this.ambiguousScriptDifferentAst = true; + } else { + this.sawUnambiguousESM = true; + } + } + + if (!this.state.soloAwait) { + node.argument = this.parseMaybeUnary(null, true); + } + + return this.finishNode(node, "AwaitExpression"); + } + + isAmbiguousAwait() { + return this.hasPrecedingLineBreak() || this.match(52) || this.match(18) || this.match(8) || this.match(30) || this.match(3) || this.match(55) || this.hasPlugin("v8intrinsic") && this.match(53); + } + + parseYield() { + const node = this.startNode(); + this.expressionScope.recordParameterInitializerError(node.start, ErrorMessages.YieldInParameter); + this.next(); + let delegating = false; + let argument = null; + + if (!this.hasPrecedingLineBreak()) { + delegating = this.eat(54); + + switch (this.state.type) { + case 21: + case 7: + case 16: + case 19: + case 11: + case 17: + case 22: + case 20: + if (!delegating) break; + + default: + argument = this.parseMaybeAssign(); + } + } + + node.delegate = delegating; + node.argument = argument; + return this.finishNode(node, "YieldExpression"); + } + + checkPipelineAtInfixOperator(left, leftStartPos) { + if (this.getPluginOption("pipelineOperator", "proposal") === "smart") { + if (left.type === "SequenceExpression") { + this.raise(leftStartPos, ErrorMessages.PipelineHeadSequenceExpression); + } + } + } + + checkHackPipeBodyEarlyErrors(startPos) { + if (!this.topicReferenceWasUsedInCurrentContext()) { + this.raise(startPos, ErrorMessages.PipeTopicUnused); + } + } + + parseSmartPipelineBodyInStyle(childExpr, startPos, startLoc) { + const bodyNode = this.startNodeAt(startPos, startLoc); + + if (this.isSimpleReference(childExpr)) { + bodyNode.callee = childExpr; + return this.finishNode(bodyNode, "PipelineBareFunction"); + } else { + this.checkSmartPipeTopicBodyEarlyErrors(startPos); + bodyNode.expression = childExpr; + return this.finishNode(bodyNode, "PipelineTopicExpression"); + } + } + + isSimpleReference(expression) { + switch (expression.type) { + case "MemberExpression": + return !expression.computed && this.isSimpleReference(expression.object); + + case "Identifier": + return true; + + default: + return false; + } + } + + checkSmartPipeTopicBodyEarlyErrors(startPos) { + if (this.match(27)) { + throw this.raise(this.state.start, ErrorMessages.PipelineBodyNoArrow); + } else if (!this.topicReferenceWasUsedInCurrentContext()) { + this.raise(startPos, ErrorMessages.PipelineTopicUnused); + } + } + + withTopicBindingContext(callback) { + const outerContextTopicState = this.state.topicContext; + this.state.topicContext = { + maxNumOfResolvableTopics: 1, + maxTopicIndex: null + }; + + try { + return callback(); + } finally { + this.state.topicContext = outerContextTopicState; + } + } + + withSmartMixTopicForbiddingContext(callback) { + const proposal = this.getPluginOption("pipelineOperator", "proposal"); + + if (proposal === "smart") { + const outerContextTopicState = this.state.topicContext; + this.state.topicContext = { + maxNumOfResolvableTopics: 0, + maxTopicIndex: null + }; + + try { + return callback(); + } finally { + this.state.topicContext = outerContextTopicState; + } + } else { + return callback(); + } + } + + withSoloAwaitPermittingContext(callback) { + const outerContextSoloAwaitState = this.state.soloAwait; + this.state.soloAwait = true; + + try { + return callback(); + } finally { + this.state.soloAwait = outerContextSoloAwaitState; + } + } + + allowInAnd(callback) { + const flags = this.prodParam.currentFlags(); + const prodParamToSet = PARAM_IN & ~flags; + + if (prodParamToSet) { + this.prodParam.enter(flags | PARAM_IN); + + try { + return callback(); + } finally { + this.prodParam.exit(); + } + } + + return callback(); + } + + disallowInAnd(callback) { + const flags = this.prodParam.currentFlags(); + const prodParamToClear = PARAM_IN & flags; + + if (prodParamToClear) { + this.prodParam.enter(flags & ~PARAM_IN); + + try { + return callback(); + } finally { + this.prodParam.exit(); + } + } + + return callback(); + } + + registerTopicReference() { + this.state.topicContext.maxTopicIndex = 0; + } + + topicReferenceIsAllowedInCurrentContext() { + return this.state.topicContext.maxNumOfResolvableTopics >= 1; + } + + topicReferenceWasUsedInCurrentContext() { + return this.state.topicContext.maxTopicIndex != null && this.state.topicContext.maxTopicIndex >= 0; + } + + parseFSharpPipelineBody(prec) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.state.potentialArrowAt = this.state.start; + const oldInFSharpPipelineDirectBody = this.state.inFSharpPipelineDirectBody; + this.state.inFSharpPipelineDirectBody = true; + const ret = this.parseExprOp(this.parseMaybeUnaryOrPrivate(), startPos, startLoc, prec); + this.state.inFSharpPipelineDirectBody = oldInFSharpPipelineDirectBody; + return ret; + } + + parseModuleExpression() { + this.expectPlugin("moduleBlocks"); + const node = this.startNode(); + this.next(); + this.eat(13); + const revertScopes = this.initializeScopes(true); + this.enterInitialScopes(); + const program = this.startNode(); + + try { + node.body = this.parseProgram(program, 16, "module"); + } finally { + revertScopes(); + } + + this.eat(16); + return this.finishNode(node, "ModuleExpression"); + } + + } + + const loopLabel = { + kind: "loop" + }, + switchLabel = { + kind: "switch" + }; + const FUNC_NO_FLAGS = 0b000, + FUNC_STATEMENT = 0b001, + FUNC_HANGING_STATEMENT = 0b010, + FUNC_NULLABLE_ID = 0b100; + const loneSurrogate = /[\uD800-\uDFFF]/u; + const keywordRelationalOperator = /in(?:stanceof)?/y; + + function babel7CompatTokens(tokens) { + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + const { + type + } = token; + + if (type === 6) { + { + const { + loc, + start, + value, + end + } = token; + const hashEndPos = start + 1; + const hashEndLoc = new Position(loc.start.line, loc.start.column + 1); + tokens.splice(i, 1, new Token({ + type: getExportedToken(33), + value: "#", + start: start, + end: hashEndPos, + startLoc: loc.start, + endLoc: hashEndLoc + }), new Token({ + type: getExportedToken(5), + value: value, + start: hashEndPos, + end: end, + startLoc: hashEndLoc, + endLoc: loc.end + })); + i++; + continue; + } + } + + if (typeof type === "number") { + token.type = getExportedToken(type); + } + } + + return tokens; + } + + class StatementParser extends ExpressionParser { + parseTopLevel(file, program) { + file.program = this.parseProgram(program); + file.comments = this.state.comments; + if (this.options.tokens) file.tokens = babel7CompatTokens(this.tokens); + return this.finishNode(file, "File"); + } + + parseProgram(program, end = 7, sourceType = this.options.sourceType) { + program.sourceType = sourceType; + program.interpreter = this.parseInterpreterDirective(); + this.parseBlockBody(program, true, true, end); + + if (this.inModule && !this.options.allowUndeclaredExports && this.scope.undefinedExports.size > 0) { + for (const [name] of Array.from(this.scope.undefinedExports)) { + const pos = this.scope.undefinedExports.get(name); + this.raise(pos, ErrorMessages.ModuleExportUndefined, name); + } + } + + return this.finishNode(program, "Program"); + } + + stmtToDirective(stmt) { + const directive = stmt; + directive.type = "Directive"; + directive.value = directive.expression; + delete directive.expression; + const directiveLiteral = directive.value; + const raw = this.input.slice(directiveLiteral.start, directiveLiteral.end); + const val = directiveLiteral.value = raw.slice(1, -1); + this.addExtra(directiveLiteral, "raw", raw); + this.addExtra(directiveLiteral, "rawValue", val); + directiveLiteral.type = "DirectiveLiteral"; + return directive; + } + + parseInterpreterDirective() { + if (!this.match(34)) { + return null; + } + + const node = this.startNode(); + node.value = this.state.value; + this.next(); + return this.finishNode(node, "InterpreterDirective"); + } + + isLet(context) { + if (!this.isContextual("let")) { + return false; + } + + return this.isLetKeyword(context); + } + + isLetKeyword(context) { + const next = this.nextTokenStart(); + const nextCh = this.codePointAtPos(next); + + if (nextCh === 92 || nextCh === 91) { + return true; + } + + if (context) return false; + if (nextCh === 123) return true; + + if (isIdentifierStart(nextCh)) { + keywordRelationalOperator.lastIndex = next; + + if (keywordRelationalOperator.test(this.input)) { + const endCh = this.codePointAtPos(keywordRelationalOperator.lastIndex); + + if (!isIdentifierChar(endCh) && endCh !== 92) { + return false; + } + } + + return true; + } + + return false; + } + + parseStatement(context, topLevel) { + if (this.match(32)) { + this.parseDecorators(true); + } + + return this.parseStatementContent(context, topLevel); + } + + parseStatementContent(context, topLevel) { + let starttype = this.state.type; + const node = this.startNode(); + let kind; + + if (this.isLet(context)) { + starttype = 73; + kind = "let"; + } + + switch (starttype) { + case 59: + return this.parseBreakContinueStatement(node, true); + + case 62: + return this.parseBreakContinueStatement(node, false); + + case 63: + return this.parseDebuggerStatement(node); + + case 89: + return this.parseDoStatement(node); + + case 90: + return this.parseForStatement(node); + + case 67: + if (this.lookaheadCharCode() === 46) break; + + if (context) { + if (this.state.strict) { + this.raise(this.state.start, ErrorMessages.StrictFunction); + } else if (context !== "if" && context !== "label") { + this.raise(this.state.start, ErrorMessages.SloppyFunction); + } + } + + return this.parseFunctionStatement(node, false, !context); + + case 79: + if (context) this.unexpected(); + return this.parseClass(node, true); + + case 68: + return this.parseIfStatement(node); + + case 69: + return this.parseReturnStatement(node); + + case 70: + return this.parseSwitchStatement(node); + + case 71: + return this.parseThrowStatement(node); + + case 72: + return this.parseTryStatement(node); + + case 74: + case 73: + kind = kind || this.state.value; + + if (context && kind !== "var") { + this.raise(this.state.start, ErrorMessages.UnexpectedLexicalDeclaration); + } + + return this.parseVarStatement(node, kind); + + case 91: + return this.parseWhileStatement(node); + + case 75: + return this.parseWithStatement(node); + + case 13: + return this.parseBlock(); + + case 21: + return this.parseEmptyStatement(node); + + case 82: + { + const nextTokenCharCode = this.lookaheadCharCode(); + + if (nextTokenCharCode === 40 || nextTokenCharCode === 46) { + break; + } + } + + case 81: + { + if (!this.options.allowImportExportEverywhere && !topLevel) { + this.raise(this.state.start, ErrorMessages.UnexpectedImportExport); + } + + this.next(); + let result; + + if (starttype === 82) { + result = this.parseImport(node); + + if (result.type === "ImportDeclaration" && (!result.importKind || result.importKind === "value")) { + this.sawUnambiguousESM = true; + } + } else { + result = this.parseExport(node); + + if (result.type === "ExportNamedDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportAllDeclaration" && (!result.exportKind || result.exportKind === "value") || result.type === "ExportDefaultDeclaration") { + this.sawUnambiguousESM = true; + } + } + + this.assertModuleNodeAllowed(node); + return result; + } + + default: + { + if (this.isAsyncFunction()) { + if (context) { + this.raise(this.state.start, ErrorMessages.AsyncFunctionInSingleStatementContext); + } + + this.next(); + return this.parseFunctionStatement(node, true, !context); + } + } + } + + const maybeName = this.state.value; + const expr = this.parseExpression(); + + if (starttype === 5 && expr.type === "Identifier" && this.eat(22)) { + return this.parseLabeledStatement(node, maybeName, expr, context); + } else { + return this.parseExpressionStatement(node, expr); + } + } + + assertModuleNodeAllowed(node) { + if (!this.options.allowImportExportEverywhere && !this.inModule) { + this.raise(node.start, SourceTypeModuleErrorMessages.ImportOutsideModule); + } + } + + takeDecorators(node) { + const decorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + if (decorators.length) { + node.decorators = decorators; + this.resetStartLocationFromNode(node, decorators[0]); + this.state.decoratorStack[this.state.decoratorStack.length - 1] = []; + } + } + + canHaveLeadingDecorator() { + return this.match(79); + } + + parseDecorators(allowExport) { + const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + while (this.match(32)) { + const decorator = this.parseDecorator(); + currentContextDecorators.push(decorator); + } + + if (this.match(81)) { + if (!allowExport) { + this.unexpected(); + } + + if (this.hasPlugin("decorators") && !this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.raise(this.state.start, ErrorMessages.DecoratorExportClass); + } + } else if (!this.canHaveLeadingDecorator()) { + throw this.raise(this.state.start, ErrorMessages.UnexpectedLeadingDecorator); + } + } + + parseDecorator() { + this.expectOnePlugin(["decorators-legacy", "decorators"]); + const node = this.startNode(); + this.next(); + + if (this.hasPlugin("decorators")) { + this.state.decoratorStack.push([]); + const startPos = this.state.start; + const startLoc = this.state.startLoc; + let expr; + + if (this.eat(18)) { + expr = this.parseExpression(); + this.expect(19); + } else { + expr = this.parseIdentifier(false); + + while (this.eat(24)) { + const node = this.startNodeAt(startPos, startLoc); + node.object = expr; + node.property = this.parseIdentifier(true); + node.computed = false; + expr = this.finishNode(node, "MemberExpression"); + } + } + + node.expression = this.parseMaybeDecoratorArguments(expr); + this.state.decoratorStack.pop(); + } else { + node.expression = this.parseExprSubscripts(); + } + + return this.finishNode(node, "Decorator"); + } + + parseMaybeDecoratorArguments(expr) { + if (this.eat(18)) { + const node = this.startNodeAtNode(expr); + node.callee = expr; + node.arguments = this.parseCallExpressionArguments(19, false); + this.toReferencedList(node.arguments); + return this.finishNode(node, "CallExpression"); + } + + return expr; + } + + parseBreakContinueStatement(node, isBreak) { + this.next(); + + if (this.isLineTerminator()) { + node.label = null; + } else { + node.label = this.parseIdentifier(); + this.semicolon(); + } + + this.verifyBreakContinue(node, isBreak); + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement"); + } + + verifyBreakContinue(node, isBreak) { + let i; + + for (i = 0; i < this.state.labels.length; ++i) { + const lab = this.state.labels[i]; + + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) break; + if (node.label && isBreak) break; + } + } + + if (i === this.state.labels.length) { + this.raise(node.start, ErrorMessages.IllegalBreakContinue, isBreak ? "break" : "continue"); + } + } + + parseDebuggerStatement(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement"); + } + + parseHeaderExpression() { + this.expect(18); + const val = this.parseExpression(); + this.expect(19); + return val; + } + + parseDoStatement(node) { + this.next(); + this.state.labels.push(loopLabel); + node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("do")); + this.state.labels.pop(); + this.expect(91); + node.test = this.parseHeaderExpression(); + this.eat(21); + return this.finishNode(node, "DoWhileStatement"); + } + + parseForStatement(node) { + this.next(); + this.state.labels.push(loopLabel); + let awaitAt = -1; + + if (this.isAwaitAllowed() && this.eatContextual("await")) { + awaitAt = this.state.lastTokStart; + } + + this.scope.enter(SCOPE_OTHER); + this.expect(18); + + if (this.match(21)) { + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, null); + } + + const startsWithLet = this.isContextual("let"); + const isLet = startsWithLet && this.isLetKeyword(); + + if (this.match(73) || this.match(74) || isLet) { + const init = this.startNode(); + const kind = isLet ? "let" : this.state.value; + this.next(); + this.parseVar(init, true, kind); + this.finishNode(init, "VariableDeclaration"); + + if ((this.match(57) || this.isContextual("of")) && init.declarations.length === 1) { + return this.parseForIn(node, init, awaitAt); + } + + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, init); + } + + const startsWithUnescapedName = this.match(5) && !this.state.containsEsc; + const refExpressionErrors = new ExpressionErrors(); + const init = this.parseExpression(true, refExpressionErrors); + const isForOf = this.isContextual("of"); + + if (isForOf) { + if (startsWithLet) { + this.raise(init.start, ErrorMessages.ForOfLet); + } else if (awaitAt === -1 && startsWithUnescapedName && init.type === "Identifier" && init.name === "async") { + this.raise(init.start, ErrorMessages.ForOfAsync); + } + } + + if (isForOf || this.match(57)) { + this.toAssignable(init, true); + const description = isForOf ? "for-of statement" : "for-in statement"; + this.checkLVal(init, description); + return this.parseForIn(node, init, awaitAt); + } else { + this.checkExpressionErrors(refExpressionErrors, true); + } + + if (awaitAt > -1) { + this.unexpected(awaitAt); + } + + return this.parseFor(node, init); + } + + parseFunctionStatement(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), isAsync); + } + + parseIfStatement(node) { + this.next(); + node.test = this.parseHeaderExpression(); + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(65) ? this.parseStatement("if") : null; + return this.finishNode(node, "IfStatement"); + } + + parseReturnStatement(node) { + if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) { + this.raise(this.state.start, ErrorMessages.IllegalReturn); + } + + this.next(); + + if (this.isLineTerminator()) { + node.argument = null; + } else { + node.argument = this.parseExpression(); + this.semicolon(); + } + + return this.finishNode(node, "ReturnStatement"); + } + + parseSwitchStatement(node) { + this.next(); + node.discriminant = this.parseHeaderExpression(); + const cases = node.cases = []; + this.expect(13); + this.state.labels.push(switchLabel); + this.scope.enter(SCOPE_OTHER); + let cur; + + for (let sawDefault; !this.match(16);) { + if (this.match(60) || this.match(64)) { + const isCase = this.match(60); + if (cur) this.finishNode(cur, "SwitchCase"); + cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { + this.raise(this.state.lastTokStart, ErrorMessages.MultipleDefaultsInSwitch); + } + + sawDefault = true; + cur.test = null; + } + + this.expect(22); + } else { + if (cur) { + cur.consequent.push(this.parseStatement(null)); + } else { + this.unexpected(); + } + } + } + + this.scope.exit(); + if (cur) this.finishNode(cur, "SwitchCase"); + this.next(); + this.state.labels.pop(); + return this.finishNode(node, "SwitchStatement"); + } + + parseThrowStatement(node) { + this.next(); + + if (this.hasPrecedingLineBreak()) { + this.raise(this.state.lastTokEnd, ErrorMessages.NewlineAfterThrow); + } + + node.argument = this.parseExpression(); + this.semicolon(); + return this.finishNode(node, "ThrowStatement"); + } + + parseCatchClauseParam() { + const param = this.parseBindingAtom(); + const simple = param.type === "Identifier"; + this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLVal(param, "catch clause", BIND_LEXICAL); + return param; + } + + parseTryStatement(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + + if (this.match(61)) { + const clause = this.startNode(); + this.next(); + + if (this.match(18)) { + this.expect(18); + clause.param = this.parseCatchClauseParam(); + this.expect(19); + } else { + clause.param = null; + this.scope.enter(SCOPE_OTHER); + } + + clause.body = this.withSmartMixTopicForbiddingContext(() => this.parseBlock(false, false)); + this.scope.exit(); + node.handler = this.finishNode(clause, "CatchClause"); + } + + node.finalizer = this.eat(66) ? this.parseBlock() : null; + + if (!node.handler && !node.finalizer) { + this.raise(node.start, ErrorMessages.NoCatchOrFinally); + } + + return this.finishNode(node, "TryStatement"); + } + + parseVarStatement(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration"); + } + + parseWhileStatement(node) { + this.next(); + node.test = this.parseHeaderExpression(); + this.state.labels.push(loopLabel); + node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("while")); + this.state.labels.pop(); + return this.finishNode(node, "WhileStatement"); + } + + parseWithStatement(node) { + if (this.state.strict) { + this.raise(this.state.start, ErrorMessages.StrictWith); + } + + this.next(); + node.object = this.parseHeaderExpression(); + node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("with")); + return this.finishNode(node, "WithStatement"); + } + + parseEmptyStatement(node) { + this.next(); + return this.finishNode(node, "EmptyStatement"); + } + + parseLabeledStatement(node, maybeName, expr, context) { + for (const label of this.state.labels) { + if (label.name === maybeName) { + this.raise(expr.start, ErrorMessages.LabelRedeclaration, maybeName); + } + } + + const kind = tokenIsLoop(this.state.type) ? "loop" : this.match(70) ? "switch" : null; + + for (let i = this.state.labels.length - 1; i >= 0; i--) { + const label = this.state.labels[i]; + + if (label.statementStart === node.start) { + label.statementStart = this.state.start; + label.kind = kind; + } else { + break; + } + } + + this.state.labels.push({ + name: maybeName, + kind: kind, + statementStart: this.state.start + }); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + this.state.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement"); + } + + parseExpressionStatement(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement"); + } + + parseBlock(allowDirectives = false, createNewLexicalScope = true, afterBlockParse) { + const node = this.startNode(); + + if (allowDirectives) { + this.state.strictErrors.clear(); + } + + this.expect(13); + + if (createNewLexicalScope) { + this.scope.enter(SCOPE_OTHER); + } + + this.parseBlockBody(node, allowDirectives, false, 16, afterBlockParse); + + if (createNewLexicalScope) { + this.scope.exit(); + } + + return this.finishNode(node, "BlockStatement"); + } + + isValidDirective(stmt) { + return stmt.type === "ExpressionStatement" && stmt.expression.type === "StringLiteral" && !stmt.expression.extra.parenthesized; + } + + parseBlockBody(node, allowDirectives, topLevel, end, afterBlockParse) { + const body = node.body = []; + const directives = node.directives = []; + this.parseBlockOrModuleBlockBody(body, allowDirectives ? directives : undefined, topLevel, end, afterBlockParse); + } + + parseBlockOrModuleBlockBody(body, directives, topLevel, end, afterBlockParse) { + const oldStrict = this.state.strict; + let hasStrictModeDirective = false; + let parsedNonDirective = false; + + while (!this.match(end)) { + const stmt = this.parseStatement(null, topLevel); + + if (directives && !parsedNonDirective) { + if (this.isValidDirective(stmt)) { + const directive = this.stmtToDirective(stmt); + directives.push(directive); + + if (!hasStrictModeDirective && directive.value.value === "use strict") { + hasStrictModeDirective = true; + this.setStrict(true); + } + + continue; + } + + parsedNonDirective = true; + this.state.strictErrors.clear(); + } + + body.push(stmt); + } + + if (afterBlockParse) { + afterBlockParse.call(this, hasStrictModeDirective); + } + + if (!oldStrict) { + this.setStrict(false); + } + + this.next(); + } + + parseFor(node, init) { + node.init = init; + this.semicolon(false); + node.test = this.match(21) ? null : this.parseExpression(); + this.semicolon(false); + node.update = this.match(19) ? null : this.parseExpression(); + this.expect(19); + node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("for")); + this.scope.exit(); + this.state.labels.pop(); + return this.finishNode(node, "ForStatement"); + } + + parseForIn(node, init, awaitAt) { + const isForIn = this.match(57); + this.next(); + + if (isForIn) { + if (awaitAt > -1) this.unexpected(awaitAt); + } else { + node.await = awaitAt > -1; + } + + if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) { + this.raise(init.start, ErrorMessages.ForInOfLoopInitializer, isForIn ? "for-in" : "for-of"); + } else if (init.type === "AssignmentPattern") { + this.raise(init.start, ErrorMessages.InvalidLhs, "for-loop"); + } + + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssignAllowIn(); + this.expect(19); + node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("for")); + this.scope.exit(); + this.state.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement"); + } + + parseVar(node, isFor, kind) { + const declarations = node.declarations = []; + const isTypescript = this.hasPlugin("typescript"); + node.kind = kind; + + for (;;) { + const decl = this.startNode(); + this.parseVarId(decl, kind); + + if (this.eat(35)) { + decl.init = isFor ? this.parseMaybeAssignDisallowIn() : this.parseMaybeAssignAllowIn(); + } else { + if (kind === "const" && !(this.match(57) || this.isContextual("of"))) { + if (!isTypescript) { + this.raise(this.state.lastTokEnd, ErrorMessages.DeclarationMissingInitializer, "Const declarations"); + } + } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(57) || this.isContextual("of")))) { + this.raise(this.state.lastTokEnd, ErrorMessages.DeclarationMissingInitializer, "Complex binding patterns"); + } + + decl.init = null; + } + + declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(20)) break; + } + + return node; + } + + parseVarId(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLVal(decl.id, "variable declaration", kind === "var" ? BIND_VAR : BIND_LEXICAL, undefined, kind !== "var"); + } + + parseFunction(node, statement = FUNC_NO_FLAGS, isAsync = false) { + const isStatement = statement & FUNC_STATEMENT; + const isHangingStatement = statement & FUNC_HANGING_STATEMENT; + const requireId = !!isStatement && !(statement & FUNC_NULLABLE_ID); + this.initFunction(node, isAsync); + + if (this.match(54) && isHangingStatement) { + this.raise(this.state.start, ErrorMessages.GeneratorInSingleStatementContext); + } + + node.generator = this.eat(54); + + if (isStatement) { + node.id = this.parseFunctionId(requireId); + } + + const oldMaybeInArrowParameters = this.state.maybeInArrowParameters; + this.state.maybeInArrowParameters = false; + this.scope.enter(SCOPE_FUNCTION); + this.prodParam.enter(functionFlags(isAsync, node.generator)); + + if (!isStatement) { + node.id = this.parseFunctionId(); + } + + this.parseFunctionParams(node, false); + this.withSmartMixTopicForbiddingContext(() => { + this.parseFunctionBodyAndFinish(node, isStatement ? "FunctionDeclaration" : "FunctionExpression"); + }); + this.prodParam.exit(); + this.scope.exit(); + + if (isStatement && !isHangingStatement) { + this.registerFunctionStatementId(node); + } + + this.state.maybeInArrowParameters = oldMaybeInArrowParameters; + return node; + } + + parseFunctionId(requireId) { + return requireId || this.match(5) ? this.parseIdentifier() : null; + } + + parseFunctionParams(node, allowModifiers) { + this.expect(18); + this.expressionScope.enter(newParameterDeclarationScope()); + node.params = this.parseBindingList(19, 41, false, allowModifiers); + this.expressionScope.exit(); + } + + registerFunctionStatementId(node) { + if (!node.id) return; + this.scope.declareName(node.id.name, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION, node.id.start); + } + + parseClass(node, isStatement, optionalId) { + this.next(); + this.takeDecorators(node); + const oldStrict = this.state.strict; + this.state.strict = true; + this.parseClassId(node, isStatement, optionalId); + this.parseClassSuper(node); + node.body = this.parseClassBody(!!node.superClass, oldStrict); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression"); + } + + isClassProperty() { + return this.match(35) || this.match(21) || this.match(16); + } + + isClassMethod() { + return this.match(18); + } + + isNonstaticConstructor(method) { + return !method.computed && !method.static && (method.key.name === "constructor" || method.key.value === "constructor"); + } + + parseClassBody(hadSuperClass, oldStrict) { + this.classScope.enter(); + const state = { + hadConstructor: false, + hadSuperClass + }; + let decorators = []; + const classBody = this.startNode(); + classBody.body = []; + this.expect(13); + this.withSmartMixTopicForbiddingContext(() => { + while (!this.match(16)) { + if (this.eat(21)) { + if (decorators.length > 0) { + throw this.raise(this.state.lastTokEnd, ErrorMessages.DecoratorSemicolon); + } + + continue; + } + + if (this.match(32)) { + decorators.push(this.parseDecorator()); + continue; + } + + const member = this.startNode(); + + if (decorators.length) { + member.decorators = decorators; + this.resetStartLocationFromNode(member, decorators[0]); + decorators = []; + } + + this.parseClassMember(classBody, member, state); + + if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) { + this.raise(member.start, ErrorMessages.DecoratorConstructor); + } + } + }); + this.state.strict = oldStrict; + this.next(); + + if (decorators.length) { + throw this.raise(this.state.start, ErrorMessages.TrailingDecorator); + } + + this.classScope.exit(); + return this.finishNode(classBody, "ClassBody"); + } + + parseClassMemberFromModifier(classBody, member) { + const key = this.parseIdentifier(true); + + if (this.isClassMethod()) { + const method = member; + method.kind = "method"; + method.computed = false; + method.key = key; + method.static = false; + this.pushClassMethod(classBody, method, false, false, false, false); + return true; + } else if (this.isClassProperty()) { + const prop = member; + prop.computed = false; + prop.key = key; + prop.static = false; + classBody.body.push(this.parseClassProperty(prop)); + return true; + } + + this.resetPreviousNodeTrailingComments(key); + return false; + } + + parseClassMember(classBody, member, state) { + const isStatic = this.isContextual("static"); + + if (isStatic) { + if (this.parseClassMemberFromModifier(classBody, member)) { + return; + } + + if (this.eat(13)) { + this.parseClassStaticBlock(classBody, member); + return; + } + } + + this.parseClassMemberWithIsStatic(classBody, member, state, isStatic); + } + + parseClassMemberWithIsStatic(classBody, member, state, isStatic) { + const publicMethod = member; + const privateMethod = member; + const publicProp = member; + const privateProp = member; + const method = publicMethod; + const publicMember = publicMethod; + member.static = isStatic; + + if (this.eat(54)) { + method.kind = "method"; + const isPrivateName = this.match(6); + this.parseClassElementName(method); + + if (isPrivateName) { + this.pushClassPrivateMethod(classBody, privateMethod, true, false); + return; + } + + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsGenerator); + } + + this.pushClassMethod(classBody, publicMethod, true, false, false, false); + return; + } + + const isContextual = this.match(5) && !this.state.containsEsc; + const isPrivate = this.match(6); + const key = this.parseClassElementName(member); + const maybeQuestionTokenStart = this.state.start; + this.parsePostMemberNameModifiers(publicMember); + + if (this.isClassMethod()) { + method.kind = "method"; + + if (isPrivate) { + this.pushClassPrivateMethod(classBody, privateMethod, false, false); + return; + } + + const isConstructor = this.isNonstaticConstructor(publicMethod); + let allowsDirectSuper = false; + + if (isConstructor) { + publicMethod.kind = "constructor"; + + if (state.hadConstructor && !this.hasPlugin("typescript")) { + this.raise(key.start, ErrorMessages.DuplicateConstructor); + } + + if (isConstructor && this.hasPlugin("typescript") && member.override) { + this.raise(key.start, ErrorMessages.OverrideOnConstructor); + } + + state.hadConstructor = true; + allowsDirectSuper = state.hadSuperClass; + } + + this.pushClassMethod(classBody, publicMethod, false, false, isConstructor, allowsDirectSuper); + } else if (this.isClassProperty()) { + if (isPrivate) { + this.pushClassPrivateProperty(classBody, privateProp); + } else { + this.pushClassProperty(classBody, publicProp); + } + } else if (isContextual && key.name === "async" && !this.isLineTerminator()) { + this.resetPreviousNodeTrailingComments(key); + const isGenerator = this.eat(54); + + if (publicMember.optional) { + this.unexpected(maybeQuestionTokenStart); + } + + method.kind = "method"; + const isPrivate = this.match(6); + this.parseClassElementName(method); + this.parsePostMemberNameModifiers(publicMember); + + if (isPrivate) { + this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true); + } else { + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAsync); + } + + this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false); + } + } else if (isContextual && (key.name === "get" || key.name === "set") && !(this.match(54) && this.isLineTerminator())) { + this.resetPreviousNodeTrailingComments(key); + method.kind = key.name; + const isPrivate = this.match(6); + this.parseClassElementName(publicMethod); + + if (isPrivate) { + this.pushClassPrivateMethod(classBody, privateMethod, false, false); + } else { + if (this.isNonstaticConstructor(publicMethod)) { + this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAccessor); + } + + this.pushClassMethod(classBody, publicMethod, false, false, false, false); + } + + this.checkGetterSetterParams(publicMethod); + } else if (this.isLineTerminator()) { + if (isPrivate) { + this.pushClassPrivateProperty(classBody, privateProp); + } else { + this.pushClassProperty(classBody, publicProp); + } + } else { + this.unexpected(); + } + } + + parseClassElementName(member) { + const { + type, + value, + start + } = this.state; + + if ((type === 5 || type === 4) && member.static && value === "prototype") { + this.raise(start, ErrorMessages.StaticPrototype); + } + + if (type === 6 && value === "constructor") { + this.raise(start, ErrorMessages.ConstructorClassPrivateField); + } + + return this.parsePropertyName(member, true); + } + + parseClassStaticBlock(classBody, member) { + var _member$decorators; + + this.expectPlugin("classStaticBlock", member.start); + this.scope.enter(SCOPE_CLASS | SCOPE_STATIC_BLOCK | SCOPE_SUPER); + const oldLabels = this.state.labels; + this.state.labels = []; + this.prodParam.enter(PARAM); + const body = member.body = []; + this.parseBlockOrModuleBlockBody(body, undefined, false, 16); + this.prodParam.exit(); + this.scope.exit(); + this.state.labels = oldLabels; + classBody.body.push(this.finishNode(member, "StaticBlock")); + + if ((_member$decorators = member.decorators) != null && _member$decorators.length) { + this.raise(member.start, ErrorMessages.DecoratorStaticBlock); + } + } + + pushClassProperty(classBody, prop) { + if (!prop.computed && (prop.key.name === "constructor" || prop.key.value === "constructor")) { + this.raise(prop.key.start, ErrorMessages.ConstructorClassField); + } + + classBody.body.push(this.parseClassProperty(prop)); + } + + pushClassPrivateProperty(classBody, prop) { + const node = this.parseClassPrivateProperty(prop); + classBody.body.push(node); + this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), CLASS_ELEMENT_OTHER, node.key.start); + } + + pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { + classBody.body.push(this.parseMethod(method, isGenerator, isAsync, isConstructor, allowsDirectSuper, "ClassMethod", true)); + } + + pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { + const node = this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true); + classBody.body.push(node); + const kind = node.kind === "get" ? node.static ? CLASS_ELEMENT_STATIC_GETTER : CLASS_ELEMENT_INSTANCE_GETTER : node.kind === "set" ? node.static ? CLASS_ELEMENT_STATIC_SETTER : CLASS_ELEMENT_INSTANCE_SETTER : CLASS_ELEMENT_OTHER; + this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), kind, node.key.start); + } + + parsePostMemberNameModifiers(methodOrProp) {} + + parseClassPrivateProperty(node) { + this.parseInitializer(node); + this.semicolon(); + return this.finishNode(node, "ClassPrivateProperty"); + } + + parseClassProperty(node) { + this.parseInitializer(node); + this.semicolon(); + return this.finishNode(node, "ClassProperty"); + } + + parseInitializer(node) { + this.scope.enter(SCOPE_CLASS | SCOPE_SUPER); + this.expressionScope.enter(newExpressionScope()); + this.prodParam.enter(PARAM); + node.value = this.eat(35) ? this.parseMaybeAssignAllowIn() : null; + this.expressionScope.exit(); + this.prodParam.exit(); + this.scope.exit(); + } + + parseClassId(node, isStatement, optionalId, bindingType = BIND_CLASS) { + if (this.match(5)) { + node.id = this.parseIdentifier(); + + if (isStatement) { + this.checkLVal(node.id, "class name", bindingType); + } + } else { + if (optionalId || !isStatement) { + node.id = null; + } else { + this.unexpected(null, ErrorMessages.MissingClassName); + } + } + } + + parseClassSuper(node) { + node.superClass = this.eat(80) ? this.parseExprSubscripts() : null; + } + + parseExport(node) { + const hasDefault = this.maybeParseExportDefaultSpecifier(node); + const parseAfterDefault = !hasDefault || this.eat(20); + const hasStar = parseAfterDefault && this.eatExportStar(node); + const hasNamespace = hasStar && this.maybeParseExportNamespaceSpecifier(node); + const parseAfterNamespace = parseAfterDefault && (!hasNamespace || this.eat(20)); + const isFromRequired = hasDefault || hasStar; + + if (hasStar && !hasNamespace) { + if (hasDefault) this.unexpected(); + this.parseExportFrom(node, true); + return this.finishNode(node, "ExportAllDeclaration"); + } + + const hasSpecifiers = this.maybeParseExportNamedSpecifiers(node); + + if (hasDefault && parseAfterDefault && !hasStar && !hasSpecifiers || hasNamespace && parseAfterNamespace && !hasSpecifiers) { + throw this.unexpected(null, 13); + } + + let hasDeclaration; + + if (isFromRequired || hasSpecifiers) { + hasDeclaration = false; + this.parseExportFrom(node, isFromRequired); + } else { + hasDeclaration = this.maybeParseExportDeclaration(node); + } + + if (isFromRequired || hasSpecifiers || hasDeclaration) { + this.checkExport(node, true, false, !!node.source); + return this.finishNode(node, "ExportNamedDeclaration"); + } + + if (this.eat(64)) { + node.declaration = this.parseExportDefaultExpression(); + this.checkExport(node, true, true); + return this.finishNode(node, "ExportDefaultDeclaration"); + } + + throw this.unexpected(null, 13); + } + + eatExportStar(node) { + return this.eat(54); + } + + maybeParseExportDefaultSpecifier(node) { + if (this.isExportDefaultSpecifier()) { + this.expectPlugin("exportDefaultFrom"); + const specifier = this.startNode(); + specifier.exported = this.parseIdentifier(true); + node.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")]; + return true; + } + + return false; + } + + maybeParseExportNamespaceSpecifier(node) { + if (this.isContextual("as")) { + if (!node.specifiers) node.specifiers = []; + const specifier = this.startNodeAt(this.state.lastTokStart, this.state.lastTokStartLoc); + this.next(); + specifier.exported = this.parseModuleExportName(); + node.specifiers.push(this.finishNode(specifier, "ExportNamespaceSpecifier")); + return true; + } + + return false; + } + + maybeParseExportNamedSpecifiers(node) { + if (this.match(13)) { + if (!node.specifiers) node.specifiers = []; + node.specifiers.push(...this.parseExportSpecifiers()); + node.source = null; + node.declaration = null; + return true; + } + + return false; + } + + maybeParseExportDeclaration(node) { + if (this.shouldParseExportDeclaration()) { + node.specifiers = []; + node.source = null; + node.declaration = this.parseExportDeclaration(node); + return true; + } + + return false; + } + + isAsyncFunction() { + if (!this.isContextual("async")) return false; + const next = this.nextTokenStart(); + return !lineBreak.test(this.input.slice(this.state.pos, next)) && this.isUnparsedContextual(next, "function"); + } + + parseExportDefaultExpression() { + const expr = this.startNode(); + const isAsync = this.isAsyncFunction(); + + if (this.match(67) || isAsync) { + this.next(); + + if (isAsync) { + this.next(); + } + + return this.parseFunction(expr, FUNC_STATEMENT | FUNC_NULLABLE_ID, isAsync); + } else if (this.match(79)) { + return this.parseClass(expr, true, true); + } else if (this.match(32)) { + if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.raise(this.state.start, ErrorMessages.DecoratorBeforeExport); + } + + this.parseDecorators(false); + return this.parseClass(expr, true, true); + } else if (this.match(74) || this.match(73) || this.isLet()) { + throw this.raise(this.state.start, ErrorMessages.UnsupportedDefaultExport); + } else { + const res = this.parseMaybeAssignAllowIn(); + this.semicolon(); + return res; + } + } + + parseExportDeclaration(node) { + return this.parseStatement(null); + } + + isExportDefaultSpecifier() { + if (this.match(5)) { + const value = this.state.value; + + if (value === "async" && !this.state.containsEsc || value === "let") { + return false; + } + + if ((value === "type" || value === "interface") && !this.state.containsEsc) { + const l = this.lookahead(); + + if (l.type === 5 && l.value !== "from" || l.type === 13) { + this.expectOnePlugin(["flow", "typescript"]); + return false; + } + } + } else if (!this.match(64)) { + return false; + } + + const next = this.nextTokenStart(); + const hasFrom = this.isUnparsedContextual(next, "from"); + + if (this.input.charCodeAt(next) === 44 || this.match(5) && hasFrom) { + return true; + } + + if (this.match(64) && hasFrom) { + const nextAfterFrom = this.input.charCodeAt(this.nextTokenStartSince(next + 4)); + return nextAfterFrom === 34 || nextAfterFrom === 39; + } + + return false; + } + + parseExportFrom(node, expect) { + if (this.eatContextual("from")) { + node.source = this.parseImportSource(); + this.checkExport(node); + const assertions = this.maybeParseImportAssertions(); + + if (assertions) { + node.assertions = assertions; + } + } else { + if (expect) { + this.unexpected(); + } else { + node.source = null; + } + } + + this.semicolon(); + } + + shouldParseExportDeclaration() { + const { + type + } = this.state; + + if (type === 32) { + this.expectOnePlugin(["decorators", "decorators-legacy"]); + + if (this.hasPlugin("decorators")) { + if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { + this.unexpected(this.state.start, ErrorMessages.DecoratorBeforeExport); + } else { + return true; + } + } + } + + return type === 73 || type === 74 || type === 67 || type === 79 || this.isLet() || this.isAsyncFunction(); + } + + checkExport(node, checkNames, isDefault, isFrom) { + if (checkNames) { + if (isDefault) { + this.checkDuplicateExports(node, "default"); + + if (this.hasPlugin("exportDefaultFrom")) { + var _declaration$extra; + + const declaration = node.declaration; + + if (declaration.type === "Identifier" && declaration.name === "from" && declaration.end - declaration.start === 4 && !((_declaration$extra = declaration.extra) != null && _declaration$extra.parenthesized)) { + this.raise(declaration.start, ErrorMessages.ExportDefaultFromAsIdentifier); + } + } + } else if (node.specifiers && node.specifiers.length) { + for (const specifier of node.specifiers) { + const { + exported + } = specifier; + const exportedName = exported.type === "Identifier" ? exported.name : exported.value; + this.checkDuplicateExports(specifier, exportedName); + + if (!isFrom && specifier.local) { + const { + local + } = specifier; + + if (local.type !== "Identifier") { + this.raise(specifier.start, ErrorMessages.ExportBindingIsString, local.value, exportedName); + } else { + this.checkReservedWord(local.name, local.start, true, false); + this.scope.checkLocalExport(local); + } + } + } + } else if (node.declaration) { + if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") { + const id = node.declaration.id; + if (!id) throw new Error("Assertion failure"); + this.checkDuplicateExports(node, id.name); + } else if (node.declaration.type === "VariableDeclaration") { + for (const declaration of node.declaration.declarations) { + this.checkDeclaration(declaration.id); + } + } + } + } + + const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; + + if (currentContextDecorators.length) { + throw this.raise(node.start, ErrorMessages.UnsupportedDecoratorExport); + } + } + + checkDeclaration(node) { + if (node.type === "Identifier") { + this.checkDuplicateExports(node, node.name); + } else if (node.type === "ObjectPattern") { + for (const prop of node.properties) { + this.checkDeclaration(prop); + } + } else if (node.type === "ArrayPattern") { + for (const elem of node.elements) { + if (elem) { + this.checkDeclaration(elem); + } + } + } else if (node.type === "ObjectProperty") { + this.checkDeclaration(node.value); + } else if (node.type === "RestElement") { + this.checkDeclaration(node.argument); + } else if (node.type === "AssignmentPattern") { + this.checkDeclaration(node.left); + } + } + + checkDuplicateExports(node, name) { + if (this.exportedIdentifiers.has(name)) { + this.raise(node.start, name === "default" ? ErrorMessages.DuplicateDefaultExport : ErrorMessages.DuplicateExport, name); + } + + this.exportedIdentifiers.add(name); + } + + parseExportSpecifiers() { + const nodes = []; + let first = true; + this.expect(13); + + while (!this.eat(16)) { + if (first) { + first = false; + } else { + this.expect(20); + if (this.eat(16)) break; + } + + const node = this.startNode(); + const isString = this.match(4); + const local = this.parseModuleExportName(); + node.local = local; + + if (this.eatContextual("as")) { + node.exported = this.parseModuleExportName(); + } else if (isString) { + node.exported = cloneStringLiteral(local); + } else { + node.exported = cloneIdentifier(local); + } + + nodes.push(this.finishNode(node, "ExportSpecifier")); + } + + return nodes; + } + + parseModuleExportName() { + if (this.match(4)) { + const result = this.parseStringLiteral(this.state.value); + const surrogate = result.value.match(loneSurrogate); + + if (surrogate) { + this.raise(result.start, ErrorMessages.ModuleExportNameHasLoneSurrogate, surrogate[0].charCodeAt(0).toString(16)); + } + + return result; + } + + return this.parseIdentifier(true); + } + + parseImport(node) { + node.specifiers = []; + + if (!this.match(4)) { + const hasDefault = this.maybeParseDefaultImportSpecifier(node); + const parseNext = !hasDefault || this.eat(20); + const hasStar = parseNext && this.maybeParseStarImportSpecifier(node); + if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node); + this.expectContextual("from"); + } + + node.source = this.parseImportSource(); + const assertions = this.maybeParseImportAssertions(); + + if (assertions) { + node.assertions = assertions; + } else { + const attributes = this.maybeParseModuleAttributes(); + + if (attributes) { + node.attributes = attributes; + } + } + + this.semicolon(); + return this.finishNode(node, "ImportDeclaration"); + } + + parseImportSource() { + if (!this.match(4)) this.unexpected(); + return this.parseExprAtom(); + } + + shouldParseDefaultImport(node) { + return this.match(5); + } + + parseImportSpecifierLocal(node, specifier, type, contextDescription) { + specifier.local = this.parseIdentifier(); + this.checkLVal(specifier.local, contextDescription, BIND_LEXICAL); + node.specifiers.push(this.finishNode(specifier, type)); + } + + parseAssertEntries() { + const attrs = []; + const attrNames = new Set(); + + do { + if (this.match(16)) { + break; + } + + const node = this.startNode(); + const keyName = this.state.value; + + if (attrNames.has(keyName)) { + this.raise(this.state.start, ErrorMessages.ModuleAttributesWithDuplicateKeys, keyName); + } + + attrNames.add(keyName); + + if (this.match(4)) { + node.key = this.parseStringLiteral(keyName); + } else { + node.key = this.parseIdentifier(true); + } + + this.expect(22); + + if (!this.match(4)) { + throw this.unexpected(this.state.start, ErrorMessages.ModuleAttributeInvalidValue); + } + + node.value = this.parseStringLiteral(this.state.value); + this.finishNode(node, "ImportAttribute"); + attrs.push(node); + } while (this.eat(20)); + + return attrs; + } + + maybeParseModuleAttributes() { + if (this.match(75) && !this.hasPrecedingLineBreak()) { + this.expectPlugin("moduleAttributes"); + this.next(); + } else { + if (this.hasPlugin("moduleAttributes")) return []; + return null; + } + + const attrs = []; + const attributes = new Set(); + + do { + const node = this.startNode(); + node.key = this.parseIdentifier(true); + + if (node.key.name !== "type") { + this.raise(node.key.start, ErrorMessages.ModuleAttributeDifferentFromType, node.key.name); + } + + if (attributes.has(node.key.name)) { + this.raise(node.key.start, ErrorMessages.ModuleAttributesWithDuplicateKeys, node.key.name); + } + + attributes.add(node.key.name); + this.expect(22); + + if (!this.match(4)) { + throw this.unexpected(this.state.start, ErrorMessages.ModuleAttributeInvalidValue); + } + + node.value = this.parseStringLiteral(this.state.value); + this.finishNode(node, "ImportAttribute"); + attrs.push(node); + } while (this.eat(20)); + + return attrs; + } + + maybeParseImportAssertions() { + if (this.isContextual("assert") && !this.hasPrecedingLineBreak()) { + this.expectPlugin("importAssertions"); + this.next(); + } else { + if (this.hasPlugin("importAssertions")) return []; + return null; + } + + this.eat(13); + const attrs = this.parseAssertEntries(); + this.eat(16); + return attrs; + } + + maybeParseDefaultImportSpecifier(node) { + if (this.shouldParseDefaultImport(node)) { + this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier", "default import specifier"); + return true; + } + + return false; + } + + maybeParseStarImportSpecifier(node) { + if (this.match(54)) { + const specifier = this.startNode(); + this.next(); + this.expectContextual("as"); + this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier", "import namespace specifier"); + return true; + } + + return false; + } + + parseNamedImportSpecifiers(node) { + let first = true; + this.expect(13); + + while (!this.eat(16)) { + if (first) { + first = false; + } else { + if (this.eat(22)) { + throw this.raise(this.state.start, ErrorMessages.DestructureNamedImport); + } + + this.expect(20); + if (this.eat(16)) break; + } + + this.parseImportSpecifier(node); + } + } + + parseImportSpecifier(node) { + const specifier = this.startNode(); + const importedIsString = this.match(4); + specifier.imported = this.parseModuleExportName(); + + if (this.eatContextual("as")) { + specifier.local = this.parseIdentifier(); + } else { + const { + imported + } = specifier; + + if (importedIsString) { + throw this.raise(specifier.start, ErrorMessages.ImportBindingIsString, imported.value); + } + + this.checkReservedWord(imported.name, specifier.start, true, true); + specifier.local = cloneIdentifier(imported); + } + + this.checkLVal(specifier.local, "import specifier", BIND_LEXICAL); + node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + } + + isThisParam(param) { + return param.type === "Identifier" && param.name === "this"; + } + + } + + class Parser extends StatementParser { + constructor(options, input) { + options = getOptions(options); + super(options, input); + this.options = options; + this.initializeScopes(); + this.plugins = pluginsMap(this.options.plugins); + this.filename = options.sourceFilename; + } + + getScopeHandler() { + return ScopeHandler; + } + + parse() { + this.enterInitialScopes(); + const file = this.startNode(); + const program = this.startNode(); + this.nextToken(); + file.errors = null; + this.parseTopLevel(file, program); + file.errors = this.state.errors; + return file; + } + + } + + function pluginsMap(plugins) { + const pluginMap = new Map(); + + for (const plugin of plugins) { + const [name, options] = Array.isArray(plugin) ? plugin : [plugin, {}]; + if (!pluginMap.has(name)) pluginMap.set(name, options || {}); + } + + return pluginMap; + } + + function parse$1(input, options) { + var _options; + + if (((_options = options) == null ? void 0 : _options.sourceType) === "unambiguous") { + options = Object.assign({}, options); + + try { + options.sourceType = "module"; + const parser = getParser(options, input); + const ast = parser.parse(); + + if (parser.sawUnambiguousESM) { + return ast; + } + + if (parser.ambiguousScriptDifferentAst) { + try { + options.sourceType = "script"; + return getParser(options, input).parse(); + } catch (_unused) {} + } else { + ast.program.sourceType = "script"; + } + + return ast; + } catch (moduleError) { + try { + options.sourceType = "script"; + return getParser(options, input).parse(); + } catch (_unused2) {} + + throw moduleError; + } + } else { + return getParser(options, input).parse(); + } + } + function parseExpression(input, options) { + const parser = getParser(options, input); + + if (parser.options.strictMode) { + parser.state.strict = true; + } + + return parser.getExpression(); + } + + function generateExportedTokenTypes(internalTokenTypes) { + const tokenTypes = {}; + + for (const typeName of Object.keys(internalTokenTypes)) { + tokenTypes[typeName] = getExportedToken(internalTokenTypes[typeName]); + } + + return tokenTypes; + } + + const tokTypes = generateExportedTokenTypes(tt); + + function getParser(options, input) { + let cls = Parser; + + if (options != null && options.plugins) { + validatePlugins(options.plugins); + cls = getParserClass(options.plugins); + } + + return new cls(options, input); + } + + const parserClassCache = {}; + + function getParserClass(pluginsFromOptions) { + const pluginList = mixinPluginNames.filter(name => hasPlugin(pluginsFromOptions, name)); + const key = pluginList.join("/"); + let cls = parserClassCache[key]; + + if (!cls) { + cls = Parser; + + for (const plugin of pluginList) { + cls = mixinPlugins[plugin](cls); + } + + parserClassCache[key] = cls; + } + + return cls; + } + + var parse_1 = lib$1.parse = parse$1; + lib$1.parseExpression = parseExpression; + lib$1.tokTypes = tokTypes; + + /* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + + const cachedSources = new Map(); + + function setSource(source) { + cachedSources.set(source.id, source); + } + + function getSource(sourceId) { + const source = cachedSources.get(sourceId); + if (!source) { + throw new Error(`Parser: source ${sourceId} was not provided.`); + } + + return source; + } + + function clearSources() { + cachedSources.clear(); + } + + let ASTs = new Map(); + + function _parse(code, opts) { + return parse_1(code, { + ...opts, + tokens: true, + }); + } + + const sourceOptions = { + generated: { + sourceType: "unambiguous", + tokens: true, + plugins: [ + "classStaticBlock", + "classPrivateProperties", + "classPrivateMethods", + "classProperties", + "objectRestSpread", + "optionalChaining", + "privateIn", + "nullishCoalescingOperator", + ], + }, + original: { + sourceType: "unambiguous", + tokens: true, + plugins: [ + "jsx", + "flow", + "doExpressions", + "optionalChaining", + "nullishCoalescingOperator", + "decorators-legacy", + "objectRestSpread", + "classStaticBlock", + "classPrivateProperties", + "classPrivateMethods", + "classProperties", + "exportDefaultFrom", + "exportNamespaceFrom", + "asyncGenerators", + "functionBind", + "functionSent", + "dynamicImport", + "react-jsx", + ], + }, + }; + + function parse(text, opts) { + let ast = {}; + if (!text) { + return ast; + } + + try { + ast = _parse(text, opts); + } catch (error) { + console.error(error); + } + + return ast; + } + + // Custom parser for parse-script-tags that adapts its input structure to + // our parser's signature + function htmlParser({ source, line }) { + return parse(source, { startLine: line, ...sourceOptions.generated }); + } + + const VUE_COMPONENT_START = /^\s* + p !== "flow" && + p !== "decorators" && + p !== "decorators2" && + (p !== "jsx" || contentType.match(/typescript-jsx/)) + ), + "decorators-legacy", + "typescript", + ], + }; + ast = parse(source.text, options); + } + + ASTs.set(source.id, ast); + return ast; + } + + function clearASTs() { + ASTs = new Map(); + } + + function traverseAst(sourceId, visitor, state) { + const ast = getAst(sourceId); + if (!ast || !Object.keys(ast).length) { + return null; + } + + lib$6.traverse(ast, visitor, state); + return ast; + } + + function hasNode(rootNode, predicate) { + try { + lib$6.traverse(rootNode, { + enter: (node, ancestors) => { + if (predicate(node, ancestors)) { + throw new Error("MATCH"); + } + }, + }); + } catch (e) { + if (e.message === "MATCH") { + return true; + } + } + return false; + } + + function replaceNode$1(ancestors, node) { + const parent = ancestors[ancestors.length - 1]; + + if (typeof parent.index === "number") { + if (Array.isArray(node)) { + parent.node[parent.key].splice(parent.index, 1, ...node); + } else { + parent.node[parent.key][parent.index] = node; + } + } else { + parent.node[parent.key] = node; + } + } + + var lib = {}; + + var sourceMap$1 = {}; + + var sourceMap = {}; + + var sourceMapGenerator = {}; + + var base64Vlq = {}; + + var base64$1 = {}; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); + + /** + * Encode an integer in the range of 0 to 63 to a single base 64 digit. + */ + base64$1.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; + } + throw new TypeError("Must be between 0 and 63: " + number); + }; + + /** + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. + */ + base64$1.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + + var littleA = 97; // 'a' + var littleZ = 122; // 'z' + + var zero = 48; // '0' + var nine = 57; // '9' + + var plus = 43; // '+' + var slash = 47; // '/' + + var littleOffset = 26; + var numberOffset = 52; + + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); + } + + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } + + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); + } + + // 62: + + if (charCode == plus) { + return 62; + } + + // 63: / + if (charCode == slash) { + return 63; + } + + // Invalid base64 digit. + return -1; + }; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + * + * Based on the Base 64 VLQ implementation in Closure Compiler: + * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java + * + * Copyright 2011 The Closure Compiler Authors. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + var base64 = base64$1; + + // A single base 64 digit can contain 6 bits of data. For the base 64 variable + // length quantities we use in the source map spec, the first bit is the sign, + // the next four bits are the actual value, and the 6th bit is the + // continuation bit. The continuation bit tells us whether there are more + // digits in this value following this digit. + // + // Continuation + // | Sign + // | | + // V V + // 101011 + + var VLQ_BASE_SHIFT = 5; + + // binary: 100000 + var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + + // binary: 011111 + var VLQ_BASE_MASK = VLQ_BASE - 1; + + // binary: 100000 + var VLQ_CONTINUATION_BIT = VLQ_BASE; + + /** + * Converts from a two-complement value to a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) + * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) + */ + function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; + } + + /** + * Converts to a two-complement value from a value where the sign bit is + * placed in the least significant bit. For example, as decimals: + * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 + * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 + */ + function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; + } + + /** + * Returns the base 64 VLQ encoded value. + */ + base64Vlq.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; + + var vlq = toVLQSigned(aValue); + + do { + digit = vlq & VLQ_BASE_MASK; + vlq >>>= VLQ_BASE_SHIFT; + if (vlq > 0) { + // There are still more digits in this value, so we must make sure the + // continuation bit is marked. + digit |= VLQ_CONTINUATION_BIT; + } + encoded += base64.encode(digit); + } while (vlq > 0); + + return encoded; + }; + + /** + * Decodes the next base 64 VLQ value from the given string and returns the + * value and the rest of the string via the out parameter. + */ + base64Vlq.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { + var strLen = aStr.length; + var result = 0; + var shift = 0; + var continuation, digit; + + do { + if (aIndex >= strLen) { + throw new Error("Expected more digits in base 64 VLQ value."); + } + + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } + + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); + + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; + }; + + var util$5 = {}; + + (function (exports) { + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + /** + * This is a helper function for getting values from parameter/options + * objects. + * + * @param args The object we are extracting values from + * @param name The name of the property we are getting. + * @param defaultValue An optional value to return if the property is missing + * from the object. If this is not specified and the property is missing, an + * error will be thrown. + */ + function getArg(aArgs, aName, aDefaultValue) { + if (aName in aArgs) { + return aArgs[aName]; + } else if (arguments.length === 3) { + return aDefaultValue; + } else { + throw new Error('"' + aName + '" is a required argument.'); + } + } + exports.getArg = getArg; + + var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; + var dataUrlRegexp = /^data:.+\,.+$/; + + function urlParse(aUrl) { + var match = aUrl.match(urlRegexp); + if (!match) { + return null; + } + return { + scheme: match[1], + auth: match[2], + host: match[3], + port: match[4], + path: match[5] + }; + } + exports.urlParse = urlParse; + + function urlGenerate(aParsedUrl) { + var url = ''; + if (aParsedUrl.scheme) { + url += aParsedUrl.scheme + ':'; + } + url += '//'; + if (aParsedUrl.auth) { + url += aParsedUrl.auth + '@'; + } + if (aParsedUrl.host) { + url += aParsedUrl.host; + } + if (aParsedUrl.port) { + url += ":" + aParsedUrl.port; + } + if (aParsedUrl.path) { + url += aParsedUrl.path; + } + return url; + } + exports.urlGenerate = urlGenerate; + + /** + * Normalizes a path, or the path portion of a URL: + * + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. + * + * Based on code in the Node.js 'path' core module. + * + * @param aPath The path or url to normalize. + */ + function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; + } + path = url.path; + } + var isAbsolute = exports.isAbsolute(path); + + var parts = path.split(/\/+/); + for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { + part = parts[i]; + if (part === '.') { + parts.splice(i, 1); + } else if (part === '..') { + up++; + } else if (up > 0) { + if (part === '') { + // The first part is blank if the path is absolute. Trying to go + // above the root is a no-op. Therefore we can remove all '..' parts + // directly after the root. + parts.splice(i + 1, up); + up = 0; + } else { + parts.splice(i, 2); + up--; + } + } + } + path = parts.join('/'); + + if (path === '') { + path = isAbsolute ? '/' : '.'; + } + + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; + } + exports.normalize = normalize; + + /** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a + * scheme-relative URL: Then the scheme of aRoot, if any, is prepended + * first. + * - Otherwise aPath is a path. If aRoot is a URL, then its path portion + * is updated with the result and aRoot is returned. Otherwise the result + * is returned. + * - If aPath is absolute, the result is aPath. + * - Otherwise the two paths are joined with a slash. + * - Joining for example 'http://' and 'www.example.com' is also supported. + */ + function join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } + + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } + + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } + + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } + + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; + } + exports.join = join; + + exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); + }; + + /** + * Make a path relative to a URL or another path. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. + */ + function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + + aRoot = aRoot.replace(/\/$/, ''); + + // It is possible for the path to be above the root. In this case, simply + // checking whether the root is a prefix of the path won't work. Instead, we + // need to remove components from the root one by one, until either we find + // a prefix that fits, or we run out of components to remove. + var level = 0; + while (aPath.indexOf(aRoot + '/') !== 0) { + var index = aRoot.lastIndexOf("/"); + if (index < 0) { + return aPath; + } + + // If the only part of the root that is left is the scheme (i.e. http://, + // file:///, etc.), one or more slashes (/), or simply nothing at all, we + // have exhausted all components, so the path is not relative to the root. + aRoot = aRoot.slice(0, index); + if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { + return aPath; + } + + ++level; + } + + // Make sure we add a "../" for each component we removed from the root. + return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); + } + exports.relative = relative; + + var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); + }()); + + function identity (s) { + return s; + } + + /** + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. + * + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr + */ + function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } + + return aStr; + } + exports.toSetString = supportsNullProto ? identity : toSetString; + + function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } + + return aStr; + } + exports.fromSetString = supportsNullProto ? identity : fromSetString; + + function isProtoString(s) { + if (!s) { + return false; + } + + var length = s.length; + + if (length < 9 /* "__proto__".length */) { + return false; + } + + if (s.charCodeAt(length - 1) !== 95 /* '_' */ || + s.charCodeAt(length - 2) !== 95 /* '_' */ || + s.charCodeAt(length - 3) !== 111 /* 'o' */ || + s.charCodeAt(length - 4) !== 116 /* 't' */ || + s.charCodeAt(length - 5) !== 111 /* 'o' */ || + s.charCodeAt(length - 6) !== 114 /* 'r' */ || + s.charCodeAt(length - 7) !== 112 /* 'p' */ || + s.charCodeAt(length - 8) !== 95 /* '_' */ || + s.charCodeAt(length - 9) !== 95 /* '_' */) { + return false; + } + + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; + } + } + + return true; + } + + /** + * Comparator between two mappings where the original positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same original source/line/column, but different generated + * line and column the same. Useful when searching for a mapping with a + * stubbed out mapping. + */ + function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByOriginalPositions = compareByOriginalPositions; + + /** + * Comparator between two mappings with deflated source and name indices where + * the generated positions are compared. + * + * Optionally pass in `true` as `onlyCompareGenerated` to consider two + * mappings with the same generated line and column, but different + * source/name/original line and column the same. Useful when searching for a + * mapping with a stubbed out mapping. + */ + function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } + + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; + } + exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + + function strcmp(aStr1, aStr2) { + if (aStr1 === aStr2) { + return 0; + } + + if (aStr1 > aStr2) { + return 1; + } + + return -1; + } + + /** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ + function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } + + return strcmp(mappingA.name, mappingB.name); + } + exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; + } (util$5)); + + var arraySet = {}; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util$4 = util$5; + var has = Object.prototype.hasOwnProperty; + var hasNativeMap = typeof Map !== "undefined"; + + /** + * A data structure which is a combination of an array and a set. Adding a new + * member is O(1), testing for membership is O(1), and finding the index of an + * element is O(1). Removing elements from the set is not supported. Only + * strings are supported for membership. + */ + function ArraySet$2() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); + } + + /** + * Static method for creating ArraySet instances from an existing array. + */ + ArraySet$2.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { + var set = new ArraySet$2(); + for (var i = 0, len = aArray.length; i < len; i++) { + set.add(aArray[i], aAllowDuplicates); + } + return set; + }; + + /** + * Return how many unique items are in this ArraySet. If duplicates have been + * added, than those do not count towards the size. + * + * @returns Number + */ + ArraySet$2.prototype.size = function ArraySet_size() { + return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; + }; + + /** + * Add the given string to this set. + * + * @param String aStr + */ + ArraySet$2.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { + var sStr = hasNativeMap ? aStr : util$4.toSetString(aStr); + var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr); + var idx = this._array.length; + if (!isDuplicate || aAllowDuplicates) { + this._array.push(aStr); + } + if (!isDuplicate) { + if (hasNativeMap) { + this._set.set(aStr, idx); + } else { + this._set[sStr] = idx; + } + } + }; + + /** + * Is the given string a member of this set? + * + * @param String aStr + */ + ArraySet$2.prototype.has = function ArraySet_has(aStr) { + if (hasNativeMap) { + return this._set.has(aStr); + } else { + var sStr = util$4.toSetString(aStr); + return has.call(this._set, sStr); + } + }; + + /** + * What is the index of the given string in the array? + * + * @param String aStr + */ + ArraySet$2.prototype.indexOf = function ArraySet_indexOf(aStr) { + if (hasNativeMap) { + var idx = this._set.get(aStr); + if (idx >= 0) { + return idx; + } + } else { + var sStr = util$4.toSetString(aStr); + if (has.call(this._set, sStr)) { + return this._set[sStr]; + } + } + + throw new Error('"' + aStr + '" is not in the set.'); + }; + + /** + * What is the element at the given index? + * + * @param Number aIdx + */ + ArraySet$2.prototype.at = function ArraySet_at(aIdx) { + if (aIdx >= 0 && aIdx < this._array.length) { + return this._array[aIdx]; + } + throw new Error('No element indexed by ' + aIdx); + }; + + /** + * Returns the array representation of this set (which has the proper indices + * indicated by indexOf). Note that this is a copy of the internal array used + * for storing the members so that no one can mess with internal state. + */ + ArraySet$2.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); + }; + + arraySet.ArraySet = ArraySet$2; + + var mappingList = {}; + + /* + * Copyright 2014 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util$3 = util$5; + + /** + * Determine whether mappingB is after mappingA with respect to generated + * position. + */ + function generatedPositionAfter(mappingA, mappingB) { + // Optimized for most common case + var lineA = mappingA.generatedLine; + var lineB = mappingB.generatedLine; + var columnA = mappingA.generatedColumn; + var columnB = mappingB.generatedColumn; + return lineB > lineA || lineB == lineA && columnB >= columnA || + util$3.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0; + } + + /** + * A data structure to provide a sorted view of accumulated mappings in a + * performance conscious manner. It trades a neglibable overhead in general + * case for a large speedup in case of mappings being added in order. + */ + function MappingList$1() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; + } + + /** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ + MappingList$1.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); + }; + + /** + * Add the given source mapping. + * + * @param Object aMapping + */ + MappingList$1.prototype.add = function MappingList_add(aMapping) { + if (generatedPositionAfter(this._last, aMapping)) { + this._last = aMapping; + this._array.push(aMapping); + } else { + this._sorted = false; + this._array.push(aMapping); + } + }; + + /** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. + * + * WARNING: This method returns internal data without copying, for + * performance. The return value must NOT be mutated, and should be treated as + * an immutable borrow. If you want to take ownership, you must make your own + * copy. + */ + MappingList$1.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util$3.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; + }; + + mappingList.MappingList = MappingList$1; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var base64VLQ$1 = base64Vlq; + var util$2 = util$5; + var ArraySet$1 = arraySet.ArraySet; + var MappingList = mappingList.MappingList; + + /** + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: + * + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. + */ + function SourceMapGenerator$1(aArgs) { + if (!aArgs) { + aArgs = {}; + } + this._file = util$2.getArg(aArgs, 'file', null); + this._sourceRoot = util$2.getArg(aArgs, 'sourceRoot', null); + this._skipValidation = util$2.getArg(aArgs, 'skipValidation', false); + this._sources = new ArraySet$1(); + this._names = new ArraySet$1(); + this._mappings = new MappingList(); + this._sourcesContents = null; + } + + SourceMapGenerator$1.prototype._version = 3; + + /** + * Creates a new SourceMapGenerator based on a SourceMapConsumer + * + * @param aSourceMapConsumer The SourceMap. + */ + SourceMapGenerator$1.fromSourceMap = + function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { + var sourceRoot = aSourceMapConsumer.sourceRoot; + var generator = new SourceMapGenerator$1({ + file: aSourceMapConsumer.file, + sourceRoot: sourceRoot + }); + aSourceMapConsumer.eachMapping(function (mapping) { + var newMapping = { + generated: { + line: mapping.generatedLine, + column: mapping.generatedColumn + } + }; + + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util$2.relative(sourceRoot, newMapping.source); + } + + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; + + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } + + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; + + /** + * Add a single mapping from original source line and column to the generated + * source's line and column for this source map being created. The mapping + * object should have the following properties: + * + * - generated: An object with the generated line and column positions. + * - original: An object with the original line and column positions. + * - source: The original source file (relative to the sourceRoot). + * - name: An optional original token name for this mapping. + */ + SourceMapGenerator$1.prototype.addMapping = + function SourceMapGenerator_addMapping(aArgs) { + var generated = util$2.getArg(aArgs, 'generated'); + var original = util$2.getArg(aArgs, 'original', null); + var source = util$2.getArg(aArgs, 'source', null); + var name = util$2.getArg(aArgs, 'name', null); + + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); + } + + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } + } + + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } + + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; + + /** + * Set the source content for a source file. + */ + SourceMapGenerator$1.prototype.setSourceContent = + function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { + var source = aSourceFile; + if (this._sourceRoot != null) { + source = util$2.relative(this._sourceRoot, source); + } + + if (aSourceContent != null) { + // Add the source content to the _sourcesContents map. + // Create a new _sourcesContents map if the property is null. + if (!this._sourcesContents) { + this._sourcesContents = Object.create(null); + } + this._sourcesContents[util$2.toSetString(source)] = aSourceContent; + } else if (this._sourcesContents) { + // Remove the source file from the _sourcesContents map. + // If the _sourcesContents map is empty, set the property to null. + delete this._sourcesContents[util$2.toSetString(source)]; + if (Object.keys(this._sourcesContents).length === 0) { + this._sourcesContents = null; + } + } + }; + + /** + * Applies the mappings of a sub-source-map for a specific source file to the + * source map being generated. Each mapping to the supplied source file is + * rewritten using the supplied source map. Note: The resolution for the + * resulting mappings is the minimium of this map and the supplied map. + * + * @param aSourceMapConsumer The source map to be applied. + * @param aSourceFile Optional. The filename of the source file. + * If omitted, SourceMapConsumer's file property will be used. + * @param aSourceMapPath Optional. The dirname of the path to the source map + * to be applied. If relative, it is relative to the SourceMapConsumer. + * This parameter is needed when the two source maps aren't in the same + * directory, and the source map to be applied contains relative source + * paths. If so, those relative source paths need to be rewritten + * relative to the SourceMapGenerator. + */ + SourceMapGenerator$1.prototype.applySourceMap = + function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) { + var sourceFile = aSourceFile; + // If aSourceFile is omitted, we will use the file property of the SourceMap + if (aSourceFile == null) { + if (aSourceMapConsumer.file == null) { + throw new Error( + 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' + + 'or the source map\'s "file" property. Both were omitted.' + ); + } + sourceFile = aSourceMapConsumer.file; + } + var sourceRoot = this._sourceRoot; + // Make "sourceFile" relative if an absolute Url is passed. + if (sourceRoot != null) { + sourceFile = util$2.relative(sourceRoot, sourceFile); + } + // Applying the SourceMap can add and remove items from the sources and + // the names array. + var newSources = new ArraySet$1(); + var newNames = new ArraySet$1(); + + // Find mappings for the "sourceFile" + this._mappings.unsortedForEach(function (mapping) { + if (mapping.source === sourceFile && mapping.originalLine != null) { + // Check if it can be mapped by the source map, then update the mapping. + var original = aSourceMapConsumer.originalPositionFor({ + line: mapping.originalLine, + column: mapping.originalColumn + }); + if (original.source != null) { + // Copy mapping + mapping.source = original.source; + if (aSourceMapPath != null) { + mapping.source = util$2.join(aSourceMapPath, mapping.source); + } + if (sourceRoot != null) { + mapping.source = util$2.relative(sourceRoot, mapping.source); + } + mapping.originalLine = original.line; + mapping.originalColumn = original.column; + if (original.name != null) { + mapping.name = original.name; + } + } + } + + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } + + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } + + }, this); + this._sources = newSources; + this._names = newNames; + + // Copy sourcesContents of applied map. + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aSourceMapPath != null) { + sourceFile = util$2.join(aSourceMapPath, sourceFile); + } + if (sourceRoot != null) { + sourceFile = util$2.relative(sourceRoot, sourceFile); + } + this.setSourceContent(sourceFile, content); + } + }, this); + }; + + /** + * A mapping can have one of the three levels of data: + * + * 1. Just the generated position. + * 2. The Generated position, original position, and original source. + * 3. Generated and original position, original source, as well as a name + * token. + * + * To maintain consistency, we validate that any new mapping being added falls + * in to one of these categories. + */ + SourceMapGenerator$1.prototype._validateMapping = + function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, + aName) { + // When aOriginal is truthy but has empty values for .line and .column, + // it is most likely a programmer error. In this case we throw a very + // specific error message to try to guide them the right way. + // For example: https://github.com/Polymer/polymer-bundler/pull/519 + if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') { + throw new Error( + 'original.line and original.column are not numbers -- you probably meant to omit ' + + 'the original mapping entirely and only map the generated position. If so, pass ' + + 'null for the original mapping instead of an object with empty or null values.' + ); + } + + if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aGenerated.line > 0 && aGenerated.column >= 0 + && !aOriginal && !aSource && !aName) { + // Case 1. + return; + } + else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated + && aOriginal && 'line' in aOriginal && 'column' in aOriginal + && aGenerated.line > 0 && aGenerated.column >= 0 + && aOriginal.line > 0 && aOriginal.column >= 0 + && aSource) { + // Cases 2 and 3. + return; + } + else { + throw new Error('Invalid mapping: ' + JSON.stringify({ + generated: aGenerated, + source: aSource, + original: aOriginal, + name: aName + })); + } + }; + + /** + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. + */ + SourceMapGenerator$1.prototype._serializeMappings = + function SourceMapGenerator_serializeMappings() { + var previousGeneratedColumn = 0; + var previousGeneratedLine = 1; + var previousOriginalColumn = 0; + var previousOriginalLine = 0; + var previousName = 0; + var previousSource = 0; + var result = ''; + var next; + var mapping; + var nameIdx; + var sourceIdx; + + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = ''; + + if (mapping.generatedLine !== previousGeneratedLine) { + previousGeneratedColumn = 0; + while (mapping.generatedLine !== previousGeneratedLine) { + next += ';'; + previousGeneratedLine++; + } + } + else { + if (i > 0) { + if (!util$2.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) { + continue; + } + next += ','; + } + } + + next += base64VLQ$1.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; + + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ$1.encode(sourceIdx - previousSource); + previousSource = sourceIdx; + + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ$1.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; + + next += base64VLQ$1.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; + + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ$1.encode(nameIdx - previousName); + previousName = nameIdx; + } + } + + result += next; + } + + return result; + }; + + SourceMapGenerator$1.prototype._generateSourcesContent = + function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { + return aSources.map(function (source) { + if (!this._sourcesContents) { + return null; + } + if (aSourceRoot != null) { + source = util$2.relative(aSourceRoot, source); + } + var key = util$2.toSetString(source); + return Object.prototype.hasOwnProperty.call(this._sourcesContents, key) + ? this._sourcesContents[key] + : null; + }, this); + }; + + /** + * Externalize the source map. + */ + SourceMapGenerator$1.prototype.toJSON = + function SourceMapGenerator_toJSON() { + var map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: this._serializeMappings() + }; + if (this._file != null) { + map.file = this._file; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } + + return map; + }; + + /** + * Render the source map being generated to a string. + */ + SourceMapGenerator$1.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; + + sourceMapGenerator.SourceMapGenerator = SourceMapGenerator$1; + + var sourceMapConsumer = {}; + + var binarySearch$1 = {}; + + (function (exports) { + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + exports.GREATEST_LOWER_BOUND = 1; + exports.LEAST_UPPER_BOUND = 2; + + /** + * Recursive implementation of binary search. + * + * @param aLow Indices here and lower do not contain the needle. + * @param aHigh Indices here and higher do not contain the needle. + * @param aNeedle The element being searched for. + * @param aHaystack The non-empty array being searched. + * @param aCompare Function which takes two elements and returns -1, 0, or 1. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + */ + function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { + // This function terminates when one of the following is true: + // + // 1. We find the exact element we are looking for. + // + // 2. We did not find the exact element, but we can return the index of + // the next-closest element. + // + // 3. We did not find the exact element, and there is no next-closest + // element than the one we are searching for, so we return -1. + var mid = Math.floor((aHigh - aLow) / 2) + aLow; + var cmp = aCompare(aNeedle, aHaystack[mid], true); + if (cmp === 0) { + // Found the element we are looking for. + return mid; + } + else if (cmp > 0) { + // Our needle is greater than aHaystack[mid]. + if (aHigh - mid > 1) { + // The element is in the upper half. + return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); + } + + // The exact needle element was not found in this haystack. Determine if + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return aHigh < aHaystack.length ? aHigh : -1; + } else { + return mid; + } + } + else { + // Our needle is less than aHaystack[mid]. + if (mid - aLow > 1) { + // The element is in the lower half. + return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); + } + + // we are in termination case (3) or (2) and return the appropriate thing. + if (aBias == exports.LEAST_UPPER_BOUND) { + return mid; + } else { + return aLow < 0 ? -1 : aLow; + } + } + } + + /** + * This is an implementation of binary search which will always try and return + * the index of the closest element if there is no exact hit. This is because + * mappings between original and generated line/col pairs are single points, + * and there is an implicit region between each of them, so a miss just means + * that you aren't on the very start of a region. + * + * @param aNeedle The element you are looking for. + * @param aHaystack The array that is being searched. + * @param aCompare A function which takes the needle and an element in the + * array and returns -1, 0, or 1 depending on whether the needle is less + * than, equal to, or greater than the element, respectively. + * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or + * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. + */ + exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { + if (aHaystack.length === 0) { + return -1; + } + + var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, + aCompare, aBias || exports.GREATEST_LOWER_BOUND); + if (index < 0) { + return -1; + } + + // We have found either the exact element, or the next-closest element than + // the one we are searching for. However, there may be more than one such + // element. Make sure we always return the smallest of these. + while (index - 1 >= 0) { + if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { + break; + } + --index; + } + + return index; + }; + } (binarySearch$1)); + + var quickSort$1 = {}; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + // It turns out that some (most?) JavaScript engines don't self-host + // `Array.prototype.sort`. This makes sense because C++ will likely remain + // faster than JS when doing raw CPU-intensive sorting. However, when using a + // custom comparator function, calling back and forth between the VM's C++ and + // JIT'd JS is rather slow *and* loses JIT type information, resulting in + // worse generated code for the comparator function than would be optimal. In + // fact, when sorting with a comparator, these costs outweigh the benefits of + // sorting in C++. By using our own JS-implemented Quick Sort (below), we get + // a ~3500ms mean speed-up in `bench/bench.html`. + + /** + * Swap the elements indexed by `x` and `y` in the array `ary`. + * + * @param {Array} ary + * The array. + * @param {Number} x + * The index of the first item. + * @param {Number} y + * The index of the second item. + */ + function swap$1(ary, x, y) { + var temp = ary[x]; + ary[x] = ary[y]; + ary[y] = temp; + } + + /** + * Returns a random integer within the range `low .. high` inclusive. + * + * @param {Number} low + * The lower bound on the range. + * @param {Number} high + * The upper bound on the range. + */ + function randomIntInRange(low, high) { + return Math.round(low + (Math.random() * (high - low))); + } + + /** + * The Quick Sort algorithm. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + * @param {Number} p + * Start index of the array + * @param {Number} r + * End index of the array + */ + function doQuickSort(ary, comparator, p, r) { + // If our lower bound is less than our upper bound, we (1) partition the + // array into two pieces and (2) recurse on each half. If it is not, this is + // the empty array and our base case. + + if (p < r) { + // (1) Partitioning. + // + // The partitioning chooses a pivot between `p` and `r` and moves all + // elements that are less than or equal to the pivot to the before it, and + // all the elements that are greater than it after it. The effect is that + // once partition is done, the pivot is in the exact place it will be when + // the array is put in sorted order, and it will not need to be moved + // again. This runs in O(n) time. + + // Always choose a random pivot so that an input array which is reverse + // sorted does not cause O(n^2) running time. + var pivotIndex = randomIntInRange(p, r); + var i = p - 1; + + swap$1(ary, pivotIndex, r); + var pivot = ary[r]; + + // Immediately after `j` is incremented in this loop, the following hold + // true: + // + // * Every element in `ary[p .. i]` is less than or equal to the pivot. + // + // * Every element in `ary[i+1 .. j-1]` is greater than the pivot. + for (var j = p; j < r; j++) { + if (comparator(ary[j], pivot) <= 0) { + i += 1; + swap$1(ary, i, j); + } + } + + swap$1(ary, i + 1, j); + var q = i + 1; + + // (2) Recurse on each half. + + doQuickSort(ary, comparator, p, q - 1); + doQuickSort(ary, comparator, q + 1, r); + } + } + + /** + * Sort the given array in-place with the given comparator function. + * + * @param {Array} ary + * An array to sort. + * @param {function} comparator + * Function to use to compare two items. + */ + quickSort$1.quickSort = function (ary, comparator) { + doQuickSort(ary, comparator, 0, ary.length - 1); + }; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var util$1 = util$5; + var binarySearch = binarySearch$1; + var ArraySet = arraySet.ArraySet; + var base64VLQ = base64Vlq; + var quickSort = quickSort$1.quickSort; + + function SourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); + } + + SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + SourceMapConsumer.prototype._version = 3; + + // `__generatedMappings` and `__originalMappings` are arrays that hold the + // parsed mapping coordinates from the source map's "mappings" attribute. They + // are lazily instantiated, accessed via the `_generatedMappings` and + // `_originalMappings` getters respectively, and we only parse the mappings + // and create these arrays once queried for a source location. We jump through + // these hoops because there can be many thousands of mappings, and parsing + // them is expensive, so we only want to do it if we must. + // + // Each object in the arrays is of the form: + // + // { + // generatedLine: The line number in the generated code, + // generatedColumn: The column number in the generated code, + // source: The path to the original source file that generated this + // chunk of code, + // originalLine: The line number in the original source that + // corresponds to this chunk of generated code, + // originalColumn: The column number in the original source that + // corresponds to this chunk of generated code, + // name: The name of the original symbol which generated this chunk of + // code. + // } + // + // All properties except for `generatedLine` and `generatedColumn` can be + // `null`. + // + // `_generatedMappings` is ordered by the generated positions. + // + // `_originalMappings` is ordered by the original positions. + + SourceMapConsumer.prototype.__generatedMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { + get: function () { + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__generatedMappings; + } + }); + + SourceMapConsumer.prototype.__originalMappings = null; + Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); + } + + return this.__originalMappings; + } + }); + + SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + SourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + throw new Error("Subclasses must implement _parseMappings"); + }; + + SourceMapConsumer.GENERATED_ORDER = 1; + SourceMapConsumer.ORIGINAL_ORDER = 2; + + SourceMapConsumer.GREATEST_LOWER_BOUND = 1; + SourceMapConsumer.LEAST_UPPER_BOUND = 2; + + /** + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @param Function aCallback + * The function that is called with each mapping. + * @param Object aContext + * Optional. If specified, this object will be the value of `this` every + * time that `aCallback` is called. + * @param aOrder + * Either `SourceMapConsumer.GENERATED_ORDER` or + * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to + * iterate over the mappings sorted by the generated file's line/column + * order or the original's source/line/column order, respectively. Defaults to + * `SourceMapConsumer.GENERATED_ORDER`. + */ + SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; + + var mappings; + switch (order) { + case SourceMapConsumer.GENERATED_ORDER: + mappings = this._generatedMappings; + break; + case SourceMapConsumer.ORIGINAL_ORDER: + mappings = this._originalMappings; + break; + default: + throw new Error("Unknown order of iteration."); + } + + var sourceRoot = this.sourceRoot; + mappings.map(function (mapping) { + var source = mapping.source === null ? null : this._sources.at(mapping.source); + if (source != null && sourceRoot != null) { + source = util$1.join(sourceRoot, source); + } + return { + source: source, + generatedLine: mapping.generatedLine, + generatedColumn: mapping.generatedColumn, + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: mapping.name === null ? null : this._names.at(mapping.name) + }; + }, this).forEach(aCallback, context); + }; + + /** + * Returns all generated line and column information for the original source, + * line, and column provided. If no column is provided, returns all mappings + * corresponding to a either the line we are searching for or the next + * closest line that has any mappings. Otherwise, returns all mappings + * corresponding to the given line and either the column we are searching for + * or the next closest column that has any offsets. + * + * The only argument is an object with the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: Optional. the column number in the original source. + * + * and an array of objects is returned, each with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util$1.getArg(aArgs, 'line'); + + // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping + // returns the index of the closest mapping less than the needle. By + // setting needle.originalColumn to 0, we thus find the last mapping for + // the given line, provided such a mapping exists. + var needle = { + source: util$1.getArg(aArgs, 'source'), + originalLine: line, + originalColumn: util$1.getArg(aArgs, 'column', 0) + }; + + if (this.sourceRoot != null) { + needle.source = util$1.relative(this.sourceRoot, needle.source); + } + if (!this._sources.has(needle.source)) { + return []; + } + needle.source = this._sources.indexOf(needle.source); + + var mappings = []; + + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util$1.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we found. Since + // mappings are sorted, this is guaranteed to find all mappings for + // the line we found. + while (mapping && mapping.originalLine === originalLine) { + mappings.push({ + line: util$1.getArg(mapping, 'generatedLine', null), + column: util$1.getArg(mapping, 'generatedColumn', null), + lastColumn: util$1.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; + + // Iterate until either we run out of mappings, or we run into + // a mapping for a different line than the one we were searching for. + // Since mappings are sorted, this is guaranteed to find all mappings for + // the line we are searching for. + while (mapping && + mapping.originalLine === line && + mapping.originalColumn == originalColumn) { + mappings.push({ + line: util$1.getArg(mapping, 'generatedLine', null), + column: util$1.getArg(mapping, 'generatedColumn', null), + lastColumn: util$1.getArg(mapping, 'lastGeneratedColumn', null) + }); + + mapping = this._originalMappings[++index]; + } + } + } + + return mappings; + }; + + sourceMapConsumer.SourceMapConsumer = SourceMapConsumer; + + /** + * A BasicSourceMapConsumer instance represents a parsed source map which we can + * query for information about the original file positions by giving it a file + * position in the generated source. + * + * The only parameter is the raw source map (either as a JSON string, or + * already parsed to an object). According to the spec, source maps have the + * following attributes: + * + * - version: Which version of the source map spec this map is following. + * - sources: An array of URLs to the original source files. + * - names: An array of identifiers which can be referrenced by individual mappings. + * - sourceRoot: Optional. The URL root from which all sources are relative. + * - sourcesContent: Optional. An array of contents of the original source files. + * - mappings: A string of base64 VLQs which contain the actual mappings. + * - file: Optional. The generated file this source map is associated with. + * + * Here is an example source map, taken from the source map spec[0]: + * + * { + * version : 3, + * file: "out.js", + * sourceRoot : "", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AA,AB;;ABCDE;" + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + */ + function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util$1.getArg(sourceMap, 'version'); + var sources = util$1.getArg(sourceMap, 'sources'); + // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which + // requires the array) to play nice here. + var names = util$1.getArg(sourceMap, 'names', []); + var sourceRoot = util$1.getArg(sourceMap, 'sourceRoot', null); + var sourcesContent = util$1.getArg(sourceMap, 'sourcesContent', null); + var mappings = util$1.getArg(sourceMap, 'mappings'); + var file = util$1.getArg(sourceMap, 'file', null); + + // Once again, Sass deviates from the spec and supplies the version as a + // string rather than a number, so we use loose equality checking here. + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + sources = sources + .map(String) + // Some source maps produce relative source paths like "./foo.js" instead of + // "foo.js". Normalize these first so that future comparisons will succeed. + // See bugzil.la/1090768. + .map(util$1.normalize) + // Always ensure that absolute sources are internally stored relative to + // the source root, if the source root is absolute. Not doing this would + // be particularly problematic when the source root is a prefix of the + // source (valid, but why??). See github issue #199 and bugzil.la/1188982. + .map(function (source) { + return sourceRoot && util$1.isAbsolute(sourceRoot) && util$1.isAbsolute(source) + ? util$1.relative(sourceRoot, source) + : source; + }); + + // Pass `true` below to allow duplicate names and sources. While source maps + // are intended to be compressed and deduplicated, the TypeScript compiler + // sometimes generates source maps with duplicates in them. See Github issue + // #72 and bugzil.la/889492. + this._names = ArraySet.fromArray(names.map(String), true); + this._sources = ArraySet.fromArray(sources, true); + + this.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; + } + + BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; + + /** + * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer + */ + BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); + + var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); + var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); + smc.sourceRoot = aSourceMap._sourceRoot; + smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), + smc.sourceRoot); + smc.file = aSourceMap._file; + + // Because we are modifying the entries (by converting string sources and + // names to indices into the sources and names ArraySets), we have to make + // a copy of the entry or else bad things happen. Shared mutable state + // strikes again! See github issue #191. + + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; + + for (var i = 0, length = generatedMappings.length; i < length; i++) { + var srcMapping = generatedMappings[i]; + var destMapping = new Mapping; + destMapping.generatedLine = srcMapping.generatedLine; + destMapping.generatedColumn = srcMapping.generatedColumn; + + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; + + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); + } + + destGeneratedMappings.push(destMapping); + } + + quickSort(smc.__originalMappings, util$1.compareByOriginalPositions); + + return smc; + }; + + /** + * The version of the source mapping spec that we are consuming. + */ + BasicSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', { + get: function () { + return this._sources.toArray().map(function (s) { + return this.sourceRoot != null ? util$1.join(this.sourceRoot, s) : s; + }, this); + } + }); + + /** + * Provide the JIT with a nice shape / hidden class. + */ + function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; + } + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + BasicSourceMapConsumer.prototype._parseMappings = + function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { + var generatedLine = 1; + var previousGeneratedColumn = 0; + var previousOriginalLine = 0; + var previousOriginalColumn = 0; + var previousSource = 0; + var previousName = 0; + var length = aStr.length; + var index = 0; + var cachedSegments = {}; + var temp = {}; + var originalMappings = []; + var generatedMappings = []; + var mapping, str, segment, end, value; + + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; + } + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; + + // Because each offset is encoded relative to the previous one, + // many segments often have the same encoding. We can exploit this + // fact by caching the parsed variable length fields of each segment, + // allowing us to avoid a second parse if we encounter the same + // segment again. + for (end = index; end < length; end++) { + if (this._charIsMappingSeparator(aStr, end)) { + break; + } + } + str = aStr.slice(index, end); + + segment = cachedSegments[str]; + if (segment) { + index += str.length; + } else { + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } + + if (segment.length === 2) { + throw new Error('Found a source, but no line and column'); + } + + if (segment.length === 3) { + throw new Error('Found a source and line, but no column'); + } + + cachedSegments[str] = segment; + } + + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; + + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; + + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; + + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; + + if (segment.length > 4) { + // Original name. + mapping.name = previousName + segment[4]; + previousName += segment[4]; + } + } + + generatedMappings.push(mapping); + if (typeof mapping.originalLine === 'number') { + originalMappings.push(mapping); + } + } + } + + quickSort(generatedMappings, util$1.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; + + quickSort(originalMappings, util$1.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; + + /** + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. + */ + BasicSourceMapConsumer.prototype._findMapping = + function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, + aColumnName, aComparator, aBias) { + // To return the position we are searching for, we must first find the + // mapping for the given position and then return the opposite position it + // points to. Because the mappings are sorted, we can use binary search to + // find the best mapping. + + if (aNeedle[aLineName] <= 0) { + throw new TypeError('Line must be greater than or equal to 1, got ' + + aNeedle[aLineName]); + } + if (aNeedle[aColumnName] < 0) { + throw new TypeError('Column must be greater than or equal to 0, got ' + + aNeedle[aColumnName]); + } + + return binarySearch.search(aNeedle, aMappings, aComparator, aBias); + }; + + /** + * Compute the last column for each generated mapping. The last column is + * inclusive. + */ + BasicSourceMapConsumer.prototype.computeColumnSpans = + function SourceMapConsumer_computeColumnSpans() { + for (var index = 0; index < this._generatedMappings.length; ++index) { + var mapping = this._generatedMappings[index]; + + // Mappings do not contain a field for the last generated columnt. We + // can come up with an optimistic estimate, however, by assuming that + // mappings are contiguous (i.e. given two consecutive mappings, the + // first mapping ends where the second one starts). + if (index + 1 < this._generatedMappings.length) { + var nextMapping = this._generatedMappings[index + 1]; + + if (mapping.generatedLine === nextMapping.generatedLine) { + mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; + continue; + } + } + + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; + } + }; + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util$1.getArg(aArgs, 'line'), + generatedColumn: util$1.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util$1.compareByGeneratedPositionsDeflated, + util$1.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + if (mapping.generatedLine === needle.generatedLine) { + var source = util$1.getArg(mapping, 'source', null); + if (source !== null) { + source = this._sources.at(source); + if (this.sourceRoot != null) { + source = util$1.join(this.sourceRoot, source); + } + } + var name = util$1.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); + } + return { + source: source, + line: util$1.getArg(mapping, 'originalLine', null), + column: util$1.getArg(mapping, 'originalColumn', null), + name: name + }; + } + } + + return { + source: null, + line: null, + column: null, + name: null + }; + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + BasicSourceMapConsumer.prototype.hasContentsOfAllSources = + function BasicSourceMapConsumer_hasContentsOfAllSources() { + if (!this.sourcesContent) { + return false; + } + return this.sourcesContent.length >= this._sources.size() && + !this.sourcesContent.some(function (sc) { return sc == null; }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + BasicSourceMapConsumer.prototype.sourceContentFor = + function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + if (!this.sourcesContent) { + return null; + } + + if (this.sourceRoot != null) { + aSource = util$1.relative(this.sourceRoot, aSource); + } + + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } + + var url; + if (this.sourceRoot != null + && (url = util$1.urlParse(this.sourceRoot))) { + // XXX: file:// URIs and absolute paths lead to unexpected behavior for + // many users. We can help them out when they expect file:// URIs to + // behave like it would if they were running a local HTTP server. See + // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. + var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); + if (url.scheme == "file" + && this._sources.has(fileUriAbsPath)) { + return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] + } + + if ((!url.path || url.path == "/") + && this._sources.has("/" + aSource)) { + return this.sourcesContent[this._sources.indexOf("/" + aSource)]; + } + } + + // This function is used recursively from + // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we + // don't want to throw if we can't find the source - we just want to + // return null, so we provide a flag to exit gracefully. + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or + * 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the + * closest element that is smaller than or greater than the one we are + * searching for, respectively, if the exact element cannot be found. + * Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + BasicSourceMapConsumer.prototype.generatedPositionFor = + function SourceMapConsumer_generatedPositionFor(aArgs) { + var source = util$1.getArg(aArgs, 'source'); + if (this.sourceRoot != null) { + source = util$1.relative(this.sourceRoot, source); + } + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; + } + source = this._sources.indexOf(source); + + var needle = { + source: source, + originalLine: util$1.getArg(aArgs, 'line'), + originalColumn: util$1.getArg(aArgs, 'column') + }; + + var index = this._findMapping( + needle, + this._originalMappings, + "originalLine", + "originalColumn", + util$1.compareByOriginalPositions, + util$1.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._originalMappings[index]; + + if (mapping.source === needle.source) { + return { + line: util$1.getArg(mapping, 'generatedLine', null), + column: util$1.getArg(mapping, 'generatedColumn', null), + lastColumn: util$1.getArg(mapping, 'lastGeneratedColumn', null) + }; + } + } + + return { + line: null, + column: null, + lastColumn: null + }; + }; + + sourceMapConsumer.BasicSourceMapConsumer = BasicSourceMapConsumer; + + /** + * An IndexedSourceMapConsumer instance represents a parsed source map which + * we can query for information. It differs from BasicSourceMapConsumer in + * that it takes "indexed" source maps (i.e. ones with a "sections" field) as + * input. + * + * The only parameter is a raw source map (either as a JSON string, or already + * parsed to an object). According to the spec for indexed source maps, they + * have the following attributes: + * + * - version: Which version of the source map spec this map is following. + * - file: Optional. The generated file this source map is associated with. + * - sections: A list of section definitions. + * + * Each value under the "sections" field has two fields: + * - offset: The offset into the original specified at which this section + * begins to apply, defined as an object with a "line" and "column" + * field. + * - map: A source map definition. This source map could also be indexed, + * but doesn't have to be. + * + * Instead of the "map" field, it's also possible to have a "url" field + * specifying a URL to retrieve a source map from, but that's currently + * unsupported. + * + * Here's an example source map, taken from the source map spec[0], but + * modified to omit a section which uses the "url" field. + * + * { + * version : 3, + * file: "app.js", + * sections: [{ + * offset: {line:100, column:10}, + * map: { + * version : 3, + * file: "section.js", + * sources: ["foo.js", "bar.js"], + * names: ["src", "maps", "are", "fun"], + * mappings: "AAAA,E;;ABCDE;" + * } + * }], + * } + * + * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + */ + function IndexedSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + } + + var version = util$1.getArg(sourceMap, 'version'); + var sections = util$1.getArg(sourceMap, 'sections'); + + if (version != this._version) { + throw new Error('Unsupported version: ' + version); + } + + this._sources = new ArraySet(); + this._names = new ArraySet(); + + var lastOffset = { + line: -1, + column: 0 + }; + this._sections = sections.map(function (s) { + if (s.url) { + // The url field will require support for asynchronicity. + // See https://github.com/mozilla/source-map/issues/16 + throw new Error('Support for url field in sections not implemented.'); + } + var offset = util$1.getArg(s, 'offset'); + var offsetLine = util$1.getArg(offset, 'line'); + var offsetColumn = util$1.getArg(offset, 'column'); + + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); + } + lastOffset = offset; + + return { + generatedOffset: { + // The offset fields are 0-based, but we use 1-based indices when + // encoding/decoding from VLQ. + generatedLine: offsetLine + 1, + generatedColumn: offsetColumn + 1 + }, + consumer: new SourceMapConsumer(util$1.getArg(s, 'map')) + } + }); + } + + IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); + IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; + + /** + * The version of the source mapping spec that we are consuming. + */ + IndexedSourceMapConsumer.prototype._version = 3; + + /** + * The list of original sources. + */ + Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { + get: function () { + var sources = []; + for (var i = 0; i < this._sections.length; i++) { + for (var j = 0; j < this._sections[i].consumer.sources.length; j++) { + sources.push(this._sections[i].consumer.sources[j]); + } + } + return sources; + } + }); + + /** + * Returns the original source, line, and column information for the generated + * source's line and column positions provided. The only argument is an object + * with the following properties: + * + * - line: The line number in the generated source. + * - column: The column number in the generated source. + * + * and an object is returned with the following properties: + * + * - source: The original source file, or null. + * - line: The line number in the original source, or null. + * - column: The column number in the original source, or null. + * - name: The original identifier, or null. + */ + IndexedSourceMapConsumer.prototype.originalPositionFor = + function IndexedSourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util$1.getArg(aArgs, 'line'), + generatedColumn: util$1.getArg(aArgs, 'column') + }; + + // Find the section containing the generated position we're trying to map + // to an original position. + var sectionIndex = binarySearch.search(needle, this._sections, + function(needle, section) { + var cmp = needle.generatedLine - section.generatedOffset.generatedLine; + if (cmp) { + return cmp; + } + + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; + } + + return section.consumer.originalPositionFor({ + line: needle.generatedLine - + (section.generatedOffset.generatedLine - 1), + column: needle.generatedColumn - + (section.generatedOffset.generatedLine === needle.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + bias: aArgs.bias + }); + }; + + /** + * Return true if we have the source content for every source in the source + * map, false otherwise. + */ + IndexedSourceMapConsumer.prototype.hasContentsOfAllSources = + function IndexedSourceMapConsumer_hasContentsOfAllSources() { + return this._sections.every(function (s) { + return s.consumer.hasContentsOfAllSources(); + }); + }; + + /** + * Returns the original source content. The only argument is the url of the + * original source file. Returns null if no original source content is + * available. + */ + IndexedSourceMapConsumer.prototype.sourceContentFor = + function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; + } + } + if (nullOnMissing) { + return null; + } + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; + + /** + * Returns the generated line and column information for the original source, + * line, and column positions provided. The only argument is an object with + * the following properties: + * + * - source: The filename of the original source. + * - line: The line number in the original source. + * - column: The column number in the original source. + * + * and an object is returned with the following properties: + * + * - line: The line number in the generated source, or null. + * - column: The column number in the generated source, or null. + */ + IndexedSourceMapConsumer.prototype.generatedPositionFor = + function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + + // Only consider this section if the requested source is in the list of + // sources of the consumer. + if (section.consumer.sources.indexOf(util$1.getArg(aArgs, 'source')) === -1) { + continue; + } + var generatedPosition = section.consumer.generatedPositionFor(aArgs); + if (generatedPosition) { + var ret = { + line: generatedPosition.line + + (section.generatedOffset.generatedLine - 1), + column: generatedPosition.column + + (section.generatedOffset.generatedLine === generatedPosition.line + ? section.generatedOffset.generatedColumn - 1 + : 0) + }; + return ret; + } + } + + return { + line: null, + column: null + }; + }; + + /** + * Parse the mappings in a string in to a data structure which we can easily + * query (the ordered arrays in the `this.__generatedMappings` and + * `this.__originalMappings` properties). + */ + IndexedSourceMapConsumer.prototype._parseMappings = + function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) { + this.__generatedMappings = []; + this.__originalMappings = []; + for (var i = 0; i < this._sections.length; i++) { + var section = this._sections[i]; + var sectionMappings = section.consumer._generatedMappings; + for (var j = 0; j < sectionMappings.length; j++) { + var mapping = sectionMappings[j]; + + var source = section.consumer._sources.at(mapping.source); + if (section.consumer.sourceRoot !== null) { + source = util$1.join(section.consumer.sourceRoot, source); + } + this._sources.add(source); + source = this._sources.indexOf(source); + + var name = section.consumer._names.at(mapping.name); + this._names.add(name); + name = this._names.indexOf(name); + + // The mappings coming from the consumer for the section have + // generated positions relative to the start of the section, so we + // need to offset them to be relative to the start of the concatenated + // generated file. + var adjustedMapping = { + source: source, + generatedLine: mapping.generatedLine + + (section.generatedOffset.generatedLine - 1), + generatedColumn: mapping.generatedColumn + + (section.generatedOffset.generatedLine === mapping.generatedLine + ? section.generatedOffset.generatedColumn - 1 + : 0), + originalLine: mapping.originalLine, + originalColumn: mapping.originalColumn, + name: name + }; + + this.__generatedMappings.push(adjustedMapping); + if (typeof adjustedMapping.originalLine === 'number') { + this.__originalMappings.push(adjustedMapping); + } + } + } + + quickSort(this.__generatedMappings, util$1.compareByGeneratedPositionsDeflated); + quickSort(this.__originalMappings, util$1.compareByOriginalPositions); + }; + + sourceMapConsumer.IndexedSourceMapConsumer = IndexedSourceMapConsumer; + + var sourceNode = {}; + + /* + * Copyright 2011 Mozilla Foundation and contributors + * Licensed under the New BSD license. See LICENSE or: + * http://opensource.org/licenses/BSD-3-Clause + */ + + var SourceMapGenerator = sourceMapGenerator.SourceMapGenerator; + var util = util$5; + + // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other + // operating systems these days (capturing the result). + var REGEX_NEWLINE = /(\r?\n)/; + + // Newline character code for charCodeAt() comparisons + var NEWLINE_CODE = 10; + + // Private symbol for identifying `SourceNode`s when multiple versions of + // the source-map library are loaded. This MUST NOT CHANGE across + // versions! + var isSourceNode = "$$$isSourceNode$$$"; + + /** + * SourceNodes provide a way to abstract over interpolating/concatenating + * snippets of generated JavaScript source code while maintaining the line and + * column information associated with the original source code. + * + * @param aLine The original line number. + * @param aColumn The original column number. + * @param aSource The original source's filename. + * @param aChunks Optional. An array of strings which are snippets of + * generated JS, or other SourceNodes. + * @param aName The original identifier. + */ + function SourceNode(aLine, aColumn, aSource, aChunks, aName) { + this.children = []; + this.sourceContents = {}; + this.line = aLine == null ? null : aLine; + this.column = aColumn == null ? null : aColumn; + this.source = aSource == null ? null : aSource; + this.name = aName == null ? null : aName; + this[isSourceNode] = true; + if (aChunks != null) this.add(aChunks); + } + + /** + * Creates a SourceNode from generated code and a SourceMapConsumer. + * + * @param aGeneratedCode The generated code + * @param aSourceMapConsumer The SourceMap for the generated code + * @param aRelativePath Optional. The path that relative sources in the + * SourceMapConsumer should be relative to. + */ + SourceNode.fromStringWithSourceMap = + function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) { + // The SourceNode we want to fill with the generated code + // and the SourceMap + var node = new SourceNode(); + + // All even indices of this array are one line of the generated code, + // while all odd indices are the newlines between two adjacent lines + // (since `REGEX_NEWLINE` captures its match). + // Processed fragments are accessed by calling `shiftNextLine`. + var remainingLines = aGeneratedCode.split(REGEX_NEWLINE); + var remainingLinesIndex = 0; + var shiftNextLine = function() { + var lineContents = getNextLine(); + // The last line of a file might not have a newline. + var newLine = getNextLine() || ""; + return lineContents + newLine; + + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; + + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + + // The generate SourceNodes we need a code range. + // To extract it current and last mapping is used. + // Here we store the last mapping. + var lastMapping = null; + + aSourceMapConsumer.eachMapping(function (mapping) { + if (lastMapping !== null) { + // We add the code from "lastMapping" to "mapping": + // First check if there is a new line in between. + if (lastGeneratedLine < mapping.generatedLine) { + // Associate first line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + lastGeneratedLine++; + lastGeneratedColumn = 0; + // The remaining code is added without mapping + } else { + // There is no new line in between. + // Associate the code between "lastGeneratedColumn" and + // "mapping.generatedColumn" with "lastMapping" + var nextLine = remainingLines[remainingLinesIndex]; + var code = nextLine.substr(0, mapping.generatedColumn - + lastGeneratedColumn); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn - + lastGeneratedColumn); + lastGeneratedColumn = mapping.generatedColumn; + addMappingWithCode(lastMapping, code); + // No more remaining code, continue + lastMapping = mapping; + return; + } + } + // We add the generated code until the first mapping + // to the SourceNode without any mapping. + // Each line is added as separate string. + while (lastGeneratedLine < mapping.generatedLine) { + node.add(shiftNextLine()); + lastGeneratedLine++; + } + if (lastGeneratedColumn < mapping.generatedColumn) { + var nextLine = remainingLines[remainingLinesIndex]; + node.add(nextLine.substr(0, mapping.generatedColumn)); + remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn); + lastGeneratedColumn = mapping.generatedColumn; + } + lastMapping = mapping; + }, this); + // We have processed all mappings. + if (remainingLinesIndex < remainingLines.length) { + if (lastMapping) { + // Associate the remaining code in the current line with "lastMapping" + addMappingWithCode(lastMapping, shiftNextLine()); + } + // and add the remaining lines without any mapping + node.add(remainingLines.splice(remainingLinesIndex).join("")); + } + + // Copy sourcesContent into SourceNode + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + if (aRelativePath != null) { + sourceFile = util.join(aRelativePath, sourceFile); + } + node.setSourceContent(sourceFile, content); + } + }); + + return node; + + function addMappingWithCode(mapping, code) { + if (mapping === null || mapping.source === undefined) { + node.add(code); + } else { + var source = aRelativePath + ? util.join(aRelativePath, mapping.source) + : mapping.source; + node.add(new SourceNode(mapping.originalLine, + mapping.originalColumn, + source, + code, + mapping.name)); + } + } + }; + + /** + * Add a chunk of generated JS to this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.add = function SourceNode_add(aChunk) { + if (Array.isArray(aChunk)) { + aChunk.forEach(function (chunk) { + this.add(chunk); + }, this); + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + if (aChunk) { + this.children.push(aChunk); + } + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Add a chunk of generated JS to the beginning of this source node. + * + * @param aChunk A string snippet of generated JS code, another instance of + * SourceNode, or an array where each member is one of those things. + */ + SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { + if (Array.isArray(aChunk)) { + for (var i = aChunk.length-1; i >= 0; i--) { + this.prepend(aChunk[i]); + } + } + else if (aChunk[isSourceNode] || typeof aChunk === "string") { + this.children.unshift(aChunk); + } + else { + throw new TypeError( + "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk + ); + } + return this; + }; + + /** + * Walk over the tree of JS snippets in this node and its children. The + * walking function is called once for each snippet of JS and is passed that + * snippet and the its original associated source's line/column location. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walk = function SourceNode_walk(aFn) { + var chunk; + for (var i = 0, len = this.children.length; i < len; i++) { + chunk = this.children[i]; + if (chunk[isSourceNode]) { + chunk.walk(aFn); + } + else { + if (chunk !== '') { + aFn(chunk, { source: this.source, + line: this.line, + column: this.column, + name: this.name }); + } + } + } + }; + + /** + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. + * + * @param aSep The separator. + */ + SourceNode.prototype.join = function SourceNode_join(aSep) { + var newChildren; + var i; + var len = this.children.length; + if (len > 0) { + newChildren = []; + for (i = 0; i < len-1; i++) { + newChildren.push(this.children[i]); + newChildren.push(aSep); + } + newChildren.push(this.children[i]); + this.children = newChildren; + } + return this; + }; + + /** + * Call String.prototype.replace on the very right-most source snippet. Useful + * for trimming whitespace from the end of a source node, etc. + * + * @param aPattern The pattern to replace. + * @param aReplacement The thing to replace the pattern with. + */ + SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { + var lastChild = this.children[this.children.length - 1]; + if (lastChild[isSourceNode]) { + lastChild.replaceRight(aPattern, aReplacement); + } + else if (typeof lastChild === 'string') { + this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); + } + else { + this.children.push(''.replace(aPattern, aReplacement)); + } + return this; + }; + + /** + * Set the source content for a source file. This will be added to the SourceMapGenerator + * in the sourcesContent field. + * + * @param aSourceFile The filename of the source file + * @param aSourceContent The content of the source file + */ + SourceNode.prototype.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; + + /** + * Walk over the tree of SourceNodes. The walking function is called for each + * source file content and is passed the filename and source content. + * + * @param aFn The traversal function. + */ + SourceNode.prototype.walkSourceContents = + function SourceNode_walkSourceContents(aFn) { + for (var i = 0, len = this.children.length; i < len; i++) { + if (this.children[i][isSourceNode]) { + this.children[i].walkSourceContents(aFn); + } + } + + var sources = Object.keys(this.sourceContents); + for (var i = 0, len = sources.length; i < len; i++) { + aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); + } + }; + + /** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ + SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; + }; + + /** + * Returns the string representation of this source node along with a source + * map. + */ + SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { + var generated = { + code: "", + line: 1, + column: 0 + }; + var map = new SourceMapGenerator(aArgs); + var sourceMappingActive = false; + var lastOriginalSource = null; + var lastOriginalLine = null; + var lastOriginalColumn = null; + var lastOriginalName = null; + this.walk(function (chunk, original) { + generated.code += chunk; + if (original.source !== null + && original.line !== null + && original.column !== null) { + if(lastOriginalSource !== original.source + || lastOriginalLine !== original.line + || lastOriginalColumn !== original.column + || lastOriginalName !== original.name) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + lastOriginalSource = original.source; + lastOriginalLine = original.line; + lastOriginalColumn = original.column; + lastOriginalName = original.name; + sourceMappingActive = true; + } else if (sourceMappingActive) { + map.addMapping({ + generated: { + line: generated.line, + column: generated.column + } + }); + lastOriginalSource = null; + sourceMappingActive = false; + } + for (var idx = 0, length = chunk.length; idx < length; idx++) { + if (chunk.charCodeAt(idx) === NEWLINE_CODE) { + generated.line++; + generated.column = 0; + // Mappings end at eol + if (idx + 1 === length) { + lastOriginalSource = null; + sourceMappingActive = false; + } else if (sourceMappingActive) { + map.addMapping({ + source: original.source, + original: { + line: original.line, + column: original.column + }, + generated: { + line: generated.line, + column: generated.column + }, + name: original.name + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); + + return { code: generated.code, map: map }; + }; + + sourceNode.SourceNode = SourceNode; + + sourceMap.SourceMapGenerator = sourceMapGenerator.SourceMapGenerator; + sourceMap.SourceMapConsumer = sourceMapConsumer.SourceMapConsumer; + sourceMap.SourceNode = sourceNode.SourceNode; + + Object.defineProperty(sourceMap$1, "__esModule", { + value: true + }); + sourceMap$1.default = void 0; + + var _sourceMap$1 = sourceMap; + + class SourceMap { + constructor(opts, code) { + this._cachedMap = void 0; + this._code = void 0; + this._opts = void 0; + this._rawMappings = void 0; + this._lastGenLine = void 0; + this._lastSourceLine = void 0; + this._lastSourceColumn = void 0; + this._cachedMap = null; + this._code = code; + this._opts = opts; + this._rawMappings = []; + } + + get() { + if (!this._cachedMap) { + const map = this._cachedMap = new _sourceMap$1.SourceMapGenerator({ + sourceRoot: this._opts.sourceRoot + }); + const code = this._code; + + if (typeof code === "string") { + map.setSourceContent(this._opts.sourceFileName.replace(/\\/g, "/"), code); + } else if (typeof code === "object") { + Object.keys(code).forEach(sourceFileName => { + map.setSourceContent(sourceFileName.replace(/\\/g, "/"), code[sourceFileName]); + }); + } + + this._rawMappings.forEach(mapping => map.addMapping(mapping), map); + } + + return this._cachedMap.toJSON(); + } + + getRawMappings() { + return this._rawMappings.slice(); + } + + mark(generatedLine, generatedColumn, line, column, identifierName, filename, force) { + if (this._lastGenLine !== generatedLine && line === null) return; + + if (!force && this._lastGenLine === generatedLine && this._lastSourceLine === line && this._lastSourceColumn === column) { + return; + } + + this._cachedMap = null; + this._lastGenLine = generatedLine; + this._lastSourceLine = line; + this._lastSourceColumn = column; + + this._rawMappings.push({ + name: identifierName || undefined, + generated: { + line: generatedLine, + column: generatedColumn + }, + source: line == null ? undefined : (filename || this._opts.sourceFileName).replace(/\\/g, "/"), + original: line == null ? undefined : { + line: line, + column: column + } + }); + } + + } + + sourceMap$1.default = SourceMap; + + var printer = {}; + + var buffer = {}; + + Object.defineProperty(buffer, "__esModule", { + value: true + }); + buffer.default = void 0; + const SPACES_RE = /^[ \t]+$/; + + let Buffer$1 = class Buffer { + constructor(map) { + this._map = null; + this._buf = ""; + this._last = 0; + this._queue = []; + this._position = { + line: 1, + column: 0 + }; + this._sourcePosition = { + identifierName: null, + line: null, + column: null, + filename: null + }; + this._disallowedPop = null; + this._map = map; + } + + get() { + this._flush(); + + const map = this._map; + const result = { + code: this._buf.trimRight(), + map: null, + rawMappings: map == null ? void 0 : map.getRawMappings() + }; + + if (map) { + Object.defineProperty(result, "map", { + configurable: true, + enumerable: true, + + get() { + return this.map = map.get(); + }, + + set(value) { + Object.defineProperty(this, "map", { + value, + writable: true + }); + } + + }); + } + + return result; + } + + append(str) { + this._flush(); + + const { + line, + column, + filename, + identifierName, + force + } = this._sourcePosition; + + this._append(str, line, column, identifierName, filename, force); + } + + queue(str) { + if (str === "\n") { + while (this._queue.length > 0 && SPACES_RE.test(this._queue[0][0])) { + this._queue.shift(); + } + } + + const { + line, + column, + filename, + identifierName, + force + } = this._sourcePosition; + + this._queue.unshift([str, line, column, identifierName, filename, force]); + } + + _flush() { + let item; + + while (item = this._queue.pop()) { + this._append(...item); + } + } + + _append(str, line, column, identifierName, filename, force) { + this._buf += str; + this._last = str.charCodeAt(str.length - 1); + let i = str.indexOf("\n"); + let last = 0; + + if (i !== 0) { + this._mark(line, column, identifierName, filename, force); + } + + while (i !== -1) { + this._position.line++; + this._position.column = 0; + last = i + 1; + + if (last < str.length) { + this._mark(++line, 0, identifierName, filename, force); + } + + i = str.indexOf("\n", last); + } + + this._position.column += str.length - last; + } + + _mark(line, column, identifierName, filename, force) { + var _this$_map; + + (_this$_map = this._map) == null ? void 0 : _this$_map.mark(this._position.line, this._position.column, line, column, identifierName, filename, force); + } + + removeTrailingNewline() { + if (this._queue.length > 0 && this._queue[0][0] === "\n") { + this._queue.shift(); + } + } + + removeLastSemicolon() { + if (this._queue.length > 0 && this._queue[0][0] === ";") { + this._queue.shift(); + } + } + + getLastChar() { + let last; + + if (this._queue.length > 0) { + const str = this._queue[0][0]; + last = str.charCodeAt(0); + } else { + last = this._last; + } + + return last; + } + + endsWithCharAndNewline() { + const queue = this._queue; + + if (queue.length > 0) { + const last = queue[0][0]; + const lastCp = last.charCodeAt(0); + if (lastCp !== 10) return; + + if (queue.length > 1) { + const secondLast = queue[1][0]; + return secondLast.charCodeAt(0); + } else { + return this._last; + } + } + } + + hasContent() { + return this._queue.length > 0 || !!this._last; + } + + exactSource(loc, cb) { + this.source("start", loc, true); + cb(); + this.source("end", loc); + + this._disallowPop("start", loc); + } + + source(prop, loc, force) { + if (prop && !loc) return; + + this._normalizePosition(prop, loc, this._sourcePosition, force); + } + + withSource(prop, loc, cb) { + if (!this._map) return cb(); + const originalLine = this._sourcePosition.line; + const originalColumn = this._sourcePosition.column; + const originalFilename = this._sourcePosition.filename; + const originalIdentifierName = this._sourcePosition.identifierName; + this.source(prop, loc); + cb(); + + if ((!this._sourcePosition.force || this._sourcePosition.line !== originalLine || this._sourcePosition.column !== originalColumn || this._sourcePosition.filename !== originalFilename) && (!this._disallowedPop || this._disallowedPop.line !== originalLine || this._disallowedPop.column !== originalColumn || this._disallowedPop.filename !== originalFilename)) { + this._sourcePosition.line = originalLine; + this._sourcePosition.column = originalColumn; + this._sourcePosition.filename = originalFilename; + this._sourcePosition.identifierName = originalIdentifierName; + this._sourcePosition.force = false; + this._disallowedPop = null; + } + } + + _disallowPop(prop, loc) { + if (prop && !loc) return; + this._disallowedPop = this._normalizePosition(prop, loc); + } + + _normalizePosition(prop, loc, targetObj, force) { + const pos = loc ? loc[prop] : null; + + if (targetObj === undefined) { + targetObj = { + identifierName: null, + line: null, + column: null, + filename: null, + force: false + }; + } + + const origLine = targetObj.line; + const origColumn = targetObj.column; + const origFilename = targetObj.filename; + targetObj.identifierName = prop === "start" && (loc == null ? void 0 : loc.identifierName) || null; + targetObj.line = pos == null ? void 0 : pos.line; + targetObj.column = pos == null ? void 0 : pos.column; + targetObj.filename = loc == null ? void 0 : loc.filename; + + if (force || targetObj.line !== origLine || targetObj.column !== origColumn || targetObj.filename !== origFilename) { + targetObj.force = force; + } + + return targetObj; + } + + getCurrentColumn() { + const extra = this._queue.reduce((acc, item) => item[0] + acc, ""); + + const lastIndex = extra.lastIndexOf("\n"); + return lastIndex === -1 ? this._position.column + extra.length : extra.length - 1 - lastIndex; + } + + getCurrentLine() { + const extra = this._queue.reduce((acc, item) => item[0] + acc, ""); + + let count = 0; + + for (let i = 0; i < extra.length; i++) { + if (extra[i] === "\n") count++; + } + + return this._position.line + count; + } + + }; + + buffer.default = Buffer$1; + + var node = {}; + + var whitespace$1 = {}; + + Object.defineProperty(whitespace$1, "__esModule", { + value: true + }); + whitespace$1.list = whitespace$1.nodes = void 0; + + var _t$9 = lib$6; + + const { + FLIPPED_ALIAS_KEYS: FLIPPED_ALIAS_KEYS$1, + isArrayExpression, + isAssignmentExpression: isAssignmentExpression$1, + isBinary: isBinary$1, + isBlockStatement, + isCallExpression: isCallExpression$3, + isFunction: isFunction$2, + isIdentifier: isIdentifier$2, + isLiteral: isLiteral$1, + isMemberExpression: isMemberExpression$3, + isObjectExpression, + isOptionalCallExpression: isOptionalCallExpression$1, + isOptionalMemberExpression: isOptionalMemberExpression$1, + isStringLiteral + } = _t$9; + + function crawl(node, state = {}) { + if (isMemberExpression$3(node) || isOptionalMemberExpression$1(node)) { + crawl(node.object, state); + if (node.computed) crawl(node.property, state); + } else if (isBinary$1(node) || isAssignmentExpression$1(node)) { + crawl(node.left, state); + crawl(node.right, state); + } else if (isCallExpression$3(node) || isOptionalCallExpression$1(node)) { + state.hasCall = true; + crawl(node.callee, state); + } else if (isFunction$2(node)) { + state.hasFunction = true; + } else if (isIdentifier$2(node)) { + state.hasHelper = state.hasHelper || isHelper(node.callee); + } + + return state; + } + + function isHelper(node) { + if (isMemberExpression$3(node)) { + return isHelper(node.object) || isHelper(node.property); + } else if (isIdentifier$2(node)) { + return node.name === "require" || node.name[0] === "_"; + } else if (isCallExpression$3(node)) { + return isHelper(node.callee); + } else if (isBinary$1(node) || isAssignmentExpression$1(node)) { + return isIdentifier$2(node.left) && isHelper(node.left) || isHelper(node.right); + } else { + return false; + } + } + + function isType(node) { + return isLiteral$1(node) || isObjectExpression(node) || isArrayExpression(node) || isIdentifier$2(node) || isMemberExpression$3(node); + } + + const nodes = { + AssignmentExpression(node) { + const state = crawl(node.right); + + if (state.hasCall && state.hasHelper || state.hasFunction) { + return { + before: state.hasFunction, + after: true + }; + } + }, + + SwitchCase(node, parent) { + return { + before: !!node.consequent.length || parent.cases[0] === node, + after: !node.consequent.length && parent.cases[parent.cases.length - 1] === node + }; + }, + + LogicalExpression(node) { + if (isFunction$2(node.left) || isFunction$2(node.right)) { + return { + after: true + }; + } + }, + + Literal(node) { + if (isStringLiteral(node) && node.value === "use strict") { + return { + after: true + }; + } + }, + + CallExpression(node) { + if (isFunction$2(node.callee) || isHelper(node)) { + return { + before: true, + after: true + }; + } + }, + + OptionalCallExpression(node) { + if (isFunction$2(node.callee)) { + return { + before: true, + after: true + }; + } + }, + + VariableDeclaration(node) { + for (let i = 0; i < node.declarations.length; i++) { + const declar = node.declarations[i]; + let enabled = isHelper(declar.id) && !isType(declar.init); + + if (!enabled) { + const state = crawl(declar.init); + enabled = isHelper(declar.init) && state.hasCall || state.hasFunction; + } + + if (enabled) { + return { + before: true, + after: true + }; + } + } + }, + + IfStatement(node) { + if (isBlockStatement(node.consequent)) { + return { + before: true, + after: true + }; + } + } + + }; + whitespace$1.nodes = nodes; + + nodes.ObjectProperty = nodes.ObjectTypeProperty = nodes.ObjectMethod = function (node, parent) { + if (parent.properties[0] === node) { + return { + before: true + }; + } + }; + + nodes.ObjectTypeCallProperty = function (node, parent) { + var _parent$properties; + + if (parent.callProperties[0] === node && !((_parent$properties = parent.properties) != null && _parent$properties.length)) { + return { + before: true + }; + } + }; + + nodes.ObjectTypeIndexer = function (node, parent) { + var _parent$properties2, _parent$callPropertie; + + if (parent.indexers[0] === node && !((_parent$properties2 = parent.properties) != null && _parent$properties2.length) && !((_parent$callPropertie = parent.callProperties) != null && _parent$callPropertie.length)) { + return { + before: true + }; + } + }; + + nodes.ObjectTypeInternalSlot = function (node, parent) { + var _parent$properties3, _parent$callPropertie2, _parent$indexers; + + if (parent.internalSlots[0] === node && !((_parent$properties3 = parent.properties) != null && _parent$properties3.length) && !((_parent$callPropertie2 = parent.callProperties) != null && _parent$callPropertie2.length) && !((_parent$indexers = parent.indexers) != null && _parent$indexers.length)) { + return { + before: true + }; + } + }; + + const list = { + VariableDeclaration(node) { + return node.declarations.map(decl => decl.init); + }, + + ArrayExpression(node) { + return node.elements; + }, + + ObjectExpression(node) { + return node.properties; + } + + }; + whitespace$1.list = list; + [["Function", true], ["Class", true], ["Loop", true], ["LabeledStatement", true], ["SwitchStatement", true], ["TryStatement", true]].forEach(function ([type, amounts]) { + if (typeof amounts === "boolean") { + amounts = { + after: amounts, + before: amounts + }; + } + + [type].concat(FLIPPED_ALIAS_KEYS$1[type] || []).forEach(function (type) { + nodes[type] = function () { + return amounts; + }; + }); + }); + + var parentheses = {}; + + Object.defineProperty(parentheses, "__esModule", { + value: true + }); + parentheses.NullableTypeAnnotation = NullableTypeAnnotation; + parentheses.FunctionTypeAnnotation = FunctionTypeAnnotation; + parentheses.UpdateExpression = UpdateExpression$1; + parentheses.ObjectExpression = ObjectExpression$1; + parentheses.DoExpression = DoExpression$1; + parentheses.Binary = Binary; + parentheses.IntersectionTypeAnnotation = parentheses.UnionTypeAnnotation = UnionTypeAnnotation; + parentheses.OptionalIndexedAccessType = OptionalIndexedAccessType; + parentheses.TSAsExpression = TSAsExpression$1; + parentheses.TSTypeAssertion = TSTypeAssertion$1; + parentheses.TSIntersectionType = parentheses.TSUnionType = TSUnionType$1; + parentheses.TSInferType = TSInferType$1; + parentheses.BinaryExpression = BinaryExpression; + parentheses.SequenceExpression = SequenceExpression$1; + parentheses.AwaitExpression = parentheses.YieldExpression = YieldExpression$1; + parentheses.ClassExpression = ClassExpression; + parentheses.UnaryLike = UnaryLike; + parentheses.FunctionExpression = FunctionExpression$1; + parentheses.ArrowFunctionExpression = ArrowFunctionExpression$1; + parentheses.ConditionalExpression = ConditionalExpression$1; + parentheses.OptionalCallExpression = parentheses.OptionalMemberExpression = OptionalMemberExpression$1; + parentheses.AssignmentExpression = AssignmentExpression$1; + parentheses.LogicalExpression = LogicalExpression; + parentheses.Identifier = Identifier$1; + + var _t$8 = lib$6; + + const { + isArrayTypeAnnotation, + isArrowFunctionExpression, + isAssignmentExpression, + isAwaitExpression, + isBinary, + isBinaryExpression, + isCallExpression: isCallExpression$2, + isClassDeclaration: isClassDeclaration$1, + isClassExpression, + isConditional, + isConditionalExpression, + isExportDeclaration, + isExportDefaultDeclaration: isExportDefaultDeclaration$1, + isExpressionStatement: isExpressionStatement$1, + isFor: isFor$1, + isForInStatement, + isForOfStatement, + isForStatement: isForStatement$1, + isIfStatement: isIfStatement$1, + isIndexedAccessType, + isIntersectionTypeAnnotation, + isLogicalExpression, + isMemberExpression: isMemberExpression$2, + isNewExpression: isNewExpression$2, + isNullableTypeAnnotation, + isObjectPattern, + isOptionalCallExpression, + isOptionalMemberExpression, + isReturnStatement, + isSequenceExpression, + isSwitchStatement, + isTSArrayType, + isTSAsExpression, + isTSIntersectionType, + isTSNonNullExpression, + isTSOptionalType, + isTSRestType, + isTSTypeAssertion, + isTSUnionType, + isTaggedTemplateExpression, + isThrowStatement, + isTypeAnnotation, + isUnaryLike, + isUnionTypeAnnotation, + isVariableDeclarator, + isWhileStatement, + isYieldExpression + } = _t$8; + const PRECEDENCE = { + "||": 0, + "??": 0, + "&&": 1, + "|": 2, + "^": 3, + "&": 4, + "==": 5, + "===": 5, + "!=": 5, + "!==": 5, + "<": 6, + ">": 6, + "<=": 6, + ">=": 6, + in: 6, + instanceof: 6, + ">>": 7, + "<<": 7, + ">>>": 7, + "+": 8, + "-": 8, + "*": 9, + "/": 9, + "%": 9, + "**": 10 + }; + + const isClassExtendsClause = (node, parent) => (isClassDeclaration$1(parent) || isClassExpression(parent)) && parent.superClass === node; + + const hasPostfixPart = (node, parent) => (isMemberExpression$2(parent) || isOptionalMemberExpression(parent)) && parent.object === node || (isCallExpression$2(parent) || isOptionalCallExpression(parent) || isNewExpression$2(parent)) && parent.callee === node || isTaggedTemplateExpression(parent) && parent.tag === node || isTSNonNullExpression(parent); + + function NullableTypeAnnotation(node, parent) { + return isArrayTypeAnnotation(parent); + } + + function FunctionTypeAnnotation(node, parent, printStack) { + return isUnionTypeAnnotation(parent) || isIntersectionTypeAnnotation(parent) || isArrayTypeAnnotation(parent) || isTypeAnnotation(parent) && isArrowFunctionExpression(printStack[printStack.length - 3]); + } + + function UpdateExpression$1(node, parent) { + return hasPostfixPart(node, parent) || isClassExtendsClause(node, parent); + } + + function ObjectExpression$1(node, parent, printStack) { + return isFirstInContext(printStack, { + expressionStatement: true, + arrowBody: true + }); + } + + function DoExpression$1(node, parent, printStack) { + return !node.async && isFirstInContext(printStack, { + expressionStatement: true + }); + } + + function Binary(node, parent) { + if (node.operator === "**" && isBinaryExpression(parent, { + operator: "**" + })) { + return parent.left === node; + } + + if (isClassExtendsClause(node, parent)) { + return true; + } + + if (hasPostfixPart(node, parent) || isUnaryLike(parent) || isAwaitExpression(parent)) { + return true; + } + + if (isBinary(parent)) { + const parentOp = parent.operator; + const parentPos = PRECEDENCE[parentOp]; + const nodeOp = node.operator; + const nodePos = PRECEDENCE[nodeOp]; + + if (parentPos === nodePos && parent.right === node && !isLogicalExpression(parent) || parentPos > nodePos) { + return true; + } + } + } + + function UnionTypeAnnotation(node, parent) { + return isArrayTypeAnnotation(parent) || isNullableTypeAnnotation(parent) || isIntersectionTypeAnnotation(parent) || isUnionTypeAnnotation(parent); + } + + function OptionalIndexedAccessType(node, parent) { + return isIndexedAccessType(parent, { + objectType: node + }); + } + + function TSAsExpression$1() { + return true; + } + + function TSTypeAssertion$1() { + return true; + } + + function TSUnionType$1(node, parent) { + return isTSArrayType(parent) || isTSOptionalType(parent) || isTSIntersectionType(parent) || isTSUnionType(parent) || isTSRestType(parent); + } + + function TSInferType$1(node, parent) { + return isTSArrayType(parent) || isTSOptionalType(parent); + } + + function BinaryExpression(node, parent) { + return node.operator === "in" && (isVariableDeclarator(parent) || isFor$1(parent)); + } + + function SequenceExpression$1(node, parent) { + if (isForStatement$1(parent) || isThrowStatement(parent) || isReturnStatement(parent) || isIfStatement$1(parent) && parent.test === node || isWhileStatement(parent) && parent.test === node || isForInStatement(parent) && parent.right === node || isSwitchStatement(parent) && parent.discriminant === node || isExpressionStatement$1(parent) && parent.expression === node) { + return false; + } + + return true; + } + + function YieldExpression$1(node, parent) { + return isBinary(parent) || isUnaryLike(parent) || hasPostfixPart(node, parent) || isAwaitExpression(parent) && isYieldExpression(node) || isConditionalExpression(parent) && node === parent.test || isClassExtendsClause(node, parent); + } + + function ClassExpression(node, parent, printStack) { + return isFirstInContext(printStack, { + expressionStatement: true, + exportDefault: true + }); + } + + function UnaryLike(node, parent) { + return hasPostfixPart(node, parent) || isBinaryExpression(parent, { + operator: "**", + left: node + }) || isClassExtendsClause(node, parent); + } + + function FunctionExpression$1(node, parent, printStack) { + return isFirstInContext(printStack, { + expressionStatement: true, + exportDefault: true + }); + } + + function ArrowFunctionExpression$1(node, parent) { + return isExportDeclaration(parent) || ConditionalExpression$1(node, parent); + } + + function ConditionalExpression$1(node, parent) { + if (isUnaryLike(parent) || isBinary(parent) || isConditionalExpression(parent, { + test: node + }) || isAwaitExpression(parent) || isTSTypeAssertion(parent) || isTSAsExpression(parent)) { + return true; + } + + return UnaryLike(node, parent); + } + + function OptionalMemberExpression$1(node, parent) { + return isCallExpression$2(parent, { + callee: node + }) || isMemberExpression$2(parent, { + object: node + }); + } + + function AssignmentExpression$1(node, parent) { + if (isObjectPattern(node.left)) { + return true; + } else { + return ConditionalExpression$1(node, parent); + } + } + + function LogicalExpression(node, parent) { + switch (node.operator) { + case "||": + if (!isLogicalExpression(parent)) return false; + return parent.operator === "??" || parent.operator === "&&"; + + case "&&": + return isLogicalExpression(parent, { + operator: "??" + }); + + case "??": + return isLogicalExpression(parent) && parent.operator !== "??"; + } + } + + function Identifier$1(node, parent, printStack) { + if (node.name === "let") { + const isFollowedByBracket = isMemberExpression$2(parent, { + object: node, + computed: true + }) || isOptionalMemberExpression(parent, { + object: node, + computed: true, + optional: false + }); + return isFirstInContext(printStack, { + expressionStatement: isFollowedByBracket, + forHead: isFollowedByBracket, + forInHead: isFollowedByBracket, + forOfHead: true + }); + } + + return node.name === "async" && isForOfStatement(parent) && node === parent.left; + } + + function isFirstInContext(printStack, { + expressionStatement = false, + arrowBody = false, + exportDefault = false, + forHead = false, + forInHead = false, + forOfHead = false + }) { + let i = printStack.length - 1; + let node = printStack[i]; + i--; + let parent = printStack[i]; + + while (i >= 0) { + if (expressionStatement && isExpressionStatement$1(parent, { + expression: node + }) || exportDefault && isExportDefaultDeclaration$1(parent, { + declaration: node + }) || arrowBody && isArrowFunctionExpression(parent, { + body: node + }) || forHead && isForStatement$1(parent, { + init: node + }) || forInHead && isForInStatement(parent, { + left: node + }) || forOfHead && isForOfStatement(parent, { + left: node + })) { + return true; + } + + if (hasPostfixPart(node, parent) && !isNewExpression$2(parent) || isSequenceExpression(parent) && parent.expressions[0] === node || isConditional(parent, { + test: node + }) || isBinary(parent, { + left: node + }) || isAssignmentExpression(parent, { + left: node + })) { + node = parent; + i--; + parent = printStack[i]; + } else { + return false; + } + } + + return false; + } + + Object.defineProperty(node, "__esModule", { + value: true + }); + node.needsWhitespace = needsWhitespace; + node.needsWhitespaceBefore = needsWhitespaceBefore$1; + node.needsWhitespaceAfter = needsWhitespaceAfter$1; + node.needsParens = needsParens$1; + + var whitespace = whitespace$1; + + var parens = parentheses; + + var _t$7 = lib$6; + + const { + FLIPPED_ALIAS_KEYS, + isCallExpression: isCallExpression$1, + isExpressionStatement, + isMemberExpression: isMemberExpression$1, + isNewExpression: isNewExpression$1 + } = _t$7; + + function expandAliases(obj) { + const newObj = {}; + + function add(type, func) { + const fn = newObj[type]; + newObj[type] = fn ? function (node, parent, stack) { + const result = fn(node, parent, stack); + return result == null ? func(node, parent, stack) : result; + } : func; + } + + for (const type of Object.keys(obj)) { + const aliases = FLIPPED_ALIAS_KEYS[type]; + + if (aliases) { + for (const alias of aliases) { + add(alias, obj[type]); + } + } else { + add(type, obj[type]); + } + } + + return newObj; + } + + const expandedParens = expandAliases(parens); + const expandedWhitespaceNodes = expandAliases(whitespace.nodes); + const expandedWhitespaceList = expandAliases(whitespace.list); + + function find(obj, node, parent, printStack) { + const fn = obj[node.type]; + return fn ? fn(node, parent, printStack) : null; + } + + function isOrHasCallExpression(node) { + if (isCallExpression$1(node)) { + return true; + } + + return isMemberExpression$1(node) && isOrHasCallExpression(node.object); + } + + function needsWhitespace(node, parent, type) { + if (!node) return 0; + + if (isExpressionStatement(node)) { + node = node.expression; + } + + let linesInfo = find(expandedWhitespaceNodes, node, parent); + + if (!linesInfo) { + const items = find(expandedWhitespaceList, node, parent); + + if (items) { + for (let i = 0; i < items.length; i++) { + linesInfo = needsWhitespace(items[i], node, type); + if (linesInfo) break; + } + } + } + + if (typeof linesInfo === "object" && linesInfo !== null) { + return linesInfo[type] || 0; + } + + return 0; + } + + function needsWhitespaceBefore$1(node, parent) { + return needsWhitespace(node, parent, "before"); + } + + function needsWhitespaceAfter$1(node, parent) { + return needsWhitespace(node, parent, "after"); + } + + function needsParens$1(node, parent, printStack) { + if (!parent) return false; + + if (isNewExpression$1(parent) && parent.callee === node) { + if (isOrHasCallExpression(node)) return true; + } + + return find(expandedParens, node, parent, printStack); + } + + var generators = {}; + + var templateLiterals = {}; + + Object.defineProperty(templateLiterals, "__esModule", { + value: true + }); + templateLiterals.TaggedTemplateExpression = TaggedTemplateExpression; + templateLiterals.TemplateElement = TemplateElement; + templateLiterals.TemplateLiteral = TemplateLiteral; + + function TaggedTemplateExpression(node) { + this.print(node.tag, node); + this.print(node.typeParameters, node); + this.print(node.quasi, node); + } + + function TemplateElement(node, parent) { + const isFirst = parent.quasis[0] === node; + const isLast = parent.quasis[parent.quasis.length - 1] === node; + const value = (isFirst ? "`" : "}") + node.value.raw + (isLast ? "`" : "${"); + this.token(value); + } + + function TemplateLiteral(node) { + const quasis = node.quasis; + + for (let i = 0; i < quasis.length; i++) { + this.print(quasis[i], node); + + if (i + 1 < quasis.length) { + this.print(node.expressions[i], node); + } + } + } + + var expressions = {}; + + Object.defineProperty(expressions, "__esModule", { + value: true + }); + expressions.UnaryExpression = UnaryExpression; + expressions.DoExpression = DoExpression; + expressions.ParenthesizedExpression = ParenthesizedExpression; + expressions.UpdateExpression = UpdateExpression; + expressions.ConditionalExpression = ConditionalExpression; + expressions.NewExpression = NewExpression; + expressions.SequenceExpression = SequenceExpression; + expressions.ThisExpression = ThisExpression; + expressions.Super = Super; + expressions.Decorator = Decorator; + expressions.OptionalMemberExpression = OptionalMemberExpression; + expressions.OptionalCallExpression = OptionalCallExpression; + expressions.CallExpression = CallExpression; + expressions.Import = Import; + expressions.EmptyStatement = EmptyStatement; + expressions.ExpressionStatement = ExpressionStatement; + expressions.AssignmentPattern = AssignmentPattern; + expressions.LogicalExpression = expressions.BinaryExpression = expressions.AssignmentExpression = AssignmentExpression; + expressions.BindExpression = BindExpression; + expressions.MemberExpression = MemberExpression; + expressions.MetaProperty = MetaProperty; + expressions.PrivateName = PrivateName; + expressions.V8IntrinsicIdentifier = V8IntrinsicIdentifier; + expressions.ModuleExpression = ModuleExpression; + expressions.AwaitExpression = expressions.YieldExpression = void 0; + + var _t$6 = lib$6; + + var n$1 = node; + + const { + isCallExpression, + isLiteral, + isMemberExpression, + isNewExpression + } = _t$6; + + function UnaryExpression(node) { + if (node.operator === "void" || node.operator === "delete" || node.operator === "typeof" || node.operator === "throw") { + this.word(node.operator); + this.space(); + } else { + this.token(node.operator); + } + + this.print(node.argument, node); + } + + function DoExpression(node) { + if (node.async) { + this.word("async"); + this.space(); + } + + this.word("do"); + this.space(); + this.print(node.body, node); + } + + function ParenthesizedExpression(node) { + this.token("("); + this.print(node.expression, node); + this.token(")"); + } + + function UpdateExpression(node) { + if (node.prefix) { + this.token(node.operator); + this.print(node.argument, node); + } else { + this.startTerminatorless(true); + this.print(node.argument, node); + this.endTerminatorless(); + this.token(node.operator); + } + } + + function ConditionalExpression(node) { + this.print(node.test, node); + this.space(); + this.token("?"); + this.space(); + this.print(node.consequent, node); + this.space(); + this.token(":"); + this.space(); + this.print(node.alternate, node); + } + + function NewExpression(node, parent) { + this.word("new"); + this.space(); + this.print(node.callee, node); + + if (this.format.minified && node.arguments.length === 0 && !node.optional && !isCallExpression(parent, { + callee: node + }) && !isMemberExpression(parent) && !isNewExpression(parent)) { + return; + } + + this.print(node.typeArguments, node); + this.print(node.typeParameters, node); + + if (node.optional) { + this.token("?."); + } + + this.token("("); + this.printList(node.arguments, node); + this.token(")"); + } + + function SequenceExpression(node) { + this.printList(node.expressions, node); + } + + function ThisExpression() { + this.word("this"); + } + + function Super() { + this.word("super"); + } + + function Decorator(node) { + this.token("@"); + this.print(node.expression, node); + this.newline(); + } + + function OptionalMemberExpression(node) { + this.print(node.object, node); + + if (!node.computed && isMemberExpression(node.property)) { + throw new TypeError("Got a MemberExpression for MemberExpression property"); + } + + let computed = node.computed; + + if (isLiteral(node.property) && typeof node.property.value === "number") { + computed = true; + } + + if (node.optional) { + this.token("?."); + } + + if (computed) { + this.token("["); + this.print(node.property, node); + this.token("]"); + } else { + if (!node.optional) { + this.token("."); + } + + this.print(node.property, node); + } + } + + function OptionalCallExpression(node) { + this.print(node.callee, node); + this.print(node.typeArguments, node); + this.print(node.typeParameters, node); + + if (node.optional) { + this.token("?."); + } + + this.token("("); + this.printList(node.arguments, node); + this.token(")"); + } + + function CallExpression(node) { + this.print(node.callee, node); + this.print(node.typeArguments, node); + this.print(node.typeParameters, node); + this.token("("); + this.printList(node.arguments, node); + this.token(")"); + } + + function Import() { + this.word("import"); + } + + function buildYieldAwait(keyword) { + return function (node) { + this.word(keyword); + + if (node.delegate) { + this.token("*"); + } + + if (node.argument) { + this.space(); + const terminatorState = this.startTerminatorless(); + this.print(node.argument, node); + this.endTerminatorless(terminatorState); + } + }; + } + + const YieldExpression = buildYieldAwait("yield"); + expressions.YieldExpression = YieldExpression; + const AwaitExpression = buildYieldAwait("await"); + expressions.AwaitExpression = AwaitExpression; + + function EmptyStatement() { + this.semicolon(true); + } + + function ExpressionStatement(node) { + this.print(node.expression, node); + this.semicolon(); + } + + function AssignmentPattern(node) { + this.print(node.left, node); + if (node.left.optional) this.token("?"); + this.print(node.left.typeAnnotation, node); + this.space(); + this.token("="); + this.space(); + this.print(node.right, node); + } + + function AssignmentExpression(node, parent) { + const parens = this.inForStatementInitCounter && node.operator === "in" && !n$1.needsParens(node, parent); + + if (parens) { + this.token("("); + } + + this.print(node.left, node); + this.space(); + + if (node.operator === "in" || node.operator === "instanceof") { + this.word(node.operator); + } else { + this.token(node.operator); + } + + this.space(); + this.print(node.right, node); + + if (parens) { + this.token(")"); + } + } + + function BindExpression(node) { + this.print(node.object, node); + this.token("::"); + this.print(node.callee, node); + } + + function MemberExpression(node) { + this.print(node.object, node); + + if (!node.computed && isMemberExpression(node.property)) { + throw new TypeError("Got a MemberExpression for MemberExpression property"); + } + + let computed = node.computed; + + if (isLiteral(node.property) && typeof node.property.value === "number") { + computed = true; + } + + if (computed) { + this.token("["); + this.print(node.property, node); + this.token("]"); + } else { + this.token("."); + this.print(node.property, node); + } + } + + function MetaProperty(node) { + this.print(node.meta, node); + this.token("."); + this.print(node.property, node); + } + + function PrivateName(node) { + this.token("#"); + this.print(node.id, node); + } + + function V8IntrinsicIdentifier(node) { + this.token("%"); + this.word(node.name); + } + + function ModuleExpression(node) { + this.word("module"); + this.space(); + this.token("{"); + + if (node.body.body.length === 0) { + this.token("}"); + } else { + this.newline(); + this.printSequence(node.body.body, node, { + indent: true + }); + this.rightBrace(); + } + } + + var statements = {}; + + Object.defineProperty(statements, "__esModule", { + value: true + }); + statements.WithStatement = WithStatement; + statements.IfStatement = IfStatement; + statements.ForStatement = ForStatement; + statements.WhileStatement = WhileStatement; + statements.DoWhileStatement = DoWhileStatement; + statements.LabeledStatement = LabeledStatement; + statements.TryStatement = TryStatement; + statements.CatchClause = CatchClause; + statements.SwitchStatement = SwitchStatement; + statements.SwitchCase = SwitchCase; + statements.DebuggerStatement = DebuggerStatement; + statements.VariableDeclaration = VariableDeclaration; + statements.VariableDeclarator = VariableDeclarator; + statements.ThrowStatement = statements.BreakStatement = statements.ReturnStatement = statements.ContinueStatement = statements.ForOfStatement = statements.ForInStatement = void 0; + + var _t$5 = lib$6; + + const { + isFor, + isForStatement, + isIfStatement, + isStatement: isStatement$1 + } = _t$5; + + function WithStatement(node) { + this.word("with"); + this.space(); + this.token("("); + this.print(node.object, node); + this.token(")"); + this.printBlock(node); + } + + function IfStatement(node) { + this.word("if"); + this.space(); + this.token("("); + this.print(node.test, node); + this.token(")"); + this.space(); + const needsBlock = node.alternate && isIfStatement(getLastStatement(node.consequent)); + + if (needsBlock) { + this.token("{"); + this.newline(); + this.indent(); + } + + this.printAndIndentOnComments(node.consequent, node); + + if (needsBlock) { + this.dedent(); + this.newline(); + this.token("}"); + } + + if (node.alternate) { + if (this.endsWith(125)) this.space(); + this.word("else"); + this.space(); + this.printAndIndentOnComments(node.alternate, node); + } + } + + function getLastStatement(statement) { + if (!isStatement$1(statement.body)) return statement; + return getLastStatement(statement.body); + } + + function ForStatement(node) { + this.word("for"); + this.space(); + this.token("("); + this.inForStatementInitCounter++; + this.print(node.init, node); + this.inForStatementInitCounter--; + this.token(";"); + + if (node.test) { + this.space(); + this.print(node.test, node); + } + + this.token(";"); + + if (node.update) { + this.space(); + this.print(node.update, node); + } + + this.token(")"); + this.printBlock(node); + } + + function WhileStatement(node) { + this.word("while"); + this.space(); + this.token("("); + this.print(node.test, node); + this.token(")"); + this.printBlock(node); + } + + const buildForXStatement = function (op) { + return function (node) { + this.word("for"); + this.space(); + + if (op === "of" && node.await) { + this.word("await"); + this.space(); + } + + this.token("("); + this.print(node.left, node); + this.space(); + this.word(op); + this.space(); + this.print(node.right, node); + this.token(")"); + this.printBlock(node); + }; + }; + + const ForInStatement = buildForXStatement("in"); + statements.ForInStatement = ForInStatement; + const ForOfStatement = buildForXStatement("of"); + statements.ForOfStatement = ForOfStatement; + + function DoWhileStatement(node) { + this.word("do"); + this.space(); + this.print(node.body, node); + this.space(); + this.word("while"); + this.space(); + this.token("("); + this.print(node.test, node); + this.token(")"); + this.semicolon(); + } + + function buildLabelStatement(prefix, key = "label") { + return function (node) { + this.word(prefix); + const label = node[key]; + + if (label) { + this.space(); + const isLabel = key == "label"; + const terminatorState = this.startTerminatorless(isLabel); + this.print(label, node); + this.endTerminatorless(terminatorState); + } + + this.semicolon(); + }; + } + + const ContinueStatement = buildLabelStatement("continue"); + statements.ContinueStatement = ContinueStatement; + const ReturnStatement = buildLabelStatement("return", "argument"); + statements.ReturnStatement = ReturnStatement; + const BreakStatement = buildLabelStatement("break"); + statements.BreakStatement = BreakStatement; + const ThrowStatement = buildLabelStatement("throw", "argument"); + statements.ThrowStatement = ThrowStatement; + + function LabeledStatement(node) { + this.print(node.label, node); + this.token(":"); + this.space(); + this.print(node.body, node); + } + + function TryStatement(node) { + this.word("try"); + this.space(); + this.print(node.block, node); + this.space(); + + if (node.handlers) { + this.print(node.handlers[0], node); + } else { + this.print(node.handler, node); + } + + if (node.finalizer) { + this.space(); + this.word("finally"); + this.space(); + this.print(node.finalizer, node); + } + } + + function CatchClause(node) { + this.word("catch"); + this.space(); + + if (node.param) { + this.token("("); + this.print(node.param, node); + this.print(node.param.typeAnnotation, node); + this.token(")"); + this.space(); + } + + this.print(node.body, node); + } + + function SwitchStatement(node) { + this.word("switch"); + this.space(); + this.token("("); + this.print(node.discriminant, node); + this.token(")"); + this.space(); + this.token("{"); + this.printSequence(node.cases, node, { + indent: true, + + addNewlines(leading, cas) { + if (!leading && node.cases[node.cases.length - 1] === cas) return -1; + } + + }); + this.token("}"); + } + + function SwitchCase(node) { + if (node.test) { + this.word("case"); + this.space(); + this.print(node.test, node); + this.token(":"); + } else { + this.word("default"); + this.token(":"); + } + + if (node.consequent.length) { + this.newline(); + this.printSequence(node.consequent, node, { + indent: true + }); + } + } + + function DebuggerStatement() { + this.word("debugger"); + this.semicolon(); + } + + function variableDeclarationIndent() { + this.token(","); + this.newline(); + + if (this.endsWith(10)) { + for (let i = 0; i < 4; i++) this.space(true); + } + } + + function constDeclarationIndent() { + this.token(","); + this.newline(); + + if (this.endsWith(10)) { + for (let i = 0; i < 6; i++) this.space(true); + } + } + + function VariableDeclaration(node, parent) { + if (node.declare) { + this.word("declare"); + this.space(); + } + + this.word(node.kind); + this.space(); + let hasInits = false; + + if (!isFor(parent)) { + for (const declar of node.declarations) { + if (declar.init) { + hasInits = true; + } + } + } + + let separator; + + if (hasInits) { + separator = node.kind === "const" ? constDeclarationIndent : variableDeclarationIndent; + } + + this.printList(node.declarations, node, { + separator + }); + + if (isFor(parent)) { + if (isForStatement(parent)) { + if (parent.init === node) return; + } else { + if (parent.left === node) return; + } + } + + this.semicolon(); + } + + function VariableDeclarator(node) { + this.print(node.id, node); + if (node.definite) this.token("!"); + this.print(node.id.typeAnnotation, node); + + if (node.init) { + this.space(); + this.token("="); + this.space(); + this.print(node.init, node); + } + } + + var classes = {}; + + Object.defineProperty(classes, "__esModule", { + value: true + }); + classes.ClassExpression = classes.ClassDeclaration = ClassDeclaration; + classes.ClassBody = ClassBody; + classes.ClassProperty = ClassProperty; + classes.ClassPrivateProperty = ClassPrivateProperty; + classes.ClassMethod = ClassMethod; + classes.ClassPrivateMethod = ClassPrivateMethod; + classes._classMethodHead = _classMethodHead; + classes.StaticBlock = StaticBlock; + + var _t$4 = lib$6; + + const { + isExportDefaultDeclaration, + isExportNamedDeclaration + } = _t$4; + + function ClassDeclaration(node, parent) { + if (!this.format.decoratorsBeforeExport || !isExportDefaultDeclaration(parent) && !isExportNamedDeclaration(parent)) { + this.printJoin(node.decorators, node); + } + + if (node.declare) { + this.word("declare"); + this.space(); + } + + if (node.abstract) { + this.word("abstract"); + this.space(); + } + + this.word("class"); + + if (node.id) { + this.space(); + this.print(node.id, node); + } + + this.print(node.typeParameters, node); + + if (node.superClass) { + this.space(); + this.word("extends"); + this.space(); + this.print(node.superClass, node); + this.print(node.superTypeParameters, node); + } + + if (node.implements) { + this.space(); + this.word("implements"); + this.space(); + this.printList(node.implements, node); + } + + this.space(); + this.print(node.body, node); + } + + function ClassBody(node) { + this.token("{"); + this.printInnerComments(node); + + if (node.body.length === 0) { + this.token("}"); + } else { + this.newline(); + this.indent(); + this.printSequence(node.body, node); + this.dedent(); + if (!this.endsWith(10)) this.newline(); + this.rightBrace(); + } + } + + function ClassProperty(node) { + this.printJoin(node.decorators, node); + this.source("end", node.key.loc); + this.tsPrintClassMemberModifiers(node, true); + + if (node.computed) { + this.token("["); + this.print(node.key, node); + this.token("]"); + } else { + this._variance(node); + + this.print(node.key, node); + } + + if (node.optional) { + this.token("?"); + } + + if (node.definite) { + this.token("!"); + } + + this.print(node.typeAnnotation, node); + + if (node.value) { + this.space(); + this.token("="); + this.space(); + this.print(node.value, node); + } + + this.semicolon(); + } + + function ClassPrivateProperty(node) { + this.printJoin(node.decorators, node); + + if (node.static) { + this.word("static"); + this.space(); + } + + this.print(node.key, node); + this.print(node.typeAnnotation, node); + + if (node.value) { + this.space(); + this.token("="); + this.space(); + this.print(node.value, node); + } + + this.semicolon(); + } + + function ClassMethod(node) { + this._classMethodHead(node); + + this.space(); + this.print(node.body, node); + } + + function ClassPrivateMethod(node) { + this._classMethodHead(node); + + this.space(); + this.print(node.body, node); + } + + function _classMethodHead(node) { + this.printJoin(node.decorators, node); + this.source("end", node.key.loc); + this.tsPrintClassMemberModifiers(node, false); + + this._methodHead(node); + } + + function StaticBlock(node) { + this.word("static"); + this.space(); + this.token("{"); + + if (node.body.length === 0) { + this.token("}"); + } else { + this.newline(); + this.printSequence(node.body, node, { + indent: true + }); + this.rightBrace(); + } + } + + var methods = {}; + + Object.defineProperty(methods, "__esModule", { + value: true + }); + methods._params = _params; + methods._parameters = _parameters; + methods._param = _param; + methods._methodHead = _methodHead; + methods._predicate = _predicate; + methods._functionHead = _functionHead; + methods.FunctionDeclaration = methods.FunctionExpression = FunctionExpression; + methods.ArrowFunctionExpression = ArrowFunctionExpression; + + var _t$3 = lib$6; + + const { + isIdentifier: isIdentifier$1 + } = _t$3; + + function _params(node) { + this.print(node.typeParameters, node); + this.token("("); + + this._parameters(node.params, node); + + this.token(")"); + this.print(node.returnType, node); + } + + function _parameters(parameters, parent) { + for (let i = 0; i < parameters.length; i++) { + this._param(parameters[i], parent); + + if (i < parameters.length - 1) { + this.token(","); + this.space(); + } + } + } + + function _param(parameter, parent) { + this.printJoin(parameter.decorators, parameter); + this.print(parameter, parent); + if (parameter.optional) this.token("?"); + this.print(parameter.typeAnnotation, parameter); + } + + function _methodHead(node) { + const kind = node.kind; + const key = node.key; + + if (kind === "get" || kind === "set") { + this.word(kind); + this.space(); + } + + if (node.async) { + this._catchUp("start", key.loc); + + this.word("async"); + this.space(); + } + + if (kind === "method" || kind === "init") { + if (node.generator) { + this.token("*"); + } + } + + if (node.computed) { + this.token("["); + this.print(key, node); + this.token("]"); + } else { + this.print(key, node); + } + + if (node.optional) { + this.token("?"); + } + + this._params(node); + } + + function _predicate(node) { + if (node.predicate) { + if (!node.returnType) { + this.token(":"); + } + + this.space(); + this.print(node.predicate, node); + } + } + + function _functionHead(node) { + if (node.async) { + this.word("async"); + this.space(); + } + + this.word("function"); + if (node.generator) this.token("*"); + this.space(); + + if (node.id) { + this.print(node.id, node); + } + + this._params(node); + + this._predicate(node); + } + + function FunctionExpression(node) { + this._functionHead(node); + + this.space(); + this.print(node.body, node); + } + + function ArrowFunctionExpression(node) { + if (node.async) { + this.word("async"); + this.space(); + } + + const firstParam = node.params[0]; + + if (!this.format.retainLines && !this.format.auxiliaryCommentBefore && !this.format.auxiliaryCommentAfter && node.params.length === 1 && isIdentifier$1(firstParam) && !hasTypesOrComments(node, firstParam)) { + this.print(firstParam, node); + } else { + this._params(node); + } + + this._predicate(node); + + this.space(); + this.token("=>"); + this.space(); + this.print(node.body, node); + } + + function hasTypesOrComments(node, param) { + var _param$leadingComment, _param$trailingCommen; + + return !!(node.typeParameters || node.returnType || node.predicate || param.typeAnnotation || param.optional || (_param$leadingComment = param.leadingComments) != null && _param$leadingComment.length || (_param$trailingCommen = param.trailingComments) != null && _param$trailingCommen.length); + } + + var modules = {}; + + Object.defineProperty(modules, "__esModule", { + value: true + }); + modules.ImportSpecifier = ImportSpecifier; + modules.ImportDefaultSpecifier = ImportDefaultSpecifier; + modules.ExportDefaultSpecifier = ExportDefaultSpecifier; + modules.ExportSpecifier = ExportSpecifier; + modules.ExportNamespaceSpecifier = ExportNamespaceSpecifier; + modules.ExportAllDeclaration = ExportAllDeclaration; + modules.ExportNamedDeclaration = ExportNamedDeclaration; + modules.ExportDefaultDeclaration = ExportDefaultDeclaration; + modules.ImportDeclaration = ImportDeclaration; + modules.ImportAttribute = ImportAttribute; + modules.ImportNamespaceSpecifier = ImportNamespaceSpecifier; + + var _t$2 = lib$6; + + const { + isClassDeclaration, + isExportDefaultSpecifier, + isExportNamespaceSpecifier, + isImportDefaultSpecifier, + isImportNamespaceSpecifier, + isStatement + } = _t$2; + + function ImportSpecifier(node) { + if (node.importKind === "type" || node.importKind === "typeof") { + this.word(node.importKind); + this.space(); + } + + this.print(node.imported, node); + + if (node.local && node.local.name !== node.imported.name) { + this.space(); + this.word("as"); + this.space(); + this.print(node.local, node); + } + } + + function ImportDefaultSpecifier(node) { + this.print(node.local, node); + } + + function ExportDefaultSpecifier(node) { + this.print(node.exported, node); + } + + function ExportSpecifier(node) { + this.print(node.local, node); + + if (node.exported && node.local.name !== node.exported.name) { + this.space(); + this.word("as"); + this.space(); + this.print(node.exported, node); + } + } + + function ExportNamespaceSpecifier(node) { + this.token("*"); + this.space(); + this.word("as"); + this.space(); + this.print(node.exported, node); + } + + function ExportAllDeclaration(node) { + this.word("export"); + this.space(); + + if (node.exportKind === "type") { + this.word("type"); + this.space(); + } + + this.token("*"); + this.space(); + this.word("from"); + this.space(); + this.print(node.source, node); + this.printAssertions(node); + this.semicolon(); + } + + function ExportNamedDeclaration(node) { + if (this.format.decoratorsBeforeExport && isClassDeclaration(node.declaration)) { + this.printJoin(node.declaration.decorators, node); + } + + this.word("export"); + this.space(); + ExportDeclaration.apply(this, arguments); + } + + function ExportDefaultDeclaration(node) { + if (this.format.decoratorsBeforeExport && isClassDeclaration(node.declaration)) { + this.printJoin(node.declaration.decorators, node); + } + + this.word("export"); + this.space(); + this.word("default"); + this.space(); + ExportDeclaration.apply(this, arguments); + } + + function ExportDeclaration(node) { + if (node.declaration) { + const declar = node.declaration; + this.print(declar, node); + if (!isStatement(declar)) this.semicolon(); + } else { + if (node.exportKind === "type") { + this.word("type"); + this.space(); + } + + const specifiers = node.specifiers.slice(0); + let hasSpecial = false; + + for (;;) { + const first = specifiers[0]; + + if (isExportDefaultSpecifier(first) || isExportNamespaceSpecifier(first)) { + hasSpecial = true; + this.print(specifiers.shift(), node); + + if (specifiers.length) { + this.token(","); + this.space(); + } + } else { + break; + } + } + + if (specifiers.length || !specifiers.length && !hasSpecial) { + this.token("{"); + + if (specifiers.length) { + this.space(); + this.printList(specifiers, node); + this.space(); + } + + this.token("}"); + } + + if (node.source) { + this.space(); + this.word("from"); + this.space(); + this.print(node.source, node); + this.printAssertions(node); + } + + this.semicolon(); + } + } + + function ImportDeclaration(node) { + this.word("import"); + this.space(); + + if (node.importKind === "type" || node.importKind === "typeof") { + this.word(node.importKind); + this.space(); + } + + const specifiers = node.specifiers.slice(0); + + if (specifiers != null && specifiers.length) { + for (;;) { + const first = specifiers[0]; + + if (isImportDefaultSpecifier(first) || isImportNamespaceSpecifier(first)) { + this.print(specifiers.shift(), node); + + if (specifiers.length) { + this.token(","); + this.space(); + } + } else { + break; + } + } + + if (specifiers.length) { + this.token("{"); + this.space(); + this.printList(specifiers, node); + this.space(); + this.token("}"); + } + + this.space(); + this.word("from"); + this.space(); + } + + this.print(node.source, node); + this.printAssertions(node); + { + var _node$attributes; + + if ((_node$attributes = node.attributes) != null && _node$attributes.length) { + this.space(); + this.word("with"); + this.space(); + this.printList(node.attributes, node); + } + } + this.semicolon(); + } + + function ImportAttribute(node) { + this.print(node.key); + this.token(":"); + this.space(); + this.print(node.value); + } + + function ImportNamespaceSpecifier(node) { + this.token("*"); + this.space(); + this.word("as"); + this.space(); + this.print(node.local, node); + } + + var types = {}; + + var lookup = []; + var revLookup = []; + var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array; + var inited = false; + function init () { + inited = true; + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + + revLookup['-'.charCodeAt(0)] = 62; + revLookup['_'.charCodeAt(0)] = 63; + } + + function toByteArray (b64) { + if (!inited) { + init(); + } + var i, j, l, tmp, placeHolders, arr; + var len = b64.length; + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0; + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders); + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len; + + var L = 0; + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]; + arr[L++] = (tmp >> 16) & 0xFF; + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4); + arr[L++] = tmp & 0xFF; + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2); + arr[L++] = (tmp >> 8) & 0xFF; + arr[L++] = tmp & 0xFF; + } + + return arr + } + + function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] + } + + function encodeChunk (uint8, start, end) { + var tmp; + var output = []; + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]); + output.push(tripletToBase64(tmp)); + } + return output.join('') + } + + function fromByteArray (uint8) { + if (!inited) { + init(); + } + var tmp; + var len = uint8.length; + var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes + var output = ''; + var parts = []; + var maxChunkLength = 16383; // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))); + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1]; + output += lookup[tmp >> 2]; + output += lookup[(tmp << 4) & 0x3F]; + output += '=='; + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]); + output += lookup[tmp >> 10]; + output += lookup[(tmp >> 4) & 0x3F]; + output += lookup[(tmp << 2) & 0x3F]; + output += '='; + } + + parts.push(output); + + return parts.join('') + } + + function read (buffer, offset, isLE, mLen, nBytes) { + var e, m; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var nBits = -7; + var i = isLE ? (nBytes - 1) : 0; + var d = isLE ? -1 : 1; + var s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) + } + + function write (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c; + var eLen = nBytes * 8 - mLen - 1; + var eMax = (1 << eLen) - 1; + var eBias = eMax >> 1; + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0); + var i = isLE ? 0 : (nBytes - 1); + var d = isLE ? 1 : -1; + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + + buffer[offset + i - d] |= s * 128; + } + + var toString$1 = {}.toString; + + var isArray$1 = Array.isArray || function (arr) { + return toString$1.call(arr) == '[object Array]'; + }; + + /*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ + + var INSPECT_MAX_BYTES = 50; + + /** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they + * get the Object implementation, which is slower but behaves correctly. + */ + Buffer.TYPED_ARRAY_SUPPORT = global$1.TYPED_ARRAY_SUPPORT !== undefined + ? global$1.TYPED_ARRAY_SUPPORT + : true; + + /* + * Export kMaxLength after typed array support is determined. + */ + kMaxLength(); + + function kMaxLength () { + return Buffer.TYPED_ARRAY_SUPPORT + ? 0x7fffffff + : 0x3fffffff + } + + function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length); + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length); + } + that.length = length; + } + + return that + } + + /** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + + function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } + + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) + } + return from(this, arg, encodingOrOffset, length) + } + + Buffer.poolSize = 8192; // not used by this implementation + + // TODO: Legacy, not needed anymore. Remove in next major version. + Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype; + return arr + }; + + function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) + } + + /** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ + Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) + }; + + if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype; + Buffer.__proto__ = Uint8Array; + } + + function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } else if (size < 0) { + throw new RangeError('"size" argument must not be negative') + } + } + + function alloc (that, size, fill, encoding) { + assertSize(size); + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) + } + + /** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ + Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) + }; + + function allocUnsafe (that, size) { + assertSize(size); + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; ++i) { + that[i] = 0; + } + } + return that + } + + /** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ + Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) + }; + /** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ + Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) + }; + + function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8'; + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') + } + + var length = byteLength(string, encoding) | 0; + that = createBuffer(that, length); + + var actual = that.write(string, encoding); + + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + that = that.slice(0, actual); + } + + return that + } + + function fromArrayLike (that, array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0; + that = createBuffer(that, length); + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255; + } + return that + } + + function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength; // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (byteOffset === undefined && length === undefined) { + array = new Uint8Array(array); + } else if (length === undefined) { + array = new Uint8Array(array, byteOffset); + } else { + array = new Uint8Array(array, byteOffset, length); + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array; + that.__proto__ = Buffer.prototype; + } else { + // Fallback: Return an object instance of the Buffer class + that = fromArrayLike(that, array); + } + return that + } + + function fromObject (that, obj) { + if (internalIsBuffer(obj)) { + var len = checked(obj.length) | 0; + that = createBuffer(that, len); + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len); + return that + } + + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } + + if (obj.type === 'Buffer' && isArray$1(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') + } + + function checked (length) { + // Note: cannot use `length < kMaxLength()` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 + } + Buffer.isBuffer = isBuffer$1; + function internalIsBuffer (b) { + return !!(b != null && b._isBuffer) + } + + Buffer.compare = function compare (a, b) { + if (!internalIsBuffer(a) || !internalIsBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length; + var y = b.length; + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i]; + y = b[i]; + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 + }; + + Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } + }; + + Buffer.concat = function concat (list, length) { + if (!isArray$1(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i; + if (length === undefined) { + length = 0; + for (i = 0; i < list.length; ++i) { + length += list[i].length; + } + } + + var buffer = Buffer.allocUnsafe(length); + var pos = 0; + for (i = 0; i < list.length; ++i) { + var buf = list[i]; + if (!internalIsBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos); + pos += buf.length; + } + return buffer + }; + + function byteLength (string, encoding) { + if (internalIsBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string; + } + + var len = string.length; + if (len === 0) return 0 + + // Use a for loop to avoid recursion + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } + } + Buffer.byteLength = byteLength; + + function slowToString (encoding, start, end) { + var loweredCase = false; + + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0; + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length; + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0; + start >>>= 0; + + if (end <= start) { + return '' + } + + if (!encoding) encoding = 'utf8'; + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase(); + loweredCase = true; + } + } + } + + // The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect + // Buffer instances. + Buffer.prototype._isBuffer = true; + + function swap (b, n, m) { + var i = b[n]; + b[n] = b[m]; + b[m] = i; + } + + Buffer.prototype.swap16 = function swap16 () { + var len = this.length; + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1); + } + return this + }; + + Buffer.prototype.swap32 = function swap32 () { + var len = this.length; + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3); + swap(this, i + 1, i + 2); + } + return this + }; + + Buffer.prototype.swap64 = function swap64 () { + var len = this.length; + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7); + swap(this, i + 1, i + 6); + swap(this, i + 2, i + 5); + swap(this, i + 3, i + 4); + } + return this + }; + + Buffer.prototype.toString = function toString () { + var length = this.length | 0; + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) + }; + + Buffer.prototype.equals = function equals (b) { + if (!internalIsBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 + }; + + Buffer.prototype.inspect = function inspect () { + var str = ''; + var max = INSPECT_MAX_BYTES; + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' '); + if (this.length > max) str += ' ... '; + } + return '' + }; + + Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!internalIsBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0; + } + if (end === undefined) { + end = target ? target.length : 0; + } + if (thisStart === undefined) { + thisStart = 0; + } + if (thisEnd === undefined) { + thisEnd = this.length; + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0; + end >>>= 0; + thisStart >>>= 0; + thisEnd >>>= 0; + + if (this === target) return 0 + + var x = thisEnd - thisStart; + var y = end - start; + var len = Math.min(x, y); + + var thisCopy = this.slice(thisStart, thisEnd); + var targetCopy = target.slice(start, end); + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i]; + y = targetCopy[i]; + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 + }; + + // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, + // OR the last index of `val` in `buffer` at offset <= `byteOffset`. + // + // Arguments: + // - buffer - a Buffer to search + // - val - a string, Buffer, or number + // - byteOffset - an index into `buffer`; will be clamped to an int32 + // - encoding - an optional encoding, relevant is val is a string + // - dir - true for indexOf, false for lastIndexOf + function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset; + byteOffset = 0; + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff; + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000; + } + byteOffset = +byteOffset; // Coerce to Number. + if (isNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1); + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset; + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1; + } else if (byteOffset < 0) { + if (dir) byteOffset = 0; + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding); + } + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (internalIsBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF; // Search for a byte value [0-255] + if (Buffer.TYPED_ARRAY_SUPPORT && + typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) + } + + throw new TypeError('val must be string, number or Buffer') + } + + function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1; + var arrLength = arr.length; + var valLength = val.length; + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase(); + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2; + arrLength /= 2; + valLength /= 2; + byteOffset /= 2; + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var i; + if (dir) { + var foundIndex = -1; + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i; + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex; + foundIndex = -1; + } + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength; + for (i = byteOffset; i >= 0; i--) { + var found = true; + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false; + break + } + } + if (found) return i + } + } + + return -1 + } + + Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 + }; + + Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) + }; + + Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) + }; + + function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0; + var remaining = buf.length - offset; + if (!length) { + length = remaining; + } else { + length = Number(length); + if (length > remaining) { + length = remaining; + } + } + + // must be an even number of digits + var strLen = string.length; + if (strLen % 2 !== 0) throw new TypeError('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2; + } + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16); + if (isNaN(parsed)) return i + buf[offset + i] = parsed; + } + return i + } + + function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) + } + + function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) + } + + function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) + } + + function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) + } + + function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) + } + + Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8'; + length = this.length; + offset = 0; + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset; + length = this.length; + offset = 0; + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0; + if (isFinite(length)) { + length = length | 0; + if (encoding === undefined) encoding = 'utf8'; + } else { + encoding = length; + length = undefined; + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) + } + + var remaining = this.length - offset; + if (length === undefined || length > remaining) length = remaining; + + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } + + if (!encoding) encoding = 'utf8'; + + var loweredCase = false; + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase(); + loweredCase = true; + } + } + }; + + Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } + }; + + function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return fromByteArray(buf) + } else { + return fromByteArray(buf.slice(start, end)) + } + } + + function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end); + var res = []; + + var i = start; + while (i < end) { + var firstByte = buf[i]; + var codePoint = null; + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1; + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint; + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte; + } + break + case 2: + secondByte = buf[i + 1]; + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F); + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint; + } + } + break + case 3: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F); + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint; + } + } + break + case 4: + secondByte = buf[i + 1]; + thirdByte = buf[i + 2]; + fourthByte = buf[i + 3]; + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F); + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint; + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD; + bytesPerSequence = 1; + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000; + res.push(codePoint >>> 10 & 0x3FF | 0xD800); + codePoint = 0xDC00 | codePoint & 0x3FF; + } + + res.push(codePoint); + i += bytesPerSequence; + } + + return decodeCodePointsArray(res) + } + + // Based on http://stackoverflow.com/a/22747272/680742, the browser with + // the lowest limit is Chrome, with 0x10000 args. + // We go 1 magnitude less, for safety + var MAX_ARGUMENTS_LENGTH = 0x1000; + + function decodeCodePointsArray (codePoints) { + var len = codePoints.length; + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = ''; + var i = 0; + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ); + } + return res + } + + function asciiSlice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F); + } + return ret + } + + function latin1Slice (buf, start, end) { + var ret = ''; + end = Math.min(buf.length, end); + + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]); + } + return ret + } + + function hexSlice (buf, start, end) { + var len = buf.length; + + if (!start || start < 0) start = 0; + if (!end || end < 0 || end > len) end = len; + + var out = ''; + for (var i = start; i < end; ++i) { + out += toHex(buf[i]); + } + return out + } + + function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end); + var res = ''; + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256); + } + return res + } + + Buffer.prototype.slice = function slice (start, end) { + var len = this.length; + start = ~~start; + end = end === undefined ? len : ~~end; + + if (start < 0) { + start += len; + if (start < 0) start = 0; + } else if (start > len) { + start = len; + } + + if (end < 0) { + end += len; + if (end < 0) end = 0; + } else if (end > len) { + end = len; + } + + if (end < start) end = start; + + var newBuf; + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end); + newBuf.__proto__ = Buffer.prototype; + } else { + var sliceLen = end - start; + newBuf = new Buffer(sliceLen, undefined); + for (var i = 0; i < sliceLen; ++i) { + newBuf[i] = this[i + start]; + } + } + + return newBuf + }; + + /* + * Need to make sure that buffer isn't trying to write out of bounds. + */ + function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') + } + + Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + + return val + }; + + Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + checkOffset(offset, byteLength, this.length); + } + + var val = this[offset + --byteLength]; + var mul = 1; + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul; + } + + return val + }; + + Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length); + return this[offset] + }; + + Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + return this[offset] | (this[offset + 1] << 8) + }; + + Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + return (this[offset] << 8) | this[offset + 1] + }; + + Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) + }; + + Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) + }; + + Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var val = this[offset]; + var mul = 1; + var i = 0; + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul; + } + mul *= 0x80; + + if (val >= mul) val -= Math.pow(2, 8 * byteLength); + + return val + }; + + Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) checkOffset(offset, byteLength, this.length); + + var i = byteLength; + var mul = 1; + var val = this[offset + --i]; + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul; + } + mul *= 0x80; + + if (val >= mul) val -= Math.pow(2, 8 * byteLength); + + return val + }; + + Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length); + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) + }; + + Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + var val = this[offset] | (this[offset + 1] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val + }; + + Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length); + var val = this[offset + 1] | (this[offset] << 8); + return (val & 0x8000) ? val | 0xFFFF0000 : val + }; + + Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) + }; + + Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) + }; + + Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + return read(this, offset, true, 23, 4) + }; + + Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length); + return read(this, offset, false, 23, 4) + }; + + Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length); + return read(this, offset, true, 52, 8) + }; + + Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length); + return read(this, offset, false, 52, 8) + }; + + function checkInt (buf, value, offset, ext, max, min) { + if (!internalIsBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') + } + + Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var mul = 1; + var i = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength + }; + + Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + byteLength = byteLength | 0; + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1; + checkInt(this, value, offset, byteLength, maxBytes, 0); + } + + var i = byteLength - 1; + var mul = 1; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF; + } + + return offset + byteLength + }; + + Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0); + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value); + this[offset] = (value & 0xff); + return offset + 1 + }; + + function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1; + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8; + } + } + + Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 + }; + + function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1; + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff; + } + } + + Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24); + this[offset + 2] = (value >>> 16); + this[offset + 1] = (value >>> 8); + this[offset] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 + }; + + Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 + }; + + Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = 0; + var mul = 1; + var sub = 0; + this[offset] = value & 0xFF; + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength + }; + + Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1); + + checkInt(this, value, offset, byteLength, limit - 1, -limit); + } + + var i = byteLength - 1; + var mul = 1; + var sub = 0; + this[offset + i] = value & 0xFF; + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1; + } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF; + } + + return offset + byteLength + }; + + Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80); + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value); + if (value < 0) value = 0xff + value + 1; + this[offset] = (value & 0xff); + return offset + 1 + }; + + Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + } else { + objectWriteUInt16(this, value, offset, true); + } + return offset + 2 + }; + + Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8); + this[offset + 1] = (value & 0xff); + } else { + objectWriteUInt16(this, value, offset, false); + } + return offset + 2 + }; + + Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff); + this[offset + 1] = (value >>> 8); + this[offset + 2] = (value >>> 16); + this[offset + 3] = (value >>> 24); + } else { + objectWriteUInt32(this, value, offset, true); + } + return offset + 4 + }; + + Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value; + offset = offset | 0; + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); + if (value < 0) value = 0xffffffff + value + 1; + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24); + this[offset + 1] = (value >>> 16); + this[offset + 2] = (value >>> 8); + this[offset + 3] = (value & 0xff); + } else { + objectWriteUInt32(this, value, offset, false); + } + return offset + 4 + }; + + function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') + } + + function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4); + } + write(buf, value, offset, littleEndian, 23, 4); + return offset + 4 + } + + Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) + }; + + Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) + }; + + function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8); + } + write(buf, value, offset, littleEndian, 52, 8); + return offset + 8 + } + + Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) + }; + + Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) + }; + + // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) + Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0; + if (!end && end !== 0) end = this.length; + if (targetStart >= target.length) targetStart = target.length; + if (!targetStart) targetStart = 0; + if (end > 0 && end < start) end = start; + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length; + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start; + } + + var len = end - start; + var i; + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start]; + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; ++i) { + target[i + targetStart] = this[i + start]; + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ); + } + + return len + }; + + // Usage: + // buffer.fill(number[, offset[, end]]) + // buffer.fill(buffer[, offset[, end]]) + // buffer.fill(string[, offset[, end]][, encoding]) + Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start; + start = 0; + end = this.length; + } else if (typeof end === 'string') { + encoding = end; + end = this.length; + } + if (val.length === 1) { + var code = val.charCodeAt(0); + if (code < 256) { + val = code; + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255; + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } + + if (end <= start) { + return this + } + + start = start >>> 0; + end = end === undefined ? this.length : end >>> 0; + + if (!val) val = 0; + + var i; + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val; + } + } else { + var bytes = internalIsBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()); + var len = bytes.length; + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len]; + } + } + + return this + }; + + // HELPER FUNCTIONS + // ================ + + var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g; + + function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, ''); + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '='; + } + return str + } + + function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') + } + + function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) + } + + function utf8ToBytes (string, units) { + units = units || Infinity; + var codePoint; + var length = string.length; + var leadSurrogate = null; + var bytes = []; + + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i); + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + continue + } + + // valid lead + leadSurrogate = codePoint; + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + leadSurrogate = codePoint; + continue + } + + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000; + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD); + } + + leadSurrogate = null; + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint); + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ); + } else { + throw new Error('Invalid code point') + } + } + + return bytes + } + + function asciiToBytes (str) { + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF); + } + return byteArray + } + + function utf16leToBytes (str, units) { + var c, hi, lo; + var byteArray = []; + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i); + hi = c >> 8; + lo = c % 256; + byteArray.push(lo); + byteArray.push(hi); + } + + return byteArray + } + + + function base64ToBytes (str) { + return toByteArray(base64clean(str)) + } + + function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i]; + } + return i + } + + function isnan (val) { + return val !== val // eslint-disable-line no-self-compare + } + + + // the following is from is-buffer, also by Feross Aboukhadijeh and with same lisence + // The _isBuffer check is for Safari 5-7 support, because it's missing + // Object.prototype.constructor. Remove this eventually + function isBuffer$1(obj) { + return obj != null && (!!obj._isBuffer || isFastBuffer(obj) || isSlowBuffer(obj)) + } + + function isFastBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) + } + + // For Node v0.10 support. Remove this eventually. + function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isFastBuffer(obj.slice(0, 0)) + } + + const object = {}; + const hasOwnProperty = object.hasOwnProperty; + const forOwn = (object, callback) => { + for (const key in object) { + if (hasOwnProperty.call(object, key)) { + callback(key, object[key]); + } + } + }; + + const extend = (destination, source) => { + if (!source) { + return destination; + } + forOwn(source, (key, value) => { + destination[key] = value; + }); + return destination; + }; + + const forEach = (array, callback) => { + const length = array.length; + let index = -1; + while (++index < length) { + callback(array[index]); + } + }; + + const toString = object.toString; + const isArray = Array.isArray; + const isBuffer = Buffer.isBuffer; + const isObject = (value) => { + // This is a very simple check, but it’s good enough for what we need. + return toString.call(value) == '[object Object]'; + }; + const isString = (value) => { + return typeof value == 'string' || + toString.call(value) == '[object String]'; + }; + const isNumber = (value) => { + return typeof value == 'number' || + toString.call(value) == '[object Number]'; + }; + const isFunction$1 = (value) => { + return typeof value == 'function'; + }; + const isMap = (value) => { + return toString.call(value) == '[object Map]'; + }; + const isSet = (value) => { + return toString.call(value) == '[object Set]'; + }; + + /*--------------------------------------------------------------------------*/ + + // https://mathiasbynens.be/notes/javascript-escapes#single + const singleEscapes = { + '"': '\\"', + '\'': '\\\'', + '\\': '\\\\', + '\b': '\\b', + '\f': '\\f', + '\n': '\\n', + '\r': '\\r', + '\t': '\\t' + // `\v` is omitted intentionally, because in IE < 9, '\v' == 'v'. + // '\v': '\\x0B' + }; + const regexSingleEscape = /["'\\\b\f\n\r\t]/; + + const regexDigit = /[0-9]/; + const regexWhitelist = /[ !#-&\(-\[\]-_a-~]/; + + const jsesc = (argument, options) => { + const increaseIndentation = () => { + oldIndent = indent; + ++options.indentLevel; + indent = options.indent.repeat(options.indentLevel); + }; + // Handle options + const defaults = { + 'escapeEverything': false, + 'minimal': false, + 'isScriptContext': false, + 'quotes': 'single', + 'wrap': false, + 'es6': false, + 'json': false, + 'compact': true, + 'lowercaseHex': false, + 'numbers': 'decimal', + 'indent': '\t', + 'indentLevel': 0, + '__inline1__': false, + '__inline2__': false + }; + const json = options && options.json; + if (json) { + defaults.quotes = 'double'; + defaults.wrap = true; + } + options = extend(defaults, options); + if ( + options.quotes != 'single' && + options.quotes != 'double' && + options.quotes != 'backtick' + ) { + options.quotes = 'single'; + } + const quote = options.quotes == 'double' ? + '"' : + (options.quotes == 'backtick' ? + '`' : + '\'' + ); + const compact = options.compact; + const lowercaseHex = options.lowercaseHex; + let indent = options.indent.repeat(options.indentLevel); + let oldIndent = ''; + const inline1 = options.__inline1__; + const inline2 = options.__inline2__; + const newLine = compact ? '' : '\n'; + let result; + let isEmpty = true; + const useBinNumbers = options.numbers == 'binary'; + const useOctNumbers = options.numbers == 'octal'; + const useDecNumbers = options.numbers == 'decimal'; + const useHexNumbers = options.numbers == 'hexadecimal'; + + if (json && argument && isFunction$1(argument.toJSON)) { + argument = argument.toJSON(); + } + + if (!isString(argument)) { + if (isMap(argument)) { + if (argument.size == 0) { + return 'new Map()'; + } + if (!compact) { + options.__inline1__ = true; + options.__inline2__ = false; + } + return 'new Map(' + jsesc(Array.from(argument), options) + ')'; + } + if (isSet(argument)) { + if (argument.size == 0) { + return 'new Set()'; + } + return 'new Set(' + jsesc(Array.from(argument), options) + ')'; + } + if (isBuffer(argument)) { + if (argument.length == 0) { + return 'Buffer.from([])'; + } + return 'Buffer.from(' + jsesc(Array.from(argument), options) + ')'; + } + if (isArray(argument)) { + result = []; + options.wrap = true; + if (inline1) { + options.__inline1__ = false; + options.__inline2__ = true; + } + if (!inline2) { + increaseIndentation(); + } + forEach(argument, (value) => { + isEmpty = false; + if (inline2) { + options.__inline2__ = false; + } + result.push( + (compact || inline2 ? '' : indent) + + jsesc(value, options) + ); + }); + if (isEmpty) { + return '[]'; + } + if (inline2) { + return '[' + result.join(', ') + ']'; + } + return '[' + newLine + result.join(',' + newLine) + newLine + + (compact ? '' : oldIndent) + ']'; + } else if (isNumber(argument)) { + if (json) { + // Some number values (e.g. `Infinity`) cannot be represented in JSON. + return JSON.stringify(argument); + } + if (useDecNumbers) { + return String(argument); + } + if (useHexNumbers) { + let hexadecimal = argument.toString(16); + if (!lowercaseHex) { + hexadecimal = hexadecimal.toUpperCase(); + } + return '0x' + hexadecimal; + } + if (useBinNumbers) { + return '0b' + argument.toString(2); + } + if (useOctNumbers) { + return '0o' + argument.toString(8); + } + } else if (!isObject(argument)) { + if (json) { + // For some values (e.g. `undefined`, `function` objects), + // `JSON.stringify(value)` returns `undefined` (which isn’t valid + // JSON) instead of `'null'`. + return JSON.stringify(argument) || 'null'; + } + return String(argument); + } else { // it’s an object + result = []; + options.wrap = true; + increaseIndentation(); + forOwn(argument, (key, value) => { + isEmpty = false; + result.push( + (compact ? '' : indent) + + jsesc(key, options) + ':' + + (compact ? '' : ' ') + + jsesc(value, options) + ); + }); + if (isEmpty) { + return '{}'; + } + return '{' + newLine + result.join(',' + newLine) + newLine + + (compact ? '' : oldIndent) + '}'; + } + } + + const string = argument; + // Loop over each code unit in the string and escape it + let index = -1; + const length = string.length; + result = ''; + while (++index < length) { + const character = string.charAt(index); + if (options.es6) { + const first = string.charCodeAt(index); + if ( // check if it’s the start of a surrogate pair + first >= 0xD800 && first <= 0xDBFF && // high surrogate + length > index + 1 // there is a next code unit + ) { + const second = string.charCodeAt(index + 1); + if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate + // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae + const codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; + let hexadecimal = codePoint.toString(16); + if (!lowercaseHex) { + hexadecimal = hexadecimal.toUpperCase(); + } + result += '\\u{' + hexadecimal + '}'; + ++index; + continue; + } + } + } + if (!options.escapeEverything) { + if (regexWhitelist.test(character)) { + // It’s a printable ASCII character that is not `"`, `'` or `\`, + // so don’t escape it. + result += character; + continue; + } + if (character == '"') { + result += quote == character ? '\\"' : character; + continue; + } + if (character == '`') { + result += quote == character ? '\\`' : character; + continue; + } + if (character == '\'') { + result += quote == character ? '\\\'' : character; + continue; + } + } + if ( + character == '\0' && + !json && + !regexDigit.test(string.charAt(index + 1)) + ) { + result += '\\0'; + continue; + } + if (regexSingleEscape.test(character)) { + // no need for a `hasOwnProperty` check here + result += singleEscapes[character]; + continue; + } + const charCode = character.charCodeAt(0); + if (options.minimal && charCode != 0x2028 && charCode != 0x2029) { + result += character; + continue; + } + let hexadecimal = charCode.toString(16); + if (!lowercaseHex) { + hexadecimal = hexadecimal.toUpperCase(); + } + const longhand = hexadecimal.length > 2 || json; + const escaped = '\\' + (longhand ? 'u' : 'x') + + ('0000' + hexadecimal).slice(longhand ? -4 : -2); + result += escaped; + continue; + } + if (options.wrap) { + result = quote + result + quote; + } + if (quote == '`') { + result = result.replace(/\$\{/g, '\\\$\{'); + } + if (options.isScriptContext) { + // https://mathiasbynens.be/notes/etago + return result + .replace(/<\/(script|style)/gi, '<\\/$1') + .replace(/` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types$1.incDec, 2) + } + if (next === 61) { return this.finishOp(types$1.assign, 2) } + return this.finishOp(types$1.plusMin, 1) + }; + + pp.readToken_lt_gt = function(code) { // '<>' + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) } + return this.finishOp(types$1.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + // ` + + + diff --git a/devtools/client/debugger/images/arrow-up.svg b/devtools/client/debugger/images/arrow-up.svg new file mode 100644 index 0000000000..7fa57c6616 --- /dev/null +++ b/devtools/client/debugger/images/arrow-up.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/arrow.svg b/devtools/client/debugger/images/arrow.svg new file mode 100644 index 0000000000..d1217f2dd2 --- /dev/null +++ b/devtools/client/debugger/images/arrow.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/blackBox.svg b/devtools/client/debugger/images/blackBox.svg new file mode 100644 index 0000000000..ab4c0401ec --- /dev/null +++ b/devtools/client/debugger/images/blackBox.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/devtools/client/debugger/images/breadcrumbs-divider.svg b/devtools/client/debugger/images/breadcrumbs-divider.svg new file mode 100644 index 0000000000..f41aa7fa0a --- /dev/null +++ b/devtools/client/debugger/images/breadcrumbs-divider.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/devtools/client/debugger/images/breakpoint.svg b/devtools/client/debugger/images/breakpoint.svg new file mode 100644 index 0000000000..95a6ef519c --- /dev/null +++ b/devtools/client/debugger/images/breakpoint.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/case-match.svg b/devtools/client/debugger/images/case-match.svg new file mode 100644 index 0000000000..5457bfb5dd --- /dev/null +++ b/devtools/client/debugger/images/case-match.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/column-marker.svg b/devtools/client/debugger/images/column-marker.svg new file mode 100644 index 0000000000..6b58715a59 --- /dev/null +++ b/devtools/client/debugger/images/column-marker.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/command-chevron.svg b/devtools/client/debugger/images/command-chevron.svg new file mode 100644 index 0000000000..8ed0338bcf --- /dev/null +++ b/devtools/client/debugger/images/command-chevron.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/disable-pausing.svg b/devtools/client/debugger/images/disable-pausing.svg new file mode 100644 index 0000000000..b073ec5f44 --- /dev/null +++ b/devtools/client/debugger/images/disable-pausing.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/enable-pausing.svg b/devtools/client/debugger/images/enable-pausing.svg new file mode 100644 index 0000000000..54d7c3676d --- /dev/null +++ b/devtools/client/debugger/images/enable-pausing.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/file-small.svg b/devtools/client/debugger/images/file-small.svg new file mode 100644 index 0000000000..ece2cc97de --- /dev/null +++ b/devtools/client/debugger/images/file-small.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/folder.svg b/devtools/client/debugger/images/folder.svg new file mode 100644 index 0000000000..a65b345bcc --- /dev/null +++ b/devtools/client/debugger/images/folder.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/globe-small.svg b/devtools/client/debugger/images/globe-small.svg new file mode 100644 index 0000000000..2c66eaa3ba --- /dev/null +++ b/devtools/client/debugger/images/globe-small.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/globe.svg b/devtools/client/debugger/images/globe.svg new file mode 100644 index 0000000000..6d03745a52 --- /dev/null +++ b/devtools/client/debugger/images/globe.svg @@ -0,0 +1,9 @@ + + + + + diff --git a/devtools/client/debugger/images/help.svg b/devtools/client/debugger/images/help.svg new file mode 100644 index 0000000000..58c2274df4 --- /dev/null +++ b/devtools/client/debugger/images/help.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/home.svg b/devtools/client/debugger/images/home.svg new file mode 100644 index 0000000000..275108f218 --- /dev/null +++ b/devtools/client/debugger/images/home.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/loader.svg b/devtools/client/debugger/images/loader.svg new file mode 100644 index 0000000000..67589cb3d5 --- /dev/null +++ b/devtools/client/debugger/images/loader.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/markup-breakpoint.svg b/devtools/client/debugger/images/markup-breakpoint.svg new file mode 100644 index 0000000000..b736c4e78c --- /dev/null +++ b/devtools/client/debugger/images/markup-breakpoint.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/devtools/client/debugger/images/next-circle.svg b/devtools/client/debugger/images/next-circle.svg new file mode 100644 index 0000000000..91fb6ddb6b --- /dev/null +++ b/devtools/client/debugger/images/next-circle.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/devtools/client/debugger/images/next.svg b/devtools/client/debugger/images/next.svg new file mode 100644 index 0000000000..c4c19bf4a1 --- /dev/null +++ b/devtools/client/debugger/images/next.svg @@ -0,0 +1,8 @@ + + + + diff --git a/devtools/client/debugger/images/pane-collapse.svg b/devtools/client/debugger/images/pane-collapse.svg new file mode 100644 index 0000000000..6f6623346e --- /dev/null +++ b/devtools/client/debugger/images/pane-collapse.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/pane-expand.svg b/devtools/client/debugger/images/pane-expand.svg new file mode 100644 index 0000000000..6498f09b1b --- /dev/null +++ b/devtools/client/debugger/images/pane-expand.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/pause.svg b/devtools/client/debugger/images/pause.svg new file mode 100644 index 0000000000..69ebe2d962 --- /dev/null +++ b/devtools/client/debugger/images/pause.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/devtools/client/debugger/images/plus.svg b/devtools/client/debugger/images/plus.svg new file mode 100644 index 0000000000..14ca4837e2 --- /dev/null +++ b/devtools/client/debugger/images/plus.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/prettyPrint.svg b/devtools/client/debugger/images/prettyPrint.svg new file mode 100644 index 0000000000..2c5a60f046 --- /dev/null +++ b/devtools/client/debugger/images/prettyPrint.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/regex-match.svg b/devtools/client/debugger/images/regex-match.svg new file mode 100644 index 0000000000..029a9e270e --- /dev/null +++ b/devtools/client/debugger/images/regex-match.svg @@ -0,0 +1,9 @@ + + + + + + + diff --git a/devtools/client/debugger/images/reload.svg b/devtools/client/debugger/images/reload.svg new file mode 100644 index 0000000000..7942ec30a3 --- /dev/null +++ b/devtools/client/debugger/images/reload.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/search.svg b/devtools/client/debugger/images/search.svg new file mode 100644 index 0000000000..0d11ff1fe7 --- /dev/null +++ b/devtools/client/debugger/images/search.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/aframe.svg b/devtools/client/debugger/images/sources/aframe.svg new file mode 100644 index 0000000000..b903d3eab9 --- /dev/null +++ b/devtools/client/debugger/images/sources/aframe.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/angular.svg b/devtools/client/debugger/images/sources/angular.svg new file mode 100644 index 0000000000..7e26c391d6 --- /dev/null +++ b/devtools/client/debugger/images/sources/angular.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/devtools/client/debugger/images/sources/babel.svg b/devtools/client/debugger/images/sources/babel.svg new file mode 100644 index 0000000000..7a64bfb93e --- /dev/null +++ b/devtools/client/debugger/images/sources/babel.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/backbone.svg b/devtools/client/debugger/images/sources/backbone.svg new file mode 100644 index 0000000000..0dab163ecb --- /dev/null +++ b/devtools/client/debugger/images/sources/backbone.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/choo.svg b/devtools/client/debugger/images/sources/choo.svg new file mode 100644 index 0000000000..efeae2ed99 --- /dev/null +++ b/devtools/client/debugger/images/sources/choo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/coffeescript.svg b/devtools/client/debugger/images/sources/coffeescript.svg new file mode 100644 index 0000000000..4db88c2d0d --- /dev/null +++ b/devtools/client/debugger/images/sources/coffeescript.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/dojo.svg b/devtools/client/debugger/images/sources/dojo.svg new file mode 100644 index 0000000000..277866813a --- /dev/null +++ b/devtools/client/debugger/images/sources/dojo.svg @@ -0,0 +1,4 @@ + +dojo_square diff --git a/devtools/client/debugger/images/sources/ember.svg b/devtools/client/debugger/images/sources/ember.svg new file mode 100644 index 0000000000..3b9ba80edf --- /dev/null +++ b/devtools/client/debugger/images/sources/ember.svg @@ -0,0 +1,4 @@ + + diff --git a/devtools/client/debugger/images/sources/express.svg b/devtools/client/debugger/images/sources/express.svg new file mode 100644 index 0000000000..e49ceb275f --- /dev/null +++ b/devtools/client/debugger/images/sources/express.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/sources/extension.svg b/devtools/client/debugger/images/sources/extension.svg new file mode 100644 index 0000000000..90ceb53835 --- /dev/null +++ b/devtools/client/debugger/images/sources/extension.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/immutable.svg b/devtools/client/debugger/images/sources/immutable.svg new file mode 100644 index 0000000000..6dd7c5047a --- /dev/null +++ b/devtools/client/debugger/images/sources/immutable.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/javascript.svg b/devtools/client/debugger/images/sources/javascript.svg new file mode 100644 index 0000000000..7afb624598 --- /dev/null +++ b/devtools/client/debugger/images/sources/javascript.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/jquery.svg b/devtools/client/debugger/images/sources/jquery.svg new file mode 100644 index 0000000000..57d81efa1e --- /dev/null +++ b/devtools/client/debugger/images/sources/jquery.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/lodash.svg b/devtools/client/debugger/images/sources/lodash.svg new file mode 100644 index 0000000000..bf8022cd6d --- /dev/null +++ b/devtools/client/debugger/images/sources/lodash.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/sources/marko.svg b/devtools/client/debugger/images/sources/marko.svg new file mode 100644 index 0000000000..79defc2f5c --- /dev/null +++ b/devtools/client/debugger/images/sources/marko.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/mobx.svg b/devtools/client/debugger/images/sources/mobx.svg new file mode 100644 index 0000000000..dacdf0cdc0 --- /dev/null +++ b/devtools/client/debugger/images/sources/mobx.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/sources/nextjs.svg b/devtools/client/debugger/images/sources/nextjs.svg new file mode 100644 index 0000000000..19d3a5ec3c --- /dev/null +++ b/devtools/client/debugger/images/sources/nextjs.svg @@ -0,0 +1,17 @@ + + + Zeit - Black on white logo + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/node.svg b/devtools/client/debugger/images/sources/node.svg new file mode 100644 index 0000000000..3ecdca040f --- /dev/null +++ b/devtools/client/debugger/images/sources/node.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/nuxtjs.svg b/devtools/client/debugger/images/sources/nuxtjs.svg new file mode 100644 index 0000000000..bf9172a87d --- /dev/null +++ b/devtools/client/debugger/images/sources/nuxtjs.svg @@ -0,0 +1,4 @@ + + diff --git a/devtools/client/debugger/images/sources/preact.svg b/devtools/client/debugger/images/sources/preact.svg new file mode 100644 index 0000000000..d860af54b6 --- /dev/null +++ b/devtools/client/debugger/images/sources/preact.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/pug.svg b/devtools/client/debugger/images/sources/pug.svg new file mode 100644 index 0000000000..0f8eb42b64 --- /dev/null +++ b/devtools/client/debugger/images/sources/pug.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/react.svg b/devtools/client/debugger/images/sources/react.svg new file mode 100644 index 0000000000..5dc19e92e1 --- /dev/null +++ b/devtools/client/debugger/images/sources/react.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/redux.svg b/devtools/client/debugger/images/sources/redux.svg new file mode 100644 index 0000000000..0ae6f5f888 --- /dev/null +++ b/devtools/client/debugger/images/sources/redux.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/rxjs.svg b/devtools/client/debugger/images/sources/rxjs.svg new file mode 100644 index 0000000000..944abc43eb --- /dev/null +++ b/devtools/client/debugger/images/sources/rxjs.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/sencha-extjs.svg b/devtools/client/debugger/images/sources/sencha-extjs.svg new file mode 100644 index 0000000000..2742ec9744 --- /dev/null +++ b/devtools/client/debugger/images/sources/sencha-extjs.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/devtools/client/debugger/images/sources/typescript.svg b/devtools/client/debugger/images/sources/typescript.svg new file mode 100644 index 0000000000..31548fa2dc --- /dev/null +++ b/devtools/client/debugger/images/sources/typescript.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/sources/underscore.svg b/devtools/client/debugger/images/sources/underscore.svg new file mode 100644 index 0000000000..a7b9d06e06 --- /dev/null +++ b/devtools/client/debugger/images/sources/underscore.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/devtools/client/debugger/images/sources/vuejs.svg b/devtools/client/debugger/images/sources/vuejs.svg new file mode 100644 index 0000000000..717ce87bb9 --- /dev/null +++ b/devtools/client/debugger/images/sources/vuejs.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/images/sources/webpack.svg b/devtools/client/debugger/images/sources/webpack.svg new file mode 100644 index 0000000000..2461a6f118 --- /dev/null +++ b/devtools/client/debugger/images/sources/webpack.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/devtools/client/debugger/images/stepIn.svg b/devtools/client/debugger/images/stepIn.svg new file mode 100644 index 0000000000..eff11c0c91 --- /dev/null +++ b/devtools/client/debugger/images/stepIn.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/devtools/client/debugger/images/stepOut.svg b/devtools/client/debugger/images/stepOut.svg new file mode 100644 index 0000000000..4e54571412 --- /dev/null +++ b/devtools/client/debugger/images/stepOut.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/devtools/client/debugger/images/tab.svg b/devtools/client/debugger/images/tab.svg new file mode 100644 index 0000000000..8362ca71d1 --- /dev/null +++ b/devtools/client/debugger/images/tab.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/trace.svg b/devtools/client/debugger/images/trace.svg new file mode 100644 index 0000000000..172f7b6c30 --- /dev/null +++ b/devtools/client/debugger/images/trace.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/webconsole-logpoint.svg b/devtools/client/debugger/images/webconsole-logpoint.svg new file mode 100644 index 0000000000..8ea068cc99 --- /dev/null +++ b/devtools/client/debugger/images/webconsole-logpoint.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/whole-word-match.svg b/devtools/client/debugger/images/whole-word-match.svg new file mode 100644 index 0000000000..ca636f13fc --- /dev/null +++ b/devtools/client/debugger/images/whole-word-match.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/devtools/client/debugger/images/window.svg b/devtools/client/debugger/images/window.svg new file mode 100644 index 0000000000..d24efd1ca8 --- /dev/null +++ b/devtools/client/debugger/images/window.svg @@ -0,0 +1,6 @@ + + + + diff --git a/devtools/client/debugger/images/worker.svg b/devtools/client/debugger/images/worker.svg new file mode 100644 index 0000000000..652fbc9c10 --- /dev/null +++ b/devtools/client/debugger/images/worker.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/devtools/client/debugger/index.html b/devtools/client/debugger/index.html new file mode 100644 index 0000000000..0030a671f8 --- /dev/null +++ b/devtools/client/debugger/index.html @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + +
+ + + + diff --git a/devtools/client/debugger/jest-test.config.js b/devtools/client/debugger/jest-test.config.js new file mode 100644 index 0000000000..e80d4b37a4 --- /dev/null +++ b/devtools/client/debugger/jest-test.config.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +/* global __dirname */ + +const sharedJestConfig = require(`${__dirname}/../shared/test-helpers/shared-jest.config`); + +const { resolve } = require("path"); +const rootDir = resolve(__dirname); +module.exports = { + rootDir, + displayName: "test", + testURL: "http://localhost/", + testEnvironment: "jsdom", + testPathIgnorePatterns: [ + "/node_modules/", + "/helpers/", + "/fixtures/", + "src/test/mochitest/examples/", + "/firefox", + "package.json", + ], + modulePathIgnorePatterns: ["test/mochitest"], + collectCoverageFrom: [ + "src/**/*.js", + "!src/**/fixtures/*.js", + "!src/test/**/*.js", + "!src/components/stories/**/*.js", + "!**/*.mock.js", + "!**/*.spec.js", + ], + transform: { + "\\.[jt]sx?$": "babel-jest", + }, + transformIgnorePatterns: ["node_modules/(?!(devtools-|react-aria-))"], + setupFilesAfterEnv: ["/src/test/tests-setup.js"], + setupFiles: ["/src/test/shim.js", "jest-localstorage-mock"], + snapshotSerializers: [ + "jest-serializer-babel-ast", + "enzyme-to-json/serializer", + ], + moduleNameMapper: { + ...sharedJestConfig.moduleNameMapper, + "\\.css$": "/../shared/test-helpers/jest-fixtures/empty-module", + "\\.svg$": "/../shared/test-helpers/jest-fixtures/svgMock.js", + }, +}; diff --git a/devtools/client/debugger/jest.config.js b/devtools/client/debugger/jest.config.js new file mode 100644 index 0000000000..cb5d2af2f9 --- /dev/null +++ b/devtools/client/debugger/jest.config.js @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +/* global __dirname */ + +const { resolve } = require("path"); +const rootDir = resolve(__dirname); +module.exports = { + rootDir, + reporters: ["default"], + projects: ["/jest-test.config.js"], +}; diff --git a/devtools/client/debugger/moz.build b/devtools/client/debugger/moz.build new file mode 100644 index 0000000000..371fe5c238 --- /dev/null +++ b/devtools/client/debugger/moz.build @@ -0,0 +1,24 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + "dist", + "src", +] + +include("../shared/build/node-templates.mozbuild") + +XPCSHELL_TESTS_MANIFESTS += ["test/xpcshell/xpcshell.ini"] + +BROWSER_CHROME_MANIFESTS += [ + "test/mochitest/browser.ini", +] + +DevToolsModules( + "panel.js", +) + +with Files("**"): + BUG_COMPONENT = ("DevTools", "Debugger") diff --git a/devtools/client/debugger/package.json b/devtools/client/debugger/package.json new file mode 100644 index 0000000000..5906254b0e --- /dev/null +++ b/devtools/client/debugger/package.json @@ -0,0 +1,101 @@ +{ + "name": "debugger", + "version": "0.6.0", + "license": "MPL-2.0", + "repository": { + "url": "git://github.com/firefox-devtools/debugger.git", + "type": "git" + }, + "bugs": { + "url": "https://github.com/firefox-devtools/debugger/issues" + }, + "homepage": "https://github.com/firefox-devtools/debugger#readme", + "engineStrict": true, + "scripts": { + "license-check": "devtools-license-check", + "links": "ls -l node_modules/ | grep ^l || echo 'no linked packages'", + "test": "TZ=Africa/Nairobi jest", + "test-ci": "TZ=Africa/Nairobi jest --json", + "test:watch": "jest --watch", + "test:coverage": "yarn test --coverage", + "test:all": "yarn test", + "watch": "node bin/watch" + }, + "dependencies": { + "acorn": "~8.8.2", + "codemirror": "^5.28.0", + "fuzzaldrin-plus": "^0.6.0", + "parse-script-tags": "github:loganfsmyth/parse-script-tags#d771732ca47e1b3554fe67d609fd18cc785c5f26", + "react": "16.8.6", + "react-aria-components": "^0.0.4", + "react-dom": "16.8.6", + "react-redux": "^5.0.7", + "react-transition-group": "^2.2.1", + "reselect": "4.1.5", + "source-map": "0.7.4", + "wasmparser": "^3.1.1" + }, + "private": true, + "workspaces": [ + "packages/*" + ], + "files": [ + "src", + "assets" + ], + "greenkeeper": { + "ignore": [ + "react", + "react-dom", + "react-redux", + "redux", + "codemirror" + ] + }, + "main": "src/main.js", + "author": "Jason Laster ", + "devDependencies": { + "@babel/core": "^7.15.5", + "@babel/plugin-proposal-class-properties": "^7.5.5", + "@babel/plugin-proposal-class-static-block": "^7.15.4", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-private-property-in-object": "^7.14.0", + "@babel/plugin-transform-modules-commonjs": "^7.5.0", + "@babel/preset-env": "^7.15.6", + "@babel/preset-react": "7.14.5", + "@babel/register": "^7.15.3", + "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@sucrase/webpack-object-rest-spread-plugin": "^1.0.0", + "babel-jest": "^23.0.0", + "babel-loader": "^8.2.2", + "babel-plugin-module-resolver": "^4.1.0", + "babel-plugin-transform-amd-to-commonjs": "1.4.0", + "buffer": "^6.0.3", + "copy-webpack-plugin": "^4.5.2", + "css-loader": "^0.26.1", + "enzyme": "^3.10.0", + "enzyme-adapter-react-16": "^1.14.0", + "enzyme-to-json": "3.3.5", + "extract-text-webpack-plugin": "^3.0.2", + "jest": "^27.2.1", + "jest-environment-jsdom": "^27.2.0", + "jest-in-case": "^1.0.2", + "jest-junit": "^6.0.0", + "jest-localstorage-mock": "^2.4.17", + "jest-serializer-babel-ast": "^0.0.5", + "redux": "^4.0.5", + "redux-mock-store": "^1.5.4", + "rollup": "3.20.2", + "rollup-plugin-inject-process-env": "^1.3.1", + "rollup-plugin-node-polyfills": "^0.2.1", + "webpack": "^3.5.5", + "workerjs": "github:jasonLaster/workerjs#1944c8b753cc9e84b6ed0cb2fbcaa25600706446" + }, + "resolutions": { + "//": "Fix workerjs babel core dependency until we figure out a good solution", + "workerjs/@babel/core": "^7.15.5", + "workerjs/@babel/register": "^7.15.3" + } +} diff --git a/devtools/client/debugger/panel.js b/devtools/client/debugger/panel.js new file mode 100644 index 0000000000..db2cdfb6a3 --- /dev/null +++ b/devtools/client/debugger/panel.js @@ -0,0 +1,348 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const { MultiLocalizationHelper } = require("devtools/shared/l10n"); +const { + FluentL10n, +} = require("devtools/client/shared/fluent-l10n/fluent-l10n"); + +loader.lazyRequireGetter( + this, + "openContentLink", + "resource://devtools/client/shared/link.js", + true +); +loader.lazyRequireGetter( + this, + "features", + "resource://devtools/client/debugger/src/utils/prefs.js", + true +); +loader.lazyRequireGetter( + this, + "getOriginalLocation", + "resource://devtools/client/debugger/src/utils/source-maps.js", + true +); +loader.lazyRequireGetter( + this, + "createLocation", + "resource://devtools/client/debugger/src/utils/location.js", + true +); +loader.lazyRequireGetter( + this, + "registerStoreObserver", + "resource://devtools/client/shared/redux/subscriber.js", + true +); + +const DBG_STRINGS_URI = [ + "devtools/client/locales/debugger.properties", + // These are used in the AppErrorBoundary component + "devtools/client/locales/startup.properties", + "devtools/client/locales/components.properties", +]; +const L10N = new MultiLocalizationHelper(...DBG_STRINGS_URI); + +async function getNodeFront(gripOrFront, toolbox) { + // Given a NodeFront + if ("actorID" in gripOrFront) { + return new Promise(resolve => resolve(gripOrFront)); + } + + const inspectorFront = await toolbox.target.getFront("inspector"); + return inspectorFront.getNodeFrontFromNodeGrip(gripOrFront); +} + +class DebuggerPanel { + constructor(iframeWindow, toolbox, commands) { + this.panelWin = iframeWindow; + this.panelWin.L10N = L10N; + + this.toolbox = toolbox; + this.commands = commands; + } + + async open() { + // whypaused-* strings are in devtools/shared as they're used in the PausedDebuggerOverlay as well + const fluentL10n = new FluentL10n(); + await fluentL10n.init(["devtools/shared/debugger-paused-reasons.ftl"]); + + const { actions, store, selectors, client } = + await this.panelWin.Debugger.bootstrap({ + commands: this.commands, + fluentBundles: fluentL10n.getBundles(), + resourceCommand: this.toolbox.resourceCommand, + workers: { + sourceMapLoader: this.toolbox.sourceMapLoader, + parserWorker: this.toolbox.parserWorker, + }, + panel: this, + }); + + this._actions = actions; + this._store = store; + this._selectors = selectors; + this._client = client; + + registerStoreObserver(this._store, this._onDebuggerStateChange.bind(this)); + + return this; + } + + _onDebuggerStateChange(state, oldState) { + const { getCurrentThread } = this._selectors; + + const currentThreadActorID = getCurrentThread(state); + if ( + currentThreadActorID && + currentThreadActorID !== getCurrentThread(oldState) + ) { + const threadFront = + this.commands.client.getFrontByID(currentThreadActorID); + this.toolbox.selectTarget(threadFront?.targetFront.actorID); + } + } + + getVarsForTests() { + return { + store: this._store, + selectors: this._selectors, + actions: this._actions, + client: this._client, + }; + } + + _getState() { + return this._store.getState(); + } + + getToolboxStore() { + return this.toolbox.store; + } + + openLink(url) { + openContentLink(url); + } + + async openConsoleAndEvaluate(input) { + const { hud } = await this.toolbox.selectTool("webconsole"); + hud.ui.wrapper.dispatchEvaluateExpression(input); + } + + async openInspector() { + this.toolbox.selectTool("inspector"); + } + + async openElementInInspector(gripOrFront) { + const onSelectInspector = this.toolbox.selectTool("inspector"); + const onGripNodeToFront = getNodeFront(gripOrFront, this.toolbox); + + const [front, inspector] = await Promise.all([ + onGripNodeToFront, + onSelectInspector, + ]); + + const onInspectorUpdated = inspector.once("inspector-updated"); + const onNodeFrontSet = this.toolbox.selection.setNodeFront(front, { + reason: "debugger", + }); + + return Promise.all([onNodeFrontSet, onInspectorUpdated]); + } + + highlightDomElement(gripOrFront) { + if (!this._highlight) { + const { highlight, unhighlight } = this.toolbox.getHighlighter(); + this._highlight = highlight; + this._unhighlight = unhighlight; + } + + return this._highlight(gripOrFront); + } + + unHighlightDomElement() { + if (!this._unhighlight) { + return Promise.resolve(); + } + + return this._unhighlight(); + } + + /** + * Return the Frame Actor ID of the currently selected frame, + * or null if the debugger isn't paused. + */ + getSelectedFrameActorID() { + const thread = this._selectors.getCurrentThread(this._getState()); + const selectedFrame = this._selectors.getSelectedFrame( + this._getState(), + thread + ); + if (selectedFrame) { + return selectedFrame.id; + } + return null; + } + + getMappedExpression(expression) { + return this._actions.getMappedExpression(expression); + } + + /** + * Return the source-mapped variables for the current scope. + * @returns {{[String]: String} | null} A dictionary mapping original variable names to generated + * variable names if map scopes is enabled, otherwise null. + */ + getMappedVariables() { + if (!this._selectors.isMapScopesEnabled(this._getState())) { + return null; + } + const thread = this._selectors.getCurrentThread(this._getState()); + return this._selectors.getSelectedScopeMappings(this._getState(), thread); + } + + isPaused() { + const thread = this._selectors.getCurrentThread(this._getState()); + return this._selectors.getIsPaused(this._getState(), thread); + } + + selectSourceURL(url, line, column) { + const cx = this._selectors.getContext(this._getState()); + return this._actions.selectSourceURL(cx, url, { line, column }); + } + + /** + * This is called when some other panels wants to open a given source + * in the debugger at a precise line/column. + * + * @param {String} generatedURL + * @param {Number} generatedLine + * @param {Number} generatedColumn + * @param {String} sourceActorId (optional) + * If the callsite knows about a particular sourceActorId, + * or if the source doesn't have a URL, you have to pass a sourceActorId. + * @param {String} reason + * A telemetry identifier to record when opening the debugger. + * This help differentiate why we opened the debugger. + * + * @return {Boolean} + * Returns true if the location is known by the debugger + * and the debugger opens it. + */ + async openSourceInDebugger({ + generatedURL, + generatedLine, + generatedColumn, + sourceActorId, + reason, + }) { + const generatedSource = sourceActorId + ? this._selectors.getSourceByActorId(this._getState(), sourceActorId) + : this._selectors.getSourceByURL(this._getState(), generatedURL); + // We won't try opening source in the debugger when we can't find the related source actor in the reducer, + // or, when it doesn't have any related source actor registered. + if ( + !generatedSource || + // Note: We're not entirely sure when this can happen, + // so we may want to revisit that at some point. + !this._selectors.getSourceActorsForSource( + this._getState(), + generatedSource.id + ).length + ) { + return false; + } + + const generatedLocation = createLocation({ + source: generatedSource, + line: generatedLine, + column: generatedColumn, + }); + + // Note that getOriginalLocation can easily return generatedLocation + // if the location can't be mapped to any original source. + // So that we may open either regular source or original sources here. + const originalLocation = await getOriginalLocation(generatedLocation, { + // Reproduce a minimal thunkArgs for getOriginalLocation. + sourceMapLoader: this.toolbox.sourceMapLoader, + getState: this._store.getState, + }); + + // view-source module only forced the load of debugger in the background. + // Now that we know we want to show a source, force displaying it in foreground. + // + // Note that browser_markup_view-source.js doesn't wait for the debugger + // to be fully loaded with the source and requires the debugger to be loaded late. + // But we might try to load display it early to improve user perception. + await this.toolbox.selectTool("jsdebugger", reason); + + const cx = this._selectors.getContext(this._getState()); + await this._actions.selectSpecificLocation(cx, originalLocation); + + // XXX: should this be moved to selectSpecificLocation?? + if (this._selectors.hasLogpoint(this._getState(), originalLocation)) { + this._actions.openConditionalPanel(originalLocation, true); + } + + return true; + } + + async selectWorker(workerDescriptorFront) { + const threadActorID = workerDescriptorFront.threadFront?.actorID; + + const isThreadAvailable = this._selectors + .getThreads(this._getState()) + .find(x => x.actor === threadActorID); + + if (!features.windowlessServiceWorkers) { + console.error( + "Selecting a worker needs the pref debugger.features.windowless-service-workers set to true" + ); + return; + } + + if (!isThreadAvailable) { + console.error(`Worker ${threadActorID} is not available for debugging`); + return; + } + + // select worker's thread + this.selectThread(threadActorID); + + // select worker's source + const source = this._selectors.getSourceByURL( + this._getState(), + workerDescriptorFront._url + ); + const sourceActor = this._selectors.getFirstSourceActorForGeneratedSource( + this._getState(), + source.id, + threadActorID + ); + const cx = this._selectors.getContext(this._getState()); + await this._actions.selectSource(cx, source, sourceActor); + } + + selectThread(threadActorID) { + const cx = this._selectors.getContext(this._getState()); + this._actions.selectThread(cx, threadActorID); + } + + toggleJavascriptTracing() { + this._actions.toggleTracing( + this._selectors.getJavascriptTracingLogMethod(this._getState()) + ); + } + + destroy() { + this.panelWin.Debugger.destroy(); + this.emit("destroyed"); + } +} + +exports.DebuggerPanel = DebuggerPanel; diff --git a/devtools/client/debugger/src/.eslintignore b/devtools/client/debugger/src/.eslintignore new file mode 100644 index 0000000000..32aadf77f5 --- /dev/null +++ b/devtools/client/debugger/src/.eslintignore @@ -0,0 +1,5 @@ +test/examples/** +test/integration/** +test/unit-sources/** +**/fixtures/** +test/mochitest/** diff --git a/devtools/client/debugger/src/.eslintrc.js b/devtools/client/debugger/src/.eslintrc.js new file mode 100644 index 0000000000..c6ffc17a5c --- /dev/null +++ b/devtools/client/debugger/src/.eslintrc.js @@ -0,0 +1,372 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +module.exports = { + plugins: ["react", "mozilla", "@babel", "import", "file-header"], + globals: { + atob: true, + btoa: true, + Cc: true, + Ci: true, + Components: true, + console: true, + Cr: true, + Cu: true, + devtools: true, + dump: true, + EventEmitter: true, + isWorker: true, + loader: true, + Services: true, + Task: true, + XPCOMUtils: true, + _Iterator: true, + __dirname: true, + process: true, + global: true, + L10N: true, + }, + extends: ["prettier", "plugin:jest/recommended"], + parserOptions: { + ecmaVersion: 2016, + sourceType: "module", + ecmaFeatures: { jsx: true }, + + // When the linter runs from the MC root, it won't pick up this project's + // babel.config.js, so we explicitly set Babel's root location so that + // it knows where to look. + babelOptions: { + root: __dirname, + }, + }, + env: { + es6: true, + browser: true, + commonjs: true, + jest: true, + }, + rules: { + // These are the rules that have been configured so far to match the + // devtools coding style. + + // Rules from the mozilla plugin + "mozilla/mark-test-function-used": 1, + "mozilla/no-aArgs": 1, + // See bug 1224289. + "mozilla/reject-importGlobalProperties": 1, + "mozilla/var-only-at-top-level": 1, + + // Rules from the React plugin + "react/jsx-uses-react": [2], + "react/jsx-uses-vars": [2], + "react/no-danger": 1, + "react/no-did-mount-set-state": 1, + "react/no-did-update-set-state": 1, + "react/no-direct-mutation-state": 1, + "react/no-unknown-property": 1, + "react/prop-types": 1, + "react/sort-comp": [ + 1, + { + order: ["propTypes", "everything-else", "render"], + }, + ], + + // Check for import errors. + "import/no-duplicates": "error", + "import/named": "error", + "import/export": "error", + + // Incompatible with jest-in-case cases. See related GitHub issue + // https://github.com/jest-community/eslint-plugin-jest/issues/534 + "jest/no-standalone-expect": "off", + + // Disallow flow control that escapes from "finally". + "no-unsafe-finally": "error", + + // Disallow using variables outside the blocks they are defined (especially + // since only let and const are used, see "no-var"). + "block-scoped-var": 2, + // Require camel case names + camelcase: ["error", { properties: "never" }], + // Warn about cyclomatic complexity in functions. + complexity: ["error", { max: 22 }], + // Don't warn for inconsistent naming when capturing this (not so important + // with auto-binding fat arrow functions). + "consistent-this": 0, + // Don't require a default case in switch statements. Avoid being forced to + // add a bogus default when you know all possible cases are handled. + "default-case": 0, + // Encourage the use of dot notation whenever possible. + "dot-notation": 2, + // Allow using == instead of ===, in the interest of landing something since + // the devtools codebase is split on convention here. + eqeqeq: 0, + // Don't require function expressions to have a name. + // This makes the code more verbose and hard to read. Our engine already + // does a fantastic job assigning a name to the function, which includes + // the enclosing function name, and worst case you have a line number that + // you can just look up. + "func-names": 0, + // Allow use of function declarations and expressions. + "func-style": 0, + // Deprecated, will be removed in 1.0. + "global-strict": 0, + // Only useful in a node environment. + "handle-callback-err": 0, + // Don't enforce the maximum depth that blocks can be nested. The complexity + // rule is a better rule to check this. + "max-depth": 0, + // Maximum depth callbacks can be nested. + "max-nested-callbacks": [2, 4], + // Don't limit the number of parameters that can be used in a function. + "max-params": 0, + // Don't limit the maximum number of statement allowed in a function. We + // already have the complexity rule that's a better measurement. + "max-statements": 0, + // Require a capital letter for constructors, only check if all new + // operators are followed by a capital letter. Don't warn when capitalized + // functions are used without the new operator. + "new-cap": [2, { capIsNew: false }], + // Disallow use of the Array constructor. + "no-array-constructor": 2, + // Allow use of bitwise operators. + "no-bitwise": 0, + // Disallow use of arguments.caller or arguments.callee. + "no-caller": 2, + // Disallow the catch clause parameter name being the same as a variable in + // the outer scope, to avoid confusion. + "no-catch-shadow": 2, + // Disallow assignment in conditional expressions. + "no-cond-assign": 2, + // Allow using the console API. + "no-console": 0, + // Allow using constant expressions in conditions like while (true) + "no-constant-condition": 0, + // Allow use of the continue statement. + "no-continue": 0, + // Disallow control characters in regular expressions. + "no-control-regex": 2, + // Disallow use of debugger. + "no-debugger": 2, + // Disallow deletion of variables (deleting properties is fine). + "no-delete-var": 2, + // Allow division operators explicitly at beginning of regular expression. + "no-div-regex": 0, + // Disallow duplicate arguments in functions. + "no-dupe-args": 2, + // Disallow duplicate keys when creating object literals. + "no-dupe-keys": 2, + // Disallow a duplicate case label. + "no-duplicate-case": 2, + // Disallow else after a return in an if. The else around the second return + // here is useless: + // if (something) { return false; } else { return true; } + "no-else-return": 2, + // Disallow empty statements. This will report an error for: + // try { something(); } catch (e) {} + // but will not report it for: + // try { something(); } catch (e) { /* Silencing the error because ...*/ } + // which is a valid use case. + "no-empty": 2, + // Disallow the use of empty character classes in regular expressions. + "no-empty-character-class": 2, + // Disallow use of labels for anything other then loops and switches. + "no-labels": 2, + // Disallow use of eval(). We have other APIs to evaluate code in content. + "no-eval": 2, + // Disallow assigning to the exception in a catch block. + "no-ex-assign": 2, + // Disallow adding to native types + "no-extend-native": 2, + // Disallow unnecessary function binding. + "no-extra-bind": 2, + // Disallow double-negation boolean casts in a boolean context. + "no-extra-boolean-cast": 2, + // Deprecated, will be removed in 1.0. + "no-extra-strict": 0, + // Disallow fallthrough of case statements, except if there is a comment. + "no-fallthrough": 2, + // Disallow comments inline after code. + "no-inline-comments": 2, + // Disallow if as the only statement in an else block. + "no-lonely-if": 2, + // Allow mixing regular variable and require declarations (not a node env). + "no-mixed-requires": 0, + // Disallow use of multiline strings (use template strings instead). + "no-multi-str": 2, + "prefer-template": "error", + "prefer-const": [ + "error", + { + destructuring: "all", + ignoreReadBeforeAssign: false, + }, + ], + // Disallow reassignments of native objects. + "no-native-reassign": 2, + // Disallow nested ternary expressions, they make the code hard to read. + "no-nested-ternary": 2, + // Allow use of new operator with the require function. + "no-new-require": 0, + // Disallow use of octal literals. + "no-octal": 2, + // Allow reassignment of function parameters. + "no-param-reassign": 0, + // Allow string concatenation with __dirname and __filename (not a node env). + "no-path-concat": 0, + // Allow use of unary operators, ++ and --. + "no-plusplus": 0, + // Allow using process.env (not a node environment). + "no-process-env": 0, + // Allow using process.exit (not a node environment). + "no-process-exit": 0, + // Disallow usage of __proto__ property. + "no-proto": 2, + // Disallow declaring the same variable more than once (we use let anyway). + "no-redeclare": 2, + // Disallow multiple spaces in a regular expression literal. + "no-regex-spaces": 2, + // Don't restrict usage of specified node modules (not a node environment). + "no-restricted-modules": 0, + // Disallow use of assignment in return statement. It is preferable for a + // single line of code to have only one easily predictable effect. + "no-return-assign": 2, + // Allow use of javascript: urls. + "no-script-url": 0, + // Disallow comparisons where both sides are exactly the same. + "no-self-compare": 2, + // Disallow use of comma operator. + "no-sequences": 2, + // Warn about declaration of variables already declared in the outer scope. + // This isn't an error because it sometimes is useful to use the same name + // in a small helper function rather than having to come up with another + // random name. + // Still, making this a warning can help people avoid being confused. + "no-shadow": 2, + // Disallow shadowing of names such as arguments. + "no-shadow-restricted-names": 2, + // Disallow sparse arrays, eg. let arr = [,,2]. + // Array destructuring is fine though: + // for (let [, breakpointPromise] of aPromises) + "no-sparse-arrays": 2, + // Allow use of synchronous methods (not a node environment). + "no-sync": 0, + // Allow the use of ternary operators. + "no-ternary": 0, + // Disallow throwing literals (eg. throw "error" instead of + // throw new Error("error")). + "no-throw-literal": 2, + // Disallow use of undeclared variables unless mentioned in a /*global */ + // block. Note that globals from head.js are automatically imported in tests + // by the import-headjs-globals rule form the mozilla eslint plugin. + "no-undef": 2, + // Allow dangling underscores in identifiers (for privates). + "no-underscore-dangle": 0, + // Allow use of undefined variable. + "no-undefined": 0, + // Disallow the use of Boolean literals in conditional expressions. + "no-unneeded-ternary": 2, + // Disallow unreachable statements after a return, throw, continue, or break + // statement. + "no-unreachable": 2, + // Disallow global and local variables that arent used, but allow unused function arguments. + "no-unused-vars": [2, { vars: "all", args: "none" }], + // Allow using variables before they are defined. + "no-use-before-define": 0, + // We use var-only-at-top-level instead of no-var as we allow top level + // vars. + "no-var": 0, + // Allow using TODO/FIXME comments. + "no-warning-comments": 0, + // Disallow use of the with statement. + "no-with": 2, + // Dont require method and property shorthand syntax for object literals. + // We use this in the code a lot, but not consistently, and this seems more + // like something to check at code review time. + "object-shorthand": 0, + // Allow more than one variable declaration per function. + "one-var": 0, + // Require use of the second argument for parseInt(). + radix: 2, + // Dont require to sort variables within the same declaration block. + // Anyway, one-var is disabled. + "sort-vars": 0, + // Require "use strict" to be defined globally in the script. + strict: [2, "global"], + // Disallow comparisons with the value NaN. + "use-isnan": 2, + // Ensure that the results of typeof are compared against a valid string. + "valid-typeof": 2, + // Allow vars to be declared anywhere in the scope. + "vars-on-top": 0, + // Disallow Yoda conditions (where literal value comes first). + yoda: 2, + + // And these are the rules that haven't been discussed so far, and that are + // disabled for now until we introduce them, one at a time. + + // Require for-in loops to have an if statement. + "guard-for-in": 0, + // allow/disallow an empty newline after var statement + "newline-after-var": 0, + // disallow the use of alert, confirm, and prompt + "no-alert": 0, + // disallow comparisons to null without a type-checking operator + "no-eq-null": 0, + // disallow overwriting functions written as function declarations + "no-func-assign": 0, + // disallow use of eval()-like methods + "no-implied-eval": 0, + // disallow function or variable declarations in nested blocks + "no-inner-declarations": 0, + // disallow invalid regular expression strings in the RegExp constructor + "no-invalid-regexp": 0, + // disallow irregular whitespace outside of strings and comments + "no-irregular-whitespace": 0, + // disallow labels that share a name with a variable + "no-label-var": 0, + // disallow unnecessary nested blocks + "no-lone-blocks": 0, + // disallow creation of functions within loops + "no-loop-func": 0, + // disallow negation of the left operand of an in expression + "no-negated-in-lhs": 0, + // disallow use of new operator when not part of the assignment or + // comparison + "no-new": 0, + // disallow use of new operator for Function object + "no-new-func": 0, + // disallow use of the Object constructor + "no-new-object": 0, + // disallows creating new instances of String,Number, and Boolean + "no-new-wrappers": 0, + // disallow the use of object properties of the global object (Math and + // JSON) as functions + "no-obj-calls": 0, + // disallow use of octal escape sequences in string literals, such as + // var foo = "Copyright \251"; + "no-octal-escape": 0, + // disallow use of undefined when initializing variables + "no-undef-init": 0, + // disallow usage of expressions in statement position + "no-unused-expressions": 0, + // disallow use of void operator + "no-void": 0, + // require assignment operator shorthand where possible or prohibit it + // entirely + "operator-assignment": 0, + + "file-header/file-header": [ + "error", + [ + "This Source Code Form is subject to the terms of the Mozilla Public", + "License, v. 2.0. If a copy of the MPL was not distributed with this", + "file, You can obtain one at .", + ], + "block", + ["-\\*-(.*)-\\*-", "eslint(.*)", "vim(.*)"], + ], + }, +}; diff --git a/devtools/client/debugger/src/actions/README.md b/devtools/client/debugger/src/actions/README.md new file mode 100644 index 0000000000..d919247838 --- /dev/null +++ b/devtools/client/debugger/src/actions/README.md @@ -0,0 +1,26 @@ +## Actions + +### Best Practices + +#### Scheduling Async Actions + +There are several use-cases with async actions that involve scheduling: + +* we do one action and cancel subsequent actions +* we do one action and subsequent calls wait on the initial call +* we start an action and show a loading state + +If you want to wait on subsequent calls you need to store action promises. +[ex][req] + +If you just want to cancel subsequent calls, you can keep track of a pending +state in the store. [ex][state] + +The advantage of adding the pending state to the store is that we can use that +in the UI: + +* disable/hide the pretty print button +* show a progress ui + +[req]: https://github.com/firefox-devtools/debugger/blob/master/src/actions/sources/loadSourceText.js +[state]: https://github.com/firefox-devtools/debugger/blob/master/src/reducers/sources.js diff --git a/devtools/client/debugger/src/actions/ast/index.js b/devtools/client/debugger/src/actions/ast/index.js new file mode 100644 index 0000000000..ec2c1ae84c --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/index.js @@ -0,0 +1,5 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export { setInScopeLines } from "./setInScopeLines"; diff --git a/devtools/client/debugger/src/actions/ast/moz.build b/devtools/client/debugger/src/actions/ast/moz.build new file mode 100644 index 0000000000..5b0152d2ad --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/moz.build @@ -0,0 +1,11 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "index.js", + "setInScopeLines.js", +) diff --git a/devtools/client/debugger/src/actions/ast/setInScopeLines.js b/devtools/client/debugger/src/actions/ast/setInScopeLines.js new file mode 100644 index 0000000000..a17510a507 --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/setInScopeLines.js @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + hasInScopeLines, + getSourceTextContent, + getVisibleSelectedFrame, +} from "../../selectors"; + +import { getSourceLineCount } from "../../utils/source"; + +import { isFulfilled } from "../../utils/async-value"; + +function getOutOfScopeLines(outOfScopeLocations) { + if (!outOfScopeLocations) { + return null; + } + + const uniqueLines = new Set(); + for (const location of outOfScopeLocations) { + for (let i = location.start.line; i < location.end.line; i++) { + uniqueLines.add(i); + } + } + + return uniqueLines; +} + +async function getInScopeLines( + cx, + location, + { dispatch, getState, parserWorker } +) { + const sourceTextContent = getSourceTextContent(getState(), location); + + let locations = null; + if (location.line && parserWorker.isLocationSupported(location)) { + locations = await parserWorker.findOutOfScopeLocations(location); + } + + const linesOutOfScope = getOutOfScopeLines(locations); + const sourceNumLines = + !sourceTextContent || !isFulfilled(sourceTextContent) + ? 0 + : getSourceLineCount(sourceTextContent.value); + + const noLinesOutOfScope = + linesOutOfScope == null || linesOutOfScope.size == 0; + + // This operation can be very costly for large files so we sacrifice a bit of readability + // for performance sake. + // We initialize an array with a fixed size and we'll directly assign value for lines + // that are not out of scope. This is much faster than having an empty array and pushing + // into it. + const sourceLines = new Array(sourceNumLines); + for (let i = 0; i < sourceNumLines; i++) { + const line = i + 1; + if (noLinesOutOfScope || !linesOutOfScope.has(line)) { + sourceLines[i] = line; + } + } + + // Finally we need to remove any undefined values, i.e. the ones that were matching + // out of scope lines. + return sourceLines.filter(i => i != undefined); +} + +export function setInScopeLines(cx) { + return async thunkArgs => { + const { getState, dispatch } = thunkArgs; + const visibleFrame = getVisibleSelectedFrame(getState()); + + if (!visibleFrame) { + return; + } + + const { location } = visibleFrame; + const sourceTextContent = getSourceTextContent(getState(), location); + + if (hasInScopeLines(getState(), location) || !sourceTextContent) { + return; + } + + const lines = await getInScopeLines(cx, location, thunkArgs); + + dispatch({ + type: "IN_SCOPE_LINES", + cx, + location, + lines, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap b/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap new file mode 100644 index 0000000000..1b9befc31b --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/tests/__snapshots__/setInScopeLines.spec.js.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getInScopeLine with selected line 1`] = ` +Array [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 10, + 11, + 12, +] +`; diff --git a/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js b/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js new file mode 100644 index 0000000000..571dd84d6d --- /dev/null +++ b/devtools/client/debugger/src/actions/ast/tests/setInScopeLines.spec.js @@ -0,0 +1,79 @@ +/* eslint max-nested-callbacks: ["error", 6] */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import readFixture from "../../tests/helpers/readFixture"; + +import { makeMockFrame, makeMockSource } from "../../../utils/test-mockup"; +import { + createStore, + selectors, + actions, + makeSource, + waitForState, +} from "../../../utils/test-head"; +import { createLocation } from "../../../utils/location"; + +const { getInScopeLines } = selectors; + +const sourceTexts = { + "scopes.js": readFixture("scopes.js"), +}; + +const mockCommandClient = { + sourceContents: async ({ source }) => ({ + source: sourceTexts[source], + contentType: "text/javascript", + }), + evaluateExpressions: async () => {}, + getFrameScopes: async () => {}, + getFrames: async () => [], + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], +}; + +describe("getInScopeLine", () => { + it("with selected line", async () => { + const client = { ...mockCommandClient }; + const store = createStore(client); + const { dispatch, getState } = store; + const source = makeMockSource("scopes.js", "scopes.js"); + const frame = makeMockFrame("scopes-4", source); + client.getFrames = async () => [frame]; + + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("scopes.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + baseSource.id + ); + + await dispatch( + actions.selectLocation( + selectors.getContext(getState()), + createLocation({ + source: baseSource, + sourceActor, + line: 5, + }) + ) + ); + + await dispatch( + actions.paused({ + thread: "FakeThread", + why: { type: "debuggerStatement" }, + frame, + }) + ); + await dispatch(actions.setInScopeLines(selectors.getContext(getState()))); + + await waitForState(store, state => getInScopeLines(state, frame.location)); + + const lines = getInScopeLines(getState(), frame.location); + + expect(lines).toMatchSnapshot(); + }); +}); diff --git a/devtools/client/debugger/src/actions/breakpoints/breakpointPositions.js b/devtools/client/debugger/src/actions/breakpoints/breakpointPositions.js new file mode 100644 index 0000000000..263b476364 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/breakpointPositions.js @@ -0,0 +1,273 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + isOriginalId, + isGeneratedId, + originalToGeneratedId, +} from "devtools/client/shared/source-map-loader/index"; + +import { + getSource, + getSourceFromId, + getBreakpointPositionsForSource, + getSourceActorsForSource, +} from "../../selectors"; + +import { makeBreakpointId } from "../../utils/breakpoint"; +import { memoizeableAction } from "../../utils/memoizableAction"; +import { fulfilled } from "../../utils/async-value"; +import { + debuggerToSourceMapLocation, + sourceMapToDebuggerLocation, + createLocation, +} from "../../utils/location"; + +async function mapLocations(generatedLocations, { getState, sourceMapLoader }) { + if (!generatedLocations.length) { + return []; + } + + const originalLocations = await sourceMapLoader.getOriginalLocations( + generatedLocations.map(debuggerToSourceMapLocation) + ); + return originalLocations.map((location, index) => ({ + // If location is null, this particular location doesn't map to any original source. + location: location + ? sourceMapToDebuggerLocation(getState(), location) + : generatedLocations[index], + generatedLocation: generatedLocations[index], + })); +} + +// Filter out positions, that are not in the original source Id +function filterBySource(positions, sourceId) { + if (!isOriginalId(sourceId)) { + return positions; + } + return positions.filter(position => position.location.sourceId == sourceId); +} + +/** + * Merge positions that refer to duplicated positions. + * Some sourcemaped positions might refer to the exact same source/line/column triple. + * + * @param {Array<{location, generatedLocation}>} positions: List of possible breakable positions + * @returns {Array<{location, generatedLocation}>} A new, filtered array. + */ +function filterByUniqLocation(positions) { + const handledBreakpointIds = new Set(); + return positions.filter(({ location }) => { + const breakpointId = makeBreakpointId(location); + if (handledBreakpointIds.has(breakpointId)) { + return false; + } + + handledBreakpointIds.add(breakpointId); + return true; + }); +} + +function convertToList(results, source) { + const positions = []; + + for (const line in results) { + for (const column of results[line]) { + positions.push( + createLocation({ + line: Number(line), + column, + source, + sourceUrl: source.url, + }) + ); + } + } + + return positions; +} + +function groupByLine(results, sourceId, line) { + const isOriginal = isOriginalId(sourceId); + const positions = {}; + + // Ensure that we have an entry for the line fetched + if (typeof line === "number") { + positions[line] = []; + } + + for (const result of results) { + const location = isOriginal ? result.location : result.generatedLocation; + + if (!positions[location.line]) { + positions[location.line] = []; + } + + positions[location.line].push(result); + } + + return positions; +} + +async function _setBreakpointPositions(cx, location, thunkArgs) { + const { client, dispatch, getState, sourceMapLoader } = thunkArgs; + const results = {}; + let generatedSource = location.source; + if (isOriginalId(location.sourceId)) { + const ranges = await sourceMapLoader.getGeneratedRangesForOriginal( + location.sourceId, + true + ); + const generatedSourceId = originalToGeneratedId(location.sourceId); + generatedSource = getSourceFromId(getState(), generatedSourceId); + + // Note: While looping here may not look ideal, in the vast majority of + // cases, the number of ranges here should be very small, and is quite + // likely to only be a single range. + for (const range of ranges) { + // Wrap infinite end positions to the next line to keep things simple + // and because we know we don't care about the end-line whitespace + // in this case. + if (range.end.column === Infinity) { + range.end = { + line: range.end.line + 1, + column: 0, + }; + } + + const actorBps = await Promise.all( + getSourceActorsForSource(getState(), generatedSourceId).map(actor => + client.getSourceActorBreakpointPositions(actor, range) + ) + ); + + for (const actorPositions of actorBps) { + for (const rangeLine of Object.keys(actorPositions)) { + let columns = actorPositions[parseInt(rangeLine, 10)]; + const existing = results[rangeLine]; + if (existing) { + columns = [...new Set([...existing, ...columns])]; + } + + results[rangeLine] = columns; + } + } + } + } else { + const { line } = location; + if (typeof line !== "number") { + throw new Error("Line is required for generated sources"); + } + + const actorColumns = await Promise.all( + getSourceActorsForSource(getState(), location.sourceId).map( + async actor => { + const positions = await client.getSourceActorBreakpointPositions( + actor, + { + start: { line: line, column: 0 }, + end: { line: line + 1, column: 0 }, + } + ); + return positions[line] || []; + } + ) + ); + + for (const columns of actorColumns) { + results[line] = (results[line] || []).concat(columns); + } + } + + let positions = convertToList(results, generatedSource); + positions = await mapLocations(positions, thunkArgs); + + positions = filterBySource(positions, location.sourceId); + positions = filterByUniqLocation(positions); + positions = groupByLine(positions, location.sourceId, location.line); + + const source = getSource(getState(), location.sourceId); + // NOTE: it's possible that the source was removed during a navigation + if (!source) { + return; + } + + dispatch({ + type: "ADD_BREAKPOINT_POSITIONS", + cx, + source, + positions, + }); +} + +function generatedSourceActorKey(state, sourceId) { + const generatedSource = getSource( + state, + isOriginalId(sourceId) ? originalToGeneratedId(sourceId) : sourceId + ); + const actors = generatedSource + ? getSourceActorsForSource(state, generatedSource.id).map( + ({ actor }) => actor + ) + : []; + return [sourceId, ...actors].join(":"); +} + +/** + * This method will force retrieving the breakable positions for a given source, on a given line. + * If this data has already been computed, it will returned the cached data. + * + * For original sources, this will query the SourceMap worker. + * For generated sources, this will query the DevTools server and the related source actors. + * + * @param Object options + * Dictionary object with many arguments: + * @param String options.sourceId + * The source we want to fetch breakable positions + * @param Number options.line + * The line we want to know which columns are breakable. + * (note that this seems to be optional for original sources) + * @return Array + * The list of all breakable positions, each object of this array will be like this: + * { + * line: Number + * column: Number + * sourceId: String + * sourceUrl: String + * } + */ +export const setBreakpointPositions = memoizeableAction( + "setBreakpointPositions", + { + getValue: ({ location }, { getState }) => { + const positions = getBreakpointPositionsForSource( + getState(), + location.sourceId + ); + if (!positions) { + return null; + } + + if ( + isGeneratedId(location.sourceId) && + location.line && + !positions[location.line] + ) { + // We always return the full position dataset, but if a given line is + // not available, we treat the whole set as loading. + return null; + } + + return fulfilled(positions); + }, + createKey({ location }, { getState }) { + const key = generatedSourceActorKey(getState(), location.sourceId); + return isGeneratedId(location.sourceId) && location.line + ? `${key}-${location.line}` + : key; + }, + action: async ({ cx, location }, thunkArgs) => + _setBreakpointPositions(cx, location, thunkArgs), + } +); diff --git a/devtools/client/debugger/src/actions/breakpoints/index.js b/devtools/client/debugger/src/actions/breakpoints/index.js new file mode 100644 index 0000000000..d188af05dc --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/index.js @@ -0,0 +1,426 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for breakpoints + * @module actions/breakpoints + */ + +import { PROMISE } from "../utils/middleware/promise"; +import { asyncStore } from "../../utils/prefs"; +import { createLocation } from "../../utils/location"; +import { + getBreakpointsList, + getXHRBreakpoints, + getSelectedSource, + getBreakpointAtLocation, + getBreakpointsForSource, + getBreakpointsAtLine, +} from "../../selectors"; +import { createXHRBreakpoint } from "../../utils/breakpoint"; +import { + addBreakpoint, + removeBreakpoint, + enableBreakpoint, + disableBreakpoint, +} from "./modify"; +import { getOriginalLocation } from "../../utils/source-maps"; + +import { isOriginalId } from "devtools/client/shared/source-map-loader/index"; +// this will need to be changed so that addCLientBreakpoint is removed + +export * from "./breakpointPositions"; +export * from "./modify"; +export * from "./syncBreakpoint"; + +export function addHiddenBreakpoint(cx, location) { + return ({ dispatch }) => { + return dispatch(addBreakpoint(cx, location, { hidden: true })); + }; +} + +/** + * Disable all breakpoints in a source + * + * @memberof actions/breakpoints + * @static + */ +export function disableBreakpointsInSource(cx, source) { + return async ({ dispatch, getState, client }) => { + const breakpoints = getBreakpointsForSource(getState(), source.id); + for (const breakpoint of breakpoints) { + if (!breakpoint.disabled) { + dispatch(disableBreakpoint(cx, breakpoint)); + } + } + }; +} + +/** + * Enable all breakpoints in a source + * + * @memberof actions/breakpoints + * @static + */ +export function enableBreakpointsInSource(cx, source) { + return async ({ dispatch, getState, client }) => { + const breakpoints = getBreakpointsForSource(getState(), source.id); + for (const breakpoint of breakpoints) { + if (breakpoint.disabled) { + dispatch(enableBreakpoint(cx, breakpoint)); + } + } + }; +} + +/** + * Toggle All Breakpoints + * + * @memberof actions/breakpoints + * @static + */ +export function toggleAllBreakpoints(cx, shouldDisableBreakpoints) { + return async ({ dispatch, getState, client }) => { + const breakpoints = getBreakpointsList(getState()); + + for (const breakpoint of breakpoints) { + if (shouldDisableBreakpoints) { + dispatch(disableBreakpoint(cx, breakpoint)); + } else { + dispatch(enableBreakpoint(cx, breakpoint)); + } + } + }; +} + +/** + * Toggle Breakpoints + * + * @memberof actions/breakpoints + * @static + */ +export function toggleBreakpoints(cx, shouldDisableBreakpoints, breakpoints) { + return async ({ dispatch }) => { + const promises = breakpoints.map(breakpoint => + shouldDisableBreakpoints + ? dispatch(disableBreakpoint(cx, breakpoint)) + : dispatch(enableBreakpoint(cx, breakpoint)) + ); + + await Promise.all(promises); + }; +} + +export function toggleBreakpointsAtLine(cx, shouldDisableBreakpoints, line) { + return async ({ dispatch, getState }) => { + const breakpoints = getBreakpointsAtLine(getState(), line); + return dispatch( + toggleBreakpoints(cx, shouldDisableBreakpoints, breakpoints) + ); + }; +} + +/** + * Removes all breakpoints + * + * @memberof actions/breakpoints + * @static + */ +export function removeAllBreakpoints(cx) { + return async ({ dispatch, getState }) => { + const breakpointList = getBreakpointsList(getState()); + + await Promise.all( + breakpointList.map(bp => dispatch(removeBreakpoint(cx, bp))) + ); + dispatch({ type: "CLEAR_BREAKPOINTS" }); + }; +} + +/** + * Removes breakpoints + * + * @memberof actions/breakpoints + * @static + */ +export function removeBreakpoints(cx, breakpoints) { + return async ({ dispatch }) => { + return Promise.all( + breakpoints.map(bp => dispatch(removeBreakpoint(cx, bp))) + ); + }; +} + +/** + * Removes all breakpoints in a source + * + * @memberof actions/breakpoints + * @static + */ +export function removeBreakpointsInSource(cx, source) { + return async ({ dispatch, getState, client }) => { + const breakpoints = getBreakpointsForSource(getState(), source.id); + for (const breakpoint of breakpoints) { + dispatch(removeBreakpoint(cx, breakpoint)); + } + }; +} + +/** + * Update the original location information of breakpoints. + +/* + * Update breakpoints for a source that just got pretty printed. + * This method maps the breakpoints currently set only against the + * non-pretty-printed (generated) source to the related pretty-printed + * (original) source by querying the SourceMap service. + * + * @param {Objeect} cx + * @param {String} sourceId - the generated source id + */ +export function updateBreakpointsForNewPrettyPrintedSource(cx, sourceId) { + return async thunkArgs => { + const { dispatch, getState } = thunkArgs; + if (isOriginalId(sourceId)) { + console.error("Can't update breakpoints on original sources"); + return; + } + const breakpoints = getBreakpointsForSource(getState(), sourceId); + // Remap the breakpoints with the original location information from + // the pretty-printed source. + const newBreakpoints = await Promise.all( + breakpoints.map(async breakpoint => { + const location = await getOriginalLocation( + breakpoint.generatedLocation, + thunkArgs + ); + return { ...breakpoint, location }; + }) + ); + + // Normally old breakpoints will be clobbered if we re-add them, but when + // remapping we have changed the source maps and the old breakpoints will + // have different locations than the new ones. Manually remove the + // old breakpoints before adding the new ones. + for (const bp of breakpoints) { + dispatch(removeBreakpoint(cx, bp)); + } + + for (const bp of newBreakpoints) { + await dispatch(addBreakpoint(cx, bp.location, bp.options, bp.disabled)); + } + }; +} + +export function toggleBreakpointAtLine(cx, line) { + return ({ dispatch, getState }) => { + const state = getState(); + const selectedSource = getSelectedSource(state); + + if (!selectedSource) { + return null; + } + + const bp = getBreakpointAtLocation(state, { line, column: undefined }); + if (bp) { + return dispatch(removeBreakpoint(cx, bp)); + } + return dispatch( + addBreakpoint( + cx, + createLocation({ + source: selectedSource, + sourceUrl: selectedSource.url, + line, + }) + ) + ); + }; +} + +export function addBreakpointAtLine( + cx, + line, + shouldLog = false, + disabled = false +) { + return ({ dispatch, getState }) => { + const state = getState(); + const source = getSelectedSource(state); + + if (!source) { + return null; + } + const breakpointLocation = createLocation({ + source, + sourceUrl: source.url, + column: undefined, + line, + }); + + const options = {}; + if (shouldLog) { + options.logValue = "displayName"; + } + + return dispatch(addBreakpoint(cx, breakpointLocation, options, disabled)); + }; +} + +export function removeBreakpointsAtLine(cx, sourceId, line) { + return ({ dispatch, getState }) => { + const breakpointsAtLine = getBreakpointsForSource( + getState(), + sourceId, + line + ); + return dispatch(removeBreakpoints(cx, breakpointsAtLine)); + }; +} + +export function disableBreakpointsAtLine(cx, sourceId, line) { + return ({ dispatch, getState }) => { + const breakpointsAtLine = getBreakpointsForSource( + getState(), + sourceId, + line + ); + return dispatch(toggleBreakpoints(cx, true, breakpointsAtLine)); + }; +} + +export function enableBreakpointsAtLine(cx, sourceId, line) { + return ({ dispatch, getState }) => { + const breakpointsAtLine = getBreakpointsForSource( + getState(), + sourceId, + line + ); + return dispatch(toggleBreakpoints(cx, false, breakpointsAtLine)); + }; +} + +export function toggleDisabledBreakpoint(cx, breakpoint) { + return ({ dispatch, getState }) => { + if (!breakpoint.disabled) { + return dispatch(disableBreakpoint(cx, breakpoint)); + } + return dispatch(enableBreakpoint(cx, breakpoint)); + }; +} + +export function enableXHRBreakpoint(index, bp) { + return ({ dispatch, getState, client }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const breakpoint = bp || xhrBreakpoints[index]; + const enabledBreakpoint = { + ...breakpoint, + disabled: false, + }; + + return dispatch({ + type: "ENABLE_XHR_BREAKPOINT", + breakpoint: enabledBreakpoint, + index, + [PROMISE]: client.setXHRBreakpoint(breakpoint.path, breakpoint.method), + }); + }; +} + +export function disableXHRBreakpoint(index, bp) { + return ({ dispatch, getState, client }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const breakpoint = bp || xhrBreakpoints[index]; + const disabledBreakpoint = { + ...breakpoint, + disabled: true, + }; + + return dispatch({ + type: "DISABLE_XHR_BREAKPOINT", + breakpoint: disabledBreakpoint, + index, + [PROMISE]: client.removeXHRBreakpoint(breakpoint.path, breakpoint.method), + }); + }; +} + +export function updateXHRBreakpoint(index, path, method) { + return ({ dispatch, getState, client }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const breakpoint = xhrBreakpoints[index]; + + const updatedBreakpoint = { + ...breakpoint, + path, + method, + text: L10N.getFormatStr("xhrBreakpoints.item.label", path), + }; + + return dispatch({ + type: "UPDATE_XHR_BREAKPOINT", + breakpoint: updatedBreakpoint, + index, + [PROMISE]: Promise.all([ + client.removeXHRBreakpoint(breakpoint.path, breakpoint.method), + client.setXHRBreakpoint(path, method), + ]), + }); + }; +} +export function togglePauseOnAny() { + return ({ dispatch, getState }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const index = xhrBreakpoints.findIndex(({ path }) => path.length === 0); + if (index < 0) { + return dispatch(setXHRBreakpoint("", "ANY")); + } + + const bp = xhrBreakpoints[index]; + if (bp.disabled) { + return dispatch(enableXHRBreakpoint(index, bp)); + } + + return dispatch(disableXHRBreakpoint(index, bp)); + }; +} + +export function setXHRBreakpoint(path, method) { + return ({ dispatch, getState, client }) => { + const breakpoint = createXHRBreakpoint(path, method); + + return dispatch({ + type: "SET_XHR_BREAKPOINT", + breakpoint, + [PROMISE]: client.setXHRBreakpoint(path, method), + }); + }; +} + +export function removeAllXHRBreakpoints() { + return async ({ dispatch, getState, client }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const promises = xhrBreakpoints.map(breakpoint => + client.removeXHRBreakpoint(breakpoint.path, breakpoint.method) + ); + await dispatch({ + type: "CLEAR_XHR_BREAKPOINTS", + [PROMISE]: Promise.all(promises), + }); + asyncStore.xhrBreakpoints = []; + }; +} + +export function removeXHRBreakpoint(index) { + return ({ dispatch, getState, client }) => { + const xhrBreakpoints = getXHRBreakpoints(getState()); + const breakpoint = xhrBreakpoints[index]; + return dispatch({ + type: "REMOVE_XHR_BREAKPOINT", + breakpoint, + index, + [PROMISE]: client.removeXHRBreakpoint(breakpoint.path, breakpoint.method), + }); + }; +} diff --git a/devtools/client/debugger/src/actions/breakpoints/modify.js b/devtools/client/debugger/src/actions/breakpoints/modify.js new file mode 100644 index 0000000000..4576a61e27 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/modify.js @@ -0,0 +1,382 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { createBreakpoint } from "../../client/firefox/create"; +import { + makeBreakpointServerLocation, + makeBreakpointId, +} from "../../utils/breakpoint"; +import { + getBreakpoint, + getBreakpointPositionsForLocation, + getFirstBreakpointPosition, + getSettledSourceTextContent, + getBreakpointsList, + getPendingBreakpointList, + isMapScopesEnabled, + getBlackBoxRanges, + isSourceMapIgnoreListEnabled, + isSourceOnSourceMapIgnoreList, +} from "../../selectors"; + +import { setBreakpointPositions } from "./breakpointPositions"; +import { setSkipPausing } from "../pause/skipPausing"; + +import { PROMISE } from "../utils/middleware/promise"; +import { recordEvent } from "../../utils/telemetry"; +import { comparePosition } from "../../utils/location"; +import { getTextAtPosition, isLineBlackboxed } from "../../utils/source"; +import { getMappedScopesForLocation } from "../pause/mapScopes"; +import { validateNavigateContext } from "../../utils/context"; + +// This file has the primitive operations used to modify individual breakpoints +// and keep them in sync with the breakpoints installed on server threads. These +// are collected here to make it easier to preserve the following invariant: +// +// Breakpoints are included in reducer state if they are disabled or requests +// have been dispatched to set them in all server threads. +// +// To maintain this property, updates to the reducer and installed breakpoints +// must happen with no intervening await. Using await allows other operations to +// modify the breakpoint state in the interim and potentially cause breakpoint +// state to go out of sync. +// +// The reducer is optimistically updated when users set or remove a breakpoint, +// but it might take a little while before the breakpoints have been set or +// removed in each thread. Once all outstanding requests sent to a thread have +// been processed, the reducer and server threads will be in sync. +// +// There is another exception to the above invariant when first connecting to +// the server: breakpoints have been installed on all generated locations in the +// pending breakpoints, but no breakpoints have been added to the reducer. When +// a matching source appears, either the server breakpoint will be removed or a +// breakpoint will be added to the reducer, to restore the above invariant. +// See syncBreakpoint.js for more. + +async function clientSetBreakpoint( + client, + cx, + { getState, dispatch }, + breakpoint +) { + const breakpointServerLocation = makeBreakpointServerLocation( + getState(), + breakpoint.generatedLocation + ); + const shouldMapBreakpointExpressions = + isMapScopesEnabled(getState()) && + breakpoint.location.source.isOriginal && + (breakpoint.options.logValue || breakpoint.options.condition); + + if (shouldMapBreakpointExpressions) { + breakpoint = await dispatch(updateBreakpointSourceMapping(cx, breakpoint)); + } + return client.setBreakpoint(breakpointServerLocation, breakpoint.options); +} + +function clientRemoveBreakpoint(client, state, generatedLocation) { + const breakpointServerLocation = makeBreakpointServerLocation( + state, + generatedLocation + ); + return client.removeBreakpoint(breakpointServerLocation); +} + +export function enableBreakpoint(cx, initialBreakpoint) { + return thunkArgs => { + const { dispatch, getState, client } = thunkArgs; + const state = getState(); + const breakpoint = getBreakpoint(state, initialBreakpoint.location); + const blackboxedRanges = getBlackBoxRanges(state); + const isSourceOnIgnoreList = + isSourceMapIgnoreListEnabled(state) && + isSourceOnSourceMapIgnoreList(state, breakpoint.location.source); + if ( + !breakpoint || + !breakpoint.disabled || + isLineBlackboxed( + blackboxedRanges[breakpoint.location.source.url], + breakpoint.location.line, + isSourceOnIgnoreList + ) + ) { + return null; + } + + dispatch(setSkipPausing(false)); + return dispatch({ + type: "SET_BREAKPOINT", + cx, + breakpoint: createBreakpoint({ ...breakpoint, disabled: false }), + [PROMISE]: clientSetBreakpoint(client, cx, thunkArgs, breakpoint), + }); + }; +} + +export function addBreakpoint( + cx, + initialLocation, + options = {}, + disabled, + shouldCancel = () => false +) { + return async thunkArgs => { + const { dispatch, getState, client } = thunkArgs; + recordEvent("add_breakpoint"); + + await dispatch( + setBreakpointPositions({ + cx, + location: initialLocation, + }) + ); + + const position = initialLocation.column + ? getBreakpointPositionsForLocation(getState(), initialLocation) + : getFirstBreakpointPosition(getState(), initialLocation); + + // No position is found if the `initialLocation` is on a non-breakable line or + // the line no longer exists. + if (!position) { + return null; + } + + const { location, generatedLocation } = position; + + if (!location.source || !generatedLocation.source) { + return null; + } + + const originalContent = getSettledSourceTextContent(getState(), location); + const originalText = getTextAtPosition( + location.source.id, + originalContent, + location + ); + + const content = getSettledSourceTextContent(getState(), generatedLocation); + const text = getTextAtPosition( + generatedLocation.source.id, + content, + generatedLocation + ); + + const id = makeBreakpointId(location); + const breakpoint = createBreakpoint({ + id, + disabled, + options, + location, + generatedLocation, + text, + originalText, + }); + + if (shouldCancel()) { + return null; + } + + dispatch(setSkipPausing(false)); + return dispatch({ + type: "SET_BREAKPOINT", + cx, + breakpoint, + // If we just clobbered an enabled breakpoint with a disabled one, we need + // to remove any installed breakpoint in the server. + [PROMISE]: disabled + ? clientRemoveBreakpoint(client, getState(), generatedLocation) + : clientSetBreakpoint(client, cx, thunkArgs, breakpoint), + }); + }; +} + +/** + * Remove a single breakpoint + * + * @memberof actions/breakpoints + * @static + */ +export function removeBreakpoint(cx, initialBreakpoint) { + return ({ dispatch, getState, client }) => { + recordEvent("remove_breakpoint"); + + const breakpoint = getBreakpoint(getState(), initialBreakpoint.location); + if (!breakpoint) { + return null; + } + + dispatch(setSkipPausing(false)); + return dispatch({ + type: "REMOVE_BREAKPOINT", + cx, + breakpoint, + // If the breakpoint is disabled then it is not installed in the server. + [PROMISE]: breakpoint.disabled + ? Promise.resolve() + : clientRemoveBreakpoint( + client, + getState(), + breakpoint.generatedLocation + ), + }); + }; +} + +/** + * Remove all installed, pending, and client breakpoints associated with a + * target generated location. + * + * @param {Object} target + * Location object where to remove breakpoints. + */ +export function removeBreakpointAtGeneratedLocation(cx, target) { + return ({ dispatch, getState, client }) => { + // remove breakpoint from the server + const onBreakpointRemoved = clientRemoveBreakpoint( + client, + getState(), + target + ); + // Remove any breakpoints matching the generated location. + const breakpoints = getBreakpointsList(getState()); + for (const breakpoint of breakpoints) { + const { generatedLocation } = breakpoint; + if ( + generatedLocation.sourceId == target.sourceId && + comparePosition(generatedLocation, target) + ) { + dispatch({ + type: "REMOVE_BREAKPOINT", + cx, + breakpoint, + [PROMISE]: onBreakpointRemoved, + }); + } + } + + // Remove any remaining pending breakpoints matching the generated location. + const pending = getPendingBreakpointList(getState()); + for (const pendingBreakpoint of pending) { + const { generatedLocation } = pendingBreakpoint; + if ( + generatedLocation.sourceUrl == target.sourceUrl && + comparePosition(generatedLocation, target) + ) { + dispatch({ + type: "REMOVE_PENDING_BREAKPOINT", + cx, + pendingBreakpoint, + }); + } + } + return onBreakpointRemoved; + }; +} + +/** + * Disable a single breakpoint + * + * @memberof actions/breakpoints + * @static + */ +export function disableBreakpoint(cx, initialBreakpoint) { + return ({ dispatch, getState, client }) => { + const breakpoint = getBreakpoint(getState(), initialBreakpoint.location); + if (!breakpoint || breakpoint.disabled) { + return null; + } + + dispatch(setSkipPausing(false)); + return dispatch({ + type: "SET_BREAKPOINT", + cx, + breakpoint: createBreakpoint({ ...breakpoint, disabled: true }), + [PROMISE]: clientRemoveBreakpoint( + client, + getState(), + breakpoint.generatedLocation + ), + }); + }; +} + +/** + * Update the options of a breakpoint. + * + * @throws {Error} "not implemented" + * @memberof actions/breakpoints + * @static + * @param {SourceLocation} location + * @see DebuggerController.Breakpoints.addBreakpoint + * @param {Object} options + * Any options to set on the breakpoint + */ +export function setBreakpointOptions(cx, location, options = {}) { + return thunkArgs => { + const { dispatch, getState, client } = thunkArgs; + let breakpoint = getBreakpoint(getState(), location); + if (!breakpoint) { + return dispatch(addBreakpoint(cx, location, options)); + } + + // Note: setting a breakpoint's options implicitly enables it. + breakpoint = createBreakpoint({ ...breakpoint, disabled: false, options }); + + return dispatch({ + type: "SET_BREAKPOINT", + cx, + breakpoint, + [PROMISE]: clientSetBreakpoint(client, cx, thunkArgs, breakpoint), + }); + }; +} + +async function updateExpression(parserWorker, mappings, originalExpression) { + const mapped = await parserWorker.mapExpression( + originalExpression, + mappings, + [], + false, + false + ); + if (!mapped) { + return originalExpression; + } + if (!originalExpression.trimEnd().endsWith(";")) { + return mapped.expression.replace(/;$/, ""); + } + return mapped.expression; +} + +function updateBreakpointSourceMapping(cx, breakpoint) { + return async ({ getState, dispatch, parserWorker }) => { + const options = { ...breakpoint.options }; + + const mappedScopes = await dispatch( + getMappedScopesForLocation(breakpoint.location) + ); + if (!mappedScopes) { + return breakpoint; + } + const { mappings } = mappedScopes; + + if (options.condition) { + options.condition = await updateExpression( + parserWorker, + mappings, + options.condition + ); + } + if (options.logValue) { + options.logValue = await updateExpression( + parserWorker, + mappings, + options.logValue + ); + } + + validateNavigateContext(getState(), cx); + return { ...breakpoint, options }; + }; +} diff --git a/devtools/client/debugger/src/actions/breakpoints/moz.build b/devtools/client/debugger/src/actions/breakpoints/moz.build new file mode 100644 index 0000000000..65910c4ef2 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/moz.build @@ -0,0 +1,13 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "breakpointPositions.js", + "index.js", + "modify.js", + "syncBreakpoint.js", +) diff --git a/devtools/client/debugger/src/actions/breakpoints/syncBreakpoint.js b/devtools/client/debugger/src/actions/breakpoints/syncBreakpoint.js new file mode 100644 index 0000000000..b52c0ddfb1 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/syncBreakpoint.js @@ -0,0 +1,138 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { setBreakpointPositions } from "./breakpointPositions"; +import { + findPosition, + makeBreakpointServerLocation, +} from "../../utils/breakpoint"; + +import { comparePosition, createLocation } from "../../utils/location"; + +import { + originalToGeneratedId, + isOriginalId, +} from "devtools/client/shared/source-map-loader/index"; +import { getSource } from "../../selectors"; +import { addBreakpoint, removeBreakpointAtGeneratedLocation } from "."; + +async function findBreakpointPosition(cx, { getState, dispatch }, location) { + const positions = await dispatch(setBreakpointPositions({ cx, location })); + + const position = findPosition(positions, location); + return position; +} + +// Breakpoint syncing occurs when a source is found that matches either the +// original or generated URL of a pending breakpoint. A new breakpoint is +// constructed that might have a different original and/or generated location, +// if the original source has changed since the pending breakpoint was created. +// There are a couple subtle aspects to syncing: +// +// - We handle both the original and generated source because there is no +// guarantee that seeing the generated source means we will also see the +// original source. When connecting, a breakpoint will be installed in the +// client for the generated location in the pending breakpoint, and we need +// to make sure that either a breakpoint is added to the reducer or that this +// client breakpoint is deleted. +// +// - If we see both the original and generated sources and the source mapping +// has changed, we need to make sure that only a single breakpoint is added +// to the reducer for the new location corresponding to the original location +// in the pending breakpoint. +export function syncPendingBreakpoint(cx, sourceId, pendingBreakpoint) { + return async thunkArgs => { + const { getState, client, dispatch } = thunkArgs; + + const source = getSource(getState(), sourceId); + + const generatedSourceId = isOriginalId(sourceId) + ? originalToGeneratedId(sourceId) + : sourceId; + + const generatedSource = getSource(getState(), generatedSourceId); + + if (!source || !generatedSource) { + return null; + } + + // /!\ Pending breakpoint locations come only with sourceUrl, line and column attributes. + // We have to map it to a specific source object and avoid trying to query its non-existent 'source' attribute. + const { location, generatedLocation } = pendingBreakpoint; + const isPendingBreakpointWithSourceMap = + location.sourceUrl != generatedLocation.sourceUrl; + const sourceGeneratedLocation = createLocation({ + ...generatedLocation, + source: generatedSource, + }); + + if (source == generatedSource && isPendingBreakpointWithSourceMap) { + // We are handling the generated source and the pending breakpoint has a + // source mapping. Supply a cancellation callback that will abort the + // breakpoint if the original source was synced to a different location, + // in which case the client breakpoint has been removed. + const breakpointServerLocation = makeBreakpointServerLocation( + getState(), + sourceGeneratedLocation + ); + return dispatch( + addBreakpoint( + cx, + sourceGeneratedLocation, + pendingBreakpoint.options, + pendingBreakpoint.disabled, + () => !client.hasBreakpoint(breakpointServerLocation) + ) + ); + } + + const originalLocation = createLocation({ + ...location, + source, + }); + + const newPosition = await findBreakpointPosition( + cx, + thunkArgs, + originalLocation + ); + + const newGeneratedLocation = newPosition?.generatedLocation; + if (!newGeneratedLocation) { + // We couldn't find a new mapping for the breakpoint. If there is a source + // mapping, remove any breakpoints for the generated location, as if the + // breakpoint moved. If the old generated location still maps to an + // original location then we don't want to add a breakpoint for it. + if (isPendingBreakpointWithSourceMap) { + dispatch( + removeBreakpointAtGeneratedLocation(cx, sourceGeneratedLocation) + ); + } + return null; + } + + const isSameLocation = comparePosition( + generatedLocation, + newGeneratedLocation + ); + + // If the new generated location has changed from that in the pending + // breakpoint, remove any breakpoint associated with the old generated + // location. + if (!isSameLocation) { + dispatch( + removeBreakpointAtGeneratedLocation(cx, sourceGeneratedLocation) + ); + } + + return dispatch( + addBreakpoint( + cx, + newGeneratedLocation, + pendingBreakpoint.options, + pendingBreakpoint.disabled + ) + ); + }; +} diff --git a/devtools/client/debugger/src/actions/breakpoints/tests/__snapshots__/breakpoints.spec.js.snap b/devtools/client/debugger/src/actions/breakpoints/tests/__snapshots__/breakpoints.spec.js.snap new file mode 100644 index 0000000000..c18c3593d9 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/tests/__snapshots__/breakpoints.spec.js.snap @@ -0,0 +1,173 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`breakpoints should add a breakpoint 1`] = ` +Array [ + Object { + "breakpoints": Array [ + Object { + "disabled": false, + "generatedLocation": Object { + "column": 1, + "line": 2, + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "a", + "sourceUrl": "http://localhost:8000/examples/a", + }, + "id": "a:2:1", + "location": Object { + "column": 1, + "line": 2, + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "a", + "sourceUrl": "http://localhost:8000/examples/a", + }, + "options": Object {}, + "originalText": "return a", + "text": "return a", + "thread": undefined, + }, + ], + "filename": "a", + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + }, +] +`; + +exports[`breakpoints should not show a breakpoint that does not have text 1`] = `Array []`; + +exports[`breakpoints should show a disabled breakpoint that does not have text 1`] = ` +Array [ + Object { + "breakpoints": Array [ + Object { + "disabled": true, + "generatedLocation": Object { + "column": 1, + "line": 5, + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "a", + "sourceUrl": "http://localhost:8000/examples/a", + }, + "id": "a:5:1", + "location": Object { + "column": 1, + "line": 5, + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "a", + "sourceUrl": "http://localhost:8000/examples/a", + }, + "options": Object {}, + "originalText": "", + "text": "", + "thread": undefined, + }, + ], + "filename": "a", + "source": Object { + "displayURL": Object { + "fileExtension": "", + "filename": "a", + "group": "localhost:8000", + "path": "/examples/a", + "search": "", + }, + "extensionName": null, + "id": "a", + "isExtension": false, + "isHTML": false, + "isOriginal": false, + "isPrettyPrinted": false, + "isWasm": false, + "url": "http://localhost:8000/examples/a", + }, + }, +] +`; diff --git a/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js new file mode 100644 index 0000000000..558d2400a8 --- /dev/null +++ b/devtools/client/debugger/src/actions/breakpoints/tests/breakpoints.spec.js @@ -0,0 +1,521 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + createStore, + selectors, + actions, + makeSource, + getTelemetryEvents, +} from "../../../utils/test-head"; + +import { mockCommandClient } from "../../tests/helpers/mockCommandClient"; +import { createLocation } from "../../../utils/location"; + +jest.mock("../../../utils/prefs", () => ({ + prefs: { + expressions: [], + }, + asyncStore: { + pendingBreakpoints: {}, + }, + features: { + inlinePreview: true, + }, +})); + +function mockClient(positionsResponse = {}) { + return { + ...mockCommandClient, + setSkipPausing: jest.fn(), + getSourceActorBreakpointPositions: async () => positionsResponse, + getSourceActorBreakableLines: async () => [], + }; +} + +describe("breakpoints", () => { + it("should add a breakpoint", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 2: [1] })); + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc1 = createLocation({ + source, + line: 2, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + await dispatch( + actions.selectLocation( + cx, + createLocation({ + source, + line: 1, + column: 1, + }) + ) + ); + + await dispatch(actions.addBreakpoint(cx, loc1)); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + const bp = selectors.getBreakpoint(getState(), loc1); + expect(bp && bp.location).toEqual(loc1); + expect(getTelemetryEvents("add_breakpoint")).toHaveLength(1); + + const bpSources = selectors.getBreakpointSources(getState()); + expect(bpSources).toMatchSnapshot(); + }); + + it("should not show a breakpoint that does not have text", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc1 = createLocation({ + source, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + await dispatch( + actions.selectLocation( + cx, + createLocation({ + source, + line: 1, + column: 1, + }) + ) + ); + + await dispatch(actions.addBreakpoint(cx, loc1)); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + const bp = selectors.getBreakpoint(getState(), loc1); + expect(bp && bp.location).toEqual(loc1); + expect(selectors.getBreakpointSources(getState())).toMatchSnapshot(); + }); + + it("should show a disabled breakpoint that does not have text", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc1 = createLocation({ + source, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + await dispatch( + actions.selectLocation( + cx, + createLocation({ + source, + line: 1, + column: 1, + }) + ) + ); + + await dispatch(actions.addBreakpoint(cx, loc1)); + const breakpoint = selectors.getBreakpoint(getState(), loc1); + if (!breakpoint) { + throw new Error("no breakpoint"); + } + + await dispatch(actions.disableBreakpoint(cx, breakpoint)); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + const bp = selectors.getBreakpoint(getState(), loc1); + expect(bp && bp.location).toEqual(loc1); + expect(selectors.getBreakpointSources(getState())).toMatchSnapshot(); + }); + + it("should not re-add a breakpoint", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc1 = createLocation({ + source, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + await dispatch( + actions.selectLocation( + cx, + createLocation({ + source, + line: 1, + column: 1, + }) + ) + ); + + await dispatch(actions.addBreakpoint(cx, loc1)); + expect(selectors.getBreakpointCount(getState())).toEqual(1); + const bp = selectors.getBreakpoint(getState(), loc1); + expect(bp && bp.location).toEqual(loc1); + + await dispatch(actions.addBreakpoint(cx, loc1)); + expect(selectors.getBreakpointCount(getState())).toEqual(1); + }); + + it("should remove a breakpoint", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1], 6: [2] }) + ); + + const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); + + const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); + + const loc1 = createLocation({ + source: aSource, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + + const loc2 = createLocation({ + source: bSource, + line: 6, + column: 2, + sourceUrl: "http://localhost:8000/examples/b", + }); + const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + bSource.id + ); + + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: bSourceActor, + }) + ); + + await dispatch( + actions.selectLocation( + cx, + createLocation({ + source: aSource, + line: 1, + column: 1, + }) + ) + ); + + await dispatch(actions.addBreakpoint(cx, loc1)); + await dispatch(actions.addBreakpoint(cx, loc2)); + + const bp = selectors.getBreakpoint(getState(), loc1); + if (!bp) { + throw new Error("no bp"); + } + await dispatch(actions.removeBreakpoint(cx, bp)); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + }); + + it("should disable a breakpoint", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1], 6: [2] }) + ); + + const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + aSource.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: aSourceActor, + }) + ); + + const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); + const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + bSource.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: bSourceActor, + }) + ); + + const loc1 = createLocation({ + source: aSource, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + + const loc2 = createLocation({ + source: bSource, + line: 6, + column: 2, + sourceUrl: "http://localhost:8000/examples/b", + }); + await dispatch(actions.addBreakpoint(cx, loc1)); + await dispatch(actions.addBreakpoint(cx, loc2)); + + const breakpoint = selectors.getBreakpoint(getState(), loc1); + if (!breakpoint) { + throw new Error("no breakpoint"); + } + + await dispatch(actions.disableBreakpoint(cx, breakpoint)); + + const bp = selectors.getBreakpoint(getState(), loc1); + expect(bp && bp.disabled).toBe(true); + }); + + it("should enable breakpoint", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1], 6: [2] }) + ); + + const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc = createLocation({ + source: aSource, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + aSource.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: aSourceActor, + }) + ); + + await dispatch(actions.addBreakpoint(cx, loc)); + let bp = selectors.getBreakpoint(getState(), loc); + if (!bp) { + throw new Error("no breakpoint"); + } + + await dispatch(actions.disableBreakpoint(cx, bp)); + + bp = selectors.getBreakpoint(getState(), loc); + if (!bp) { + throw new Error("no breakpoint"); + } + + expect(bp && bp.disabled).toBe(true); + + await dispatch(actions.enableBreakpoint(cx, bp)); + + bp = selectors.getBreakpoint(getState(), loc); + expect(bp && !bp.disabled).toBe(true); + }); + + it("should toggle all the breakpoints", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1], 6: [2] }) + ); + + const aSource = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const aSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + aSource.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: aSourceActor, + }) + ); + + const bSource = await dispatch(actions.newGeneratedSource(makeSource("b"))); + const bSourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + bSource.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: bSourceActor, + }) + ); + + const loc1 = createLocation({ + source: aSource, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + + const loc2 = createLocation({ + source: bSource, + line: 6, + column: 2, + sourceUrl: "http://localhost:8000/examples/b", + }); + + await dispatch(actions.addBreakpoint(cx, loc1)); + await dispatch(actions.addBreakpoint(cx, loc2)); + + await dispatch(actions.toggleAllBreakpoints(cx, true)); + + let bp1 = selectors.getBreakpoint(getState(), loc1); + let bp2 = selectors.getBreakpoint(getState(), loc2); + + expect(bp1 && bp1.disabled).toBe(true); + expect(bp2 && bp2.disabled).toBe(true); + + await dispatch(actions.toggleAllBreakpoints(cx, false)); + + bp1 = selectors.getBreakpoint(getState(), loc1); + bp2 = selectors.getBreakpoint(getState(), loc2); + expect(bp1 && bp1.disabled).toBe(false); + expect(bp2 && bp2.disabled).toBe(false); + }); + + it("should toggle a breakpoint at a location", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + const loc = createLocation({ source, line: 5, column: 1 }); + const getBp = () => selectors.getBreakpoint(getState(), loc); + await dispatch(actions.selectLocation(cx, loc)); + + await dispatch(actions.toggleBreakpointAtLine(cx, 5)); + const bp = getBp(); + expect(bp && !bp.disabled).toBe(true); + + await dispatch(actions.toggleBreakpointAtLine(cx, 5)); + expect(getBp()).toBe(undefined); + }); + + it("should disable/enable a breakpoint at a location", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + const location = createLocation({ source, line: 5, column: 1 }); + const getBp = () => selectors.getBreakpoint(getState(), location); + await dispatch( + actions.selectLocation(cx, createLocation({ source, line: 1 })) + ); + + await dispatch(actions.toggleBreakpointAtLine(cx, 5)); + let bp = getBp(); + expect(bp && !bp.disabled).toBe(true); + bp = getBp(); + if (!bp) { + throw new Error("no bp"); + } + await dispatch(actions.toggleDisabledBreakpoint(cx, bp)); + bp = getBp(); + expect(bp && bp.disabled).toBe(true); + }); + + it("should set the breakpoint condition", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc = createLocation({ + source, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await dispatch(actions.addBreakpoint(cx, loc)); + + let bp = selectors.getBreakpoint(getState(), loc); + expect(bp && bp.options.condition).toBe(undefined); + + await dispatch( + actions.setBreakpointOptions(cx, loc, { + condition: "const foo = 0", + getTextForLine: () => {}, + }) + ); + + bp = selectors.getBreakpoint(getState(), loc); + expect(bp && bp.options.condition).toBe("const foo = 0"); + }); + + it("should set the condition and enable a breakpoint", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 5: [1] })); + + const source = await dispatch(actions.newGeneratedSource(makeSource("a"))); + const loc = createLocation({ + source, + line: 5, + column: 1, + sourceUrl: "http://localhost:8000/examples/a", + }); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await dispatch(actions.addBreakpoint(cx, loc)); + let bp = selectors.getBreakpoint(getState(), loc); + if (!bp) { + throw new Error("no breakpoint"); + } + + await dispatch(actions.disableBreakpoint(cx, bp)); + + bp = selectors.getBreakpoint(getState(), loc); + expect(bp && bp.options.condition).toBe(undefined); + + await dispatch( + actions.setBreakpointOptions(cx, loc, { + condition: "const foo = 0", + getTextForLine: () => {}, + }) + ); + const newBreakpoint = selectors.getBreakpoint(getState(), loc); + expect(newBreakpoint && !newBreakpoint.disabled).toBe(true); + expect(newBreakpoint && newBreakpoint.options.condition).toBe( + "const foo = 0" + ); + }); + + it("should remove the pretty-printed breakpoint that was added", async () => { + const { dispatch, getState, cx } = createStore(mockClient({ 1: [0] })); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("a.js")) + ); + const loc = createLocation({ + source, + line: 1, + column: 0, + sourceUrl: "http://localhost:8000/examples/a.js", + }); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await dispatch(actions.addBreakpoint(cx, loc)); + await dispatch(actions.togglePrettyPrint(cx, "a.js")); + + const breakpoint = selectors.getBreakpointsList(getState())[0]; + + await dispatch(actions.removeBreakpoint(cx, breakpoint)); + + const breakpointList = selectors.getPendingBreakpointList(getState()); + expect(breakpointList.length).toBe(0); + }); +}); diff --git a/devtools/client/debugger/src/actions/event-listeners.js b/devtools/client/debugger/src/actions/event-listeners.js new file mode 100644 index 0000000000..9c59e930a7 --- /dev/null +++ b/devtools/client/debugger/src/actions/event-listeners.js @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getActiveEventListeners, + getEventListenerExpanded, + shouldLogEventBreakpoints, +} from "../selectors"; + +async function updateBreakpoints(dispatch, client, newEvents) { + await client.setEventListenerBreakpoints(newEvents); + dispatch({ type: "UPDATE_EVENT_LISTENERS", active: newEvents }); +} + +async function updateExpanded(dispatch, newExpanded) { + dispatch({ + type: "UPDATE_EVENT_LISTENER_EXPANDED", + expanded: newExpanded, + }); +} + +export function addEventListenerBreakpoints(eventsToAdd) { + return async ({ dispatch, client, getState }) => { + const activeListenerBreakpoints = await getActiveEventListeners(getState()); + + const newEvents = [ + ...new Set([...eventsToAdd, ...activeListenerBreakpoints]), + ]; + await updateBreakpoints(dispatch, client, newEvents); + }; +} + +export function removeEventListenerBreakpoints(eventsToRemove) { + return async ({ dispatch, client, getState }) => { + const activeListenerBreakpoints = await getActiveEventListeners(getState()); + + const newEvents = activeListenerBreakpoints.filter( + event => !eventsToRemove.includes(event) + ); + + await updateBreakpoints(dispatch, client, newEvents); + }; +} + +export function toggleEventLogging() { + return async ({ dispatch, getState, client }) => { + const logEventBreakpoints = !shouldLogEventBreakpoints(getState()); + await client.toggleEventLogging(logEventBreakpoints); + dispatch({ type: "TOGGLE_EVENT_LISTENERS", logEventBreakpoints }); + }; +} + +export function addEventListenerExpanded(category) { + return async ({ dispatch, getState }) => { + const expanded = await getEventListenerExpanded(getState()); + const newExpanded = [...new Set([...expanded, category])]; + await updateExpanded(dispatch, newExpanded); + }; +} + +export function removeEventListenerExpanded(category) { + return async ({ dispatch, getState }) => { + const expanded = await getEventListenerExpanded(getState()); + + const newExpanded = expanded.filter(expand => expand != category); + + updateExpanded(dispatch, newExpanded); + }; +} + +export function getEventListenerBreakpointTypes() { + return async ({ dispatch, client }) => { + const categories = await client.getEventListenerBreakpointTypes(); + dispatch({ type: "RECEIVE_EVENT_LISTENER_TYPES", categories }); + }; +} diff --git a/devtools/client/debugger/src/actions/exceptions.js b/devtools/client/debugger/src/actions/exceptions.js new file mode 100644 index 0000000000..f1746ec2bb --- /dev/null +++ b/devtools/client/debugger/src/actions/exceptions.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export function addExceptionFromResources(resources) { + return async function ({ dispatch }) { + for (const resource of resources) { + const { pageError } = resource; + if (!pageError.error) { + continue; + } + const { columnNumber, lineNumber, sourceId, errorMessage } = pageError; + const stacktrace = pageError.stacktrace || []; + + const exception = { + columnNumber, + lineNumber, + sourceActorId: sourceId, + errorMessage, + stacktrace, + threadActorId: resource.targetFront.targetForm.threadActor, + }; + + dispatch({ + type: "ADD_EXCEPTION", + exception, + }); + } + }; +} diff --git a/devtools/client/debugger/src/actions/expressions.js b/devtools/client/debugger/src/actions/expressions.js new file mode 100644 index 0000000000..e324038bfb --- /dev/null +++ b/devtools/client/debugger/src/actions/expressions.js @@ -0,0 +1,195 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getExpression, + getExpressions, + getSelectedFrame, + getSelectedFrameId, + getSelectedSource, + getSelectedScopeMappings, + getSelectedFrameBindings, + getCurrentThread, + getIsPaused, + isMapScopesEnabled, +} from "../selectors"; +import { PROMISE } from "./utils/middleware/promise"; +import { wrapExpression } from "../utils/expressions"; +import { features } from "../utils/prefs"; + +/** + * Add expression for debugger to watch + * + * @param {object} expression + * @param {number} expression.id + * @memberof actions/pause + * @static + */ +export function addExpression(cx, input) { + return async ({ dispatch, getState, parserWorker }) => { + if (!input) { + return null; + } + + const expressionError = await parserWorker.hasSyntaxError(input); + + const expression = getExpression(getState(), input); + if (expression) { + return dispatch(evaluateExpression(cx, expression)); + } + + dispatch({ type: "ADD_EXPRESSION", cx, input, expressionError }); + + const newExpression = getExpression(getState(), input); + if (newExpression) { + return dispatch(evaluateExpression(cx, newExpression)); + } + + return null; + }; +} + +export function autocomplete(cx, input, cursor) { + return async ({ dispatch, getState, client }) => { + if (!input) { + return; + } + const frameId = getSelectedFrameId(getState(), cx.thread); + const result = await client.autocomplete(input, cursor, frameId); + dispatch({ type: "AUTOCOMPLETE", cx, input, result }); + }; +} + +export function clearAutocomplete() { + return { type: "CLEAR_AUTOCOMPLETE" }; +} + +export function clearExpressionError() { + return { type: "CLEAR_EXPRESSION_ERROR" }; +} + +export function updateExpression(cx, input, expression) { + return async ({ dispatch, getState, parserWorker }) => { + if (!input) { + return; + } + + const expressionError = await parserWorker.hasSyntaxError(input); + dispatch({ + type: "UPDATE_EXPRESSION", + cx, + expression, + input: expressionError ? expression.input : input, + expressionError, + }); + + dispatch(evaluateExpressions(cx)); + }; +} + +/** + * + * @param {object} expression + * @param {number} expression.id + * @memberof actions/pause + * @static + */ +export function deleteExpression(expression) { + return ({ dispatch }) => { + dispatch({ + type: "DELETE_EXPRESSION", + input: expression.input, + }); + }; +} + +/** + * + * @memberof actions/pause + * @param {number} selectedFrameId + * @static + */ +export function evaluateExpressions(cx) { + return async function ({ dispatch, getState, client }) { + const expressions = getExpressions(getState()); + const inputs = expressions.map(({ input }) => input); + const frameId = getSelectedFrameId(getState(), cx.thread); + const results = await client.evaluateExpressions(inputs, { + frameId, + threadId: cx.thread, + }); + dispatch({ type: "EVALUATE_EXPRESSIONS", cx, inputs, results }); + }; +} + +function evaluateExpression(cx, expression) { + return async function ({ dispatch, getState, client }) { + if (!expression.input) { + console.warn("Expressions should not be empty"); + return null; + } + + let { input } = expression; + const frame = getSelectedFrame(getState(), cx.thread); + + if (frame) { + const selectedSource = getSelectedSource(getState()); + + if ( + selectedSource && + frame.location.source.isOriginal && + selectedSource.isOriginal + ) { + const mapResult = await dispatch(getMappedExpression(input)); + if (mapResult) { + input = mapResult.expression; + } + } + } + + const frameId = getSelectedFrameId(getState(), cx.thread); + + return dispatch({ + type: "EVALUATE_EXPRESSION", + cx, + thread: cx.thread, + input: expression.input, + [PROMISE]: client.evaluate(wrapExpression(input), { + frameId, + }), + }); + }; +} + +/** + * Gets information about original variable names from the source map + * and replaces all posible generated names. + */ +export function getMappedExpression(expression) { + return async function ({ dispatch, getState, parserWorker }) { + const thread = getCurrentThread(getState()); + const mappings = getSelectedScopeMappings(getState(), thread); + const bindings = getSelectedFrameBindings(getState(), thread); + + // We bail early if we do not need to map the expression. This is important + // because mapping an expression can be slow if the parserWorker + // worker is busy doing other work. + // + // 1. there are no mappings - we do not need to map original expressions + // 2. does not contain `await` - we do not need to map top level awaits + // 3. does not contain `=` - we do not need to map assignments + const shouldMapScopes = isMapScopesEnabled(getState()) && mappings; + if (!shouldMapScopes && !expression.match(/(await|=)/)) { + return null; + } + + return parserWorker.mapExpression( + expression, + mappings, + bindings || [], + features.mapExpressionBindings && getIsPaused(getState(), thread), + features.mapAwaitExpression + ); + }; +} diff --git a/devtools/client/debugger/src/actions/file-search.js b/devtools/client/debugger/src/actions/file-search.js new file mode 100644 index 0000000000..4ea2ea01bb --- /dev/null +++ b/devtools/client/debugger/src/actions/file-search.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { searchSourceForHighlight } from "../utils/editor"; + +import { getSelectedSourceTextContent, getSearchOptions } from "../selectors"; + +import { closeActiveSearch, clearHighlightLineRange } from "./ui"; + +export function doSearchForHighlight(query, editor, line, ch) { + return async ({ getState, dispatch }) => { + const sourceTextContent = getSelectedSourceTextContent(getState()); + if (!sourceTextContent) { + return; + } + + dispatch(searchContentsForHighlight(query, editor, line, ch)); + }; +} + +// Expose an action to the React component, so that it can call the searchWorker. +export function querySearchWorker(query, text, modifiers) { + return ({ searchWorker }) => { + return searchWorker.getMatches(query, text, modifiers); + }; +} + +export function searchContentsForHighlight(query, editor, line, ch) { + return async ({ getState, dispatch }) => { + const modifiers = getSearchOptions(getState(), "file-search"); + const sourceTextContent = getSelectedSourceTextContent(getState()); + + if (!query || !editor || !sourceTextContent || !modifiers) { + return; + } + + const ctx = { ed: editor, cm: editor.codeMirror }; + searchSourceForHighlight(ctx, false, query, true, modifiers, line, ch); + }; +} + +export function closeFileSearch(cx, editor) { + return ({ getState, dispatch }) => { + dispatch(closeActiveSearch()); + dispatch(clearHighlightLineRange()); + }; +} diff --git a/devtools/client/debugger/src/actions/index.js b/devtools/client/debugger/src/actions/index.js new file mode 100644 index 0000000000..ab6eec75f1 --- /dev/null +++ b/devtools/client/debugger/src/actions/index.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import * as ast from "./ast"; +import * as breakpoints from "./breakpoints"; +import * as exceptions from "./exceptions"; +import * as expressions from "./expressions"; +import * as eventListeners from "./event-listeners"; +import * as pause from "./pause"; +import * as navigation from "./navigation"; +import * as ui from "./ui"; +import * as fileSearch from "./file-search"; +import * as projectTextSearch from "./project-text-search"; +import * as quickOpen from "./quick-open"; +import * as sourcesTree from "./sources-tree"; +import * as sources from "./sources"; +import * as sourcesActors from "./source-actors"; +import * as tabs from "./tabs"; +import * as threads from "./threads"; +import * as toolbox from "./toolbox"; +import * as preview from "./preview"; +import * as tracing from "./tracing"; + +import { objectInspector } from "devtools/client/shared/components/reps/index"; + +export default { + ...ast, + ...navigation, + ...breakpoints, + ...exceptions, + ...expressions, + ...eventListeners, + ...sources, + ...sourcesActors, + ...tabs, + ...pause, + ...ui, + ...fileSearch, + ...objectInspector.actions, + ...projectTextSearch, + ...quickOpen, + ...sourcesTree, + ...threads, + ...toolbox, + ...preview, + ...tracing, +}; diff --git a/devtools/client/debugger/src/actions/moz.build b/devtools/client/debugger/src/actions/moz.build new file mode 100644 index 0000000000..770fc61139 --- /dev/null +++ b/devtools/client/debugger/src/actions/moz.build @@ -0,0 +1,31 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + "ast", + "breakpoints", + "pause", + "sources", + "utils", +] + +CompiledModules( + "event-listeners.js", + "exceptions.js", + "expressions.js", + "file-search.js", + "index.js", + "navigation.js", + "preview.js", + "project-text-search.js", + "quick-open.js", + "source-actors.js", + "sources-tree.js", + "tabs.js", + "toolbox.js", + "tracing.js", + "threads.js", + "ui.js", +) diff --git a/devtools/client/debugger/src/actions/navigation.js b/devtools/client/debugger/src/actions/navigation.js new file mode 100644 index 0000000000..03d06a2baa --- /dev/null +++ b/devtools/client/debugger/src/actions/navigation.js @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { clearDocuments } from "../utils/editor"; +import sourceQueue from "../utils/source-queue"; + +import { clearWasmStates } from "../utils/wasm"; +import { getMainThread, getThreadContext } from "../selectors"; +import { evaluateExpressions } from "../actions/expressions"; + +/** + * Redux actions for the navigation state + * @module actions/navigation + */ + +/** + * @memberof actions/navigation + * @static + */ +export function willNavigate(event) { + return async function ({ + dispatch, + getState, + client, + sourceMapLoader, + parserWorker, + }) { + sourceQueue.clear(); + sourceMapLoader.clearSourceMaps(); + clearWasmStates(); + clearDocuments(); + parserWorker.clear(); + const thread = getMainThread(getState()); + + dispatch({ + type: "NAVIGATE", + mainThread: { ...thread, url: event.url }, + }); + }; +} + +/** + * @memberof actions/navigation + * @static + */ +export function navigated() { + return async function ({ getState, dispatch, panel }) { + try { + // Update the watched expressions once the page is fully loaded + const threadcx = getThreadContext(getState()); + await dispatch(evaluateExpressions(threadcx)); + } catch (e) { + // This may throw if we resume during the page load. + // browser_dbg-debugger-buttons.js highlights this, especially on MacOS or when ran many times + console.error("Failed to update expression on navigation", e); + } + + panel.emit("reloaded"); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/breakOnNext.js b/devtools/client/debugger/src/actions/pause/breakOnNext.js new file mode 100644 index 0000000000..02df827cb1 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/breakOnNext.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Debugger breakOnNext command. + * It's different from the comand action because we also want to + * highlight the pause icon. + * + * @memberof actions/pause + * @static + */ +export function breakOnNext(cx) { + return async ({ dispatch, getState, client }) => { + await client.breakOnNext(cx.thread); + return dispatch({ type: "BREAK_ON_NEXT", thread: cx.thread }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/commands.js b/devtools/client/debugger/src/actions/pause/commands.js new file mode 100644 index 0000000000..27478d6ad2 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/commands.js @@ -0,0 +1,157 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getSelectedFrame, + getThreadContext, + getCurrentThread, + getIsCurrentThreadPaused, +} from "../../selectors"; +import { PROMISE } from "../utils/middleware/promise"; +import { evaluateExpressions } from "../expressions"; +import { selectLocation } from "../sources"; +import { fetchScopes } from "./fetchScopes"; +import { fetchFrames } from "./fetchFrames"; +import { recordEvent } from "../../utils/telemetry"; +import assert from "../../utils/assert"; + +export function selectThread(cx, thread) { + return async ({ dispatch, getState, client }) => { + if (getCurrentThread(getState()) === thread) { + return; + } + + dispatch({ cx, type: "SELECT_THREAD", thread }); + + // Get a new context now that the current thread has changed. + const threadcx = getThreadContext(getState()); + // Note that this is a rethorical assertion as threadcx.thread is updated by SELECT_THREAD action + assert(threadcx.thread == thread, "Thread mismatch"); + + const serverRequests = []; + // Update the watched expressions as we may never have evaluated them against this thread + serverRequests.push(dispatch(evaluateExpressions(threadcx))); + + // If we were paused on the newly selected thread, ensure: + // - select the source where we are paused, + // - fetching the paused stackframes, + // - fetching the paused scope, so that variable preview are working on the selected source. + // (frames and scopes is supposed to be fetched on pause, + // but if two threads pause concurrently, it might be cancelled) + const frame = getSelectedFrame(getState(), thread); + if (frame) { + serverRequests.push(dispatch(selectLocation(threadcx, frame.location))); + serverRequests.push(dispatch(fetchFrames(threadcx))); + serverRequests.push(dispatch(fetchScopes(threadcx))); + } + + await Promise.all(serverRequests); + }; +} + +/** + * Debugger commands like stepOver, stepIn, stepUp + * + * @param string $0.type + * @memberof actions/pause + * @static + */ +export function command(type) { + return async ({ dispatch, getState, client }) => { + if (!type) { + return null; + } + // For now, all commands are by default against the currently selected thread + const thread = getCurrentThread(getState()); + + const frame = getSelectedFrame(getState(), thread); + + return dispatch({ + type: "COMMAND", + command: type, + thread, + [PROMISE]: client[type](thread, frame?.id), + }); + }; +} + +/** + * StepIn + * @memberof actions/pause + * @static + * @returns {Function} {@link command} + */ +export function stepIn() { + return ({ dispatch, getState }) => { + if (!getIsCurrentThreadPaused(getState())) { + return null; + } + return dispatch(command("stepIn")); + }; +} + +/** + * stepOver + * @memberof actions/pause + * @static + * @returns {Function} {@link command} + */ +export function stepOver() { + return ({ dispatch, getState }) => { + if (!getIsCurrentThreadPaused(getState())) { + return null; + } + return dispatch(command("stepOver")); + }; +} + +/** + * stepOut + * @memberof actions/pause + * @static + * @returns {Function} {@link command} + */ +export function stepOut() { + return ({ dispatch, getState }) => { + if (!getIsCurrentThreadPaused(getState())) { + return null; + } + return dispatch(command("stepOut")); + }; +} + +/** + * resume + * @memberof actions/pause + * @static + * @returns {Function} {@link command} + */ +export function resume() { + return ({ dispatch, getState }) => { + if (!getIsCurrentThreadPaused(getState())) { + return null; + } + recordEvent("continue"); + return dispatch(command("resume")); + }; +} + +/** + * restart frame + * @memberof actions/pause + * @static + */ +export function restart(cx, frame) { + return async ({ dispatch, getState, client }) => { + if (!getIsCurrentThreadPaused(getState())) { + return null; + } + return dispatch({ + type: "COMMAND", + command: "restart", + thread: cx.thread, + [PROMISE]: client.restart(cx.thread, frame.id), + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/continueToHere.js b/devtools/client/debugger/src/actions/pause/continueToHere.js new file mode 100644 index 0000000000..56aa117eab --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/continueToHere.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getSelectedSource, + getSelectedFrame, + getClosestBreakpointPosition, + getBreakpoint, +} from "../../selectors"; +import { createLocation } from "../../utils/location"; +import { addHiddenBreakpoint } from "../breakpoints"; +import { setBreakpointPositions } from "../breakpoints/breakpointPositions"; + +import { resume } from "./commands"; + +export function continueToHere(cx, location) { + return async function ({ dispatch, getState }) { + const { line, column } = location; + const selectedSource = getSelectedSource(getState()); + const selectedFrame = getSelectedFrame(getState(), cx.thread); + + if (!selectedFrame || !selectedSource) { + return; + } + + const debugLine = selectedFrame.location.line; + // If the user selects a line to continue to, + // it must be different than the currently paused line. + if (!column && debugLine == line) { + return; + } + + await dispatch(setBreakpointPositions({ cx, location })); + const position = getClosestBreakpointPosition(getState(), location); + + // If the user selects a location in the editor, + // there must be a place we can pause on that line. + if (column && !position) { + return; + } + + const pauseLocation = column && position ? position.location : location; + + // Set a hidden breakpoint if we do not already have a breakpoint + // at the closest position + if (!getBreakpoint(getState(), pauseLocation)) { + await dispatch( + addHiddenBreakpoint( + cx, + createLocation({ + source: selectedSource, + line: pauseLocation.line, + column: pauseLocation.column, + }) + ) + ); + } + + dispatch(resume(cx)); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/expandScopes.js b/devtools/client/debugger/src/actions/pause/expandScopes.js new file mode 100644 index 0000000000..fa431ee0b9 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/expandScopes.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getScopeItemPath } from "../../utils/pause/scopes/utils"; + +export function setExpandedScope(cx, item, expanded) { + return function ({ dispatch, getState }) { + return dispatch({ + type: "SET_EXPANDED_SCOPE", + cx, + thread: cx.thread, + path: getScopeItemPath(item), + expanded, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/fetchFrames.js b/devtools/client/debugger/src/actions/pause/fetchFrames.js new file mode 100644 index 0000000000..42295ae026 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/fetchFrames.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { isValidThreadContext } from "../../utils/context"; + +export function fetchFrames(cx) { + return async function ({ dispatch, client, getState }) { + const { thread } = cx; + let frames; + try { + frames = await client.getFrames(thread); + } catch (e) { + // getFrames will fail if the thread has resumed. In this case the thread + // should no longer be valid and the frames we would have fetched would be + // discarded anyways. + if (isValidThreadContext(getState(), cx)) { + throw e; + } + } + dispatch({ type: "FETCHED_FRAMES", thread, frames, cx }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/fetchScopes.js b/devtools/client/debugger/src/actions/pause/fetchScopes.js new file mode 100644 index 0000000000..691b3ce006 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/fetchScopes.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSelectedFrame, getGeneratedFrameScope } from "../../selectors"; +import { mapScopes } from "./mapScopes"; +import { generateInlinePreview } from "./inlinePreview"; +import { PROMISE } from "../utils/middleware/promise"; + +export function fetchScopes(cx) { + return async function ({ dispatch, getState, client }) { + const frame = getSelectedFrame(getState(), cx.thread); + if (!frame || getGeneratedFrameScope(getState(), frame.id)) { + return; + } + + const scopes = dispatch({ + type: "ADD_SCOPES", + cx, + thread: cx.thread, + frame, + [PROMISE]: client.getFrameScopes(frame), + }); + + scopes.then(() => { + dispatch(generateInlinePreview(cx, frame)); + }); + await dispatch(mapScopes(cx, scopes, frame)); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/highlightCalls.js b/devtools/client/debugger/src/actions/pause/highlightCalls.js new file mode 100644 index 0000000000..aec82fe35b --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/highlightCalls.js @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getSymbols, + getSelectedFrame, + getCurrentThread, +} from "../../selectors"; + +// a is an ast location with start and end positions (line and column). +// b is a single position (line and column). +// This function tests to see if the b position +// falls within the range given in a. +function inHouseContainsPosition(a, b) { + const bColumn = b.column || 0; + const startsBefore = + a.start.line < b.line || + (a.start.line === b.line && a.start.column <= bColumn); + const endsAfter = + a.end.line > b.line || (a.end.line === b.line && a.end.column >= bColumn); + + return startsBefore && endsAfter; +} + +export function highlightCalls(cx) { + return async function ({ dispatch, getState, parserWorker }) { + if (!cx) { + return null; + } + + const frame = await getSelectedFrame( + getState(), + getCurrentThread(getState()) + ); + + if (!frame || !parserWorker.isLocationSupported(frame.location)) { + return null; + } + + const { thread } = cx; + + const originalAstScopes = await parserWorker.getScopes(frame.location); + if (!originalAstScopes) { + return null; + } + + const symbols = getSymbols(getState(), frame.location); + + if (!symbols) { + return null; + } + + if (!symbols.callExpressions) { + return null; + } + + const localAstScope = originalAstScopes[0]; + const allFunctionCalls = symbols.callExpressions; + + const highlightedCalls = allFunctionCalls.filter(function (call) { + const containsStart = inHouseContainsPosition( + localAstScope, + call.location.start + ); + const containsEnd = inHouseContainsPosition( + localAstScope, + call.location.end + ); + return containsStart && containsEnd; + }); + + return dispatch({ + type: "HIGHLIGHT_CALLS", + thread, + highlightedCalls, + }); + }; +} + +export function unhighlightCalls(cx) { + return async function ({ dispatch, getState }) { + const { thread } = cx; + return dispatch({ + type: "UNHIGHLIGHT_CALLS", + thread, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/index.js b/devtools/client/debugger/src/actions/pause/index.js new file mode 100644 index 0000000000..be31894019 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/index.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the pause state + * @module actions/pause + */ + +export { + selectThread, + stepIn, + stepOver, + stepOut, + resume, + restart, +} from "./commands"; +export { fetchFrames } from "./fetchFrames"; +export { fetchScopes } from "./fetchScopes"; +export { paused } from "./paused"; +export { resumed } from "./resumed"; +export { continueToHere } from "./continueToHere"; +export { breakOnNext } from "./breakOnNext"; +export { resetBreakpointsPaneState } from "./resetBreakpointsPaneState"; +export { mapFrames } from "./mapFrames"; +export { mapDisplayNames } from "./mapDisplayNames"; +export { pauseOnExceptions } from "./pauseOnExceptions"; +export { selectFrame } from "./selectFrame"; +export { toggleSkipPausing, setSkipPausing } from "./skipPausing"; +export { toggleMapScopes } from "./mapScopes"; +export { setExpandedScope } from "./expandScopes"; +export { generateInlinePreview } from "./inlinePreview"; +export { highlightCalls, unhighlightCalls } from "./highlightCalls"; diff --git a/devtools/client/debugger/src/actions/pause/inlinePreview.js b/devtools/client/debugger/src/actions/pause/inlinePreview.js new file mode 100644 index 0000000000..e3a4e614c0 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/inlinePreview.js @@ -0,0 +1,244 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getOriginalFrameScope, + getGeneratedFrameScope, + getInlinePreviews, + getSelectedLocation, +} from "../../selectors"; +import { features } from "../../utils/prefs"; +import { validateThreadContext } from "../../utils/context"; + +// We need to display all variables in the current functional scope so +// include all data for block scopes until the first functional scope +function getLocalScopeLevels(originalAstScopes) { + let levels = 0; + while ( + originalAstScopes[levels] && + originalAstScopes[levels].type === "block" + ) { + levels++; + } + return levels; +} + +export function generateInlinePreview(cx, frame) { + return async function ({ dispatch, getState, parserWorker, client }) { + if (!frame || !features.inlinePreview) { + return null; + } + + const { thread } = cx; + + // Avoid regenerating inline previews when we already have preview data + if (getInlinePreviews(getState(), thread, frame.id)) { + return null; + } + + const originalFrameScopes = getOriginalFrameScope( + getState(), + thread, + frame.location.sourceId, + frame.id + ); + + const generatedFrameScopes = getGeneratedFrameScope( + getState(), + thread, + frame.id + ); + + let scopes = originalFrameScopes?.scope || generatedFrameScopes?.scope; + + if (!scopes || !scopes.bindings) { + return null; + } + + // It's important to use selectedLocation, because we don't know + // if we'll be viewing the original or generated frame location + const selectedLocation = getSelectedLocation(getState()); + if (!selectedLocation) { + return null; + } + + if (!parserWorker.isLocationSupported(selectedLocation)) { + return null; + } + + const originalAstScopes = await parserWorker.getScopes(selectedLocation); + validateThreadContext(getState(), cx); + if (!originalAstScopes) { + return null; + } + + const allPreviews = []; + const pausedOnLine = selectedLocation.line; + const levels = getLocalScopeLevels(originalAstScopes); + + for ( + let curLevel = 0; + curLevel <= levels && scopes && scopes.bindings; + curLevel++ + ) { + const bindings = { ...scopes.bindings.variables }; + scopes.bindings.arguments.forEach(argument => { + Object.keys(argument).forEach(key => { + bindings[key] = argument[key]; + }); + }); + + const previewBindings = Object.keys(bindings).map(async name => { + // We want to show values of properties of objects only and not + // function calls on other data types like someArr.forEach etc.. + let properties = null; + const objectGrip = bindings[name].value; + if (objectGrip.actor && objectGrip.class === "Object") { + properties = await client.loadObjectProperties( + { + name, + path: name, + contents: { value: objectGrip }, + }, + cx.thread + ); + } + + const previewsFromBindings = getBindingValues( + originalAstScopes, + pausedOnLine, + name, + bindings[name].value, + curLevel, + properties + ); + + allPreviews.push(...previewsFromBindings); + }); + await Promise.all(previewBindings); + + scopes = scopes.parent; + } + + // Sort previews by line and column so they're displayed in the right order in the editor + allPreviews.sort((previewA, previewB) => { + if (previewA.line < previewB.line) { + return -1; + } + if (previewA.line > previewB.line) { + return 1; + } + // If we have the same line number + return previewA.column < previewB.column ? -1 : 1; + }); + + const previews = {}; + for (const preview of allPreviews) { + const { line } = preview; + if (!previews[line]) { + previews[line] = []; + } + previews[line].push(preview); + } + + return dispatch({ + type: "ADD_INLINE_PREVIEW", + thread, + frame, + previews, + }); + }; +} + +function getBindingValues( + originalAstScopes, + pausedOnLine, + name, + value, + curLevel, + properties +) { + const previews = []; + + const binding = originalAstScopes[curLevel]?.bindings[name]; + if (!binding) { + return previews; + } + + // Show a variable only once ( an object and it's child property are + // counted as different ) + const identifiers = new Set(); + + // We start from end as we want to show values besides variable + // located nearest to the breakpoint + for (let i = binding.refs.length - 1; i >= 0; i--) { + const ref = binding.refs[i]; + // Subtracting 1 from line as codemirror lines are 0 indexed + const line = ref.start.line - 1; + const column = ref.start.column; + // We don't want to render inline preview below the paused line + if (line >= pausedOnLine - 1) { + continue; + } + + const { displayName, displayValue } = getExpressionNameAndValue( + name, + value, + ref, + properties + ); + + // Variable with same name exists, display value of current or + // closest to the current scope's variable + if (identifiers.has(displayName)) { + continue; + } + identifiers.add(displayName); + + previews.push({ + line, + column, + name: displayName, + value: displayValue, + }); + } + return previews; +} + +function getExpressionNameAndValue( + name, + value, + // TODO: Add data type to ref + ref, + properties +) { + let displayName = name; + let displayValue = value; + + // Only variables of type Object will have properties + if (properties) { + let { meta } = ref; + // Presence of meta property means expression contains child property + // reference eg: objName.propName + while (meta) { + // Initially properties will be an array, after that it will be an object + if (displayValue === value) { + const property = properties.find(prop => prop.name === meta.property); + displayValue = property?.contents.value; + displayName += `.${meta.property}`; + } else if (displayValue?.preview?.ownProperties) { + const { ownProperties } = displayValue.preview; + Object.keys(ownProperties).forEach(prop => { + if (prop === meta.property) { + displayValue = ownProperties[prop].value; + displayName += `.${meta.property}`; + } + }); + } + meta = meta.parent; + } + } + + return { displayName, displayValue }; +} diff --git a/devtools/client/debugger/src/actions/pause/mapDisplayNames.js b/devtools/client/debugger/src/actions/pause/mapDisplayNames.js new file mode 100644 index 0000000000..a7abbc36bd --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/mapDisplayNames.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getFrames, getSymbols } from "../../selectors"; + +import { findClosestFunction } from "../../utils/ast"; + +function mapDisplayName(frame, { getState }) { + if (frame.isOriginal) { + return frame; + } + + const symbols = getSymbols(getState(), frame.location); + + if (!symbols || !symbols.functions) { + return frame; + } + + const originalFunction = findClosestFunction(symbols, frame.location); + + if (!originalFunction) { + return frame; + } + + const originalDisplayName = originalFunction.name; + return { ...frame, originalDisplayName }; +} + +export function mapDisplayNames(cx) { + return function ({ dispatch, getState }) { + const frames = getFrames(getState(), cx.thread); + + if (!frames) { + return; + } + + const mappedFrames = frames.map(frame => + mapDisplayName(frame, { getState }) + ); + + dispatch({ + type: "MAP_FRAME_DISPLAY_NAMES", + cx, + thread: cx.thread, + frames: mappedFrames, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/mapFrames.js b/devtools/client/debugger/src/actions/pause/mapFrames.js new file mode 100644 index 0000000000..d677677505 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/mapFrames.js @@ -0,0 +1,157 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getFrames, + getBlackBoxRanges, + getSelectedFrame, +} from "../../selectors"; + +import { isFrameBlackBoxed } from "../../utils/source"; + +import assert from "../../utils/assert"; +import { getOriginalLocation } from "../../utils/source-maps"; +import { + debuggerToSourceMapLocation, + sourceMapToDebuggerLocation, +} from "../../utils/location"; +import { isGeneratedId } from "devtools/client/shared/source-map-loader/index"; + +function getSelectedFrameId(state, thread, frames) { + let selectedFrame = getSelectedFrame(state, thread); + const blackboxedRanges = getBlackBoxRanges(state); + + if (selectedFrame && !isFrameBlackBoxed(selectedFrame, blackboxedRanges)) { + return selectedFrame.id; + } + + selectedFrame = frames.find(frame => { + return !isFrameBlackBoxed(frame, blackboxedRanges); + }); + return selectedFrame?.id; +} + +async function updateFrameLocation(frame, thunkArgs) { + if (frame.isOriginal) { + return Promise.resolve(frame); + } + const location = await getOriginalLocation(frame.location, thunkArgs, true); + return { + ...frame, + location, + generatedLocation: frame.generatedLocation || frame.location, + }; +} + +function updateFrameLocations(frames, thunkArgs) { + if (!frames || !frames.length) { + return Promise.resolve(frames); + } + + return Promise.all( + frames.map(frame => updateFrameLocation(frame, thunkArgs)) + ); +} + +function isWasmOriginalSourceFrame(frame, getState) { + if (isGeneratedId(frame.location.sourceId)) { + return false; + } + + return Boolean(frame.generatedLocation?.source.isWasm); +} + +async function expandFrames(frames, { getState, sourceMapLoader }) { + const result = []; + for (let i = 0; i < frames.length; ++i) { + const frame = frames[i]; + if (frame.isOriginal || !isWasmOriginalSourceFrame(frame, getState)) { + result.push(frame); + continue; + } + const originalFrames = await sourceMapLoader.getOriginalStackFrames( + debuggerToSourceMapLocation(frame.generatedLocation) + ); + if (!originalFrames) { + result.push(frame); + continue; + } + + assert(!!originalFrames.length, "Expected at least one original frame"); + // First entry has not specific location -- use one from original frame. + originalFrames[0] = { + ...originalFrames[0], + location: frame.location, + }; + + originalFrames.forEach((originalFrame, j) => { + if (!originalFrame.location) { + return; + } + + // Keep outer most frame with true actor ID, and generate uniquie + // one for the nested frames. + const id = j == 0 ? frame.id : `${frame.id}-originalFrame${j}`; + result.push({ + id, + displayName: originalFrame.displayName, + location: sourceMapToDebuggerLocation( + getState(), + originalFrame.location + ), + index: frame.index, + source: null, + thread: frame.thread, + scope: frame.scope, + this: frame.this, + isOriginal: true, + // More fields that will be added by the mapDisplayNames and + // updateFrameLocation. + generatedLocation: frame.generatedLocation, + originalDisplayName: originalFrame.displayName, + originalVariables: originalFrame.variables, + asyncCause: frame.asyncCause, + state: frame.state, + }); + }); + } + return result; +} + +/** + * Map call stack frame locations and display names to originals. + * e.g. + * 1. When the debuggee pauses + * 2. When a source is pretty printed + * 3. When symbols are loaded + * @memberof actions/pause + * @static + */ +export function mapFrames(cx) { + return async function (thunkArgs) { + const { dispatch, getState } = thunkArgs; + const frames = getFrames(getState(), cx.thread); + if (!frames) { + return; + } + + let mappedFrames = await updateFrameLocations(frames, thunkArgs); + + mappedFrames = await expandFrames(mappedFrames, thunkArgs); + + const selectedFrameId = getSelectedFrameId( + getState(), + cx.thread, + mappedFrames + ); + + dispatch({ + type: "MAP_FRAMES", + cx, + thread: cx.thread, + frames: mappedFrames, + selectedFrameId, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/mapScopes.js b/devtools/client/debugger/src/actions/pause/mapScopes.js new file mode 100644 index 0000000000..2a352dc578 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/mapScopes.js @@ -0,0 +1,194 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getSelectedFrameId, + getSettledSourceTextContent, + isMapScopesEnabled, + getSelectedFrame, + getSelectedGeneratedScope, + getSelectedOriginalScope, + getThreadContext, + getFirstSourceActorForGeneratedSource, +} from "../../selectors"; +import { + loadOriginalSourceText, + loadGeneratedSourceText, +} from "../sources/loadSourceText"; +import { PROMISE } from "../utils/middleware/promise"; +import assert from "../../utils/assert"; + +import { log } from "../../utils/log"; +import { isGenerated } from "../../utils/source"; + +import { buildMappedScopes } from "../../utils/pause/mapScopes"; +import { isFulfilled } from "../../utils/async-value"; + +import { getMappedLocation } from "../../utils/source-maps"; + +const expressionRegex = /\bfp\(\)/g; + +export async function buildOriginalScopes( + frame, + client, + cx, + frameId, + generatedScopes +) { + if (!frame.originalVariables) { + throw new TypeError("(frame.originalVariables: XScopeVariables)"); + } + const originalVariables = frame.originalVariables; + const frameBase = originalVariables.frameBase || ""; + + const inputs = []; + for (let i = 0; i < originalVariables.vars.length; i++) { + const { expr } = originalVariables.vars[i]; + const expression = expr + ? expr.replace(expressionRegex, frameBase) + : "void 0"; + + inputs[i] = expression; + } + + const results = await client.evaluateExpressions(inputs, { + frameId, + }); + + const variables = {}; + for (let i = 0; i < originalVariables.vars.length; i++) { + const { name } = originalVariables.vars[i]; + variables[name] = { value: results[i].result }; + } + + const bindings = { + arguments: [], + variables, + }; + + const { actor } = await generatedScopes; + const scope = { + type: "function", + scopeKind: "", + actor, + bindings, + parent: null, + function: null, + block: null, + }; + return { + mappings: {}, + scope, + }; +} + +export function toggleMapScopes() { + return async function ({ dispatch, getState }) { + if (isMapScopesEnabled(getState())) { + dispatch({ type: "TOGGLE_MAP_SCOPES", mapScopes: false }); + return; + } + + dispatch({ type: "TOGGLE_MAP_SCOPES", mapScopes: true }); + + const cx = getThreadContext(getState()); + + if (getSelectedOriginalScope(getState(), cx.thread)) { + return; + } + + const scopes = getSelectedGeneratedScope(getState(), cx.thread); + const frame = getSelectedFrame(getState(), cx.thread); + if (!scopes || !frame) { + return; + } + + dispatch(mapScopes(cx, Promise.resolve(scopes.scope), frame)); + }; +} + +export function mapScopes(cx, scopes, frame) { + return async function (thunkArgs) { + const { dispatch, client, getState } = thunkArgs; + assert(cx.thread == frame.thread, "Thread mismatch"); + + await dispatch({ + type: "MAP_SCOPES", + cx, + thread: cx.thread, + frame, + [PROMISE]: (async function () { + if (frame.isOriginal && frame.originalVariables) { + const frameId = getSelectedFrameId(getState(), cx.thread); + return buildOriginalScopes(frame, client, cx, frameId, scopes); + } + + return dispatch(getMappedScopes(cx, scopes, frame)); + })(), + }); + }; +} + +export function getMappedScopes(cx, scopes, frame) { + return async function (thunkArgs) { + const { getState, dispatch } = thunkArgs; + const generatedSource = frame.generatedLocation.source; + + const source = frame.location.source; + + if ( + !isMapScopesEnabled(getState()) || + !source || + !generatedSource || + generatedSource.isWasm || + source.isPrettyPrinted || + isGenerated(source) + ) { + return null; + } + + // Load source text for the original source + await dispatch(loadOriginalSourceText({ cx, source })); + + const generatedSourceActor = getFirstSourceActorForGeneratedSource( + getState(), + generatedSource.id + ); + + // Also load source text for its corresponding generated source + await dispatch( + loadGeneratedSourceText({ + cx, + sourceActor: generatedSourceActor, + }) + ); + + try { + // load original source text content + const content = getSettledSourceTextContent(getState(), frame.location); + + return await buildMappedScopes( + source, + content && isFulfilled(content) + ? content.value + : { type: "text", value: "", contentType: undefined }, + frame, + await scopes, + thunkArgs + ); + } catch (e) { + log(e); + return null; + } + }; +} + +export function getMappedScopesForLocation(location) { + return async function (thunkArgs) { + const { dispatch, getState } = thunkArgs; + const cx = getThreadContext(getState()); + const mappedLocation = await getMappedLocation(location, thunkArgs); + return dispatch(getMappedScopes(cx, null, mappedLocation)); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/moz.build b/devtools/client/debugger/src/actions/pause/moz.build new file mode 100644 index 0000000000..54cf792166 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/moz.build @@ -0,0 +1,27 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "breakOnNext.js", + "commands.js", + "continueToHere.js", + "expandScopes.js", + "fetchFrames.js", + "fetchScopes.js", + "highlightCalls.js", + "index.js", + "inlinePreview.js", + "mapDisplayNames.js", + "mapFrames.js", + "mapScopes.js", + "paused.js", + "pauseOnExceptions.js", + "resetBreakpointsPaneState.js", + "resumed.js", + "selectFrame.js", + "skipPausing.js", +) diff --git a/devtools/client/debugger/src/actions/pause/pauseOnExceptions.js b/devtools/client/debugger/src/actions/pause/pauseOnExceptions.js new file mode 100644 index 0000000000..e7c04ded61 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/pauseOnExceptions.js @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { PROMISE } from "../utils/middleware/promise"; +import { recordEvent } from "../../utils/telemetry"; + +/** + * + * @memberof actions/pause + * @static + */ +export function pauseOnExceptions( + shouldPauseOnExceptions, + shouldPauseOnCaughtExceptions +) { + return ({ dispatch, getState, client }) => { + recordEvent("pause_on_exceptions", { + exceptions: shouldPauseOnExceptions, + // There's no "n" in the key below (#1463117) + ["caught_exceptio"]: shouldPauseOnCaughtExceptions, + }); + + return dispatch({ + type: "PAUSE_ON_EXCEPTIONS", + shouldPauseOnExceptions, + shouldPauseOnCaughtExceptions, + [PROMISE]: client.pauseOnExceptions( + shouldPauseOnExceptions, + shouldPauseOnCaughtExceptions + ), + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/paused.js b/devtools/client/debugger/src/actions/pause/paused.js new file mode 100644 index 0000000000..0e797035a5 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/paused.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getHiddenBreakpoint, + isEvaluatingExpression, + getSelectedFrame, + getThreadContext, +} from "../../selectors"; + +import { mapFrames, fetchFrames } from "."; +import { removeBreakpoint } from "../breakpoints"; +import { evaluateExpressions } from "../expressions"; +import { selectLocation } from "../sources"; +import assert from "../../utils/assert"; + +import { fetchScopes } from "./fetchScopes"; + +/** + * Debugger has just paused + * + * @param {object} pauseInfo + * @memberof actions/pause + * @static + */ +export function paused(pauseInfo) { + return async function ({ dispatch, getState }) { + const { thread, frame, why } = pauseInfo; + + dispatch({ type: "PAUSED", thread, why, frame }); + + // Get a context capturing the newly paused and selected thread. + const cx = getThreadContext(getState()); + // Note that this is a rethorical assertion as threadcx.thread is updated by PAUSED action + assert(cx.thread == thread, "Thread mismatch"); + + // When we use "continue to here" feature we register an "hidden" breakpoint + // that should be removed on the next paused, even if we didn't hit it and + // paused for any other reason. + const hiddenBreakpoint = getHiddenBreakpoint(getState()); + if (hiddenBreakpoint) { + dispatch(removeBreakpoint(cx, hiddenBreakpoint)); + } + + // The THREAD_STATE's "paused" resource only passes the top level stack frame, + // we dispatch the PAUSED action with it so that we can right away + // display it and update the UI to be paused. + // But we then fetch all the other frames: + await dispatch(fetchFrames(cx)); + // And map them to original source locations. + // Note that this will wait for all related original sources to be loaded in the reducers. + // So this step may pause for a little while. + await dispatch(mapFrames(cx)); + + // If we paused on a particular frame, automatically select the related source + // and highlight the paused line + const selectedFrame = getSelectedFrame(getState(), thread); + if (selectedFrame) { + await dispatch(selectLocation(cx, selectedFrame.location)); + } + + // Fetch the previews for variables visible in the currently selected paused stackframe + await dispatch(fetchScopes(cx)); + + // Run after fetching scoping data so that it may make use of the sourcemap + // expression mappings for local variables. + const atException = why.type == "exception"; + if (!atException || !isEvaluatingExpression(getState(), thread)) { + await dispatch(evaluateExpressions(cx)); + } + }; +} diff --git a/devtools/client/debugger/src/actions/pause/resetBreakpointsPaneState.js b/devtools/client/debugger/src/actions/pause/resetBreakpointsPaneState.js new file mode 100644 index 0000000000..a602c58896 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/resetBreakpointsPaneState.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Action for the breakpoints panel while paused. + * + * @memberof actions/pause + * @static + */ +export function resetBreakpointsPaneState(thread) { + return async ({ dispatch }) => { + dispatch({ + type: "RESET_BREAKPOINTS_PANE_STATE", + thread, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/resumed.js b/devtools/client/debugger/src/actions/pause/resumed.js new file mode 100644 index 0000000000..323e9f0ff8 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/resumed.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { isStepping, getPauseReason, getThreadContext } from "../../selectors"; +import { evaluateExpressions } from "../expressions"; +import { inDebuggerEval } from "../../utils/pause"; + +/** + * Debugger has just resumed + * + * @memberof actions/pause + * @static + */ +export function resumed(thread) { + return async ({ dispatch, client, getState }) => { + const why = getPauseReason(getState(), thread); + const wasPausedInEval = inDebuggerEval(why); + const wasStepping = isStepping(getState(), thread); + + dispatch({ type: "RESUME", thread, wasStepping }); + + const cx = getThreadContext(getState()); + if (!wasStepping && !wasPausedInEval && cx.thread == thread) { + await dispatch(evaluateExpressions(cx)); + } + }; +} diff --git a/devtools/client/debugger/src/actions/pause/selectFrame.js b/devtools/client/debugger/src/actions/pause/selectFrame.js new file mode 100644 index 0000000000..f97be42787 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/selectFrame.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { selectLocation } from "../sources"; +import { evaluateExpressions } from "../expressions"; +import { fetchScopes } from "./fetchScopes"; +import assert from "../../utils/assert"; + +/** + * @memberof actions/pause + * @static + */ +export function selectFrame(cx, frame) { + return async ({ dispatch, getState }) => { + assert(cx.thread == frame.thread, "Thread mismatch"); + + // Frames that aren't on-stack do not support evalling and may not + // have live inspectable scopes, so we do not allow selecting them. + if (frame.state !== "on-stack") { + dispatch(selectLocation(cx, frame.location)); + return; + } + + dispatch({ + type: "SELECT_FRAME", + cx, + thread: cx.thread, + frame, + }); + + // It's important that we wait for selectLocation to finish because + // we rely on the source being loaded and symbols fetched below. + await dispatch(selectLocation(cx, frame.location)); + + dispatch(evaluateExpressions(cx)); + dispatch(fetchScopes(cx)); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/skipPausing.js b/devtools/client/debugger/src/actions/pause/skipPausing.js new file mode 100644 index 0000000000..1ecdf33b76 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/skipPausing.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSkipPausing } from "../../selectors"; + +/** + * @memberof actions/pause + * @static + */ +export function toggleSkipPausing() { + return async ({ dispatch, client, getState }) => { + const skipPausing = !getSkipPausing(getState()); + await client.setSkipPausing(skipPausing); + dispatch({ type: "TOGGLE_SKIP_PAUSING", skipPausing }); + }; +} + +/** + * @memberof actions/pause + * @static + */ +export function setSkipPausing(skipPausing) { + return async ({ dispatch, client, getState }) => { + const currentlySkipping = getSkipPausing(getState()); + if (currentlySkipping === skipPausing) { + return; + } + + await client.setSkipPausing(skipPausing); + dispatch({ type: "TOGGLE_SKIP_PAUSING", skipPausing }); + }; +} diff --git a/devtools/client/debugger/src/actions/pause/tests/__snapshots__/pauseOnExceptions.spec.js.snap b/devtools/client/debugger/src/actions/pause/tests/__snapshots__/pauseOnExceptions.spec.js.snap new file mode 100644 index 0000000000..55b8d3e724 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/tests/__snapshots__/pauseOnExceptions.spec.js.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`pauseOnExceptions should track telemetry for pauseOnException changes 1`] = ` +Array [ + Object { + "caught_exceptio": false, + "exceptions": true, + }, +] +`; diff --git a/devtools/client/debugger/src/actions/pause/tests/pause.spec.js b/devtools/client/debugger/src/actions/pause/tests/pause.spec.js new file mode 100644 index 0000000000..3a562ccfdd --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/tests/pause.spec.js @@ -0,0 +1,413 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + createSourceObject, + waitForState, + makeSource, + makeOriginalSource, + makeFrame, +} from "../../../utils/test-head"; + +import { makeWhyNormal } from "../../../utils/test-mockup"; +import { createLocation } from "../../../utils/location"; + +const { isStepping } = selectors; + +let stepInResolve = null; +const mockCommandClient = { + stepIn: () => + new Promise(_resolve => { + stepInResolve = _resolve; + }), + stepOver: () => new Promise(_resolve => _resolve), + evaluate: async () => {}, + evaluateExpressions: async () => [], + resume: async () => {}, + getFrameScopes: async frame => frame.scope, + getFrames: async () => [], + setBreakpoint: () => new Promise(_resolve => {}), + sourceContents: ({ source }) => { + return new Promise((resolve, reject) => { + switch (source) { + case "foo1": + return resolve({ + source: "function foo1() {\n return 5;\n}", + contentType: "text/javascript", + }); + case "await": + return resolve({ + source: "async function aWait() {\n await foo(); return 5;\n}", + contentType: "text/javascript", + }); + + case "foo": + return resolve({ + source: "function foo() {\n return -5;\n}", + contentType: "text/javascript", + }); + case "foo-original": + return resolve({ + source: "\n\nfunction fooOriginal() {\n return -5;\n}", + contentType: "text/javascript", + }); + case "foo-wasm": + return resolve({ + source: { binary: new ArrayBuffer(0) }, + contentType: "application/wasm", + }); + case "foo-wasm/originalSource": + return resolve({ + source: "fn fooBar() {}\nfn barZoo() { fooBar() }", + contentType: "text/rust", + }); + } + + return resolve(); + }); + }, + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], + actorID: "threadActorID", +}; + +const mockFrameId = "1"; + +function createPauseInfo( + frameLocation = createLocation({ + source: createSourceObject("foo1"), + line: 2, + }), + frameOpts = {} +) { + const frames = [ + makeFrame( + { id: mockFrameId, sourceId: frameLocation.sourceId }, + { + location: frameLocation, + generatedLocation: frameLocation, + ...frameOpts, + } + ), + ]; + return { + thread: "FakeThread", + frame: frames[0], + frames, + loadedObjects: [], + why: makeWhyNormal(), + }; +} + +describe("pause", () => { + describe("stepping", () => { + it("should set and clear the command", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + const mockPauseInfo = createPauseInfo(); + + await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + await dispatch(actions.paused(mockPauseInfo)); + const cx = selectors.getThreadContext(getState()); + const stepped = dispatch(actions.stepIn(cx)); + expect(isStepping(getState(), "FakeThread")).toBeTruthy(); + if (!stepInResolve) { + throw new Error("no stepInResolve"); + } + await stepInResolve(); + await stepped; + expect(isStepping(getState(), "FakeThread")).toBeFalsy(); + }); + + it("should only step when paused", async () => { + const client = { stepIn: jest.fn() }; + const { dispatch, cx } = createStore(client); + + dispatch(actions.stepIn(cx)); + expect(client.stepIn.mock.calls).toHaveLength(0); + }); + + it("should step when paused", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + const mockPauseInfo = createPauseInfo(); + + await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + await dispatch(actions.paused(mockPauseInfo)); + const cx = selectors.getThreadContext(getState()); + dispatch(actions.stepIn(cx)); + expect(isStepping(getState(), "FakeThread")).toBeTruthy(); + }); + + it("getting frame scopes with bindings", async () => { + const client = { ...mockCommandClient }; + const store = createStore(client, {}); + const { dispatch, getState } = store; + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + const generatedLocation = createLocation({ + source, + line: 1, + column: 0, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ), + }); + const mockPauseInfo = createPauseInfo(generatedLocation, { + scope: { + bindings: { + variables: { b: { value: {} } }, + arguments: [{ a: { value: {} } }], + }, + }, + }); + + const { frames } = mockPauseInfo; + client.getFrames = async () => frames; + await dispatch(actions.newOriginalSources([makeOriginalSource(source)])); + + await dispatch(actions.paused(mockPauseInfo)); + expect(selectors.getFrames(getState(), "FakeThread")).toEqual([ + { + id: mockFrameId, + generatedLocation, + location: generatedLocation, + originalDisplayName: "foo", + scope: { + bindings: { + arguments: [{ a: { value: {} } }], + variables: { b: { value: {} } }, + }, + }, + thread: "FakeThread", + }, + ]); + + expect(selectors.getFrameScopes(getState(), "FakeThread")).toEqual({ + generated: { + 1: { + pending: false, + scope: { + bindings: { + arguments: [{ a: { value: {} } }], + variables: { b: { value: {} } }, + }, + }, + }, + }, + mappings: { 1: undefined }, + original: { 1: { pending: false, scope: undefined } }, + }); + + expect( + selectors.getSelectedFrameBindings(getState(), "FakeThread") + ).toEqual(["b", "a"]); + }); + + it("maps frame locations and names to original source", async () => { + const sourceMapLoaderMock = { + getOriginalLocation: () => Promise.resolve(originalLocation), + getOriginalLocations: async items => items, + getOriginalSourceText: async () => ({ + text: "\n\nfunction fooOriginal() {\n return -5;\n}", + contentType: "text/javascript", + }), + getGeneratedLocation: async location => location, + }; + + const client = { ...mockCommandClient }; + const store = createStore(client, {}, sourceMapLoaderMock); + const { dispatch, getState } = store; + + const originalSource = await dispatch( + actions.newGeneratedSource(makeSource("foo-original")) + ); + + const originalLocation = createLocation({ + source: originalSource, + line: 3, + column: 0, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + originalSource.id + ), + }); + + const generatedSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + const generatedLocation = createLocation({ + source: generatedSource, + line: 1, + column: 0, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + generatedSource.id + ), + }); + const mockPauseInfo = createPauseInfo(generatedLocation); + + const { frames } = mockPauseInfo; + client.getFrames = async () => frames; + + await dispatch(actions.paused(mockPauseInfo)); + expect(selectors.getFrames(getState(), "FakeThread")).toEqual([ + { + id: mockFrameId, + generatedLocation, + location: originalLocation, + originalDisplayName: "fooOriginal", + scope: { bindings: { arguments: [], variables: {} } }, + thread: "FakeThread", + }, + ]); + }); + + it("maps frame to original frames", async () => { + const sourceMapLoaderMock = { + getOriginalStackFrames: loc => Promise.resolve(originStackFrames), + getOriginalLocation: () => Promise.resolve(originalLocation), + getOriginalLocations: async items => items, + getOriginalSourceText: async () => ({ + text: "fn fooBar() {}\nfn barZoo() { fooBar() }", + contentType: "text/rust", + }), + getGeneratedRangesForOriginal: async () => [], + }; + + const client = { ...mockCommandClient }; + const store = createStore(client, {}, sourceMapLoaderMock); + const { dispatch, getState } = store; + + const generatedSource = await dispatch( + actions.newGeneratedSource( + makeSource("foo-wasm", { introductionType: "wasm" }) + ) + ); + + const generatedLocation = createLocation({ + source: generatedSource, + line: 1, + column: 0, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + generatedSource.id + ), + }); + const mockPauseInfo = createPauseInfo(generatedLocation); + const { frames } = mockPauseInfo; + client.getFrames = async () => frames; + + const [originalSource] = await dispatch( + actions.newOriginalSources([makeOriginalSource(generatedSource)]) + ); + + const originalLocation = createLocation({ + source: originalSource, + line: 1, + column: 1, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + originalSource.id + ), + }); + const originalLocation2 = createLocation({ + source: originalSource, + line: 2, + column: 14, + sourceActor: selectors.getFirstSourceActorForGeneratedSource( + getState(), + originalSource.id + ), + }); + + const originStackFrames = [ + { + displayName: "fooBar", + thread: "FakeThread", + }, + { + displayName: "barZoo", + location: originalLocation2, + thread: "FakeThread", + }, + ]; + + await dispatch(actions.paused(mockPauseInfo)); + expect(selectors.getFrames(getState(), "FakeThread")).toEqual([ + { + asyncCause: undefined, + displayName: "fooBar", + generatedLocation, + id: "1", + index: undefined, + isOriginal: true, + location: originalLocation, + originalDisplayName: "fooBar", + originalVariables: undefined, + scope: { bindings: { arguments: [], variables: {} } }, + source: null, + state: undefined, + this: undefined, + thread: "FakeThread", + }, + { + asyncCause: undefined, + displayName: "barZoo", + generatedLocation, + id: "1-originalFrame1", + index: undefined, + isOriginal: true, + location: originalLocation2, + originalDisplayName: "barZoo", + originalVariables: undefined, + scope: { bindings: { arguments: [], variables: {} } }, + source: null, + state: undefined, + this: undefined, + thread: "FakeThread", + }, + ]); + }); + }); + + describe("resumed", () => { + it("should not evaluate expression while stepping", async () => { + const client = { ...mockCommandClient, evaluateExpressions: jest.fn() }; + const { dispatch, getState } = createStore(client); + const mockPauseInfo = createPauseInfo(); + + await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + await dispatch(actions.paused(mockPauseInfo)); + + const cx = selectors.getThreadContext(getState()); + dispatch(actions.stepIn(cx)); + await dispatch(actions.resumed(mockCommandClient.actorID)); + expect(client.evaluateExpressions.mock.calls).toHaveLength(1); + }); + + it("resuming - will re-evaluate watch expressions", async () => { + const client = { ...mockCommandClient, evaluateExpressions: jest.fn() }; + const store = createStore(client); + const { dispatch, getState, cx } = store; + const mockPauseInfo = createPauseInfo(); + + await dispatch(actions.newGeneratedSource(makeSource("foo1"))); + await dispatch(actions.newGeneratedSource(makeSource("foo"))); + await dispatch(actions.addExpression(cx, "foo")); + await waitForState(store, state => selectors.getExpression(state, "foo")); + + client.evaluateExpressions.mockReturnValue(Promise.resolve(["YAY"])); + await dispatch(actions.paused(mockPauseInfo)); + + await dispatch(actions.resumed(mockCommandClient.actorID)); + const expression = selectors.getExpression(getState(), "foo"); + expect(expression && expression.value).toEqual("YAY"); + }); + }); +}); diff --git a/devtools/client/debugger/src/actions/pause/tests/pauseOnExceptions.spec.js b/devtools/client/debugger/src/actions/pause/tests/pauseOnExceptions.spec.js new file mode 100644 index 0000000000..bc8d000697 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/tests/pauseOnExceptions.spec.js @@ -0,0 +1,24 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + createStore, + getTelemetryEvents, +} from "../../../utils/test-head"; + +import { + getShouldPauseOnExceptions, + getShouldPauseOnCaughtExceptions, +} from "../../../selectors/pause"; + +describe("pauseOnExceptions", () => { + it("should track telemetry for pauseOnException changes", async () => { + const { dispatch, getState } = createStore({ pauseOnExceptions: () => {} }); + dispatch(actions.pauseOnExceptions(true, false)); + expect(getTelemetryEvents("pause_on_exceptions")).toMatchSnapshot(); + expect(getShouldPauseOnExceptions(getState())).toBe(true); + expect(getShouldPauseOnCaughtExceptions(getState())).toBe(false); + }); +}); diff --git a/devtools/client/debugger/src/actions/pause/tests/skipPausing.spec.js b/devtools/client/debugger/src/actions/pause/tests/skipPausing.spec.js new file mode 100644 index 0000000000..83006c3089 --- /dev/null +++ b/devtools/client/debugger/src/actions/pause/tests/skipPausing.spec.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { actions, selectors, createStore } from "../../../utils/test-head"; + +describe("sources - pretty print", () => { + it("returns a pretty source for a minified file", async () => { + const client = { setSkipPausing: jest.fn() }; + const { dispatch, getState } = createStore(client); + + await dispatch(actions.toggleSkipPausing()); + expect(selectors.getSkipPausing(getState())).toBe(true); + + await dispatch(actions.toggleSkipPausing()); + expect(selectors.getSkipPausing(getState())).toBe(false); + }); +}); diff --git a/devtools/client/debugger/src/actions/preview.js b/devtools/client/debugger/src/actions/preview.js new file mode 100644 index 0000000000..992737e2d1 --- /dev/null +++ b/devtools/client/debugger/src/actions/preview.js @@ -0,0 +1,211 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { isConsole } from "../utils/preview"; +import { findBestMatchExpression } from "../utils/ast"; +import { getGrip, getFront } from "../utils/evaluation-result"; +import { getExpressionFromCoords } from "../utils/editor/get-expression"; +import { isNodeTest } from "../utils/environment"; + +import { + getPreview, + isLineInScope, + isSelectedFrameVisible, + getSelectedSource, + getSelectedLocation, + getSelectedFrame, + getSymbols, + getCurrentThread, + getPreviewCount, + getSelectedException, +} from "../selectors"; + +import { getMappedExpression } from "./expressions"; + +function findExpressionMatch(state, codeMirror, tokenPos) { + const location = getSelectedLocation(state); + if (!location) { + return null; + } + + const symbols = getSymbols(state, location); + + let match; + if (!symbols) { + match = getExpressionFromCoords(codeMirror, tokenPos); + } else { + match = findBestMatchExpression(symbols, tokenPos); + } + return match; +} + +export function updatePreview(cx, target, tokenPos, codeMirror) { + return ({ dispatch, getState }) => { + const cursorPos = target.getBoundingClientRect(); + + if ( + !isSelectedFrameVisible(getState()) || + !isLineInScope(getState(), tokenPos.line) + ) { + return; + } + + const match = findExpressionMatch(getState(), codeMirror, tokenPos); + if (!match) { + return; + } + + const { expression, location } = match; + + if (isConsole(expression)) { + return; + } + + dispatch(setPreview(cx, expression, location, tokenPos, cursorPos, target)); + }; +} + +export function setPreview( + cx, + expression, + location, + tokenPos, + cursorPos, + target +) { + return async ({ dispatch, getState, client }) => { + dispatch({ type: "START_PREVIEW" }); + const previewCount = getPreviewCount(getState()); + if (getPreview(getState())) { + dispatch(clearPreview(cx)); + } + + const source = getSelectedSource(getState()); + if (!source) { + return; + } + + const thread = getCurrentThread(getState()); + const selectedFrame = getSelectedFrame(getState(), thread); + + if (location && source.isOriginal) { + const mapResult = await dispatch(getMappedExpression(expression)); + if (mapResult) { + expression = mapResult.expression; + } + } + + if (!selectedFrame) { + return; + } + + const { result } = await client.evaluate(expression, { + frameId: selectedFrame.id, + }); + + const resultGrip = getGrip(result); + + // Error case occurs for a token that follows an errored evaluation + // https://github.com/firefox-devtools/debugger/pull/8056 + // Accommodating for null allows us to show preview for falsy values + // line "", false, null, Nan, and more + if (resultGrip === null) { + return; + } + + // Handle cases where the result is invisible to the debugger + // and not possible to preview. Bug 1548256 + if ( + resultGrip && + resultGrip.class && + typeof resultGrip.class === "string" && + resultGrip.class.includes("InvisibleToDebugger") + ) { + return; + } + + const root = { + path: expression, + contents: { + value: resultGrip, + front: getFront(result), + }, + }; + const properties = await client.loadObjectProperties(root, thread); + + // The first time a popup is rendered, the mouse should be hovered + // on the token. If it happens to be hovered on whitespace, it should + // not render anything + if (!target.matches(":hover") && !isNodeTest()) { + return; + } + + // Don't finish dispatching if another setPreview was started + if (previewCount != getPreviewCount(getState())) { + return; + } + + dispatch({ + type: "SET_PREVIEW", + cx, + value: { + expression, + resultGrip, + properties, + root, + location, + tokenPos, + cursorPos, + target, + }, + }); + }; +} + +export function clearPreview(cx) { + return ({ dispatch, getState, client }) => { + const currentSelection = getPreview(getState()); + if (!currentSelection) { + return null; + } + + return dispatch({ + type: "CLEAR_PREVIEW", + cx, + }); + }; +} + +export function setExceptionPreview(cx, target, tokenPos, codeMirror) { + return async ({ dispatch, getState }) => { + const cursorPos = target.getBoundingClientRect(); + + const match = findExpressionMatch(getState(), codeMirror, tokenPos); + if (!match) { + return; + } + + const tokenColumnStart = match.location.start.column + 1; + const exception = getSelectedException( + getState(), + tokenPos.line, + tokenColumnStart + ); + if (!exception) { + return; + } + + dispatch({ + type: "SET_PREVIEW", + cx, + value: { + exception, + location: match.location, + tokenPos, + cursorPos, + target, + }, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/project-text-search.js b/devtools/client/debugger/src/actions/project-text-search.js new file mode 100644 index 0000000000..26ea0df107 --- /dev/null +++ b/devtools/client/debugger/src/actions/project-text-search.js @@ -0,0 +1,171 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the search state + * @module actions/search + */ + +import { isFulfilled } from "../utils/async-value"; +import { + getFirstSourceActorForGeneratedSource, + getSourceList, + getSettledSourceTextContent, + isSourceBlackBoxed, + getSearchOptions, +} from "../selectors"; +import { createLocation } from "../utils/location"; +import { matchesGlobPatterns } from "../utils/source"; +import { loadSourceText } from "./sources/loadSourceText"; +import { + getProjectSearchOperation, + getProjectSearchStatus, +} from "../selectors/project-text-search"; +import { statusType } from "../reducers/project-text-search"; +import { searchKeys } from "../constants"; + +export function addSearchQuery(cx, query) { + return { type: "ADD_QUERY", cx, query }; +} + +export function addOngoingSearch(cx, ongoingSearch) { + return { type: "ADD_ONGOING_SEARCH", cx, ongoingSearch }; +} + +export function addSearchResult(cx, location, matches) { + return { + type: "ADD_SEARCH_RESULT", + cx, + location, + matches, + }; +} + +export function clearSearchResults(cx) { + return { type: "CLEAR_SEARCH_RESULTS", cx }; +} + +export function clearSearch(cx) { + return { type: "CLEAR_SEARCH", cx }; +} + +export function updateSearchStatus(cx, status) { + return { type: "UPDATE_STATUS", cx, status }; +} + +export function closeProjectSearch(cx) { + return ({ dispatch, getState }) => { + dispatch(stopOngoingSearch(cx)); + dispatch({ type: "CLOSE_PROJECT_SEARCH" }); + }; +} + +export function stopOngoingSearch(cx) { + return ({ dispatch, getState }) => { + const state = getState(); + const ongoingSearch = getProjectSearchOperation(state); + const status = getProjectSearchStatus(state); + if (ongoingSearch && status !== statusType.done) { + ongoingSearch.cancel(); + dispatch(updateSearchStatus(cx, statusType.cancelled)); + } + }; +} + +export function searchSources(cx, query) { + let cancelled = false; + + const search = async ({ dispatch, getState }) => { + dispatch(stopOngoingSearch(cx)); + await dispatch(addOngoingSearch(cx, search)); + await dispatch(clearSearchResults(cx)); + await dispatch(addSearchQuery(cx, query)); + dispatch(updateSearchStatus(cx, statusType.fetching)); + const searchOptions = getSearchOptions( + getState(), + searchKeys.PROJECT_SEARCH + ); + const validSources = getSourceList(getState()).filter( + source => + !isSourceBlackBoxed(getState(), source) && + !matchesGlobPatterns(source, searchOptions.excludePatterns) + ); + // Sort original entries first so that search results are more useful. + // Deprioritize third-party scripts, so their results show last. + validSources.sort((a, b) => { + function isThirdParty(source) { + return ( + source?.url && + (source.url.includes("node_modules") || + source.url.includes("bower_components")) + ); + } + + if (a.isOriginal && !isThirdParty(a)) { + return -1; + } + + if (b.isOriginal && !isThirdParty(b)) { + return 1; + } + + if (!isThirdParty(a) && isThirdParty(b)) { + return -1; + } + if (isThirdParty(a) && !isThirdParty(b)) { + return 1; + } + return 0; + }); + + for (const source of validSources) { + if (cancelled) { + return; + } + + const sourceActor = getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + await dispatch(loadSourceText(cx, source, sourceActor)); + await dispatch(searchSource(cx, source, sourceActor, query)); + } + dispatch(updateSearchStatus(cx, statusType.done)); + }; + + search.cancel = () => { + cancelled = true; + }; + + return search; +} + +export function searchSource(cx, source, sourceActor, query) { + return async ({ dispatch, getState, searchWorker }) => { + if (!source) { + return; + } + const state = getState(); + const location = createLocation({ + source, + sourceActor, + }); + + const options = getSearchOptions(state, searchKeys.PROJECT_SEARCH); + const content = getSettledSourceTextContent(state, location); + let matches = []; + + if (content && isFulfilled(content) && content.value.type === "text") { + matches = await searchWorker.findSourceMatches( + content.value, + query, + options + ); + } + if (!matches.length) { + return; + } + dispatch(addSearchResult(cx, location, matches)); + }; +} diff --git a/devtools/client/debugger/src/actions/quick-open.js b/devtools/client/debugger/src/actions/quick-open.js new file mode 100644 index 0000000000..e5f5352292 --- /dev/null +++ b/devtools/client/debugger/src/actions/quick-open.js @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export function setQuickOpenQuery(query) { + return { + type: "SET_QUICK_OPEN_QUERY", + query, + }; +} + +export function openQuickOpen(query) { + if (query != null) { + return { type: "OPEN_QUICK_OPEN", query }; + } + return { type: "OPEN_QUICK_OPEN" }; +} + +export function closeQuickOpen() { + return { type: "CLOSE_QUICK_OPEN" }; +} diff --git a/devtools/client/debugger/src/actions/source-actors.js b/devtools/client/debugger/src/actions/source-actors.js new file mode 100644 index 0000000000..9782e493b3 --- /dev/null +++ b/devtools/client/debugger/src/actions/source-actors.js @@ -0,0 +1,12 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export function insertSourceActors(sourceActors) { + return function ({ dispatch }) { + dispatch({ + type: "INSERT_SOURCE_ACTORS", + sourceActors, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/sources-tree.js b/devtools/client/debugger/src/actions/sources-tree.js new file mode 100644 index 0000000000..ae750a3df7 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources-tree.js @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export function setExpandedState(expanded) { + return { type: "SET_EXPANDED_STATE", expanded }; +} + +export function focusItem(item) { + return { type: "SET_FOCUSED_SOURCE_ITEM", item }; +} diff --git a/devtools/client/debugger/src/actions/sources/blackbox.js b/devtools/client/debugger/src/actions/sources/blackbox.js new file mode 100644 index 0000000000..6821a0e140 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/blackbox.js @@ -0,0 +1,223 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the sources state + * @module actions/sources + */ + +import { + isOriginalId, + originalToGeneratedId, +} from "devtools/client/shared/source-map-loader/index"; +import { recordEvent } from "../../utils/telemetry"; +import { toggleBreakpoints } from "../breakpoints"; +import { + getSourceActorsForSource, + isSourceBlackBoxed, + getBlackBoxRanges, + getBreakpointsForSource, +} from "../../selectors"; + +export async function blackboxSourceActorsForSource( + thunkArgs, + source, + shouldBlackBox, + ranges = [] +) { + const { getState, client, sourceMapLoader } = thunkArgs; + let sourceId = source.id; + // If the source is the original, then get the source id of its generated file + // and the range for where the original is represented in the generated file + // (which might be a bundle including other files). + if (isOriginalId(source.id)) { + sourceId = originalToGeneratedId(source.id); + const range = await sourceMapLoader.getFileGeneratedRange(source.id); + ranges = []; + if (range) { + ranges.push(range); + // TODO bug 1752108: Investigate blackboxing lines in original files, + // there is likely to be issues as the whole genrated file + // representing the original file will always be blackboxed. + console.warn( + "The might be unxpected issues when ignoring lines in an original file. " + + "The whole original source is being blackboxed." + ); + } else { + throw new Error( + `Unable to retrieve generated ranges for original source ${source.url}` + ); + } + } + + for (const actor of getSourceActorsForSource(getState(), sourceId)) { + await client.blackBox(actor, shouldBlackBox, ranges); + } +} + +/** + * Toggle blackboxing for the whole source or for specific lines in a source + * + * @param {Object} cx + * @param {Object} source - The source to be blackboxed/unblackboxed. + * @param {Boolean} [shouldBlackBox] - Specifies if the source should be blackboxed (true + * or unblackboxed (false). When this is not provided + * option is decided based on the blackboxed state + * of the source. + * @param {Array} [ranges] - List of line/column offsets to blackbox, these + * are provided only when blackboxing lines. + * The range structure: + * const range = { + * start: { line: 1, column: 5 }, + * end: { line: 3, column: 4 }, + * } + */ +export function toggleBlackBox(cx, source, shouldBlackBox, ranges = []) { + return async thunkArgs => { + const { dispatch, getState } = thunkArgs; + + shouldBlackBox = + typeof shouldBlackBox == "boolean" + ? shouldBlackBox + : !isSourceBlackBoxed(getState(), source); + + await blackboxSourceActorsForSource( + thunkArgs, + source, + shouldBlackBox, + ranges + ); + + if (shouldBlackBox) { + recordEvent("blackbox"); + // If ranges is an empty array, it would mean we are blackboxing the whole + // source. To do that lets reset the content to an empty array. + if (!ranges.length) { + dispatch({ type: "BLACKBOX_WHOLE_SOURCES", sources: [source] }); + await toggleBreakpointsInBlackboxedSources({ + thunkArgs, + cx, + shouldDisable: true, + sources: [source], + }); + } else { + const currentRanges = getBlackBoxRanges(getState())[source.url] || []; + ranges = ranges.filter(newRange => { + // To avoid adding duplicate ranges make sure + // no range already exists with same start and end lines. + const duplicate = currentRanges.findIndex( + r => + r.start.line == newRange.start.line && + r.end.line == newRange.end.line + ); + return duplicate == -1; + }); + dispatch({ type: "BLACKBOX_SOURCE_RANGES", source, ranges }); + await toggleBreakpointsInRangesForBlackboxedSource({ + thunkArgs, + cx, + shouldDisable: true, + source, + ranges, + }); + } + } else { + // if there are no ranges to blackbox, then we are unblackboxing + // the whole source + // eslint-disable-next-line no-lonely-if + if (!ranges.length) { + dispatch({ type: "UNBLACKBOX_WHOLE_SOURCES", sources: [source] }); + toggleBreakpointsInBlackboxedSources({ + thunkArgs, + cx, + shouldDisable: false, + sources: [source], + }); + } else { + dispatch({ type: "UNBLACKBOX_SOURCE_RANGES", source, ranges }); + const blackboxRanges = getBlackBoxRanges(getState()); + if (!blackboxRanges[source.url].length) { + dispatch({ type: "UNBLACKBOX_WHOLE_SOURCES", sources: [source] }); + } + await toggleBreakpointsInRangesForBlackboxedSource({ + thunkArgs, + cx, + shouldDisable: false, + source, + ranges, + }); + } + } + }; +} + +async function toggleBreakpointsInRangesForBlackboxedSource({ + thunkArgs, + cx, + shouldDisable, + source, + ranges, +}) { + const { dispatch, getState } = thunkArgs; + for (const range of ranges) { + const breakpoints = getBreakpointsForSource(getState(), source.id, range); + await dispatch(toggleBreakpoints(cx, shouldDisable, breakpoints)); + } +} + +async function toggleBreakpointsInBlackboxedSources({ + thunkArgs, + cx, + shouldDisable, + sources, +}) { + const { dispatch, getState } = thunkArgs; + for (const source of sources) { + const breakpoints = getBreakpointsForSource(getState(), source.id); + await dispatch(toggleBreakpoints(cx, shouldDisable, breakpoints)); + } +} + +/* + * Blackboxes a group of sources together + * + * @param {Object} cx + * @param {Array} sourcesToBlackBox - The list of sources to blackbox + * @param {Boolean} shouldBlackbox - Specifies if the sources should blackboxed (true) + * or unblackboxed (false). + */ +export function blackBoxSources(cx, sourcesToBlackBox, shouldBlackBox) { + return async thunkArgs => { + const { dispatch, getState } = thunkArgs; + + const sources = sourcesToBlackBox.filter( + source => isSourceBlackBoxed(getState(), source) !== shouldBlackBox + ); + + if (!sources.length) { + return; + } + + for (const source of sources) { + await blackboxSourceActorsForSource(thunkArgs, source, shouldBlackBox); + } + + if (shouldBlackBox) { + recordEvent("blackbox"); + } + + dispatch({ + type: shouldBlackBox + ? "BLACKBOX_WHOLE_SOURCES" + : "UNBLACKBOX_WHOLE_SOURCES", + sources, + }); + await toggleBreakpointsInBlackboxedSources({ + thunkArgs, + cx, + shouldDisable: shouldBlackBox, + sources, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/sources/breakableLines.js b/devtools/client/debugger/src/actions/sources/breakableLines.js new file mode 100644 index 0000000000..d028d480c0 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/breakableLines.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { isOriginalId } from "devtools/client/shared/source-map-loader/index"; +import { + getBreakableLines, + getSourceActorBreakableLines, +} from "../../selectors"; +import { setBreakpointPositions } from "../breakpoints/breakpointPositions"; + +function calculateBreakableLines(positions) { + const lines = []; + for (const line in positions) { + if (positions[line].length) { + lines.push(Number(line)); + } + } + + return lines; +} + +/** + * Ensure that breakable lines for a given source are fetched. + * + * @param Object cx + * @param Object location + */ +export function setBreakableLines(cx, location) { + return async ({ getState, dispatch, client }) => { + let breakableLines; + if (isOriginalId(location.source.id)) { + const positions = await dispatch( + setBreakpointPositions({ cx, location }) + ); + breakableLines = calculateBreakableLines(positions); + + const existingBreakableLines = getBreakableLines( + getState(), + location.source.id + ); + if (existingBreakableLines) { + breakableLines = [ + ...new Set([...existingBreakableLines, ...breakableLines]), + ]; + } + + dispatch({ + type: "SET_ORIGINAL_BREAKABLE_LINES", + cx, + sourceId: location.source.id, + breakableLines, + }); + } else { + // Ignore re-fetching the breakable lines for source actor we already fetched + breakableLines = getSourceActorBreakableLines( + getState(), + location.sourceActor.id + ); + if (breakableLines) { + return; + } + breakableLines = await client.getSourceActorBreakableLines( + location.sourceActor + ); + dispatch({ + type: "SET_SOURCE_ACTOR_BREAKABLE_LINES", + sourceActorId: location.sourceActor.id, + breakableLines, + }); + } + }; +} diff --git a/devtools/client/debugger/src/actions/sources/index.js b/devtools/client/debugger/src/actions/sources/index.js new file mode 100644 index 0000000000..813f50262b --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/index.js @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export * from "./blackbox"; +export * from "./breakableLines"; +export * from "./loadSourceText"; +export * from "./newSources"; +export * from "./prettyPrint"; +export * from "./select"; +export { setSymbols } from "./symbols"; + +export function setOverrideSource(cx, source, path) { + return ({ client, dispatch }) => { + if (!source || !source.url) { + return; + } + const { url } = source; + client.setOverride(url, path); + dispatch({ + type: "SET_OVERRIDE", + cx, + url, + path, + }); + }; +} + +export function removeOverrideSource(cx, source) { + return ({ client, dispatch }) => { + if (!source || !source.url) { + return; + } + const { url } = source; + client.removeOverride(url); + dispatch({ + type: "REMOVE_OVERRIDE", + cx, + url, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/sources/loadSourceText.js b/devtools/client/debugger/src/actions/sources/loadSourceText.js new file mode 100644 index 0000000000..8210b07a97 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/loadSourceText.js @@ -0,0 +1,256 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { PROMISE } from "../utils/middleware/promise"; +import { + getSourceTextContent, + getSettledSourceTextContent, + getGeneratedSource, + getSourcesEpoch, + getBreakpointsForSource, + getSourceActorsForSource, + getFirstSourceActorForGeneratedSource, +} from "../../selectors"; +import { addBreakpoint } from "../breakpoints"; + +import { prettyPrintSource } from "./prettyPrint"; +import { isFulfilled, fulfilled } from "../../utils/async-value"; + +import { isPretty } from "../../utils/source"; +import { createLocation } from "../../utils/location"; +import { memoizeableAction } from "../../utils/memoizableAction"; + +async function loadGeneratedSource(sourceActor, { client }) { + // If no source actor can be found then the text for the + // source cannot be loaded. + if (!sourceActor) { + throw new Error("Source actor is null or not defined"); + } + + let response; + try { + response = await client.sourceContents(sourceActor); + } catch (e) { + throw new Error(`sourceContents failed: ${e}`); + } + + return { + text: response.source, + contentType: response.contentType || "text/javascript", + }; +} + +async function loadOriginalSource( + source, + { getState, client, sourceMapLoader, prettyPrintWorker } +) { + if (isPretty(source)) { + const generatedSource = getGeneratedSource(getState(), source); + if (!generatedSource) { + throw new Error("Unable to find minified original."); + } + + const content = getSettledSourceTextContent( + getState(), + createLocation({ + source: generatedSource, + }) + ); + + return prettyPrintSource( + sourceMapLoader, + prettyPrintWorker, + generatedSource, + content, + getSourceActorsForSource(getState(), generatedSource.id) + ); + } + + const result = await sourceMapLoader.getOriginalSourceText(source.id); + if (!result) { + // The way we currently try to load and select a pending + // selected location, it is possible that we will try to fetch the + // original source text right after the source map has been cleared + // after a navigation event. + throw new Error("Original source text unavailable"); + } + return result; +} + +async function loadGeneratedSourceTextPromise(cx, sourceActor, thunkArgs) { + const { dispatch, getState } = thunkArgs; + const epoch = getSourcesEpoch(getState()); + + await dispatch({ + type: "LOAD_GENERATED_SOURCE_TEXT", + sourceActorId: sourceActor.actor, + epoch, + [PROMISE]: loadGeneratedSource(sourceActor, thunkArgs), + }); + + await onSourceTextContentAvailable( + cx, + sourceActor.sourceObject, + sourceActor, + thunkArgs + ); +} + +async function loadOriginalSourceTextPromise(cx, source, thunkArgs) { + const { dispatch, getState } = thunkArgs; + const epoch = getSourcesEpoch(getState()); + await dispatch({ + type: "LOAD_ORIGINAL_SOURCE_TEXT", + sourceId: source.id, + epoch, + [PROMISE]: loadOriginalSource(source, thunkArgs), + }); + + await onSourceTextContentAvailable(cx, source, null, thunkArgs); +} + +/** + * Function called everytime a new original or generated source gets its text content + * fetched from the server and registered in the reducer. + * + * @param {Object} cx + * @param {Object} source + * @param {Object} sourceActor (optional) + * If this is a generated source, we expect a precise source actor. + * @param {Object} thunkArgs + */ +async function onSourceTextContentAvailable( + cx, + source, + sourceActor, + { dispatch, getState, parserWorker } +) { + const location = createLocation({ + source, + sourceActor, + }); + const content = getSettledSourceTextContent(getState(), location); + if (!content) { + return; + } + + if (parserWorker.isLocationSupported(location)) { + parserWorker.setSource( + source.id, + isFulfilled(content) + ? content.value + : { type: "text", value: "", contentType: undefined } + ); + } + + // Update the text in any breakpoints for this source by re-adding them. + const breakpoints = getBreakpointsForSource(getState(), source.id); + for (const breakpoint of breakpoints) { + await dispatch( + addBreakpoint( + cx, + breakpoint.location, + breakpoint.options, + breakpoint.disabled + ) + ); + } +} + +/** + * Loads the source text for the generated source based of the source actor + * @param {Object} sourceActor + * There can be more than one source actor per source + * so the source actor needs to be specified. This is + * required for generated sources but will be null for + * original/pretty printed sources. + */ +export const loadGeneratedSourceText = memoizeableAction( + "loadGeneratedSourceText", + { + getValue: ({ sourceActor }, { getState }) => { + if (!sourceActor) { + return null; + } + + const sourceTextContent = getSourceTextContent( + getState(), + createLocation({ + source: sourceActor.sourceObject, + sourceActor, + }) + ); + + if (!sourceTextContent || sourceTextContent.state === "pending") { + return sourceTextContent; + } + + // This currently swallows source-load-failure since we return fulfilled + // here when content.state === "rejected". In an ideal world we should + // propagate that error upward. + return fulfilled(sourceTextContent); + }, + createKey: ({ sourceActor }, { getState }) => { + const epoch = getSourcesEpoch(getState()); + return `${epoch}:${sourceActor.actor}`; + }, + action: ({ cx, sourceActor }, thunkArgs) => + loadGeneratedSourceTextPromise(cx, sourceActor, thunkArgs), + } +); + +/** + * Loads the source text for an original source and source actor + * @param {Object} source + * The original source to load the source text + */ +export const loadOriginalSourceText = memoizeableAction( + "loadOriginalSourceText", + { + getValue: ({ source }, { getState }) => { + if (!source) { + return null; + } + + const sourceTextContent = getSourceTextContent( + getState(), + createLocation({ + source, + }) + ); + if (!sourceTextContent || sourceTextContent.state === "pending") { + return sourceTextContent; + } + + // This currently swallows source-load-failure since we return fulfilled + // here when content.state === "rejected". In an ideal world we should + // propagate that error upward. + return fulfilled(sourceTextContent); + }, + createKey: ({ source }, { getState }) => { + const epoch = getSourcesEpoch(getState()); + return `${epoch}:${source.id}`; + }, + action: ({ cx, source }, thunkArgs) => + loadOriginalSourceTextPromise(cx, source, thunkArgs), + } +); + +export function loadSourceText(cx, source, sourceActor) { + return async ({ dispatch, getState }) => { + if (!source) { + return null; + } + if (source.isOriginal) { + return dispatch(loadOriginalSourceText({ cx, source })); + } + if (!sourceActor) { + sourceActor = getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + } + return dispatch(loadGeneratedSourceText({ cx, sourceActor })); + }; +} diff --git a/devtools/client/debugger/src/actions/sources/moz.build b/devtools/client/debugger/src/actions/sources/moz.build new file mode 100644 index 0000000000..9972e9f09b --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/moz.build @@ -0,0 +1,17 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "blackbox.js", + "breakableLines.js", + "index.js", + "loadSourceText.js", + "newSources.js", + "prettyPrint.js", + "select.js", + "symbols.js", +) diff --git a/devtools/client/debugger/src/actions/sources/newSources.js b/devtools/client/debugger/src/actions/sources/newSources.js new file mode 100644 index 0000000000..1e95c6d79d --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/newSources.js @@ -0,0 +1,367 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the sources state + * @module actions/sources + */ +import { PROMISE } from "../utils/middleware/promise"; +import { insertSourceActors } from "../../actions/source-actors"; +import { + makeSourceId, + createGeneratedSource, + createSourceMapOriginalSource, + createSourceActor, +} from "../../client/firefox/create"; +import { toggleBlackBox } from "./blackbox"; +import { syncPendingBreakpoint } from "../breakpoints"; +import { loadSourceText } from "./loadSourceText"; +import { togglePrettyPrint } from "./prettyPrint"; +import { toggleSourceMapIgnoreList } from "../ui"; +import { selectLocation, setBreakableLines } from "../sources"; + +import { getRawSourceURL, isPrettyURL } from "../../utils/source"; +import { createLocation } from "../../utils/location"; +import { + getBlackBoxRanges, + getSource, + getSourceFromId, + hasSourceActor, + getSourceByActorId, + getPendingSelectedLocation, + getPendingBreakpointsForSource, + getContext, +} from "../../selectors"; + +import { prefs } from "../../utils/prefs"; +import sourceQueue from "../../utils/source-queue"; +import { validateNavigateContext, ContextError } from "../../utils/context"; + +function loadSourceMaps(cx, sources) { + return async function ({ dispatch }) { + try { + const sourceList = await Promise.all( + sources.map(async sourceActor => { + const originalSourcesInfo = await dispatch( + loadSourceMap(cx, sourceActor) + ); + originalSourcesInfo.forEach( + sourcesInfo => (sourcesInfo.sourceActor = sourceActor) + ); + sourceQueue.queueOriginalSources(originalSourcesInfo); + return originalSourcesInfo; + }) + ); + + await sourceQueue.flush(); + return sourceList.flat(); + } catch (error) { + if (!(error instanceof ContextError)) { + throw error; + } + } + return []; + }; +} + +/** + * @memberof actions/sources + * @static + */ +function loadSourceMap(cx, sourceActor) { + return async function ({ dispatch, getState, sourceMapLoader }) { + if (!prefs.clientSourceMapsEnabled || !sourceActor.sourceMapURL) { + return []; + } + + let data = null; + try { + // Ignore sourceMapURL on scripts that are part of HTML files, since + // we currently treat sourcemaps as Source-wide, not SourceActor-specific. + const source = getSourceByActorId(getState(), sourceActor.id); + if (source) { + data = await sourceMapLoader.getOriginalURLs({ + // Using source ID here is historical and eventually we'll want to + // switch to all of this being per-source-actor. + id: source.id, + url: sourceActor.url || "", + sourceMapBaseURL: sourceActor.sourceMapBaseURL || "", + sourceMapURL: sourceActor.sourceMapURL || "", + isWasm: sourceActor.introductionType === "wasm", + }); + dispatch({ + type: "ADD_SOURCEMAP_IGNORE_LIST_SOURCES", + [PROMISE]: sourceMapLoader.getSourceMapIgnoreList(source.id), + }); + } + } catch (e) { + console.error(e); + } + + if (!data || !data.length) { + // If this source doesn't have a sourcemap or there are no original files + // existing, enable it for pretty printing + dispatch({ + type: "CLEAR_SOURCE_ACTOR_MAP_URL", + cx, + sourceActorId: sourceActor.id, + }); + return []; + } + + validateNavigateContext(getState(), cx); + return data; + }; +} + +// If a request has been made to show this source, go ahead and +// select it. +function checkSelectedSource(cx, sourceId) { + return async ({ dispatch, getState }) => { + const state = getState(); + const pendingLocation = getPendingSelectedLocation(state); + + if (!pendingLocation || !pendingLocation.url) { + return; + } + + const source = getSource(state, sourceId); + + if (!source || !source.url) { + return; + } + + const pendingUrl = pendingLocation.url; + const rawPendingUrl = getRawSourceURL(pendingUrl); + + if (rawPendingUrl === source.url) { + if (isPrettyURL(pendingUrl)) { + const prettySource = await dispatch(togglePrettyPrint(cx, source.id)); + dispatch(checkPendingBreakpoints(cx, prettySource, null)); + return; + } + + await dispatch( + selectLocation( + cx, + createLocation({ + source, + line: + typeof pendingLocation.line === "number" + ? pendingLocation.line + : 0, + column: pendingLocation.column, + }) + ) + ); + } + }; +} + +function checkPendingBreakpoints(cx, source, sourceActor) { + return async ({ dispatch, getState }) => { + const pendingBreakpoints = getPendingBreakpointsForSource( + getState(), + source + ); + + if (pendingBreakpoints.length === 0) { + return; + } + + // load the source text if there is a pending breakpoint for it + await dispatch(loadSourceText(cx, source, sourceActor)); + await dispatch( + setBreakableLines(cx, createLocation({ source, sourceActor })) + ); + + await Promise.all( + pendingBreakpoints.map(pendingBp => { + return dispatch(syncPendingBreakpoint(cx, source.id, pendingBp)); + }) + ); + }; +} + +function restoreBlackBoxedSources(cx, sources) { + return async ({ dispatch, getState }) => { + const currentRanges = getBlackBoxRanges(getState()); + + if (!Object.keys(currentRanges).length) { + return; + } + + for (const source of sources) { + const ranges = currentRanges[source.url]; + if (ranges) { + // If the ranges is an empty then the whole source was blackboxed. + await dispatch(toggleBlackBox(cx, source, true, ranges)); + } + } + + if (prefs.sourceMapIgnoreListEnabled) { + await dispatch(toggleSourceMapIgnoreList(cx, true)); + } + }; +} + +export function newOriginalSources(originalSourcesInfo) { + return async ({ dispatch, getState }) => { + const state = getState(); + const seen = new Set(); + + const actors = []; + const actorsSources = {}; + + for (const { id, url, sourceActor } of originalSourcesInfo) { + if (seen.has(id) || getSource(state, id)) { + continue; + } + seen.add(id); + + if (!actorsSources[sourceActor.actor]) { + actors.push(sourceActor); + actorsSources[sourceActor.actor] = []; + } + + actorsSources[sourceActor.actor].push( + createSourceMapOriginalSource(id, url) + ); + } + + const cx = getContext(state); + + // Add the original sources per the generated source actors that + // they are primarily from. + actors.forEach(sourceActor => { + dispatch({ + type: "ADD_ORIGINAL_SOURCES", + cx, + originalSources: actorsSources[sourceActor.actor], + generatedSourceActor: sourceActor, + }); + }); + + // Accumulate the sources back into one list + const actorsSourcesValues = Object.values(actorsSources); + let sources = []; + if (actorsSourcesValues.length) { + sources = actorsSourcesValues.reduce((acc, sourceList) => + acc.concat(sourceList) + ); + } + + await dispatch(checkNewSources(cx, sources)); + + for (const source of sources) { + dispatch(checkPendingBreakpoints(cx, source, null)); + } + + return sources; + }; +} + +// Wrapper around newGeneratedSources, only used by tests +export function newGeneratedSource(sourceInfo) { + return async ({ dispatch }) => { + const sources = await dispatch(newGeneratedSources([sourceInfo])); + return sources[0]; + }; +} + +export function newGeneratedSources(sourceResources) { + return async ({ dispatch, getState, client }) => { + if (!sourceResources.length) { + return []; + } + + const resultIds = []; + const newSourcesObj = {}; + const newSourceActors = []; + + for (const sourceResource of sourceResources) { + // By the time we process the sources, the related target + // might already have been destroyed. It means that the sources + // are also about to be destroyed, so ignore them. + // (This is covered by browser_toolbox_backward_forward_navigation.js) + if (sourceResource.targetFront.isDestroyed()) { + continue; + } + const id = makeSourceId(sourceResource); + + if (!getSource(getState(), id) && !newSourcesObj[id]) { + newSourcesObj[id] = createGeneratedSource(sourceResource); + } + + const actorId = sourceResource.actor; + + // We are sometimes notified about a new source multiple times if we + // request a new source list and also get a source event from the server. + if (!hasSourceActor(getState(), actorId)) { + newSourceActors.push( + createSourceActor( + sourceResource, + getSource(getState(), id) || newSourcesObj[id] + ) + ); + } + + resultIds.push(id); + } + + const newSources = Object.values(newSourcesObj); + + const cx = getContext(getState()); + dispatch(addSources(cx, newSources)); + dispatch(insertSourceActors(newSourceActors)); + + await dispatch(checkNewSources(cx, newSources)); + + (async () => { + await dispatch(loadSourceMaps(cx, newSourceActors)); + + // We would like to sync breakpoints after we are done + // loading source maps as sometimes generated and original + // files share the same paths. + for (const sourceActor of newSourceActors) { + // For HTML pages, we fetch all new incoming inline script, + // which will be related to one dedicated source actor. + // Whereas, for regular sources, if we have many source actors, + // this is for the same URL. And code expecting to have breakable lines + // will request breakable lines for that particular source actor. + if (sourceActor.sourceObject.isHTML) { + await dispatch( + setBreakableLines( + cx, + createLocation({ source: sourceActor.sourceObject, sourceActor }) + ) + ); + } + dispatch( + checkPendingBreakpoints(cx, sourceActor.sourceObject, sourceActor) + ); + } + })(); + + return resultIds.map(id => getSourceFromId(getState(), id)); + }; +} + +function addSources(cx, sources) { + return ({ dispatch, getState }) => { + dispatch({ type: "ADD_SOURCES", cx, sources }); + }; +} + +function checkNewSources(cx, sources) { + return async ({ dispatch, getState }) => { + for (const source of sources) { + dispatch(checkSelectedSource(cx, source.id)); + } + + await dispatch(restoreBlackBoxedSources(cx, sources)); + + return sources; + }; +} diff --git a/devtools/client/debugger/src/actions/sources/prettyPrint.js b/devtools/client/debugger/src/actions/sources/prettyPrint.js new file mode 100644 index 0000000000..66e3f4129b --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/prettyPrint.js @@ -0,0 +1,339 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + generatedToOriginalId, + originalToGeneratedId, +} from "devtools/client/shared/source-map-loader/index"; + +import assert from "../../utils/assert"; +import { recordEvent } from "../../utils/telemetry"; +import { updateBreakpointsForNewPrettyPrintedSource } from "../breakpoints"; +import { createLocation } from "../../utils/location"; + +import { + getPrettySourceURL, + isGenerated, + isJavaScript, +} from "../../utils/source"; +import { isFulfilled } from "../../utils/async-value"; +import { getOriginalLocation } from "../../utils/source-maps"; +import { prefs } from "../../utils/prefs"; +import { + loadGeneratedSourceText, + loadOriginalSourceText, +} from "./loadSourceText"; +import { mapFrames } from "../pause"; +import { selectSpecificLocation } from "../sources"; +import { createPrettyPrintOriginalSource } from "../../client/firefox/create"; + +import { + getSource, + getFirstSourceActorForGeneratedSource, + getSourceByURL, + getSelectedLocation, + getThreadContext, +} from "../../selectors"; + +import { selectSource } from "./select"; + +import DevToolsUtils from "devtools/shared/DevToolsUtils"; + +const LINE_BREAK_REGEX = /\r\n?|\n|\u2028|\u2029/g; +function matchAllLineBreaks(str) { + return Array.from(str.matchAll(LINE_BREAK_REGEX)); +} + +function getPrettyOriginalSourceURL(generatedSource) { + return getPrettySourceURL(generatedSource.url || generatedSource.id); +} + +export async function prettyPrintSource( + sourceMapLoader, + prettyPrintWorker, + generatedSource, + content, + actors +) { + if (!content || !isFulfilled(content)) { + throw new Error("Cannot pretty-print a file that has not loaded"); + } + + const contentValue = content.value; + if ( + (!isJavaScript(generatedSource, contentValue) && !generatedSource.isHTML) || + contentValue.type !== "text" + ) { + throw new Error( + `Can't prettify ${contentValue.contentType} files, only HTML and Javascript.` + ); + } + + const url = getPrettyOriginalSourceURL(generatedSource); + + let prettyPrintWorkerResult; + if (generatedSource.isHTML) { + prettyPrintWorkerResult = await prettyPrintHtmlFile({ + prettyPrintWorker, + generatedSource, + content, + actors, + }); + } else { + prettyPrintWorkerResult = await prettyPrintWorker.prettyPrint({ + sourceText: contentValue.value, + indent: " ".repeat(prefs.indentSize), + url, + }); + } + + // The source map URL service used by other devtools listens to changes to + // sources based on their actor IDs, so apply the sourceMap there too. + const generatedSourceIds = [ + generatedSource.id, + ...actors.map(item => item.actor), + ]; + await sourceMapLoader.setSourceMapForGeneratedSources( + generatedSourceIds, + prettyPrintWorkerResult.sourceMap + ); + + return { + text: prettyPrintWorkerResult.code, + contentType: contentValue.contentType, + }; +} + +/** + * Pretty print inline script inside an HTML file + * + * @param {Object} options + * @param {PrettyPrintDispatcher} options.prettyPrintWorker: The prettyPrint worker + * @param {Object} options.generatedSource: The HTML source we want to pretty print + * @param {Object} options.content + * @param {Array} options.actors: An array of the HTML file inline script sources data + * + * @returns Promise A promise that resolves with an object of the following shape: + * - {String} code: The prettified HTML text + * - {Object} sourceMap: The sourceMap object + */ +async function prettyPrintHtmlFile({ + prettyPrintWorker, + generatedSource, + content, + actors, +}) { + const url = getPrettyOriginalSourceURL(generatedSource); + const contentValue = content.value; + const htmlFileText = contentValue.value; + const prettyPrintWorkerResult = { code: htmlFileText }; + + const allLineBreaks = matchAllLineBreaks(htmlFileText); + let lineCountDelta = 0; + + // Sort inline script actors so they are in the same order as in the html document. + actors.sort((a, b) => { + if (a.sourceStartLine === b.sourceStartLine) { + return a.sourceStartColumn > b.sourceStartColumn; + } + return a.sourceStartLine > b.sourceStartLine; + }); + + const prettyPrintTaskId = generatedSource.id; + + // We don't want to replace part of the HTML document in the loop since it would require + // to account for modified lines for each iteration. + // Instead, we'll put each sections to replace in this array, where elements will be + // objects of the following shape: + // {Integer} startIndex: The start index in htmlFileText of the section we want to replace + // {Integer} endIndex: The end index in htmlFileText of the section we want to replace + // {String} prettyText: The pretty text we'll replace the original section with + // Once we iterated over all the inline scripts, we'll do the replacements (on the html + // file text) in reverse order, so we don't need have to care about the modified lines + // for each iteration. + const replacements = []; + + const seenLocations = new Set(); + + for (const sourceInfo of actors) { + // We can get duplicate source actors representing the same inline script which will + // cause trouble in the pretty printing here. This should be fixed on the server (see + // Bug 1824979), but in the meantime let's not handle the same location twice so the + // pretty printing is not impacted. + const location = `${sourceInfo.sourceStartLine}:${sourceInfo.sourceStartColumn}`; + if (!sourceInfo.sourceLength || seenLocations.has(location)) { + continue; + } + seenLocations.add(location); + // Here we want to get the index of the last line break before the script tag. + // In allLineBreaks, this would be the item at (script tag line - 1) + // Since sourceInfo.sourceStartLine is 1-based, we need to get the item at (sourceStartLine - 2) + const indexAfterPreviousLineBreakInHtml = + sourceInfo.sourceStartLine > 1 + ? allLineBreaks[sourceInfo.sourceStartLine - 2].index + 1 + : 0; + const startIndex = + indexAfterPreviousLineBreakInHtml + sourceInfo.sourceStartColumn; + const endIndex = startIndex + sourceInfo.sourceLength; + const scriptText = htmlFileText.substring(startIndex, endIndex); + DevToolsUtils.assert( + scriptText.length == sourceInfo.sourceLength, + "script text has expected length" + ); + + // Here we're going to pretty print each inline script content. + // Since we want to have a sourceMap that we'll apply to the whole HTML file, + // we'll only collect the sourceMap once we handled all inline scripts. + // `taskId` allows us to signal to the worker that all those calls are part of the + // same bigger file, and we'll use it later to get the sourceMap. + const prettyText = await prettyPrintWorker.prettyPrintInlineScript({ + taskId: prettyPrintTaskId, + sourceText: scriptText, + indent: " ".repeat(prefs.indentSize), + url, + originalStartLine: sourceInfo.sourceStartLine, + originalStartColumn: sourceInfo.sourceStartColumn, + // The generated line will be impacted by the previous inline scripts that were + // pretty printed, which is why we offset with lineCountDelta + generatedStartLine: sourceInfo.sourceStartLine + lineCountDelta, + generatedStartColumn: sourceInfo.sourceStartColumn, + lineCountDelta, + }); + + // We need to keep track of the line added/removed in order to properly offset + // the mapping of the pretty-print text + lineCountDelta += + matchAllLineBreaks(prettyText).length - + matchAllLineBreaks(scriptText).length; + + replacements.push({ + startIndex, + endIndex, + prettyText, + }); + } + + // `getSourceMap` allow us to collect the computed source map resulting of the calls + // to `prettyPrint` with the same taskId. + prettyPrintWorkerResult.sourceMap = await prettyPrintWorker.getSourceMap( + prettyPrintTaskId + ); + + // Sort replacement in reverse order so we can replace code in the HTML file more easily + replacements.sort((a, b) => a.startIndex < b.startIndex); + for (const { startIndex, endIndex, prettyText } of replacements) { + prettyPrintWorkerResult.code = + prettyPrintWorkerResult.code.substring(0, startIndex) + + prettyText + + prettyPrintWorkerResult.code.substring(endIndex); + } + + return prettyPrintWorkerResult; +} + +function createPrettySource(cx, source) { + return async ({ dispatch, sourceMapLoader, getState }) => { + const url = getPrettyOriginalSourceURL(source); + const id = generatedToOriginalId(source.id, url); + const prettySource = createPrettyPrintOriginalSource(id, url); + + dispatch({ + type: "ADD_ORIGINAL_SOURCES", + cx, + originalSources: [prettySource], + }); + return prettySource; + }; +} + +function selectPrettyLocation(cx, prettySource) { + return async thunkArgs => { + const { dispatch, getState } = thunkArgs; + let location = getSelectedLocation(getState()); + + // If we were selecting a particular line in the minified/generated source, + // try to select the matching line in the prettified/original source. + if ( + location && + location.line >= 1 && + location.sourceId == originalToGeneratedId(prettySource.id) + ) { + location = await getOriginalLocation(location, thunkArgs); + + return dispatch( + selectSpecificLocation( + cx, + createLocation({ ...location, source: prettySource }) + ) + ); + } + + return dispatch(selectSource(cx, prettySource)); + }; +} + +/** + * Toggle the pretty printing of a source's text. + * Nothing will happen for non-javascript files. + * + * @param Object cx + * @param String sourceId + * The source ID for the minified/generated source object. + * @returns Promise + * A promise that resolves to the Pretty print/original source object. + */ +export function togglePrettyPrint(cx, sourceId) { + return async ({ dispatch, getState }) => { + const source = getSource(getState(), sourceId); + if (!source) { + return {}; + } + + if (!source.isPrettyPrinted) { + recordEvent("pretty_print"); + } + + assert( + isGenerated(source), + "Pretty-printing only allowed on generated sources" + ); + + const sourceActor = getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(loadGeneratedSourceText({ cx, sourceActor })); + + const url = getPrettySourceURL(source.url); + const prettySource = getSourceByURL(getState(), url); + + if (prettySource) { + return dispatch(selectPrettyLocation(cx, prettySource)); + } + + const newPrettySource = await dispatch(createPrettySource(cx, source)); + + // Force loading the pretty source/original text. + // This will end up calling prettyPrintSource() of this module, and + // more importantly, will populate the sourceMapLoader, which is used by selectPrettyLocation. + await dispatch(loadOriginalSourceText({ cx, source: newPrettySource })); + // Select the pretty/original source based on the location we may + // have had against the minified/generated source. + // This uses source map to map locations. + // Also note that selecting a location force many things: + // * opening tabs + // * fetching symbols/inline scope + // * fetching breakable lines + await dispatch(selectPrettyLocation(cx, newPrettySource)); + + const threadcx = getThreadContext(getState()); + // Update frames to the new pretty/original source (in case we were paused) + await dispatch(mapFrames(threadcx)); + // Update breakpoints locations to the new pretty/original source + await dispatch(updateBreakpointsForNewPrettyPrintedSource(cx, sourceId)); + + return newPrettySource; + }; +} diff --git a/devtools/client/debugger/src/actions/sources/select.js b/devtools/client/debugger/src/actions/sources/select.js new file mode 100644 index 0000000000..c4443432a0 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/select.js @@ -0,0 +1,264 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the sources state + * @module actions/sources + */ + +import { isOriginalId } from "devtools/client/shared/source-map-loader/index"; + +import { setSymbols } from "./symbols"; +import { setInScopeLines } from "../ast"; +import { togglePrettyPrint } from "./prettyPrint"; +import { addTab, closeTab } from "../tabs"; +import { loadSourceText } from "./loadSourceText"; +import { mapDisplayNames } from "../pause"; +import { setBreakableLines } from "."; + +import { prefs } from "../../utils/prefs"; +import { isMinified } from "../../utils/source"; +import { createLocation } from "../../utils/location"; +import { getRelatedMapLocation } from "../../utils/source-maps"; + +import { + getSource, + getFirstSourceActorForGeneratedSource, + getSourceByURL, + getPrettySource, + getSelectedLocation, + getShouldSelectOriginalLocation, + canPrettyPrintSource, + getIsCurrentThreadPaused, + getSourceTextContent, + tabExists, +} from "../../selectors"; + +// This is only used by jest tests (and within this module) +export const setSelectedLocation = ( + cx, + location, + shouldSelectOriginalLocation +) => ({ + type: "SET_SELECTED_LOCATION", + cx, + location, + shouldSelectOriginalLocation, +}); + +// This is only used by jest tests (and within this module) +export const setPendingSelectedLocation = (cx, url, options) => ({ + type: "SET_PENDING_SELECTED_LOCATION", + cx, + url, + line: options?.line, + column: options?.column, +}); + +// This is only used by jest tests (and within this module) +export const clearSelectedLocation = cx => ({ + type: "CLEAR_SELECTED_LOCATION", + cx, +}); + +/** + * Deterministically select a source that has a given URL. This will + * work regardless of the connection status or if the source exists + * yet. + * + * This exists mostly for external things to interact with the + * debugger. + */ +export function selectSourceURL(cx, url, options) { + return async ({ dispatch, getState }) => { + const source = getSourceByURL(getState(), url); + if (!source) { + return dispatch(setPendingSelectedLocation(cx, url, options)); + } + + const location = createLocation({ ...options, source }); + return dispatch(selectLocation(cx, location)); + }; +} + +/** + * Wrapper around selectLocation, which creates the location object for us. + * Note that it ignores the currently selected source and will select + * the precise generated/original source passed as argument. + * + * @param {Object} cx + * @param {String} source + * The precise source to select. + * @param {String} sourceActor + * The specific source actor of the source to + * select the source text. This is optional. + */ +export function selectSource(cx, source, sourceActor) { + return async ({ dispatch }) => { + // `createLocation` requires a source object, but we may use selectSource to close the last tab, + // where source will be null and the location will be an empty object. + const location = source ? createLocation({ source, sourceActor }) : {}; + + return dispatch(selectSpecificLocation(cx, location)); + }; +} + +/** + * Select a new location. + * This will automatically select the source in the source tree (if visible) + * and open the source (a new tab and the source editor) + * as well as highlight a precise line in the editor. + * + * Note that by default, this may map your passed location to the original + * or generated location based on the selected source state. (see keepContext) + * + * @param {Object} cx + * @param {Object} location + * @param {Object} options + * @param {boolean} options.keepContext + * If false, this will ignore the currently selected source + * and select the generated or original location, even if we + * were currently selecting the other source type. + */ +export function selectLocation(cx, location, { keepContext = true } = {}) { + return async thunkArgs => { + const { dispatch, getState, client } = thunkArgs; + + if (!client) { + // No connection, do nothing. This happens when the debugger is + // shut down too fast and it tries to display a default source. + return; + } + + let source = location.source; + + if (!source) { + // If there is no source we deselect the current selected source + dispatch(clearSelectedLocation(cx)); + return; + } + + // Preserve the current source map context (original / generated) + // when navigating to a new location. + // i.e. if keepContext isn't manually overriden to false, + // we will convert the source we want to select to either + // original/generated in order to match the currently selected one. + // If the currently selected source is original, we will + // automatically map `location` to refer to the original source, + // even if that used to refer only to the generated source. + let shouldSelectOriginalLocation = getShouldSelectOriginalLocation( + getState() + ); + if (keepContext) { + if (shouldSelectOriginalLocation != isOriginalId(location.sourceId)) { + // getRelatedMapLocation will convert to the related generated/original location. + // i.e if the original location is passed, the related generated location will be returned and vice versa. + location = await getRelatedMapLocation(location, thunkArgs); + // Note that getRelatedMapLocation may return the exact same location. + // For example, if the source-map is half broken, it may return a generated location + // while we were selecting original locations. So we may be seeing bundles intermittently + // when stepping through broken source maps. And we will see original sources when stepping + // through functional original sources. + + source = location.source; + } + } else { + shouldSelectOriginalLocation = isOriginalId(location.sourceId); + } + + let sourceActor = location.sourceActor; + if (!sourceActor) { + sourceActor = getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + location = createLocation({ ...location, sourceActor }); + } + + if (!tabExists(getState(), source.id)) { + dispatch(addTab(source, sourceActor)); + } + + dispatch(setSelectedLocation(cx, location, shouldSelectOriginalLocation)); + + await dispatch(loadSourceText(cx, source, sourceActor)); + + await dispatch(setBreakableLines(cx, location)); + + const loadedSource = getSource(getState(), source.id); + + if (!loadedSource) { + // If there was a navigation while we were loading the loadedSource + return; + } + + const sourceTextContent = getSourceTextContent(getState(), location); + + if ( + keepContext && + prefs.autoPrettyPrint && + !getPrettySource(getState(), loadedSource.id) && + canPrettyPrintSource(getState(), location) && + isMinified(source, sourceTextContent) + ) { + await dispatch(togglePrettyPrint(cx, loadedSource.id)); + dispatch(closeTab(cx, loadedSource)); + } + + await dispatch(setSymbols({ cx, location })); + dispatch(setInScopeLines(cx)); + + if (getIsCurrentThreadPaused(getState())) { + await dispatch(mapDisplayNames(cx)); + } + }; +} + +/** + * Select a location while ignoring the currently selected source. + * This will select the generated location even if the currently + * select source is an original source. And the other way around. + * + * @param {Object} cx + * @param {Object} location + * The location to select, object which includes enough + * information to specify a precise source, line and column. + */ +export function selectSpecificLocation(cx, location) { + return selectLocation(cx, location, { keepContext: false }); +} + +/** + * Select the "mapped location". + * + * If the passed location is on a generated source, select the + * related location in the original source. + * If the passed location is on an original source, select the + * related location in the generated source. + */ +export function jumpToMappedLocation(cx, location) { + return async function (thunkArgs) { + const { client, dispatch } = thunkArgs; + if (!client) { + return null; + } + + // Map to either an original or a generated source location + const pairedLocation = await getRelatedMapLocation(location, thunkArgs); + + return dispatch(selectSpecificLocation(cx, pairedLocation)); + }; +} + +// This is only used by tests +export function jumpToMappedSelectedLocation(cx) { + return async function ({ dispatch, getState }) { + const location = getSelectedLocation(getState()); + if (!location) { + return; + } + + await dispatch(jumpToMappedLocation(cx, location)); + }; +} diff --git a/devtools/client/debugger/src/actions/sources/symbols.js b/devtools/client/debugger/src/actions/sources/symbols.js new file mode 100644 index 0000000000..5a1fb1f967 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/symbols.js @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSymbols } from "../../selectors"; + +import { PROMISE } from "../utils/middleware/promise"; +import { loadSourceText } from "./loadSourceText"; + +import { memoizeableAction } from "../../utils/memoizableAction"; +import { fulfilled } from "../../utils/async-value"; + +async function doSetSymbols( + cx, + location, + { dispatch, getState, parserWorker } +) { + await dispatch(loadSourceText(cx, location.source, location.sourceActor)); + + await dispatch({ + type: "SET_SYMBOLS", + cx, + location, + [PROMISE]: parserWorker.getSymbols(location.sourceId), + }); +} + +export const setSymbols = memoizeableAction("setSymbols", { + getValue: ({ location }, { getState, parserWorker }) => { + if (!parserWorker.isLocationSupported(location)) { + return fulfilled(null); + } + + const symbols = getSymbols(getState(), location); + if (!symbols) { + return null; + } + + return fulfilled(symbols); + }, + createKey: ({ location }) => location.sourceId, + action: ({ cx, location }, thunkArgs) => + doSetSymbols(cx, location, thunkArgs), +}); diff --git a/devtools/client/debugger/src/actions/sources/tests/blackbox.spec.js b/devtools/client/debugger/src/actions/sources/tests/blackbox.spec.js new file mode 100644 index 0000000000..2ff8420b23 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/tests/blackbox.spec.js @@ -0,0 +1,249 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + makeSource, +} from "../../../utils/test-head"; + +import { initialSourceBlackBoxState } from "../../../reducers/source-blackbox"; + +describe("blackbox", () => { + it("should blackbox and unblackbox a source based on the current state of the source ", async () => { + const store = createStore({ + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }); + const { dispatch, getState, cx } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + await dispatch(actions.toggleBlackBox(cx, fooSource)); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + let blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual([]); + + await dispatch(actions.toggleBlackBox(cx, fooSource)); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + }); + + it("should blackbox and unblackbox a source when explicilty specified", async () => { + const store = createStore({ + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }); + const { dispatch, getState, cx } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + + // check the state before trying to blackbox + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + let blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + + // should blackbox the whole source + await dispatch(actions.toggleBlackBox(cx, fooSource, true, [])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual([]); + + // should unblackbox the whole source + await dispatch(actions.toggleBlackBox(cx, fooSource, false, [])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + }); + + it("should blackbox and unblackbox lines in a source", async () => { + const store = createStore({ + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }); + const { dispatch, getState, cx } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + + const range1 = { + start: { line: 10, column: 3 }, + end: { line: 15, column: 4 }, + }; + + const range2 = { + start: { line: 5, column: 3 }, + end: { line: 7, column: 6 }, + }; + + await dispatch(actions.toggleBlackBox(cx, fooSource, true, [range1])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + let blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual([range1]); + + // add new blackbox lines in the second range + await dispatch(actions.toggleBlackBox(cx, fooSource, true, [range2])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + // ranges are stored asc order + expect(blackboxRanges[fooSource.url]).toEqual([range2, range1]); + + // un-blackbox lines in the first range + await dispatch(actions.toggleBlackBox(cx, fooSource, false, [range1])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual([range2]); + + // un-blackbox lines in the second range + await dispatch(actions.toggleBlackBox(cx, fooSource, false, [range2])); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + }); + + it("should undo blackboxed lines when whole source unblackboxed", async () => { + const store = createStore({ + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }); + const { dispatch, getState, cx } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + + const range1 = { + start: { line: 1, column: 5 }, + end: { line: 3, column: 4 }, + }; + + const range2 = { + start: { line: 5, column: 3 }, + end: { line: 7, column: 6 }, + }; + + await dispatch( + actions.toggleBlackBox(cx, fooSource, true, [range1, range2]) + ); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + let blackboxRanges = selectors.getBlackBoxRanges(getState()); + // The ranges are ordered in based on the lines & cols in ascending + expect(blackboxRanges[fooSource.url]).toEqual([range2, range1]); + + // un-blackbox the whole source + await dispatch(actions.toggleBlackBox(cx, fooSource)); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + }); + + it("should restore the blackboxed state correctly debugger load", async () => { + const mockAsyncStoreBlackBoxedRanges = { + "http://localhost:8000/examples/foo": [ + { + start: { line: 1, column: 5 }, + end: { line: 3, column: 4 }, + }, + ], + }; + + function loadInitialState() { + const blackboxedRanges = mockAsyncStoreBlackBoxedRanges; + return { + sourceBlackBox: initialSourceBlackBoxState({ blackboxedRanges }), + }; + } + const store = createStore( + { + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }, + loadInitialState() + ); + const { dispatch, getState } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + const blackboxRanges = selectors.getBlackBoxRanges(getState()); + const mockFooSourceRange = mockAsyncStoreBlackBoxedRanges[fooSource.url]; + expect(blackboxRanges[fooSource.url]).toEqual(mockFooSourceRange); + }); + + it("should unblackbox lines after blackboxed state has been restored", async () => { + const mockAsyncStoreBlackBoxedRanges = { + "http://localhost:8000/examples/foo": [ + { + start: { line: 1, column: 5 }, + end: { line: 3, column: 4 }, + }, + ], + }; + + function loadInitialState() { + const blackboxedRanges = mockAsyncStoreBlackBoxedRanges; + return { + sourceBlackBox: initialSourceBlackBoxState({ blackboxedRanges }), + }; + } + const store = createStore( + { + blackBox: async () => true, + getSourceActorBreakableLines: async () => [], + }, + loadInitialState() + ); + const { dispatch, getState, cx } = store; + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo")) + ); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(true); + + let blackboxRanges = selectors.getBlackBoxRanges(getState()); + const mockFooSourceRange = mockAsyncStoreBlackBoxedRanges[fooSource.url]; + expect(blackboxRanges[fooSource.url]).toEqual(mockFooSourceRange); + + //unblackbox the blackboxed line + await dispatch( + actions.toggleBlackBox(cx, fooSource, false, mockFooSourceRange) + ); + + expect(selectors.isSourceBlackBoxed(getState(), fooSource)).toEqual(false); + + blackboxRanges = selectors.getBlackBoxRanges(getState()); + expect(blackboxRanges[fooSource.url]).toEqual(undefined); + }); +}); diff --git a/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js b/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js new file mode 100644 index 0000000000..f81fc856dd --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/tests/loadSource.spec.js @@ -0,0 +1,363 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + watchForState, + createStore, + makeOriginalSource, + makeSource, +} from "../../../utils/test-head"; +import { + createSource, + mockCommandClient, +} from "../../tests/helpers/mockCommandClient"; +import { getBreakpointsList } from "../../../selectors"; +import { isFulfilled, isRejected } from "../../../utils/async-value"; +import { createLocation } from "../../../utils/location"; + +describe("loadGeneratedSourceText", () => { + it("should load source text", async () => { + const store = createStore(mockCommandClient); + const { dispatch, getState, cx } = store; + + const foo1Source = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + const foo1SourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + foo1Source.id + ); + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: foo1SourceActor, + }) + ); + + const foo1Content = selectors.getSettledSourceTextContent( + getState(), + createLocation({ + source: foo1Source, + sourceActor: foo1SourceActor, + }) + ); + + expect( + foo1Content && + isFulfilled(foo1Content) && + foo1Content.value.type === "text" + ? foo1Content.value.value.indexOf("return foo1") + : -1 + ).not.toBe(-1); + + const foo2Source = await dispatch( + actions.newGeneratedSource(makeSource("foo2")) + ); + const foo2SourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + foo2Source.id + ); + + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: foo2SourceActor, + }) + ); + + const foo2Content = selectors.getSettledSourceTextContent( + getState(), + createLocation({ + source: foo2Source, + sourceActor: foo2SourceActor, + }) + ); + + expect( + foo2Content && + isFulfilled(foo2Content) && + foo2Content.value.type === "text" + ? foo2Content.value.value.indexOf("return foo2") + : -1 + ).not.toBe(-1); + }); + + it("should update breakpoint text when a source loads", async () => { + const fooOrigContent = createSource("fooOrig", "var fooOrig = 42;"); + const fooGenContent = createSource("fooGen", "var fooGen = 42;"); + + const store = createStore( + { + ...mockCommandClient, + sourceContents: async () => fooGenContent, + getSourceActorBreakpointPositions: async () => ({ 1: [0] }), + getSourceActorBreakableLines: async () => [], + }, + {}, + { + getGeneratedRangesForOriginal: async () => [ + { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } }, + ], + getOriginalLocations: async items => + items.map(item => ({ + ...item, + sourceId: + item.sourceId === fooGenSource1.id + ? fooOrigSources1[0].id + : fooOrigSources2[0].id, + })), + getOriginalSourceText: async s => ({ + text: fooOrigContent.source, + contentType: fooOrigContent.contentType, + }), + } + ); + const { cx, dispatch, getState } = store; + + const fooGenSource1 = await dispatch( + actions.newGeneratedSource(makeSource("fooGen1")) + ); + + const fooOrigSources1 = await dispatch( + actions.newOriginalSources([makeOriginalSource(fooGenSource1)]) + ); + const fooGenSource2 = await dispatch( + actions.newGeneratedSource(makeSource("fooGen2")) + ); + + const fooOrigSources2 = await dispatch( + actions.newOriginalSources([makeOriginalSource(fooGenSource2)]) + ); + + await dispatch( + actions.loadOriginalSourceText({ + cx, + source: fooOrigSources1[0], + }) + ); + + await dispatch( + actions.addBreakpoint( + cx, + createLocation({ + source: fooOrigSources1[0], + line: 1, + column: 0, + }), + {} + ) + ); + + const breakpoint1 = getBreakpointsList(getState())[0]; + expect(breakpoint1.text).toBe(""); + expect(breakpoint1.originalText).toBe("var fooOrig = 42;"); + + const fooGenSource1SourceActor = + selectors.getFirstSourceActorForGeneratedSource( + getState(), + fooGenSource1.id + ); + + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: fooGenSource1SourceActor, + }) + ); + + const breakpoint2 = getBreakpointsList(getState())[0]; + expect(breakpoint2.text).toBe("var fooGen = 42;"); + expect(breakpoint2.originalText).toBe("var fooOrig = 42;"); + + const fooGenSource2SourceActor = + selectors.getFirstSourceActorForGeneratedSource( + getState(), + fooGenSource2.id + ); + + await dispatch( + actions.loadGeneratedSourceText({ + cx, + sourceActor: fooGenSource2SourceActor, + }) + ); + + await dispatch( + actions.addBreakpoint( + cx, + createLocation({ + source: fooGenSource2, + line: 1, + column: 0, + }), + {} + ) + ); + + const breakpoint3 = getBreakpointsList(getState())[1]; + expect(breakpoint3.text).toBe("var fooGen = 42;"); + expect(breakpoint3.originalText).toBe(""); + + await dispatch( + actions.loadOriginalSourceText({ + cx, + source: fooOrigSources2[0], + }) + ); + + const breakpoint4 = getBreakpointsList(getState())[1]; + expect(breakpoint4.text).toBe("var fooGen = 42;"); + expect(breakpoint4.originalText).toBe("var fooOrig = 42;"); + }); + + it("loads two sources w/ one request", async () => { + let resolve; + let count = 0; + const { dispatch, getState, cx } = createStore({ + sourceContents: () => + new Promise(r => { + count++; + resolve = r; + }), + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], + }); + const id = "foo"; + + const source = await dispatch(actions.newGeneratedSource(makeSource(id))); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + const loading = dispatch( + actions.loadGeneratedSourceText({ cx, sourceActor }) + ); + + if (!resolve) { + throw new Error("no resolve"); + } + resolve({ source: "yay", contentType: "text/javascript" }); + await loading; + expect(count).toEqual(1); + + const content = selectors.getSettledSourceTextContent( + getState(), + createLocation({ + source, + sourceActor, + }) + ); + expect( + content && + isFulfilled(content) && + content.value.type === "text" && + content.value.value + ).toEqual("yay"); + }); + + it("doesn't re-load loaded sources", async () => { + let resolve; + let count = 0; + const { dispatch, getState, cx } = createStore({ + sourceContents: () => + new Promise(r => { + count++; + resolve = r; + }), + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], + }); + const id = "foo"; + + const source = await dispatch(actions.newGeneratedSource(makeSource(id))); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + const loading = dispatch( + actions.loadGeneratedSourceText({ cx, sourceActor }) + ); + + if (!resolve) { + throw new Error("no resolve"); + } + resolve({ source: "yay", contentType: "text/javascript" }); + await loading; + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + expect(count).toEqual(1); + + const content = selectors.getSettledSourceTextContent( + getState(), + createLocation({ + source, + sourceActor, + }) + ); + expect( + content && + isFulfilled(content) && + content.value.type === "text" && + content.value.value + ).toEqual("yay"); + }); + + it("should indicate a loading source", async () => { + const store = createStore(mockCommandClient); + const { dispatch, cx, getState } = store; + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo2")) + ); + + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + const wasLoading = watchForState(store, state => { + return !selectors.getSettledSourceTextContent( + state, + createLocation({ + source, + sourceActor, + }) + ); + }); + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + expect(wasLoading()).toBe(true); + }); + + it("should indicate an errored source text", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("bad-id")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + const content = selectors.getSettledSourceTextContent( + getState(), + createLocation({ + source, + sourceActor, + }) + ); + expect( + content && isRejected(content) && typeof content.value === "string" + ? content.value.indexOf("sourceContents failed") + : -1 + ).not.toBe(-1); + }); +}); diff --git a/devtools/client/debugger/src/actions/sources/tests/newSources.spec.js b/devtools/client/debugger/src/actions/sources/tests/newSources.spec.js new file mode 100644 index 0000000000..730c5b32eb --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/tests/newSources.spec.js @@ -0,0 +1,172 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + makeSource, + makeSourceURL, + makeOriginalSource, + waitForState, +} from "../../../utils/test-head"; +const { getSource, getSourceCount, getSelectedSource, getSourceByURL } = + selectors; +import sourceQueue from "../../../utils/source-queue"; +import { generatedToOriginalId } from "devtools/client/shared/source-map-loader/index"; + +import { mockCommandClient } from "../../tests/helpers/mockCommandClient"; + +describe("sources - new sources", () => { + it("should add sources to state", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + await dispatch(actions.newGeneratedSource(makeSource("base.js"))); + await dispatch(actions.newGeneratedSource(makeSource("jquery.js"))); + + expect(getSourceCount(getState())).toEqual(2); + const base = getSource(getState(), "base.js"); + const jquery = getSource(getState(), "jquery.js"); + expect(base && base.id).toEqual("base.js"); + expect(jquery && jquery.id).toEqual("jquery.js"); + }); + + it("should not add multiple identical generated sources", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + + const generated = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + + await dispatch(actions.newOriginalSources([makeOriginalSource(generated)])); + await dispatch(actions.newOriginalSources([makeOriginalSource(generated)])); + + expect(getSourceCount(getState())).toEqual(2); + }); + + it("should not add multiple identical original sources", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + + await dispatch(actions.newGeneratedSource(makeSource("base.js"))); + await dispatch(actions.newGeneratedSource(makeSource("base.js"))); + + expect(getSourceCount(getState())).toEqual(1); + }); + + it("should automatically select a pending source", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + const baseSourceURL = makeSourceURL("base.js"); + await dispatch(actions.selectSourceURL(cx, baseSourceURL)); + + expect(getSelectedSource(getState())).toBe(undefined); + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + + const selected = getSelectedSource(getState()); + expect(selected && selected.url).toBe(baseSource.url); + }); + + it("should add original sources", async () => { + const { dispatch, getState } = createStore( + mockCommandClient, + {}, + { + getOriginalURLs: async source => [ + { + id: generatedToOriginalId(source.id, "magic.js"), + url: "magic.js", + }, + ], + getOriginalLocations: async items => items, + getOriginalLocation: location => location, + } + ); + + await dispatch( + actions.newGeneratedSource( + makeSource("base.js", { sourceMapURL: "base.js.map" }) + ) + ); + const magic = getSourceByURL(getState(), "magic.js"); + expect(magic && magic.url).toEqual("magic.js"); + }); + + // eslint-disable-next-line + it("should not attempt to fetch original sources if it's missing a source map url", async () => { + const getOriginalURLs = jest.fn(); + const { dispatch } = createStore( + mockCommandClient, + {}, + { + getOriginalURLs, + getOriginalLocations: async items => items, + getOriginalLocation: location => location, + } + ); + + await dispatch(actions.newGeneratedSource(makeSource("base.js"))); + expect(getOriginalURLs).not.toHaveBeenCalled(); + }); + + // eslint-disable-next-line + it("should process new sources immediately, without waiting for source maps to be fetched first", async () => { + const { dispatch, getState } = createStore( + mockCommandClient, + {}, + { + getOriginalURLs: async () => new Promise(_ => {}), + getOriginalLocations: async items => items, + getOriginalLocation: location => location, + } + ); + await dispatch( + actions.newGeneratedSource( + makeSource("base.js", { sourceMapURL: "base.js.map" }) + ) + ); + expect(getSourceCount(getState())).toEqual(1); + const base = getSource(getState(), "base.js"); + expect(base && base.id).toEqual("base.js"); + }); + + // eslint-disable-next-line + it("shouldn't let one slow loading source map delay all the other source maps", async () => { + const dbg = createStore( + mockCommandClient, + {}, + { + getOriginalURLs: async source => { + if (source.id == "foo.js") { + // simulate a hang loading foo.js.map + return new Promise(_ => {}); + } + const url = source.id.replace(".js", ".cljs"); + return [ + { + id: generatedToOriginalId(source.id, url), + url, + }, + ]; + }, + getOriginalLocations: async items => items, + getGeneratedLocation: location => location, + } + ); + const { dispatch, getState } = dbg; + await dispatch( + actions.newGeneratedSources([ + makeSource("foo.js", { sourceMapURL: "foo.js.map" }), + makeSource("bar.js", { sourceMapURL: "bar.js.map" }), + makeSource("bazz.js", { sourceMapURL: "bazz.js.map" }), + ]) + ); + await sourceQueue.flush(); + await waitForState(dbg, state => getSourceCount(state) == 5); + expect(getSourceCount(getState())).toEqual(5); + const barCljs = getSourceByURL(getState(), "bar.cljs"); + expect(barCljs && barCljs.url).toEqual("bar.cljs"); + const bazzCljs = getSourceByURL(getState(), "bazz.cljs"); + expect(bazzCljs && bazzCljs.url).toEqual("bazz.cljs"); + }); +}); diff --git a/devtools/client/debugger/src/actions/sources/tests/select.spec.js b/devtools/client/debugger/src/actions/sources/tests/select.spec.js new file mode 100644 index 0000000000..3fcf24f2b7 --- /dev/null +++ b/devtools/client/debugger/src/actions/sources/tests/select.spec.js @@ -0,0 +1,288 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + createSourceObject, + makeFrame, + makeSource, + makeSourceURL, + waitForState, + makeOriginalSource, +} from "../../../utils/test-head"; +import { + getSource, + getSourceCount, + getSelectedSource, + getSourceTabs, + getSelectedLocation, + getSymbols, +} from "../../../selectors/"; +import { createLocation } from "../../../utils/location"; + +import { mockCommandClient } from "../../tests/helpers/mockCommandClient"; + +process.on("unhandledRejection", (reason, p) => {}); + +function initialLocation(sourceId) { + return createLocation({ source: createSourceObject(sourceId), line: 1 }); +} + +describe("sources", () => { + it("should select a source", async () => { + // Note that we pass an empty client in because the action checks + // if it exists. + const store = createStore(mockCommandClient); + const { dispatch, getState } = store; + + const frame = makeFrame({ id: "1", sourceId: "foo1" }); + + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("foo1")) + ); + await dispatch( + actions.paused({ + thread: "FakeThread", + why: { type: "debuggerStatement" }, + frame, + frames: [frame], + }) + ); + + const cx = selectors.getThreadContext(getState()); + await dispatch( + actions.selectLocation( + cx, + createLocation({ source: baseSource, line: 1, column: 5 }) + ) + ); + + const selectedSource = getSelectedSource(getState()); + if (!selectedSource) { + throw new Error("bad selectedSource"); + } + expect(selectedSource.id).toEqual("foo1"); + + const source = getSource(getState(), selectedSource.id); + if (!source) { + throw new Error("bad source"); + } + expect(source.id).toEqual("foo1"); + }); + + it("should select next tab on tab closed if no previous tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + await dispatch(actions.newGeneratedSource(makeSource("bar.js"))); + await dispatch(actions.newGeneratedSource(makeSource("baz.js"))); + + // 3rd tab + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + + // 2nd tab + await dispatch(actions.selectLocation(cx, initialLocation("bar.js"))); + + // 1st tab + await dispatch(actions.selectLocation(cx, initialLocation("baz.js"))); + + // 3rd tab is reselected + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + + // closes the 1st tab, which should have no previous tab + await dispatch(actions.closeTab(cx, fooSource)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("bar.js"); + expect(getSourceTabs(getState())).toHaveLength(2); + }); + + it("should open a tab for the source", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + await dispatch(actions.newGeneratedSource(makeSource("foo.js"))); + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + + const tabs = getSourceTabs(getState()); + expect(tabs).toHaveLength(1); + expect(tabs[0].url).toEqual("http://localhost:8000/examples/foo.js"); + }); + + it("should select previous tab on tab closed", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + await dispatch(actions.newGeneratedSource(makeSource("foo.js"))); + await dispatch(actions.newGeneratedSource(makeSource("bar.js"))); + + const bazSource = await dispatch( + actions.newGeneratedSource(makeSource("baz.js")) + ); + + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + await dispatch(actions.selectLocation(cx, initialLocation("bar.js"))); + await dispatch(actions.selectLocation(cx, initialLocation("baz.js"))); + await dispatch(actions.closeTab(cx, bazSource)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("bar.js"); + expect(getSourceTabs(getState())).toHaveLength(2); + }); + + it("should keep the selected source when other tab closed", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + await dispatch(actions.newGeneratedSource(makeSource("foo.js"))); + await dispatch(actions.newGeneratedSource(makeSource("bar.js"))); + const bazSource = await dispatch( + actions.newGeneratedSource(makeSource("baz.js")) + ); + + // 3rd tab + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + + // 2nd tab + await dispatch(actions.selectLocation(cx, initialLocation("bar.js"))); + + // 1st tab + await dispatch(actions.selectLocation(cx, initialLocation("baz.js"))); + + // 3rd tab is reselected + await dispatch(actions.selectLocation(cx, initialLocation("foo.js"))); + await dispatch(actions.closeTab(cx, bazSource)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("foo.js"); + expect(getSourceTabs(getState())).toHaveLength(2); + }); + + it("should not select new sources that lack a URL", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + + await dispatch( + actions.newGeneratedSource({ + ...makeSource("foo"), + url: "", + }) + ); + + expect(getSourceCount(getState())).toEqual(1); + const selectedLocation = getSelectedLocation(getState()); + expect(selectedLocation).toEqual(undefined); + }); + + it("sets and clears selected location correctly", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + const source = await dispatch( + actions.newGeneratedSource(makeSource("testSource")) + ); + const location = createLocation({ source }); + + // set value + dispatch(actions.setSelectedLocation(cx, location)); + expect(getSelectedLocation(getState())).toEqual({ + sourceId: source.id, + ...location, + }); + + // clear value + dispatch(actions.clearSelectedLocation(cx)); + expect(getSelectedLocation(getState())).toEqual(null); + }); + + it("sets and clears pending selected location correctly", () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + const url = "testURL"; + const options = { line: "testLine", column: "testColumn" }; + + // set value + dispatch(actions.setPendingSelectedLocation(cx, url, options)); + const setResult = getState().sources.pendingSelectedLocation; + expect(setResult).toEqual({ + url, + line: options.line, + column: options.column, + }); + + // clear value + dispatch(actions.clearSelectedLocation(cx)); + const clearResult = getState().sources.pendingSelectedLocation; + expect(clearResult).toEqual({ url: "" }); + }); + + it("should keep the generated the viewing context", async () => { + const store = createStore(mockCommandClient); + const { dispatch, getState, cx } = store; + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + baseSource.id + ); + + const location = createLocation({ + source: baseSource, + line: 1, + sourceActor, + }); + await dispatch(actions.selectLocation(cx, location)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe(baseSource.id); + await waitForState(store, state => getSymbols(state, location)); + }); + + it("should change the original the viewing context", async () => { + const { dispatch, getState, cx } = createStore( + mockCommandClient, + {}, + { + getOriginalLocation: async location => ({ ...location, line: 12 }), + getOriginalLocations: async items => items, + getGeneratedRangesForOriginal: async () => [], + getOriginalSourceText: async () => ({ text: "" }), + } + ); + + const baseGenSource = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + + const baseSources = await dispatch( + actions.newOriginalSources([makeOriginalSource(baseGenSource)]) + ); + await dispatch(actions.selectSource(cx, baseSources[0])); + + await dispatch( + actions.selectSpecificLocation( + cx, + createLocation({ + source: baseSources[0], + line: 1, + }) + ) + ); + + const selected = getSelectedLocation(getState()); + expect(selected && selected.line).toBe(1); + }); + + describe("selectSourceURL", () => { + it("should automatically select a pending source", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + const baseSourceURL = makeSourceURL("base.js"); + await dispatch(actions.selectSourceURL(cx, baseSourceURL)); + + expect(getSelectedSource(getState())).toBe(undefined); + const baseSource = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + + const selected = getSelectedSource(getState()); + expect(selected && selected.url).toBe(baseSource.url); + }); + }); +}); diff --git a/devtools/client/debugger/src/actions/tabs.js b/devtools/client/debugger/src/actions/tabs.js new file mode 100644 index 0000000000..1b3c0d3f43 --- /dev/null +++ b/devtools/client/debugger/src/actions/tabs.js @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux actions for the editor tabs + * @module actions/tabs + */ + +import { removeDocument } from "../utils/editor"; +import { selectSource } from "./sources"; + +import { + getSourceByURL, + getSourceTabs, + getNewSelectedSource, +} from "../selectors"; + +export function addTab(source, sourceActor) { + return { + type: "ADD_TAB", + source, + sourceActor, + }; +} + +export function moveTab(url, tabIndex) { + return { + type: "MOVE_TAB", + url, + tabIndex, + }; +} + +export function moveTabBySourceId(sourceId, tabIndex) { + return { + type: "MOVE_TAB_BY_SOURCE_ID", + sourceId, + tabIndex, + }; +} + +/** + * @memberof actions/tabs + * @static + */ +export function closeTab(cx, source, reason = "click") { + return ({ dispatch, getState, client }) => { + removeDocument(source.id); + + const tabs = getSourceTabs(getState()); + dispatch({ type: "CLOSE_TAB", source }); + + const newSource = getNewSelectedSource(getState(), tabs); + dispatch(selectSource(cx, newSource)); + }; +} + +/** + * @memberof actions/tabs + * @static + */ +export function closeTabs(cx, urls) { + return ({ dispatch, getState, client }) => { + const sources = urls + .map(url => getSourceByURL(getState(), url)) + .filter(Boolean); + + const tabs = getSourceTabs(getState()); + sources.map(source => removeDocument(source.id)); + dispatch({ type: "CLOSE_TABS", sources }); + + const source = getNewSelectedSource(getState(), tabs); + dispatch(selectSource(cx, source)); + }; +} diff --git a/devtools/client/debugger/src/actions/tests/__snapshots__/expressions.spec.js.snap b/devtools/client/debugger/src/actions/tests/__snapshots__/expressions.spec.js.snap new file mode 100644 index 0000000000..f27eb26f50 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/__snapshots__/expressions.spec.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`expressions should get the autocomplete matches for the input 1`] = ` +Array [ + "toLocaleString", + "toSource", + "toString", + "toolbar", + "top", +] +`; diff --git a/devtools/client/debugger/src/actions/tests/__snapshots__/pending-breakpoints.spec.js.snap b/devtools/client/debugger/src/actions/tests/__snapshots__/pending-breakpoints.spec.js.snap new file mode 100644 index 0000000000..741e45d6d8 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/__snapshots__/pending-breakpoints.spec.js.snap @@ -0,0 +1,44 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`initializing when pending breakpoints exist in prefs syncs pending breakpoints 1`] = ` +Object { + "http://localhost:8000/examples/bar.js:5:2": Object { + "astLocation": Object { + "index": 0, + "name": undefined, + "offset": Object { + "line": 5, + }, + }, + "disabled": false, + "generatedLocation": Object { + "column": 2, + "line": 5, + "source": Object { + "id": "", + "url": "http://localhost:8000/examples/bar.js", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "", + "sourceUrl": "http://localhost:8000/examples/bar.js", + }, + "location": Object { + "column": 2, + "line": 5, + "source": Object { + "id": "", + "url": "http://localhost:8000/examples/bar.js", + }, + "sourceActor": null, + "sourceActorId": undefined, + "sourceId": "", + "sourceUrl": "http://localhost:8000/examples/bar.js", + }, + "options": Object { + "condition": null, + "hidden": false, + }, + }, +} +`; diff --git a/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap b/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap new file mode 100644 index 0000000000..026bfe4a89 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/__snapshots__/preview.spec.js.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`preview should generate previews 1`] = `null`; diff --git a/devtools/client/debugger/src/actions/tests/expressions.spec.js b/devtools/client/debugger/src/actions/tests/expressions.spec.js new file mode 100644 index 0000000000..48b06ebd1a --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/expressions.spec.js @@ -0,0 +1,184 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + makeSource, +} from "../../utils/test-head"; + +import { makeMockFrame } from "../../utils/test-mockup"; + +const mockThreadFront = { + evaluate: (script, { frameId }) => + new Promise((resolve, reject) => { + if (!frameId) { + resolve("bla"); + } else { + resolve("boo"); + } + }), + evaluateExpressions: (inputs, { frameId }) => + Promise.all( + inputs.map( + input => + new Promise((resolve, reject) => { + if (!frameId) { + resolve("bla"); + } else { + resolve("boo"); + } + }) + ) + ), + getFrameScopes: async () => {}, + getFrames: async () => [], + sourceContents: () => ({ source: "", contentType: "text/javascript" }), + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], + autocomplete: () => { + return new Promise(resolve => { + resolve({ + from: "foo", + matches: ["toLocaleString", "toSource", "toString", "toolbar", "top"], + matchProp: "to", + }); + }); + }, +}; + +describe("expressions", () => { + it("should add an expression", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + + await dispatch(actions.addExpression(cx, "foo")); + expect(selectors.getExpressions(getState())).toHaveLength(1); + }); + + it("should not add empty expressions", () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + + dispatch(actions.addExpression(cx, undefined)); + dispatch(actions.addExpression(cx, "")); + expect(selectors.getExpressions(getState())).toHaveLength(0); + }); + + it("should not add invalid expressions", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + await dispatch(actions.addExpression(cx, "foo#")); + const state = getState(); + expect(selectors.getExpressions(state)).toHaveLength(0); + expect(selectors.getExpressionError(state)).toBe(true); + }); + + it("should update an expression", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + + await dispatch(actions.addExpression(cx, "foo")); + const expression = selectors.getExpression(getState(), "foo"); + if (!expression) { + throw new Error("expression must exist"); + } + + await dispatch(actions.updateExpression(cx, "bar", expression)); + const bar = selectors.getExpression(getState(), "bar"); + + expect(bar && bar.input).toBe("bar"); + }); + + it("should not update an expression w/ invalid code", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + + await dispatch(actions.addExpression(cx, "foo")); + const expression = selectors.getExpression(getState(), "foo"); + if (!expression) { + throw new Error("expression must exist"); + } + await dispatch(actions.updateExpression(cx, "#bar", expression)); + expect(selectors.getExpression(getState(), "bar")).toBeUndefined(); + }); + + it("should delete an expression", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + + await dispatch(actions.addExpression(cx, "foo")); + await dispatch(actions.addExpression(cx, "bar")); + expect(selectors.getExpressions(getState())).toHaveLength(2); + + const expression = selectors.getExpression(getState(), "foo"); + + if (!expression) { + throw new Error("expression must exist"); + } + + const bar = selectors.getExpression(getState(), "bar"); + dispatch(actions.deleteExpression(expression)); + expect(selectors.getExpressions(getState())).toHaveLength(1); + expect(bar && bar.input).toBe("bar"); + }); + + it("should evaluate expressions global scope", async () => { + const { dispatch, getState, cx } = createStore(mockThreadFront); + await dispatch(actions.addExpression(cx, "foo")); + await dispatch(actions.addExpression(cx, "bar")); + + let foo = selectors.getExpression(getState(), "foo"); + let bar = selectors.getExpression(getState(), "bar"); + expect(foo && foo.value).toBe("bla"); + expect(bar && bar.value).toBe("bla"); + + await dispatch(actions.evaluateExpressions(cx)); + foo = selectors.getExpression(getState(), "foo"); + bar = selectors.getExpression(getState(), "bar"); + expect(foo && foo.value).toBe("bla"); + expect(bar && bar.value).toBe("bla"); + }); + + it("should evaluate expressions in specific scope", async () => { + const { dispatch, getState } = createStore(mockThreadFront); + await createFrames(getState, dispatch); + + const cx = selectors.getThreadContext(getState()); + await dispatch(actions.newGeneratedSource(makeSource("source"))); + await dispatch(actions.addExpression(cx, "foo")); + await dispatch(actions.addExpression(cx, "bar")); + + let foo = selectors.getExpression(getState(), "foo"); + let bar = selectors.getExpression(getState(), "bar"); + expect(foo && foo.value).toBe("boo"); + expect(bar && bar.value).toBe("boo"); + + await dispatch(actions.evaluateExpressions(cx)); + foo = selectors.getExpression(getState(), "foo"); + bar = selectors.getExpression(getState(), "bar"); + expect(foo && foo.value).toBe("boo"); + expect(bar && bar.value).toBe("boo"); + }); + + it("should get the autocomplete matches for the input", async () => { + const { cx, dispatch, getState } = createStore(mockThreadFront); + await dispatch(actions.autocomplete(cx, "to", 2)); + expect(selectors.getAutocompleteMatchset(getState())).toMatchSnapshot(); + }); +}); + +async function createFrames(getState, dispatch) { + const frame = makeMockFrame(); + await dispatch(actions.newGeneratedSource(makeSource("example.js"))); + await dispatch(actions.newGeneratedSource(makeSource("source"))); + + await dispatch( + actions.paused({ + thread: "FakeThread", + frame, + frames: [frame], + why: { type: "just because" }, + }) + ); + + await dispatch( + actions.selectFrame(selectors.getThreadContext(getState()), frame) + ); +} diff --git a/devtools/client/debugger/src/actions/tests/fixtures/immutable.js b/devtools/client/debugger/src/actions/tests/fixtures/immutable.js new file mode 100644 index 0000000000..e8ac7fb233 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/fixtures/immutable.js @@ -0,0 +1,2 @@ + +const m = Immutable.Map({a: 2}) diff --git a/devtools/client/debugger/src/actions/tests/fixtures/reactComponent.js b/devtools/client/debugger/src/actions/tests/fixtures/reactComponent.js new file mode 100644 index 0000000000..526c852d99 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/fixtures/reactComponent.js @@ -0,0 +1,7 @@ +import React, { Component } from "react"; + +class FixtureComponent extends Component { + render() { + return null; + } +} diff --git a/devtools/client/debugger/src/actions/tests/fixtures/reactFuncComponent.js b/devtools/client/debugger/src/actions/tests/fixtures/reactFuncComponent.js new file mode 100644 index 0000000000..3103161fe0 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/fixtures/reactFuncComponent.js @@ -0,0 +1,5 @@ +import React, { Component } from "react"; + +export default FixtureComponent = (props) => { + return
props.a
; +} diff --git a/devtools/client/debugger/src/actions/tests/fixtures/scopes.js b/devtools/client/debugger/src/actions/tests/fixtures/scopes.js new file mode 100644 index 0000000000..3a38097f5e --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/fixtures/scopes.js @@ -0,0 +1,11 @@ +// Program Scope + +function outer() { + function inner() { + const x = 1; + } + + const declaration = function() { + const x = 1; + }; +} diff --git a/devtools/client/debugger/src/actions/tests/helpers/breakpoints.js b/devtools/client/debugger/src/actions/tests/helpers/breakpoints.js new file mode 100644 index 0000000000..e0279e5fc1 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/helpers/breakpoints.js @@ -0,0 +1,77 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { createLocation } from "../../../utils/location"; + +export function mockPendingBreakpoint(overrides = {}) { + const { sourceUrl, line, column, condition, disabled, hidden } = overrides; + return { + location: createLocation({ + source: { + id: "", + url: sourceUrl || "http://localhost:8000/examples/bar.js", + }, + sourceId: "", + sourceUrl: sourceUrl || "http://localhost:8000/examples/bar.js", + line: line || 5, + column: column || 1, + }), + generatedLocation: createLocation({ + source: { + id: "", + url: sourceUrl || "http://localhost:8000/examples/bar.js", + }, + sourceId: "", + sourceUrl: sourceUrl || "http://localhost:8000/examples/bar.js", + line: line || 5, + column: column || 1, + }), + astLocation: { + name: undefined, + offset: { + line: line || 5, + }, + index: 0, + }, + options: { + condition: condition || null, + hidden: hidden || false, + }, + disabled: disabled || false, + }; +} + +export function generateBreakpoint(filename, line = 5, column = 0) { + return { + id: "breakpoint", + originalText: "", + text: "", + location: createLocation({ + source: { + url: `http://localhost:8000/examples/${filename}`, + id: filename, + }, + sourceUrl: `http://localhost:8000/examples/${filename}`, + sourceId: filename, + line, + column, + }), + generatedLocation: createLocation({ + source: { + url: `http://localhost:8000/examples/${filename}`, + id: filename, + }, + sourceUrl: `http://localhost:8000/examples/${filename}`, + sourceId: filename, + line, + column, + }), + astLocation: undefined, + options: { + condition: "", + hidden: false, + }, + disabled: false, + }; +} diff --git a/devtools/client/debugger/src/actions/tests/helpers/mockCommandClient.js b/devtools/client/debugger/src/actions/tests/helpers/mockCommandClient.js new file mode 100644 index 0000000000..38dd55c274 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/helpers/mockCommandClient.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export function createSource(name, code) { + name = name.replace(/\..*$/, ""); + return { + source: code || `function ${name}() {\n return ${name} \n}`, + contentType: "text/javascript", + }; +} + +const sources = [ + "a", + "b", + "foo", + "bar", + "foo1", + "foo2", + "a.js", + "baz.js", + "foobar.js", + "barfoo.js", + "foo.js", + "bar.js", + "base.js", + "bazz.js", + "jquery.js", +]; + +export const mockCommandClient = { + sourceContents: function ({ source }) { + return new Promise((resolve, reject) => { + if (sources.includes(source)) { + resolve(createSource(source)); + } + + reject(`unknown source: ${source}`); + }); + }, + setBreakpoint: async () => {}, + removeBreakpoint: _id => Promise.resolve(), + threadFront: async () => {}, + getFrameScopes: async () => {}, + getFrames: async () => [], + evaluateExpressions: async () => {}, + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], +}; diff --git a/devtools/client/debugger/src/actions/tests/helpers/readFixture.js b/devtools/client/debugger/src/actions/tests/helpers/readFixture.js new file mode 100644 index 0000000000..6c23641226 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/helpers/readFixture.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import fs from "fs"; +import path from "path"; + +export default function readFixture(name) { + const text = fs.readFileSync( + path.join(__dirname, `../fixtures/${name}`), + "utf8" + ); + return text; +} diff --git a/devtools/client/debugger/src/actions/tests/navigation.spec.js b/devtools/client/debugger/src/actions/tests/navigation.spec.js new file mode 100644 index 0000000000..e2572fde80 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/navigation.spec.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { createStore, selectors, actions } from "../../utils/test-head"; + +jest.mock("../../utils/editor"); + +const { getActiveSearch } = selectors; + +const threadFront = { + sourceContents: async () => ({ + source: "function foo1() {\n const foo = 5; return foo;\n}", + contentType: "text/javascript", + }), + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], +}; + +describe("navigation", () => { + it("navigation removes activeSearch 'file' value", async () => { + const { dispatch, getState } = createStore(threadFront); + dispatch(actions.setActiveSearch("file")); + expect(getActiveSearch(getState())).toBe("file"); + + await dispatch(actions.willNavigate("will-navigate")); + expect(getActiveSearch(getState())).toBe(null); + }); +}); diff --git a/devtools/client/debugger/src/actions/tests/pending-breakpoints.spec.js b/devtools/client/debugger/src/actions/tests/pending-breakpoints.spec.js new file mode 100644 index 0000000000..2baa17a79f --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/pending-breakpoints.spec.js @@ -0,0 +1,294 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// TODO: we would like to mock this in the local tests +import { + generateBreakpoint, + mockPendingBreakpoint, +} from "./helpers/breakpoints.js"; + +import { mockCommandClient } from "./helpers/mockCommandClient"; +import { asyncStore } from "../../utils/prefs"; + +function loadInitialState(opts = {}) { + const mockedPendingBreakpoint = mockPendingBreakpoint({ ...opts, column: 2 }); + const l = mockedPendingBreakpoint.location; + const id = `${l.sourceUrl}:${l.line}:${l.column}`; + asyncStore.pendingBreakpoints = { [id]: mockedPendingBreakpoint }; + + return { pendingBreakpoints: asyncStore.pendingBreakpoints }; +} + +jest.mock("../../utils/prefs", () => ({ + prefs: { + clientSourceMapsEnabled: true, + expressions: [], + }, + asyncStore: { + pendingBreakpoints: {}, + }, + clear: jest.fn(), + features: { + inlinePreview: true, + }, +})); + +import { + createStore, + selectors, + actions, + makeSource, + makeSourceURL, + waitForState, +} from "../../utils/test-head"; + +import sourceMapLoader from "devtools/client/shared/source-map-loader/index"; + +function mockClient(bpPos = {}) { + return { + ...mockCommandClient, + setSkipPausing: jest.fn(), + getSourceActorBreakpointPositions: async () => bpPos, + getSourceActorBreakableLines: async () => [], + }; +} + +function mockSourceMaps() { + return { + ...sourceMapLoader, + getOriginalSourceText: async id => ({ + id, + text: "", + contentType: "text/javascript", + }), + getGeneratedRangesForOriginal: async () => [ + { start: { line: 0, column: 0 }, end: { line: 10, column: 10 } }, + ], + getOriginalLocations: async items => items, + }; +} + +describe("when adding breakpoints", () => { + it("a corresponding pending breakpoint should be added", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1] }), + loadInitialState(), + mockSourceMaps() + ); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + const bp = generateBreakpoint("foo.js", 5, 1); + + await dispatch(actions.addBreakpoint(cx, bp.location)); + + expect(selectors.getPendingBreakpointList(getState())).toHaveLength(2); + }); +}); + +describe("initializing when pending breakpoints exist in prefs", () => { + it("syncs pending breakpoints", async () => { + const { getState } = createStore( + mockClient({ 5: [0] }), + loadInitialState(), + mockSourceMaps() + ); + const bps = selectors.getPendingBreakpoints(getState()); + expect(bps).toMatchSnapshot(); + }); + + it("re-adding breakpoints update existing pending breakpoints", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [1, 2] }), + loadInitialState(), + mockSourceMaps() + ); + const bar = generateBreakpoint("bar.js", 5, 1); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + await dispatch(actions.addBreakpoint(cx, bar.location)); + + const bps = selectors.getPendingBreakpointList(getState()); + expect(bps).toHaveLength(2); + }); + + it("adding bps doesn't remove existing pending breakpoints", async () => { + const { dispatch, getState, cx } = createStore( + mockClient({ 5: [0] }), + loadInitialState(), + mockSourceMaps() + ); + const bp = generateBreakpoint("foo.js"); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await dispatch(actions.addBreakpoint(cx, bp.location)); + + const bps = selectors.getPendingBreakpointList(getState()); + expect(bps).toHaveLength(2); + }); +}); + +describe("initializing with disabled pending breakpoints in prefs", () => { + it("syncs breakpoints with pending breakpoints", async () => { + const store = createStore( + mockClient({ 5: [2] }), + loadInitialState({ disabled: true }), + mockSourceMaps() + ); + + const { getState, dispatch, cx } = store; + + const source = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await waitForState(store, state => { + const bps = selectors.getBreakpointsForSource(state, source.id); + return bps && !!Object.values(bps).length; + }); + + const bp = selectors.getBreakpointsList(getState()).find(({ location }) => { + return ( + location.line == 5 && + location.column == 2 && + location.sourceId == source.id + ); + }); + + if (!bp) { + throw new Error("no bp"); + } + expect(bp.location.sourceId).toEqual(source.id); + expect(bp.disabled).toEqual(true); + }); +}); + +describe("adding sources", () => { + it("corresponding breakpoints are added for a single source", async () => { + const store = createStore( + mockClient({ 5: [2] }), + loadInitialState({ disabled: true }), + mockSourceMaps() + ); + const { getState, dispatch, cx } = store; + + expect(selectors.getBreakpointCount(getState())).toEqual(0); + + const source = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source.id + ); + + await dispatch(actions.loadGeneratedSourceText({ cx, sourceActor })); + + await waitForState(store, state => selectors.getBreakpointCount(state) > 0); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + }); + + it("corresponding breakpoints are added to the original source", async () => { + const sourceURL = makeSourceURL("bar.js"); + const store = createStore(mockClient({ 5: [2] }), loadInitialState(), { + getOriginalURLs: async source => [ + { + id: sourceMapLoader.generatedToOriginalId(source.id, sourceURL), + url: sourceURL, + }, + ], + getOriginalSourceText: async () => ({ text: "" }), + getGeneratedLocation: async location => location, + getOriginalLocation: async location => location, + getGeneratedRangesForOriginal: async () => [ + { start: { line: 0, column: 0 }, end: { line: 10, column: 10 } }, + ], + getOriginalLocations: async items => + items.map(item => ({ + ...item, + sourceId: sourceMapLoader.generatedToOriginalId( + item.sourceId, + sourceURL + ), + })), + }); + + const { getState, dispatch } = store; + + expect(selectors.getBreakpointCount(getState())).toEqual(0); + + await dispatch( + actions.newGeneratedSource(makeSource("bar.js", { sourceMapURL: "foo" })) + ); + + await waitForState(store, state => selectors.getBreakpointCount(state) > 0); + + expect(selectors.getBreakpointCount(getState())).toEqual(1); + }); + + it("add corresponding breakpoints for multiple sources", async () => { + const store = createStore( + mockClient({ 5: [2] }), + loadInitialState({ disabled: true }), + mockSourceMaps() + ); + const { getState, dispatch, cx } = store; + + expect(selectors.getBreakpointCount(getState())).toEqual(0); + + const [source1, source2] = await dispatch( + actions.newGeneratedSources([makeSource("bar.js"), makeSource("foo.js")]) + ); + const sourceActor1 = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source1.id + ); + const sourceActor2 = selectors.getFirstSourceActorForGeneratedSource( + getState(), + source2.id + ); + + await dispatch( + actions.loadGeneratedSourceText({ cx, sourceActor: sourceActor1 }) + ); + await dispatch( + actions.loadGeneratedSourceText({ cx, sourceActor: sourceActor2 }) + ); + + await waitForState(store, state => selectors.getBreakpointCount(state) > 0); + expect(selectors.getBreakpointCount(getState())).toEqual(1); + }); +}); diff --git a/devtools/client/debugger/src/actions/tests/preview.spec.js b/devtools/client/debugger/src/actions/tests/preview.spec.js new file mode 100644 index 0000000000..3b6c9c23ac --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/preview.spec.js @@ -0,0 +1,217 @@ +/* eslint max-nested-callbacks: ["error", 6] */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + createStore, + selectors, + actions, + makeSource, + makeFrame, + waitForState, + waitATick, +} from "../../utils/test-head"; +import { createLocation } from "../../utils/location"; + +function waitForPreview(store, expression) { + return waitForState(store, state => { + const preview = selectors.getPreview(state); + return preview && preview.expression == expression; + }); +} + +function mockThreadFront(overrides) { + return { + evaluate: async () => ({ result: {} }), + getFrameScopes: async () => {}, + getFrames: async () => [], + sourceContents: async () => ({ + source: "", + contentType: "text/javascript", + }), + getSourceActorBreakpointPositions: async () => ({}), + getSourceActorBreakableLines: async () => [], + evaluateExpressions: async () => [], + loadObjectProperties: async () => ({}), + ...overrides, + }; +} + +function dispatchSetPreview(dispatch, context, expression, target) { + return dispatch( + actions.setPreview( + context, + expression, + { + start: { url: "foo.js", line: 1, column: 2 }, + end: { url: "foo.js", line: 1, column: 5 }, + }, + { line: 2, column: 3 }, + target.getBoundingClientRect(), + target + ) + ); +} + +async function pause(store, client) { + const { dispatch, cx, getState } = store; + const source = makeSource("base.js"); + const base = await dispatch(actions.newGeneratedSource(source)); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + base.id + ); + + await dispatch(actions.selectSource(cx, base, sourceActor)); + const location = createLocation({ source: base, sourceActor }); + await waitForState(store, state => selectors.getSymbols(state, location)); + + const { thread } = cx; + const frames = [makeFrame({ id: "frame1", sourceId: base.id, thread })]; + client.getFrames = async () => frames; + + await dispatch( + actions.paused({ + thread, + frame: frames[0], + loadedObjects: [], + why: { type: "debuggerStatement" }, + }) + ); +} + +describe("preview", () => { + it("should generate previews", async () => { + const store = createStore(mockThreadFront()); + const { dispatch, getState, cx } = store; + const source = makeSource("base.js"); + const base = await dispatch(actions.newGeneratedSource(source)); + + await dispatch(actions.selectSource(cx, base)); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + base.id + ); + const location = createLocation({ source: base, sourceActor }); + + await waitForState(store, state => selectors.getSymbols(state, location)); + const frames = [makeFrame({ id: "f1", sourceId: base.id })]; + + await dispatch( + actions.paused({ + thread: store.cx.thread, + frame: frames[0], + frames, + loadedObjects: [], + why: { type: "debuggerStatement" }, + }) + ); + + const newCx = selectors.getContext(getState()); + const firstTarget = document.createElement("div"); + + dispatchSetPreview(dispatch, newCx, "foo", firstTarget); + + expect(selectors.getPreview(getState())).toMatchSnapshot(); + }); + + // When a 2nd setPreview is called before a 1st setPreview dispatches + // and the 2nd setPreview has not dispatched yet, + // the first setPreview should not finish dispatching + it("queued previews (w/ the 1st finishing first)", async () => { + let resolveFirst, resolveSecond; + const promises = [ + new Promise(resolve => { + resolveFirst = resolve; + }), + new Promise(resolve => { + resolveSecond = resolve; + }), + ]; + + const client = mockThreadFront({ + loadObjectProperties: () => promises.shift(), + }); + const store = createStore(client); + + const { dispatch, getState } = store; + await pause(store, client); + + const newCx = selectors.getContext(getState()); + const firstTarget = document.createElement("div"); + const secondTarget = document.createElement("div"); + + // Start the dispatch of the first setPreview. At this point, it will not + // finish execution until we resolve the firstSetPreview + dispatchSetPreview(dispatch, newCx, "firstSetPreview", firstTarget); + + // Start the dispatch of the second setPreview. At this point, it will not + // finish execution until we resolve the secondSetPreview + dispatchSetPreview(dispatch, newCx, "secondSetPreview", secondTarget); + + let fail = false; + + resolveFirst(); + waitForPreview(store, "firstSetPreview").then(() => { + fail = true; + }); + + resolveSecond(); + await waitForPreview(store, "secondSetPreview"); + expect(fail).toEqual(false); + + const preview = selectors.getPreview(getState()); + expect(preview && preview.expression).toEqual("secondSetPreview"); + }); + + // When a 2nd setPreview is called before a 1st setPreview dispatches + // and the 2nd setPreview has dispatched, + // the first setPreview should not finish dispatching + it("queued previews (w/ the 2nd finishing first)", async () => { + let resolveFirst, resolveSecond; + const promises = [ + new Promise(resolve => { + resolveFirst = resolve; + }), + new Promise(resolve => { + resolveSecond = resolve; + }), + ]; + + const client = mockThreadFront({ + loadObjectProperties: () => promises.shift(), + }); + const store = createStore(client); + + const { dispatch, getState } = store; + await pause(store, client); + + const cx = selectors.getThreadContext(getState()); + const firstTarget = document.createElement("div"); + const secondTarget = document.createElement("div"); + + // Start the dispatch of the first setPreview. At this point, it will not + // finish execution until we resolve the firstSetPreview + dispatchSetPreview(dispatch, cx, "firstSetPreview", firstTarget); + + // Start the dispatch of the second setPreview. At this point, it will not + // finish execution until we resolve the secondSetPreview + dispatchSetPreview(dispatch, cx, "secondSetPreview", secondTarget); + + let fail = false; + + resolveSecond(); + await waitForPreview(store, "secondSetPreview"); + + resolveFirst(); + waitForPreview(store, "firstSetPreview").then(() => { + fail = true; + }); + + await waitATick(() => expect(fail).toEqual(false)); + + const preview = selectors.getPreview(getState()); + expect(preview && preview.expression).toEqual("secondSetPreview"); + }); +}); diff --git a/devtools/client/debugger/src/actions/tests/sources-tree.spec.js b/devtools/client/debugger/src/actions/tests/sources-tree.spec.js new file mode 100644 index 0000000000..916b2d015b --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/sources-tree.spec.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { actions, selectors, createStore } from "../../utils/test-head"; +const { getExpandedState } = selectors; + +describe("source tree", () => { + it("should set the expanded state", () => { + const { dispatch, getState } = createStore(); + const expandedState = new Set(["foo", "bar"]); + + expect(getExpandedState(getState())).toEqual(new Set([])); + dispatch(actions.setExpandedState(expandedState)); + expect(getExpandedState(getState())).toEqual(expandedState); + }); +}); diff --git a/devtools/client/debugger/src/actions/tests/tabs.spec.js b/devtools/client/debugger/src/actions/tests/tabs.spec.js new file mode 100644 index 0000000000..419e5b7e60 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/tabs.spec.js @@ -0,0 +1,187 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + actions, + selectors, + createStore, + makeSource, +} from "../../utils/test-head"; +const { getSelectedSource, getSourceTabs } = selectors; +import { createLocation } from "../../utils/location"; + +import { mockCommandClient } from "./helpers/mockCommandClient"; + +describe("closing tabs", () => { + it("closing a tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + dispatch(actions.closeTab(cx, fooSource)); + + expect(getSelectedSource(getState())).toBe(undefined); + expect(getSourceTabs(getState())).toHaveLength(0); + }); + + it("closing the inactive tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const barSource = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: barSource, line: 1 })) + ); + dispatch(actions.closeTab(cx, fooSource)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("bar.js"); + expect(getSourceTabs(getState())).toHaveLength(1); + }); + + it("closing the only tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + dispatch(actions.closeTab(cx, fooSource)); + + expect(getSelectedSource(getState())).toBe(undefined); + expect(getSourceTabs(getState())).toHaveLength(0); + }); + + it("closing the active tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const barSource = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: barSource, line: 1 })) + ); + await dispatch(actions.closeTab(cx, barSource)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("foo.js"); + expect(getSourceTabs(getState())).toHaveLength(1); + }); + + it("closing many inactive tabs", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const barSource = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + const bazzSource = await dispatch( + actions.newGeneratedSource(makeSource("bazz.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: barSource, line: 1 })) + ); + await dispatch( + actions.selectLocation( + cx, + createLocation({ source: bazzSource, line: 1 }) + ) + ); + + const tabs = [ + "http://localhost:8000/examples/foo.js", + "http://localhost:8000/examples/bar.js", + ]; + dispatch(actions.closeTabs(cx, tabs)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("bazz.js"); + expect(getSourceTabs(getState())).toHaveLength(1); + }); + + it("closing many tabs including the active tab", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const barSource = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + const bazzSource = await dispatch( + actions.newGeneratedSource(makeSource("bazz.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: barSource, line: 1 })) + ); + await dispatch( + actions.selectLocation( + cx, + createLocation({ source: bazzSource, line: 1 }) + ) + ); + const tabs = [ + "http://localhost:8000/examples/bar.js", + "http://localhost:8000/examples/bazz.js", + ]; + await dispatch(actions.closeTabs(cx, tabs)); + + const selected = getSelectedSource(getState()); + expect(selected && selected.id).toBe("foo.js"); + expect(getSourceTabs(getState())).toHaveLength(1); + }); + + it("closing all the tabs", async () => { + const { dispatch, getState, cx } = createStore(mockCommandClient); + + const fooSource = await dispatch( + actions.newGeneratedSource(makeSource("foo.js")) + ); + const barSource = await dispatch( + actions.newGeneratedSource(makeSource("bar.js")) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: fooSource, line: 1 })) + ); + await dispatch( + actions.selectLocation(cx, createLocation({ source: barSource, line: 1 })) + ); + await dispatch( + actions.closeTabs(cx, [ + "http://localhost:8000/examples/foo.js", + "http://localhost:8000/examples/bar.js", + ]) + ); + + expect(getSelectedSource(getState())).toBe(undefined); + expect(getSourceTabs(getState())).toHaveLength(0); + }); +}); diff --git a/devtools/client/debugger/src/actions/tests/ui.spec.js b/devtools/client/debugger/src/actions/tests/ui.spec.js new file mode 100644 index 0000000000..0e13681a12 --- /dev/null +++ b/devtools/client/debugger/src/actions/tests/ui.spec.js @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + createStore, + selectors, + actions, + makeSource, +} from "../../utils/test-head"; +import { createLocation } from "../../utils/location"; +import { mockCommandClient } from "./helpers/mockCommandClient"; + +const { + getActiveSearch, + getFrameworkGroupingState, + getPaneCollapse, + getHighlightedLineRangeForSelectedSource, +} = selectors; + +describe("ui", () => { + it("should toggle the visible state of file search", () => { + const { dispatch, getState } = createStore(); + expect(getActiveSearch(getState())).toBe(null); + dispatch(actions.setActiveSearch("file")); + expect(getActiveSearch(getState())).toBe("file"); + }); + + it("should close file search", () => { + const { dispatch, getState } = createStore(); + expect(getActiveSearch(getState())).toBe(null); + dispatch(actions.setActiveSearch("file")); + dispatch(actions.closeActiveSearch()); + expect(getActiveSearch(getState())).toBe(null); + }); + + it("should toggle the collapse state of a pane", () => { + const { dispatch, getState } = createStore(); + expect(getPaneCollapse(getState(), "start")).toBe(false); + dispatch(actions.togglePaneCollapse("start", true)); + expect(getPaneCollapse(getState(), "start")).toBe(true); + }); + + it("should toggle the collapsed state of frameworks in the callstack", () => { + const { dispatch, getState } = createStore(); + const currentState = getFrameworkGroupingState(getState()); + dispatch(actions.toggleFrameworkGrouping(!currentState)); + expect(getFrameworkGroupingState(getState())).toBe(!currentState); + }); + + it("should highlight lines", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + const base = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + base.id + ); + const cx = selectors.getThreadContext(getState()); + //await dispatch(actions.selectSource(cx, base, sourceActor)); + const location = createLocation({ + source: base, + line: 1, + sourceActor, + }); + await dispatch(actions.selectLocation(cx, location)); + + const range = { start: 3, end: 5, sourceId: base.id }; + dispatch(actions.highlightLineRange(range)); + expect(getHighlightedLineRangeForSelectedSource(getState())).toEqual(range); + }); + + it("should clear highlight lines", async () => { + const { dispatch, getState } = createStore(mockCommandClient); + const base = await dispatch( + actions.newGeneratedSource(makeSource("base.js")) + ); + const sourceActor = selectors.getFirstSourceActorForGeneratedSource( + getState(), + base.id + ); + const cx = selectors.getThreadContext(getState()); + await dispatch(actions.selectSource(cx, base, sourceActor)); + const range = { start: 3, end: 5, sourceId: "2" }; + dispatch(actions.highlightLineRange(range)); + dispatch(actions.clearHighlightLineRange()); + expect(getHighlightedLineRangeForSelectedSource(getState())).toEqual(null); + }); +}); diff --git a/devtools/client/debugger/src/actions/threads.js b/devtools/client/debugger/src/actions/threads.js new file mode 100644 index 0000000000..13f53e7c67 --- /dev/null +++ b/devtools/client/debugger/src/actions/threads.js @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { createThread } from "../client/firefox/create"; +import { getSourcesToRemoveForThread } from "../selectors"; + +export function addTarget(targetFront) { + return { type: "INSERT_THREAD", newThread: createThread(targetFront) }; +} + +export function removeTarget(targetFront) { + return ({ getState, dispatch }) => { + const threadActorID = targetFront.targetForm.threadActor; + + // Just before emitting the REMOVE_THREAD action, + // synchronously compute the list of source and source actor objects + // which should be removed as that one target get removed. + // + // The list of source objects isn't trivial to compute as these objects + // are shared across targets/threads. + const { actors, sources } = getSourcesToRemoveForThread( + getState(), + threadActorID + ); + + dispatch({ + type: "REMOVE_THREAD", + threadActorID, + actors, + sources, + }); + }; +} + +export function toggleJavaScriptEnabled(enabled) { + return async ({ dispatch, client }) => { + await client.toggleJavaScriptEnabled(enabled); + dispatch({ + type: "TOGGLE_JAVASCRIPT_ENABLED", + value: enabled, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/toolbox.js b/devtools/client/debugger/src/actions/toolbox.js new file mode 100644 index 0000000000..a343c92863 --- /dev/null +++ b/devtools/client/debugger/src/actions/toolbox.js @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * @memberof actions/toolbox + * @static + */ +export function openLink(url) { + return async function ({ panel }) { + return panel.openLink(url); + }; +} + +export function evaluateInConsole(inputString) { + return async ({ panel }) => { + return panel.openConsoleAndEvaluate(inputString); + }; +} + +export function openElementInInspectorCommand(grip) { + return async ({ panel }) => { + return panel.openElementInInspector(grip); + }; +} + +export function openInspector(grip) { + return async ({ panel }) => { + return panel.openInspector(); + }; +} + +export function highlightDomElement(grip) { + return async ({ panel }) => { + return panel.highlightDomElement(grip); + }; +} + +export function unHighlightDomElement(grip) { + return async ({ panel }) => { + return panel.unHighlightDomElement(grip); + }; +} diff --git a/devtools/client/debugger/src/actions/tracing.js b/devtools/client/debugger/src/actions/tracing.js new file mode 100644 index 0000000000..9cbe7bc20e --- /dev/null +++ b/devtools/client/debugger/src/actions/tracing.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getIsThreadCurrentlyTracing, getAllThreads } from "../selectors"; +import { PROMISE } from "./utils/middleware/promise"; + +/** + * Toggle ON/OFF Javascript tracing for all targets, + * using the specified log method. + * + * @param {string} logMethod + * Can be "stdout" or "console". See TracerActor. + */ +export function toggleTracing(logMethod) { + return async ({ dispatch, getState, client, panel }) => { + // Check if any of the thread is currently tracing. + // For now, the UI can only toggle all the targets all at once. + const threads = getAllThreads(getState()); + const isTracingEnabled = threads.some(thread => + getIsThreadCurrentlyTracing(getState(), thread.actor) + ); + + // Automatically open the split console when enabling tracing to the console + if (!isTracingEnabled && logMethod == "console") { + await panel.toolbox.openSplitConsole({ focusConsoleInput: false }); + } + + return dispatch({ + type: "TOGGLE_TRACING", + [PROMISE]: isTracingEnabled + ? client.stopTracing() + : client.startTracing(logMethod), + }); + }; +} + +/** + * Called when tracing is toggled ON/OFF on a particular thread. + */ +export function tracingToggled(thread, enabled) { + return ({ dispatch }) => { + dispatch({ + type: "TRACING_TOGGLED", + thread, + enabled, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/ui.js b/devtools/client/debugger/src/actions/ui.js new file mode 100644 index 0000000000..67b2629135 --- /dev/null +++ b/devtools/client/debugger/src/actions/ui.js @@ -0,0 +1,290 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + getActiveSearch, + getPaneCollapse, + getQuickOpenEnabled, + getSource, + getSourceContent, + getMainThread, + getIgnoreListSourceUrls, + getSourceByURL, + getBreakpointsForSource, +} from "../selectors"; +import { selectSource } from "../actions/sources/select"; +import { + getEditor, + getLocationsInViewport, + updateDocuments, +} from "../utils/editor"; +import { blackboxSourceActorsForSource } from "./sources/blackbox"; +import { toggleBreakpoints } from "./breakpoints"; +import { copyToTheClipboard } from "../utils/clipboard"; +import { isFulfilled } from "../utils/async-value"; +import { primaryPaneTabs } from "../constants"; + +export function setPrimaryPaneTab(tabName) { + return { type: "SET_PRIMARY_PANE_TAB", tabName }; +} + +export function closeActiveSearch() { + return { + type: "TOGGLE_ACTIVE_SEARCH", + value: null, + }; +} + +export function setActiveSearch(activeSearch) { + return ({ dispatch, getState }) => { + const activeSearchState = getActiveSearch(getState()); + if (activeSearchState === activeSearch) { + return; + } + + if (getQuickOpenEnabled(getState())) { + dispatch({ type: "CLOSE_QUICK_OPEN" }); + } + + // Open start panel if it was collapsed so the project search UI is visible + if ( + activeSearch === primaryPaneTabs.PROJECT_SEARCH && + getPaneCollapse(getState(), "start") + ) { + dispatch({ + type: "TOGGLE_PANE", + position: "start", + paneCollapsed: false, + }); + } + + dispatch({ + type: "TOGGLE_ACTIVE_SEARCH", + value: activeSearch, + }); + }; +} + +export function toggleFrameworkGrouping(toggleValue) { + return ({ dispatch, getState }) => { + dispatch({ + type: "TOGGLE_FRAMEWORK_GROUPING", + value: toggleValue, + }); + }; +} + +export function toggleInlinePreview(toggleValue) { + return ({ dispatch, getState }) => { + dispatch({ + type: "TOGGLE_INLINE_PREVIEW", + value: toggleValue, + }); + }; +} + +export function toggleEditorWrapping(toggleValue) { + return ({ dispatch, getState }) => { + updateDocuments(doc => doc.cm.setOption("lineWrapping", toggleValue)); + + dispatch({ + type: "TOGGLE_EDITOR_WRAPPING", + value: toggleValue, + }); + }; +} + +export function toggleSourceMapsEnabled(toggleValue) { + return ({ dispatch, getState }) => { + dispatch({ + type: "TOGGLE_SOURCE_MAPS_ENABLED", + value: toggleValue, + }); + }; +} + +export function showSource(cx, sourceId) { + return ({ dispatch, getState }) => { + const source = getSource(getState(), sourceId); + if (!source) { + return; + } + + if (getPaneCollapse(getState(), "start")) { + dispatch({ + type: "TOGGLE_PANE", + position: "start", + paneCollapsed: false, + }); + } + + dispatch(setPrimaryPaneTab("sources")); + + dispatch(selectSource(cx, source)); + }; +} + +export function togglePaneCollapse(position, paneCollapsed) { + return ({ dispatch, getState }) => { + const prevPaneCollapse = getPaneCollapse(getState(), position); + if (prevPaneCollapse === paneCollapsed) { + return; + } + + // Set active search to null when closing start panel if project search was active + if ( + position === "start" && + paneCollapsed && + getActiveSearch(getState()) === primaryPaneTabs.PROJECT_SEARCH + ) { + dispatch(closeActiveSearch()); + } + + dispatch({ + type: "TOGGLE_PANE", + position, + paneCollapsed, + }); + }; +} + +/** + * Highlight one or many lines in CodeMirror for a given source. + * + * @param {Object} location + * @param {String} location.sourceId + * The precise source to highlight. + * @param {Number} location.start + * The 1-based index of first line to highlight. + * @param {Number} location.end + * The 1-based index of last line to highlight. + */ +export function highlightLineRange(location) { + return { + type: "HIGHLIGHT_LINES", + location, + }; +} + +export function flashLineRange(location) { + return ({ dispatch }) => { + dispatch(highlightLineRange(location)); + setTimeout(() => dispatch(clearHighlightLineRange()), 200); + }; +} + +export function clearHighlightLineRange() { + return { + type: "CLEAR_HIGHLIGHT_LINES", + }; +} + +export function openConditionalPanel(location, log = false) { + if (!location) { + return null; + } + + return { + type: "OPEN_CONDITIONAL_PANEL", + location, + log, + }; +} + +export function closeConditionalPanel() { + return { + type: "CLOSE_CONDITIONAL_PANEL", + }; +} + +export function clearProjectDirectoryRoot(cx) { + return { + type: "SET_PROJECT_DIRECTORY_ROOT", + cx, + url: "", + name: "", + }; +} + +export function setProjectDirectoryRoot(cx, newRoot, newName) { + return ({ dispatch, getState }) => { + // If the new project root is against the top level thread, + // replace its thread ID with "top-level", so that later, + // getDirectoryForUniquePath could match the project root, + // even after a page reload where the new top level thread actor ID + // will be different. + const mainThread = getMainThread(getState()); + if (mainThread && newRoot.startsWith(mainThread.actor)) { + newRoot = newRoot.replace(mainThread.actor, "top-level"); + } + dispatch({ + type: "SET_PROJECT_DIRECTORY_ROOT", + cx, + url: newRoot, + name: newName, + }); + }; +} + +export function updateViewport() { + return { + type: "SET_VIEWPORT", + viewport: getLocationsInViewport(getEditor()), + }; +} + +export function updateCursorPosition(cursorPosition) { + return { type: "SET_CURSOR_POSITION", cursorPosition }; +} + +export function setOrientation(orientation) { + return { type: "SET_ORIENTATION", orientation }; +} + +export function setSearchOptions(searchKey, searchOptions) { + return { type: "SET_SEARCH_OPTIONS", searchKey, searchOptions }; +} + +export function copyToClipboard(location) { + return ({ dispatch, getState }) => { + const content = getSourceContent(getState(), location); + if (content && isFulfilled(content) && content.value.type === "text") { + copyToTheClipboard(content.value.value); + } + }; +} + +export function setJavascriptTracingLogMethod(value) { + return ({ dispatch, getState }) => { + dispatch({ + type: "SET_JAVASCRIPT_TRACING_LOG_METHOD", + value, + }); + }; +} + +export function setHideOrShowIgnoredSources(shouldHide) { + return ({ dispatch, getState }) => { + dispatch({ type: "HIDE_IGNORED_SOURCES", shouldHide }); + }; +} + +export function toggleSourceMapIgnoreList(cx, shouldEnable) { + return async thunkArgs => { + const { dispatch, getState } = thunkArgs; + const ignoreListSourceUrls = getIgnoreListSourceUrls(getState()); + // Blackbox the source actors on the server + for (const url of ignoreListSourceUrls) { + const source = getSourceByURL(getState(), url); + await blackboxSourceActorsForSource(thunkArgs, source, shouldEnable); + // Disable breakpoints in sources on the ignore list + const breakpoints = getBreakpointsForSource(getState(), source.id); + await dispatch(toggleBreakpoints(cx, shouldEnable, breakpoints)); + } + await dispatch({ + type: "ENABLE_SOURCEMAP_IGNORELIST", + shouldEnable, + }); + }; +} diff --git a/devtools/client/debugger/src/actions/utils/create-store.js b/devtools/client/debugger/src/actions/utils/create-store.js new file mode 100644 index 0000000000..9527c67afc --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/create-store.js @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* global window */ + +/** + * Redux store utils + * @module utils/create-store + */ + +import { createStore, applyMiddleware } from "redux"; +import { waitUntilService } from "./middleware/wait-service"; +import { log } from "./middleware/log"; +import { promise } from "./middleware/promise"; +import { thunk } from "./middleware/thunk"; +import { timing } from "./middleware/timing"; +import { context } from "./middleware/context"; + +/** + * @memberof utils/create-store + * @static + */ + +/** + * This creates a dispatcher with all the standard middleware in place + * that all code requires. It can also be optionally configured in + * various ways, such as logging and recording. + * + * @param {object} opts: + * - log: log all dispatched actions to console + * - history: an array to store every action in. Should only be + * used in tests. + * - middleware: array of middleware to be included in the redux store + * @memberof utils/create-store + * @static + */ +const configureStore = (opts = {}) => { + const middleware = [ + thunk(opts.makeThunkArgs), + context, + promise, + + // Order is important: services must go last as they always + // operate on "already transformed" actions. Actions going through + // them shouldn't have any special fields like promises, they + // should just be normal JSON objects. + waitUntilService, + ]; + + if (opts.middleware) { + opts.middleware.forEach(fn => middleware.push(fn)); + } + + if (opts.log) { + middleware.push(log); + } + + if (opts.timing) { + middleware.push(timing); + } + + // Hook in the redux devtools browser extension if it exists + const devtoolsExt = + typeof window === "object" && window.devToolsExtension + ? window.devToolsExtension() + : f => f; + + return applyMiddleware(...middleware)(devtoolsExt(createStore)); +}; + +export default configureStore; diff --git a/devtools/client/debugger/src/actions/utils/middleware/context.js b/devtools/client/debugger/src/actions/utils/middleware/context.js new file mode 100644 index 0000000000..ebadaa4eff --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/context.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { + validateNavigateContext, + validateContext, +} from "../../../utils/context"; + +function validateActionContext(getState, action) { + if (action.type == "COMMAND" && action.status == "done") { + // The thread will have resumed execution since the action was initiated, + // so just make sure we haven't navigated. + validateNavigateContext(getState(), action.cx); + return; + } + + // Validate using all available information in the context. + validateContext(getState(), action.cx); +} + +// Middleware which looks for actions that have a cx property and ignores +// them if the context is no longer valid. +function context({ dispatch, getState }) { + return next => action => { + if ("cx" in action) { + validateActionContext(getState, action); + } + return next(action); + }; +} + +export { context }; diff --git a/devtools/client/debugger/src/actions/utils/middleware/log.js b/devtools/client/debugger/src/actions/utils/middleware/log.js new file mode 100644 index 0000000000..b9592ce22c --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/log.js @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import flags from "devtools/shared/flags"; +import { prefs } from "../../../utils/prefs"; + +const ignoreList = [ + "ADD_BREAKPOINT_POSITIONS", + "SET_SYMBOLS", + "OUT_OF_SCOPE_LOCATIONS", + "MAP_SCOPES", + "MAP_FRAMES", + "ADD_SCOPES", + "IN_SCOPE_LINES", + "REMOVE_BREAKPOINT", + "NODE_PROPERTIES_LOADED", + "SET_FOCUSED_SOURCE_ITEM", + "NODE_EXPAND", + "IN_SCOPE_LINES", + "SET_PREVIEW", +]; + +function cloneAction(action) { + action = action || {}; + action = { ...action }; + + // ADD_TAB, ... + if (action.source?.text) { + const source = { ...action.source, text: "" }; + action.source = source; + } + + if (action.sources) { + const sources = action.sources.slice(0, 20).map(source => { + const url = !source.url || source.url.includes("data:") ? "" : source.url; + return { ...source, url }; + }); + action.sources = sources; + } + + // LOAD_SOURCE_TEXT + if (action.text) { + action.text = ""; + } + + if (action.value?.text) { + const value = { ...action.value, text: "" }; + action.value = value; + } + + return action; +} + +function formatPause(pause) { + return { + ...pause, + pauseInfo: { why: pause.why }, + scopes: [], + loadedObjects: [], + }; +} + +function serializeAction(action) { + try { + action = cloneAction(action); + if (ignoreList.includes(action.type)) { + action = {}; + } + + if (action.type === "PAUSED") { + action = formatPause(action); + } + + const serializer = function (key, value) { + // Serialize Object/LongString fronts + if (value?.getGrip) { + return value.getGrip(); + } + return value; + }; + + // dump(`> ${action.type}...\n ${JSON.stringify(action, serializer)}\n`); + return JSON.stringify(action, serializer); + } catch (e) { + console.error(e); + return ""; + } +} + +/** + * A middleware that logs all actions coming through the system + * to the console. + */ +export function log({ dispatch, getState }) { + return next => action => { + const asyncMsg = !action.status ? "" : `[${action.status}]`; + + if (prefs.logActions) { + if (flags.testing) { + dump( + `[ACTION] ${action.type} ${asyncMsg} - ${serializeAction(action)}\n` + ); + } else { + console.log(action, asyncMsg); + } + } + + next(action); + }; +} diff --git a/devtools/client/debugger/src/actions/utils/middleware/moz.build b/devtools/client/debugger/src/actions/utils/middleware/moz.build new file mode 100644 index 0000000000..f46a0bb725 --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/moz.build @@ -0,0 +1,15 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "context.js", + "log.js", + "promise.js", + "thunk.js", + "timing.js", + "wait-service.js", +) diff --git a/devtools/client/debugger/src/actions/utils/middleware/promise.js b/devtools/client/debugger/src/actions/utils/middleware/promise.js new file mode 100644 index 0000000000..52054a1fcc --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/promise.js @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { executeSoon } from "../../../utils/DevToolsUtils"; + +import { pending, rejected, fulfilled } from "../../../utils/async-value"; +export function asyncActionAsValue(action) { + if (action.status === "start") { + return pending(); + } + if (action.status === "error") { + return rejected(action.error); + } + return fulfilled(action.value); +} + +let seqIdVal = 1; + +function seqIdGen() { + return seqIdVal++; +} + +function promiseMiddleware({ dispatch, getState }) { + return next => action => { + if (!(PROMISE in action)) { + return next(action); + } + + const seqId = seqIdGen().toString(); + const { [PROMISE]: promiseInst, ...originalActionProperties } = action; + + // Create a new action that doesn't have the promise field and has + // the `seqId` field that represents the sequence id + action = { ...originalActionProperties, seqId }; + + dispatch({ ...action, status: "start" }); + + // Return the promise so action creators can still compose if they + // want to. + return Promise.resolve(promiseInst) + .finally(() => new Promise(resolve => executeSoon(resolve))) + .then( + value => { + dispatch({ ...action, status: "done", value: value }); + return value; + }, + error => { + dispatch({ + ...action, + status: "error", + error: error.message || error, + }); + return Promise.reject(error); + } + ); + }; +} + +export const PROMISE = "@@dispatch/promise"; +export { promiseMiddleware as promise }; diff --git a/devtools/client/debugger/src/actions/utils/middleware/thunk.js b/devtools/client/debugger/src/actions/utils/middleware/thunk.js new file mode 100644 index 0000000000..fba17d516c --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/thunk.js @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * A middleware that allows thunks (functions) to be dispatched. If + * it's a thunk, it is called with an argument that contains + * `dispatch`, `getState`, and any additional args passed in via the + * middleware constructure. This allows the action to create multiple + * actions (most likely asynchronously). + */ +export function thunk(makeArgs) { + return ({ dispatch, getState }) => { + const args = { dispatch, getState }; + + return next => action => { + return typeof action === "function" + ? action(makeArgs ? makeArgs(args, getState()) : args) + : next(action); + }; + }; +} diff --git a/devtools/client/debugger/src/actions/utils/middleware/timing.js b/devtools/client/debugger/src/actions/utils/middleware/timing.js new file mode 100644 index 0000000000..d0bfa05977 --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/timing.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Redux middleware that sets performance markers for all actions such that they + * will appear in performance tooling under the User Timing API + */ + +const mark = window.performance?.mark + ? window.performance.mark.bind(window.performance) + : a => {}; + +const measure = window.performance?.measure + ? window.performance.measure.bind(window.performance) + : (a, b, c) => {}; + +export function timing(store) { + return next => action => { + mark(`${action.type}_start`); + const result = next(action); + mark(`${action.type}_end`); + measure(`${action.type}`, `${action.type}_start`, `${action.type}_end`); + return result; + }; +} diff --git a/devtools/client/debugger/src/actions/utils/middleware/wait-service.js b/devtools/client/debugger/src/actions/utils/middleware/wait-service.js new file mode 100644 index 0000000000..337df7e336 --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/middleware/wait-service.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * A middleware which acts like a service, because it is stateful + * and "long-running" in the background. It provides the ability + * for actions to install a function to be run once when a specific + * condition is met by an action coming through the system. Think of + * it as a thunk that blocks until the condition is met. Example: + * + * ```js + * const services = { WAIT_UNTIL: require('wait-service').NAME }; + * + * { type: services.WAIT_UNTIL, + * predicate: action => action.type === "ADD_ITEM", + * run: (dispatch, getState, action) => { + * // Do anything here. You only need to accept the arguments + * // if you need them. `action` is the action that satisfied + * // the predicate. + * } + * } + * ``` + */ +export const NAME = "@@service/waitUntil"; + +export function waitUntilService({ dispatch, getState }) { + let pending = []; + + function checkPending(action) { + const readyRequests = []; + const stillPending = []; + + // Find the pending requests whose predicates are satisfied with + // this action. Wait to run the requests until after we update the + // pending queue because the request handler may synchronously + // dispatch again and run this service (that use case is + // completely valid). + for (const request of pending) { + if (request.predicate(action)) { + readyRequests.push(request); + } else { + stillPending.push(request); + } + } + + pending = stillPending; + for (const request of readyRequests) { + request.run(dispatch, getState, action); + } + } + + return next => action => { + if (action.type === NAME) { + pending.push(action); + return null; + } + const result = next(action); + checkPending(action); + return result; + }; +} diff --git a/devtools/client/debugger/src/actions/utils/moz.build b/devtools/client/debugger/src/actions/utils/moz.build new file mode 100644 index 0000000000..08a43a218c --- /dev/null +++ b/devtools/client/debugger/src/actions/utils/moz.build @@ -0,0 +1,12 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [ + "middleware", +] + +CompiledModules( + "create-store.js", +) diff --git a/devtools/client/debugger/src/client/README.md b/devtools/client/debugger/src/client/README.md new file mode 100644 index 0000000000..4681a4e15e --- /dev/null +++ b/devtools/client/debugger/src/client/README.md @@ -0,0 +1,47 @@ +# DevTools Client + +The DevTools client is responsible for managing the communication between the +client application and JS server. + +- When the server sends a notification to the client, the client receives an + "event" and notifies the application via redux actions. +- When the application, wants to send a command to the server, it invokes + "commands" in the client. + +The Debugger supports a Firefox and a Chrome client, which lets it attach and +debug Firefox, Chrome, and Node contexts. The clients are defined in +`src/client` and have an `onConnect` function, and a `commands` and `events` +module. + +Both clients implement client adapters for translating commands and events into +JSON packets. The chrome client debugger adapter is defined in +[chrome-remote-interface][chrome-remote-interface]. The Firefox client is maintained in +[devtools-client.js][devtools-client.js]. + +## Firefox + +### Remote Debugger Protocol + +The [Remote Debugger Protocol][protocol] specifies the client / server API. + +### Interrupt + +When the client wants to add a breakpoint, it avoids race conditions by doing +temporary pauses called interrupts. + +We want to do these interrupts transparently, so we've decided that the client +should not notify the application that the thread has been paused or resumed. + +[protocol]: https://searchfox.org/mozilla-central/source/devtools/docs/backend/protocol.md +[devtools-client.js]: https://searchfox.org/mozilla-central/source/devtools/client/devtools-client.js + +## Chrome + +### Chrome Debugger Protocol + +The chrome debugger protocol is available [here][devtools-protocol-viewer]. And +is maintained in the devtools-protocol [repo][devtools-protocol-gh]. + +[chrome-remote-interface]: https://github.com/cyrus-and/chrome-remote-interface +[devtools-protocol-viewer]: https://chromedevtools.github.io/devtools-protocol/ +[devtools-protocol-gh]: https://github.com/ChromeDevTools/devtools-protocol diff --git a/devtools/client/debugger/src/client/firefox.js b/devtools/client/debugger/src/client/firefox.js new file mode 100644 index 0000000000..d66d168e37 --- /dev/null +++ b/devtools/client/debugger/src/client/firefox.js @@ -0,0 +1,215 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { setupCommands, clientCommands } from "./firefox/commands"; +import { setupCreate, createPause } from "./firefox/create"; +import { features } from "../utils/prefs"; + +import { recordEvent } from "../utils/telemetry"; +import sourceQueue from "../utils/source-queue"; +import { getContext } from "../selectors"; + +let actions; +let commands; +let targetCommand; +let resourceCommand; + +export async function onConnect(_commands, _resourceCommand, _actions, store) { + actions = _actions; + commands = _commands; + targetCommand = _commands.targetCommand; + resourceCommand = _resourceCommand; + + setupCommands(commands); + setupCreate({ store }); + + sourceQueue.initialize(actions); + + const { descriptorFront } = commands; + const { targetFront } = targetCommand; + + // For tab, browser and webextension toolboxes, we want to enable watching for + // worker targets as soon as the debugger is opened. + // And also for service workers, if the related experimental feature is enabled + if ( + descriptorFront.isTabDescriptor || + descriptorFront.isWebExtensionDescriptor || + descriptorFront.isBrowserProcessDescriptor + ) { + targetCommand.listenForWorkers = true; + if (descriptorFront.isLocalTab && features.windowlessServiceWorkers) { + targetCommand.listenForServiceWorkers = true; + targetCommand.destroyServiceWorkersOnNavigation = true; + } + await targetCommand.startListening(); + } + + const options = { + // `pauseWorkersUntilAttach` is one option set when the debugger panel is opened rather that from the toolbox. + // The reason is to support early breakpoints in workers, which will force the workers to pause + // and later on (when TargetMixin.attachThread is called) resume worker execution, after passing the breakpoints. + // We only observe workers when the debugger panel is opened (see the few lines before and listenForWorkers = true). + // So if we were passing `pauseWorkersUntilAttach=true` from the toolbox code, workers would freeze as we would not watch + // for their targets and not resume them. + pauseWorkersUntilAttach: true, + + // Bug 1719615 - Immediately turn on WASM debugging when the debugger opens. + // We avoid enabling that as soon as DevTools open as WASM generates different kind of machine code + // with debugging instruction which significantly increase the memory usage. + observeWasm: true, + }; + await commands.threadConfigurationCommand.updateConfiguration(options); + + // Select the top level target by default + await actions.selectThread( + getContext(store.getState()), + targetFront.threadFront.actor + ); + + await targetCommand.watchTargets({ + types: targetCommand.ALL_TYPES, + onAvailable: onTargetAvailable, + onDestroyed: onTargetDestroyed, + }); + + // Use independant listeners for SOURCE and THREAD_STATE in order to ease + // doing batching and notify about a set of SOURCE's in one redux action. + await resourceCommand.watchResources([resourceCommand.TYPES.SOURCE], { + onAvailable: onSourceAvailable, + }); + await resourceCommand.watchResources([resourceCommand.TYPES.THREAD_STATE], { + onAvailable: onThreadStateAvailable, + }); + await resourceCommand.watchResources([resourceCommand.TYPES.TRACING_STATE], { + onAvailable: onTracingStateAvailable, + }); + + await resourceCommand.watchResources([resourceCommand.TYPES.ERROR_MESSAGE], { + onAvailable: actions.addExceptionFromResources, + }); + await resourceCommand.watchResources([resourceCommand.TYPES.DOCUMENT_EVENT], { + onAvailable: onDocumentEventAvailable, + // we only care about future events for DOCUMENT_EVENT + ignoreExistingResources: true, + }); +} + +export function onDisconnect() { + targetCommand.unwatchTargets({ + types: targetCommand.ALL_TYPES, + onAvailable: onTargetAvailable, + onDestroyed: onTargetDestroyed, + }); + resourceCommand.unwatchResources([resourceCommand.TYPES.SOURCE], { + onAvailable: onSourceAvailable, + }); + resourceCommand.unwatchResources([resourceCommand.TYPES.THREAD_STATE], { + onAvailable: onThreadStateAvailable, + }); + resourceCommand.unwatchResources([resourceCommand.TYPES.TRACING_STATE], { + onAvailable: onTracingStateAvailable, + }); + resourceCommand.unwatchResources([resourceCommand.TYPES.ERROR_MESSAGE], { + onAvailable: actions.addExceptionFromResources, + }); + resourceCommand.unwatchResources([resourceCommand.TYPES.DOCUMENT_EVENT], { + onAvailable: onDocumentEventAvailable, + }); + sourceQueue.clear(); +} + +async function onTargetAvailable({ targetFront, isTargetSwitching }) { + const isBrowserToolbox = commands.descriptorFront.isBrowserProcessDescriptor; + const isNonTopLevelFrameTarget = + !targetFront.isTopLevel && + targetFront.targetType === targetCommand.TYPES.FRAME; + + if (isBrowserToolbox && isNonTopLevelFrameTarget) { + // In the BrowserToolbox, non-top-level frame targets are already + // debugged via content-process targets. + // Do not attach the thread here, as it was already done by the + // corresponding content-process target. + return; + } + + if (!targetFront.isTopLevel) { + await actions.addTarget(targetFront); + return; + } + + // At this point, we expect the target and its thread to be attached. + const { threadFront } = targetFront; + if (!threadFront) { + console.error("The thread for", targetFront, "isn't attached."); + return; + } + + // Retrieve possible event listener breakpoints + actions.getEventListenerBreakpointTypes().catch(e => console.error(e)); + + // Initialize the event breakpoints on the thread up front so that + // they are active once attached. + actions.addEventListenerBreakpoints([]).catch(e => console.error(e)); + + await actions.addTarget(targetFront); +} + +function onTargetDestroyed({ targetFront }) { + actions.removeTarget(targetFront); +} + +async function onSourceAvailable(sources) { + await actions.newGeneratedSources(sources); +} + +async function onThreadStateAvailable(resources) { + for (const resource of resources) { + if (resource.targetFront.isDestroyed()) { + continue; + } + const threadFront = await resource.targetFront.getFront("thread"); + if (resource.state == "paused") { + const pause = await createPause(threadFront.actor, resource); + await actions.paused(pause); + recordEvent("pause", { reason: resource.why.type }); + } else if (resource.state == "resumed") { + await actions.resumed(threadFront.actorID); + } + } +} + +async function onTracingStateAvailable(resources) { + for (const resource of resources) { + if (resource.targetFront.isDestroyed()) { + continue; + } + const threadFront = await resource.targetFront.getFront("thread"); + await actions.tracingToggled(threadFront.actor, resource.enabled); + } +} + +function onDocumentEventAvailable(events) { + for (const event of events) { + // Only consider top level document, and ignore remote iframes top document + if (!event.targetFront.isTopLevel) continue; + // The browser toolbox debugger doesn't support the iframe dropdown. + // you will always see all the sources of all targets of your debugging context. + // + // But still allow it to clear the debugger when reloading the addon, or when + // switching between fallback document and other addon document. + if ( + event.isFrameSwitching && + !commands.descriptorFront.isWebExtensionDescriptor + ) { + continue; + } + if (event.name == "will-navigate") { + actions.willNavigate({ url: event.newURI }); + } else if (event.name == "dom-complete") { + actions.navigated(); + } + } +} + +export { clientCommands }; diff --git a/devtools/client/debugger/src/client/firefox/commands.js b/devtools/client/debugger/src/client/firefox/commands.js new file mode 100644 index 0000000000..06f9d73854 --- /dev/null +++ b/devtools/client/debugger/src/client/firefox/commands.js @@ -0,0 +1,537 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { createFrame } from "./create"; +import { makeBreakpointServerLocationId } from "../../utils/breakpoint"; + +import Reps from "devtools/client/shared/components/reps/index"; + +let commands; +let breakpoints; + +// The maximal number of stackframes to retrieve when pausing +const CALL_STACK_PAGE_SIZE = 1000; + +function setupCommands(innerCommands) { + commands = innerCommands; + breakpoints = {}; +} + +function currentTarget() { + return commands.targetCommand.targetFront; +} + +function currentThreadFront() { + return currentTarget().threadFront; +} + +/** + * Create an object front for the passed grip + * + * @param {Object} grip + * @param {Object} frame: An optional frame that will manage the created object front. + * if not passed, the current thread front will manage the object. + * @returns {ObjectFront} + */ +function createObjectFront(grip, frame) { + if (!grip.actor) { + throw new Error("Actor is missing"); + } + const threadFront = frame?.thread + ? lookupThreadFront(frame.thread) + : currentThreadFront(); + const frameFront = frame ? threadFront.getActorByID(frame.id) : null; + return commands.client.createObjectFront(grip, threadFront, frameFront); +} + +async function loadObjectProperties(root, threadActorID) { + const { utils } = Reps.objectInspector; + const properties = await utils.loadProperties.loadItemProperties( + root, + commands.client, + undefined, + threadActorID + ); + return utils.node.getChildren({ + item: root, + loadedProperties: new Map([[root.path, properties]]), + }); +} + +function releaseActor(actor) { + if (!actor) { + return Promise.resolve(); + } + const objFront = commands.client.getFrontByID(actor); + + if (!objFront) { + return Promise.resolve(); + } + + return objFront.release().catch(() => {}); +} + +function lookupTarget(thread) { + if (thread == currentThreadFront().actor) { + return currentTarget(); + } + + const targets = commands.targetCommand.getAllTargets( + commands.targetCommand.ALL_TYPES + ); + return targets.find(target => target.targetForm.threadActor == thread); +} + +function lookupThreadFront(thread) { + const target = lookupTarget(thread); + return target.threadFront; +} + +function listThreadFronts() { + const targets = commands.targetCommand.getAllTargets( + commands.targetCommand.ALL_TYPES + ); + return targets.map(target => target.threadFront).filter(front => !!front); +} + +function forEachThread(iteratee) { + // We have to be careful here to atomically initiate the operation on every + // thread, with no intervening await. Otherwise, other code could run and + // trigger additional thread operations. Requests on server threads will + // resolve in FIFO order, and this could result in client and server state + // going out of sync. + + const promises = listThreadFronts().map( + // If a thread shuts down while sending the message then it will + // throw. Ignore these exceptions. + t => iteratee(t).catch(e => console.log(e)) + ); + + return Promise.all(promises); +} + +/** + * Start JavaScript tracing for all targets. + * + * @param {String} logMethod + * Where to log the traces. Can be stdout or console. + */ +async function startTracing(logMethod) { + const targets = commands.targetCommand.getAllTargets( + commands.targetCommand.ALL_TYPES + ); + await Promise.all( + targets.map(async targetFront => { + const tracerFront = await targetFront.getFront("tracer"); + return tracerFront.startTracing(logMethod); + }) + ); +} + +/** + * Stop JavaScript tracing for all targets. + */ +async function stopTracing() { + const targets = commands.targetCommand.getAllTargets( + commands.targetCommand.ALL_TYPES + ); + await Promise.all( + targets.map(async targetFront => { + const tracerFront = await targetFront.getFront("tracer"); + return tracerFront.stopTracing(); + }) + ); +} + +function resume(thread, frameId) { + return lookupThreadFront(thread).resume(); +} + +function stepIn(thread, frameId) { + return lookupThreadFront(thread).stepIn(frameId); +} + +function stepOver(thread, frameId) { + return lookupThreadFront(thread).stepOver(frameId); +} + +function stepOut(thread, frameId) { + return lookupThreadFront(thread).stepOut(frameId); +} + +function restart(thread, frameId) { + return lookupThreadFront(thread).restart(frameId); +} + +function breakOnNext(thread) { + return lookupThreadFront(thread).breakOnNext(); +} + +async function sourceContents({ actor, thread }) { + const sourceThreadFront = lookupThreadFront(thread); + const sourceFront = sourceThreadFront.source({ actor }); + const { source, contentType } = await sourceFront.source(); + return { source, contentType }; +} + +async function setXHRBreakpoint(path, method) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (!hasWatcherSupport) { + // Without watcher support, forward setXHRBreakpoint to all threads. + await forEachThread(thread => thread.setXHRBreakpoint(path, method)); + return; + } + const breakpointsFront = + await commands.targetCommand.watcherFront.getBreakpointListActor(); + await breakpointsFront.setXHRBreakpoint(path, method); +} + +async function removeXHRBreakpoint(path, method) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (!hasWatcherSupport) { + // Without watcher support, forward removeXHRBreakpoint to all threads. + await forEachThread(thread => thread.removeXHRBreakpoint(path, method)); + return; + } + const breakpointsFront = + await commands.targetCommand.watcherFront.getBreakpointListActor(); + await breakpointsFront.removeXHRBreakpoint(path, method); +} + +export function toggleJavaScriptEnabled(enabled) { + return commands.targetConfigurationCommand.updateConfiguration({ + javascriptEnabled: enabled, + }); +} + +async function addWatchpoint(object, property, label, watchpointType) { + if (!currentTarget().getTrait("watchpoints")) { + return; + } + const objectFront = createObjectFront(object); + await objectFront.addWatchpoint(property, label, watchpointType); +} + +async function removeWatchpoint(object, property) { + if (!currentTarget().getTrait("watchpoints")) { + return; + } + const objectFront = createObjectFront(object); + await objectFront.removeWatchpoint(property); +} + +function hasBreakpoint(location) { + return !!breakpoints[makeBreakpointServerLocationId(location)]; +} + +function getServerBreakpointsList() { + return Object.values(breakpoints); +} + +async function setBreakpoint(location, options) { + const breakpoint = breakpoints[makeBreakpointServerLocationId(location)]; + if ( + breakpoint && + JSON.stringify(breakpoint.options) == JSON.stringify(options) + ) { + return null; + } + breakpoints[makeBreakpointServerLocationId(location)] = { location, options }; + + // Map frontend options to a more restricted subset of what + // the server supports. For example frontend uses `hidden` attribute + // which isn't meant to be passed to the server. + // (note that protocol.js specification isn't enough to filter attributes, + // all primitive attributes will be passed as-is) + const serverOptions = { + condition: options.condition, + logValue: options.logValue, + }; + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (!hasWatcherSupport) { + // Without watcher support, unconditionally forward setBreakpoint to all threads. + return forEachThread(async thread => + thread.setBreakpoint(location, serverOptions) + ); + } + const breakpointsFront = + await commands.targetCommand.watcherFront.getBreakpointListActor(); + await breakpointsFront.setBreakpoint(location, serverOptions); + + // Call setBreakpoint for threads linked to targets + // not managed by the watcher. + return forEachThread(async thread => { + if ( + !commands.targetCommand.hasTargetWatcherSupport( + thread.targetFront.targetType + ) + ) { + return thread.setBreakpoint(location, serverOptions); + } + + return Promise.resolve(); + }); +} + +async function removeBreakpoint(location) { + delete breakpoints[makeBreakpointServerLocationId(location)]; + + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (!hasWatcherSupport) { + // Without watcher support, unconditionally forward removeBreakpoint to all threads. + return forEachThread(async thread => thread.removeBreakpoint(location)); + } + const breakpointsFront = + await commands.targetCommand.watcherFront.getBreakpointListActor(); + await breakpointsFront.removeBreakpoint(location); + + // Call removeBreakpoint for threads linked to targets + // not managed by the watcher. + return forEachThread(async thread => { + if ( + !commands.targetCommand.hasTargetWatcherSupport( + thread.targetFront.targetType + ) + ) { + return thread.removeBreakpoint(location); + } + + return Promise.resolve(); + }); +} + +async function evaluateExpressions(scripts, options) { + return Promise.all(scripts.map(script => evaluate(script, options))); +} + +async function evaluate(script, { frameId, threadId } = {}) { + if (!currentTarget() || !script) { + return { result: null }; + } + + const selectedTargetFront = threadId ? lookupTarget(threadId) : null; + + return commands.scriptCommand.execute(script, { + frameActor: frameId, + selectedTargetFront, + }); +} + +async function autocomplete(input, cursor, frameId) { + if (!currentTarget() || !input) { + return {}; + } + const consoleFront = await currentTarget().getFront("console"); + if (!consoleFront) { + return {}; + } + + return new Promise(resolve => { + consoleFront.autocomplete( + input, + cursor, + result => resolve(result), + frameId + ); + }); +} + +function getProperties(thread, grip) { + const objClient = lookupThreadFront(thread).pauseGrip(grip); + + return objClient.getPrototypeAndProperties().then(resp => { + const { ownProperties, safeGetterValues } = resp; + for (const name in safeGetterValues) { + const { enumerable, writable, getterValue } = safeGetterValues[name]; + ownProperties[name] = { enumerable, writable, value: getterValue }; + } + return resp; + }); +} + +async function getFrames(thread) { + const threadFront = lookupThreadFront(thread); + const response = await threadFront.getFrames(0, CALL_STACK_PAGE_SIZE); + + return Promise.all( + response.frames.map((frame, i) => createFrame(thread, frame, i)) + ); +} + +async function getFrameScopes(frame) { + const frameFront = lookupThreadFront(frame.thread).getActorByID(frame.id); + return frameFront.getEnvironment(); +} + +async function pauseOnExceptions( + shouldPauseOnExceptions, + shouldPauseOnCaughtExceptions +) { + await commands.threadConfigurationCommand.updateConfiguration({ + pauseOnExceptions: shouldPauseOnExceptions, + ignoreCaughtExceptions: !shouldPauseOnCaughtExceptions, + }); +} + +async function blackBox(sourceActor, shouldBlackBox, ranges) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (hasWatcherSupport) { + const blackboxingFront = + await commands.targetCommand.watcherFront.getBlackboxingActor(); + if (shouldBlackBox) { + await blackboxingFront.blackbox(sourceActor.url, ranges); + } else { + await blackboxingFront.unblackbox(sourceActor.url, ranges); + } + } else { + const sourceFront = currentThreadFront().source({ + actor: sourceActor.actor, + }); + // If there are no ranges, the whole source is being blackboxed + if (!ranges.length) { + await toggleBlackBoxSourceFront(sourceFront, shouldBlackBox); + return; + } + // Blackbox the specific ranges + for (const range of ranges) { + await toggleBlackBoxSourceFront(sourceFront, shouldBlackBox, range); + } + } +} + +async function toggleBlackBoxSourceFront(sourceFront, shouldBlackBox, range) { + if (shouldBlackBox) { + await sourceFront.blackBox(range); + } else { + await sourceFront.unblackBox(range); + } +} + +async function setSkipPausing(shouldSkip) { + await commands.threadConfigurationCommand.updateConfiguration({ + skipBreakpoints: shouldSkip, + }); +} + +async function setEventListenerBreakpoints(ids) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (!hasWatcherSupport) { + await forEachThread(thread => thread.setActiveEventBreakpoints(ids)); + return; + } + const breakpointListFront = + await commands.targetCommand.watcherFront.getBreakpointListActor(); + await breakpointListFront.setActiveEventBreakpoints(ids); +} + +async function getEventListenerBreakpointTypes() { + return currentThreadFront().getAvailableEventBreakpoints(); +} + +function pauseGrip(thread, func) { + return lookupThreadFront(thread).pauseGrip(func); +} + +async function toggleEventLogging(logEventBreakpoints) { + await commands.threadConfigurationCommand.updateConfiguration({ + logEventBreakpoints, + }); +} + +function getMainThread() { + return currentThreadFront().actor; +} + +async function getSourceActorBreakpointPositions({ thread, actor }, range) { + const sourceThreadFront = lookupThreadFront(thread); + const sourceFront = sourceThreadFront.source({ actor }); + return sourceFront.getBreakpointPositionsCompressed(range); +} + +async function getSourceActorBreakableLines({ thread, actor }) { + let actorLines = []; + try { + const sourceThreadFront = lookupThreadFront(thread); + const sourceFront = sourceThreadFront.source({ actor }); + actorLines = await sourceFront.getBreakableLines(); + } catch (e) { + // Exceptions could be due to the target thread being shut down. + console.warn(`getSourceActorBreakableLines failed: ${e}`); + } + + return actorLines; +} + +function getFrontByID(actorID) { + return commands.client.getFrontByID(actorID); +} + +function fetchAncestorFramePositions(index) { + currentThreadFront().fetchAncestorFramePositions(index); +} + +async function setOverride(url, path) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (hasWatcherSupport) { + const networkFront = + await commands.targetCommand.watcherFront.getNetworkParentActor(); + return networkFront.override(url, path); + } + return null; +} + +async function removeOverride(url) { + const hasWatcherSupport = commands.targetCommand.hasTargetWatcherSupport(); + if (hasWatcherSupport) { + const networkFront = + await commands.targetCommand.watcherFront.getNetworkParentActor(); + networkFront.removeOverride(url); + } +} + +const clientCommands = { + autocomplete, + blackBox, + createObjectFront, + loadObjectProperties, + releaseActor, + pauseGrip, + startTracing, + stopTracing, + resume, + stepIn, + stepOut, + stepOver, + restart, + breakOnNext, + sourceContents, + getSourceActorBreakpointPositions, + getSourceActorBreakableLines, + hasBreakpoint, + getServerBreakpointsList, + setBreakpoint, + setXHRBreakpoint, + removeXHRBreakpoint, + addWatchpoint, + removeWatchpoint, + removeBreakpoint, + evaluate, + evaluateExpressions, + getProperties, + getFrameScopes, + getFrames, + pauseOnExceptions, + toggleEventLogging, + getMainThread, + setSkipPausing, + setEventListenerBreakpoints, + getEventListenerBreakpointTypes, + getFrontByID, + fetchAncestorFramePositions, + toggleJavaScriptEnabled, + setOverride, + removeOverride, +}; + +export { setupCommands, clientCommands }; diff --git a/devtools/client/debugger/src/client/firefox/create.js b/devtools/client/debugger/src/client/firefox/create.js new file mode 100644 index 0000000000..97976aa358 --- /dev/null +++ b/devtools/client/debugger/src/client/firefox/create.js @@ -0,0 +1,392 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This module converts Firefox specific types to the generic types + +import { + hasSource, + hasSourceActor, + getSourceActor, + getSourceCount, +} from "../../selectors"; +import { features } from "../../utils/prefs"; +import { isUrlExtension } from "../../utils/source"; +import { createLocation } from "../../utils/location"; +import { getDisplayURL } from "../../utils/sources-tree/getURL"; + +let store; + +/** + * This function is to be called first before any other + * and allow having access to any instances of classes that are + * useful for this module + * + * @param {Object} dependencies + * @param {Object} dependencies.store + * The redux store object of the debugger frontend. + */ +export function setupCreate(dependencies) { + store = dependencies.store; +} + +export async function createFrame(thread, frame, index = 0) { + if (!frame) { + return null; + } + + // Because of throttling, the source may be available a bit late. + const sourceActor = await waitForSourceActorToBeRegisteredInStore( + frame.where.actor + ); + + const location = createLocation({ + source: sourceActor.sourceObject, + sourceActor, + line: frame.where.line, + column: frame.where.column, + }); + + return { + id: frame.actorID, + thread, + displayName: frame.displayName, + location, + generatedLocation: location, + this: frame.this, + source: null, + index, + asyncCause: frame.asyncCause, + state: frame.state, + type: frame.type, + }; +} + +/** + * This method wait for the given source actor to be registered in Redux store. + * + * @param {String} sourceActorId + * Actor ID of the source to be waiting for. + */ +async function waitForSourceActorToBeRegisteredInStore(sourceActorId) { + if (!hasSourceActor(store.getState(), sourceActorId)) { + await new Promise(resolve => { + const unsubscribe = store.subscribe(check); + let currentSize = null; + function check() { + const previousSize = currentSize; + currentSize = store.getState().sourceActors.mutableSourceActors.size; + // For perf reason, avoid any extra computation if sources did not change + if (previousSize == currentSize) { + return; + } + if (hasSourceActor(store.getState(), sourceActorId)) { + unsubscribe(); + resolve(); + } + } + }); + } + return getSourceActor(store.getState(), sourceActorId); +} + +/** + * This method wait for the given source to be registered in Redux store. + * + * @param {String} sourceId + * The id of the source to be waiting for. + */ +export async function waitForSourceToBeRegisteredInStore(sourceId) { + return new Promise(resolve => { + if (hasSource(store.getState(), sourceId)) { + resolve(); + return; + } + const unsubscribe = store.subscribe(check); + let currentSize = null; + function check() { + const previousSize = currentSize; + currentSize = getSourceCount(store.getState()); + // For perf reason, avoid any extra computation if sources did not change + if (previousSize == currentSize) { + return; + } + if (hasSource(store.getState(), sourceId)) { + unsubscribe(); + resolve(); + } + } + }); +} + +// Compute the reducer's source ID for a given source front/resource. +// +// We have four kind of "sources": +// * "sources" in sources.js reducer, which map to 1 or many: +// * "source actors" in source-actors.js reducer, which map 1 for 1 with: +// * "SOURCE" resources coming from ResourceCommand API +// * SourceFront, which are retrieved via `ThreadFront.source(sourceResource)` +// +// Note that SOURCE resources are actually the "form" of the SourceActor, +// with the addition of `resourceType` and `targetFront` attributes. +// +// Unfortunately, the debugger frontend interacts with these 4 type of objects. +// The last three actually try to represent the exact same thing. +// +// Here this method received a SOURCE resource (the 3rd bullet point) +export function makeSourceId(sourceResource) { + // Allows Jest to use custom, simplier IDs + if ("mockedJestID" in sourceResource) { + return sourceResource.mockedJestID; + } + // By default, within a given target, all sources will be grouped by URL. + // You will be having a unique Source object in sources.js reducer, + // while you might have many Source Actor objects in source-actors.js reducer. + // + // There is two distinct usecases here: + // * HTML pages, which will have one source object which represents the whole HTML page + // and it will relate to many source actors. One for each inline + + + +

Testing Script Tags in HTML

+ +

+ Some arbitrary intermediate content to affect the offsets of the scripts +

+ + + diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/private-fields.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/private-fields.js new file mode 100644 index 0000000000..ca9abc8f1d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/private-fields.js @@ -0,0 +1,24 @@ +class MyClass { + constructor(secret, ...rest) { + const self = this; + this.#secret = secret; + self.#restParams = rest; + } + + #secret; + #restParams; + #salt = "bloup"; + creationDate = new Date(); + + #getSalt() { + return this.#salt; + } + + debug() { + const self = this; + const creationDate = this.creationDate; + const secret = this.#secret; + const salt = self.#getSalt(); + return `${creationDate}|${salt}|${secret}`; + } +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/proto.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/proto.js new file mode 100644 index 0000000000..38c3b63ac7 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/proto.js @@ -0,0 +1,14 @@ +const foo = function() {}; + +const bar = () => {}; + +const TodoView = Backbone.View.extend({ + tagName: "li", + initialize: function() {}, + doThing(b) { + console.log("hi", b); + }, + render: function() { + return this; + } +}); diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/resolveToken.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/resolveToken.js new file mode 100644 index 0000000000..4660f0f568 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/resolveToken.js @@ -0,0 +1,40 @@ +const a = 1; +let b = 0; + +function getA() { + return a; +} + +function setB(newB) { + b = newB; +} + +const plusAB = (function(x, y) { + const obj = { x, y }; + function insideClosure(alpha, beta) { + return alpha + beta + obj.x + obj.y; + } + + return insideClosure; +})(a, b); + +function withMultipleScopes() { + var outer = 1; + function innerScope() { + var inner = outer + 1; + return inner; + } + + const fromIIFE = (function(toIIFE) { + return innerScope() + toIIFE; + })(1); + + { + // random block + let x = outer + fromIIFE; + if (x) { + const y = x * x; + console.log(y); + } + } +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/arrow-function.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/arrow-function.js new file mode 100644 index 0000000000..4ec72fd450 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/arrow-function.js @@ -0,0 +1,11 @@ +export {}; + +let outer = (p1) => { + console.log(this); + + (function() { + var inner = (p2) => { + console.log(this); + }; + })(); +}; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/binding-types.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/binding-types.js new file mode 100644 index 0000000000..8c9cc05d1d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/binding-types.js @@ -0,0 +1,24 @@ +import def from ""; +import { named } from ""; +import { thing as otherNamed } from ""; +import * as namespace from ""; + +function fn() {} +class cls { + method(){ + + } +} + +var aVar; +let aLet; +const aConst = ""; + +(function inner() { + this; + arguments; +}); + +{ + function blockFn(){} +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/block-statement.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/block-statement.js new file mode 100644 index 0000000000..5e64d1180f --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/block-statement.js @@ -0,0 +1,13 @@ +export {}; + +let first; + +{ + var second; + function third() {} + class Fourth {} + let fifth; + const sixth = 6; +} + +var seventh; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-declaration.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-declaration.js new file mode 100644 index 0000000000..1c2c74dcbc --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-declaration.js @@ -0,0 +1,14 @@ +export {}; + +class Outer { + method() { + class Inner { + m() { + console.log(this); + } + } + } +} + +@decorator +class Second {} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-expression.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-expression.js new file mode 100644 index 0000000000..16b6841d71 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-expression.js @@ -0,0 +1,11 @@ +export {}; + +var Outer = class Outer { + method() { + var Inner = class { + m() { + console.log(this); + } + }; + } +}; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-property.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-property.js new file mode 100644 index 0000000000..a80cad3a87 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/class-property.js @@ -0,0 +1,10 @@ +export {}; + +class Foo { + prop = this.init(); + + other = do { + var one; + let two; + }; +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/complex-nesting.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/complex-nesting.js new file mode 100644 index 0000000000..40763f556f --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/complex-nesting.js @@ -0,0 +1,29 @@ +function named(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = root; +function root() { + function fn(arg) { + var _this = this, + _arguments = arguments; + + console.log(this, arguments); + console.log("pause here", fn, root); + + var arrow = function arrow(argArrow) { + console.log(_this, _arguments); + console.log("pause here", fn, root); + }; + arrow("arrow-arg"); + } + + fn.call("this-value", "arg-value"); +} +module.exports = exports["default"]; + +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/expressions.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/expressions.js new file mode 100644 index 0000000000..6698acd8e8 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/expressions.js @@ -0,0 +1,6 @@ +const foo = {}; + +foo.bar().baz; +(0, foo.bar)().baz; +Object(foo.bar)().baz; +__webpack_require__.i(foo.bar)().baz; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/flowtype-bindings.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/flowtype-bindings.js new file mode 100644 index 0000000000..385797c044 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/flowtype-bindings.js @@ -0,0 +1,11 @@ +import type { One, Two, Three } from "./src/mod"; + +type Other = { + root: typeof root, +}; + +const aConst = (window: Array); + +export default function root() { + +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/fn-body-lex-and-nonlex.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/fn-body-lex-and-nonlex.js new file mode 100644 index 0000000000..a7f6d7670a --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/fn-body-lex-and-nonlex.js @@ -0,0 +1,23 @@ +function fn() { + var nonlex; + let lex; + +} + +function fn2() { + function nonlex(){} + let lex; + +} + +function fn3() { + var nonlex; + class Thing {} + +} + +function fn4() { + function nonlex(){} + class Thing {} + +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/for-loops.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/for-loops.js new file mode 100644 index 0000000000..747eeeae7d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/for-loops.js @@ -0,0 +1,13 @@ +export {}; + +for (var one;;) {} +for (let two;;) {} +for (const three = 3;;) {} + +for (var four in {}) {} +for (let five in {}) {} +for (const six in {}) {} + +for (var seven of {}) {} +for (let eight of {}) {} +for (const nine of {}) {} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-declaration.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-declaration.js new file mode 100644 index 0000000000..759374b437 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-declaration.js @@ -0,0 +1,11 @@ +export {}; + +function outer(p1) {} + +{ + function middle(p2) { + function inner(p3) {} + + console.log(this); + } +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-expression.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-expression.js new file mode 100644 index 0000000000..436413533e --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/function-expression.js @@ -0,0 +1,7 @@ +export {}; + +let fn = function(p1) {}; + +let fn2 = function withName(p2) { + console.log(this); +}; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/jsx-component.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/jsx-component.js new file mode 100644 index 0000000000..ffe1c1dfce --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/jsx-component.js @@ -0,0 +1,6 @@ +import SomeComponent from ""; + +; +; +; +; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/out-of-order-declarations.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/out-of-order-declarations.js new file mode 100644 index 0000000000..4f36d9fc38 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/out-of-order-declarations.js @@ -0,0 +1,21 @@ +var val; + +export default function root() { + var val; + + var fn; + + this; + + function callback() { + console.log(val, fn, callback, root, this); + + var val; + + function fn(){}; + } + + callback(); +} + +import aDefault from "./src/mod"; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/pattern-declarations.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/pattern-declarations.js new file mode 100644 index 0000000000..6810ef4614 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/pattern-declarations.js @@ -0,0 +1,2 @@ +var { prop: one } = {}; +var [ two ] = []; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/simple-module.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/simple-module.js new file mode 100644 index 0000000000..b25cc7a863 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/simple-module.js @@ -0,0 +1,11 @@ +import foo from "foo"; + +console.log(foo); + +var one = 1; +let two = 2; +const three = 3; + +function fn() {} + +this; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/switch-statement.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/switch-statement.js new file mode 100644 index 0000000000..7163c3811d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/switch-statement.js @@ -0,0 +1,22 @@ +export {}; + +switch (foo) { + case "zero": + var zero; + case "one": + let one; + case "two": + let two; + case "three": { + let three; + } +} + +switch (foo) { + case "": + function two(){} +} +switch (foo) { + case "": + class three {} +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/try-catch.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/try-catch.js new file mode 100644 index 0000000000..8ccf4db592 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/try-catch.js @@ -0,0 +1,9 @@ +export {}; + +try { + var first; + let second; +} catch (err) { + var third; + let fourth; +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/ts-sample.ts b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/ts-sample.ts new file mode 100644 index 0000000000..e23ff83754 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/ts-sample.ts @@ -0,0 +1,41 @@ + +// TSEnumDeclaration +enum Color { + // TSEnumMember + Red, + Green, + Blue, +} + +class Example { + // TSParameterProperty + constructor(public foo) { + + } + + method(): never { + throw new Error(); + } +} + +// TSTypeAssertion +var foo = window; + +// TSAsExpression +(window as any); + +// TSNonNullExpression +(window!); + +// TSModuleDeclaration +namespace TheSpace { + function fn() { + + } +} + +// TSImportEqualsDeclaration +import ImportedClass = require("mod"); + +// TSExportAssignment +export = Example; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/tsx-sample.tsx b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/tsx-sample.tsx new file mode 100644 index 0000000000..9e2b9faf8b --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/tsx-sample.tsx @@ -0,0 +1,41 @@ + +// TSEnumDeclaration +enum Color { + // TSEnumMember + Red, + Green, + Blue, +} + +class Example { + // TSParameterProperty + constructor(public foo) { + + } + + method(): never { + throw new Error(); + } +} + +// JSXElement +var foo = window; + +// TSAsExpression +(window as any); + +// TSNonNullExpression +(window!); + +// TSModuleDeclaration +namespace TheSpace { + function fn() { + + } +} + +// TSImportEqualsDeclaration +import ImportedClass = require("mod"); + +// TSExportAssignment +export = Example; diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/vue-sample.vue b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/vue-sample.vue new file mode 100644 index 0000000000..0fceee99d1 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/scopes/vue-sample.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/statements.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/statements.js new file mode 100644 index 0000000000..f2c113570e --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/statements.js @@ -0,0 +1,40 @@ +debugger; debugger; +console.log("a"); console.log("a"); + +// assignments with valid pause locations +this.x = 3; +var a = 4; +var d = [foo()] +var f = 3, e = 4; +var g = [], h = {}; + +// assignments with invalid pause locations +var b = foo(); +c = foo(); + + +const arr = [ + '1', + 2, + foo() +] + +const obj = { + a: '1', + b: 2, + c: foo(), +} + +foo( + 1, + foo( + 1 + ), + 3 +) + +throw new Error("3"); +3; + +while (i < 6) { break } +while (i < 6) { continue;} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/thisExpression.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/thisExpression.js new file mode 100644 index 0000000000..dd398db426 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/thisExpression.js @@ -0,0 +1,11 @@ +class Test { + constructor() { + this.foo = { + a: "foobar" + }; + } + + bar() { + console.log(this.foo.a); + } +} diff --git a/devtools/client/debugger/src/workers/parser/tests/fixtures/var.js b/devtools/client/debugger/src/workers/parser/tests/fixtures/var.js new file mode 100644 index 0000000000..509ad368e8 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/fixtures/var.js @@ -0,0 +1,21 @@ +var foo = 1; +let bar = 2; +const baz = 3; +const a = 4, + b = 5; +a = 5; + +var { foo: { baw } } = {} +var {bap} = {} +var {ll = 3} = {} + + +var [first] = [1] + +var { a: _a } = 3 + +var [oh, {my: god}] = [{},{}] + +var [[oj], [{oy, vey: _vey, mitzvot: _mitz = 4}]] = [{},{}] + +var [one, ...stuff] = [] diff --git a/devtools/client/debugger/src/workers/parser/tests/framework.spec.js b/devtools/client/debugger/src/workers/parser/tests/framework.spec.js new file mode 100644 index 0000000000..d41f45b71c --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/framework.spec.js @@ -0,0 +1,63 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSymbols } from "../getSymbols"; +import { populateOriginalSource } from "./helpers"; +import cases from "jest-in-case"; + +cases( + "Parser.getFramework", + ({ name, file, value }) => { + const source = populateOriginalSource("frameworks/plainJavascript"); + const symbols = getSymbols(source.id); + expect(symbols.framework).toBeNull(); + }, + [ + { + name: "is undefined when no framework", + file: "frameworks/plainJavascript", + value: null, + }, + { + name: "does not get confused with angular (#6833)", + file: "frameworks/angular1FalsePositive", + value: null, + }, + { + name: "recognizes ES6 React component", + file: "frameworks/reactComponent", + value: "React", + }, + { + name: "recognizes ES5 React component", + file: "frameworks/reactComponentEs5", + value: "React", + }, + { + name: "recognizes Angular 1 module", + file: "frameworks/angular1Module", + value: "Angular", + }, + { + name: "recognizes declarative Vue file", + file: "frameworks/vueFileDeclarative", + value: "Vue", + }, + { + name: "recognizes component Vue file", + file: "frameworks/vueFileComponent", + value: "Vue", + }, + { + name: "recognizes the react library file", + file: "framework/reactLibrary", + value: "React", + }, + { + name: "recognizes the redux library file", + file: "framework/reduxLibrary", + value: "React", + }, + ] +); diff --git a/devtools/client/debugger/src/workers/parser/tests/getScopes.spec.js b/devtools/client/debugger/src/workers/parser/tests/getScopes.spec.js new file mode 100644 index 0000000000..fa19197a92 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/getScopes.spec.js @@ -0,0 +1,227 @@ +/* eslint max-nested-callbacks: ["error", 4]*/ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import getScopes from "../getScopes"; +import { populateOriginalSource } from "./helpers"; +import cases from "jest-in-case"; + +cases( + "Parser.getScopes", + ({ name, file, type, locations }) => { + const source = populateOriginalSource(file, type); + + locations.forEach(([line, column]) => { + const scopes = getScopes({ + sourceId: source.id, + line, + column, + }); + + expect(scopes).toMatchSnapshot( + `getScopes ${name} at line ${line} column ${column}` + ); + }); + }, + [ + { + name: "finds scope bindings in fn body with both lex and non-lex items", + file: "scopes/fn-body-lex-and-nonlex", + locations: [ + [4, 0], + [10, 0], + [16, 0], + [22, 0], + ], + }, + { + name: "finds scope bindings in a vue file", + file: "scopes/vue-sample", + type: "vue", + locations: [[14, 0]], + }, + { + name: "finds scope bindings in a typescript file", + file: "scopes/ts-sample", + type: "ts", + locations: [ + [9, 0], + [13, 4], + [17, 0], + [33, 0], + ], + }, + { + name: "finds scope bindings in a typescript-jsx file", + file: "scopes/tsx-sample", + type: "tsx", + locations: [ + [9, 0], + [13, 4], + [17, 0], + [33, 0], + ], + }, + { + name: "finds scope bindings in a module", + file: "scopes/simple-module", + locations: [[7, 0]], + }, + { + name: "finds scope bindings in a JSX element", + file: "scopes/jsx-component", + locations: [[2, 0]], + }, + { + name: "finds scope bindings for complex binding nesting", + file: "scopes/complex-nesting", + locations: [ + [16, 4], + [20, 6], + ], + }, + { + name: "finds scope bindings for function declarations", + file: "scopes/function-declaration", + locations: [ + [2, 0], + [3, 20], + [5, 1], + [9, 0], + ], + }, + { + name: "finds scope bindings for function expressions", + file: "scopes/function-expression", + locations: [ + [2, 0], + [3, 23], + [6, 0], + ], + }, + { + name: "finds scope bindings for arrow functions", + file: "scopes/arrow-function", + locations: [ + [2, 0], + [4, 0], + [7, 0], + [8, 0], + ], + }, + { + name: "finds scope bindings for class declarations", + file: "scopes/class-declaration", + locations: [ + [2, 0], + [5, 0], + [7, 0], + ], + }, + { + name: "finds scope bindings for class expressions", + file: "scopes/class-expression", + locations: [ + [2, 0], + [5, 0], + [7, 0], + ], + }, + { + name: "finds scope bindings for for loops", + file: "scopes/for-loops", + locations: [ + [2, 0], + [3, 17], + [4, 17], + [5, 25], + [7, 22], + [8, 22], + [9, 23], + [11, 23], + [12, 23], + [13, 24], + ], + }, + { + name: "finds scope bindings for try..catch", + file: "scopes/try-catch", + locations: [ + [2, 0], + [4, 0], + [7, 0], + ], + }, + { + name: "finds scope bindings for out of order declarations", + file: "scopes/out-of-order-declarations", + locations: [ + [2, 0], + [5, 0], + [11, 0], + [14, 0], + [17, 0], + ], + }, + { + name: "finds scope bindings for block statements", + file: "scopes/block-statement", + locations: [ + [2, 0], + [6, 0], + ], + }, + { + name: "finds scope bindings for class properties", + file: "scopes/class-property", + locations: [ + [2, 0], + [4, 16], + [6, 12], + [7, 0], + ], + }, + { + name: "finds scope bindings and exclude Flowtype", + file: "scopes/flowtype-bindings", + locations: [ + [8, 0], + [10, 0], + ], + }, + { + name: "finds scope bindings for declarations with patterns", + file: "scopes/pattern-declarations", + locations: [[1, 0]], + }, + { + name: "finds scope bindings for switch statements", + file: "scopes/switch-statement", + locations: [ + [2, 0], + [5, 0], + [7, 0], + [9, 0], + [11, 0], + [17, 0], + [21, 0], + ], + }, + { + name: "finds scope bindings with proper types", + file: "scopes/binding-types", + locations: [ + [5, 0], + [9, 0], + [18, 0], + [23, 0], + ], + }, + { + name: "finds scope bindings with expression metadata", + file: "scopes/expressions", + locations: [[2, 0]], + }, + ] +); diff --git a/devtools/client/debugger/src/workers/parser/tests/getSymbols.spec.js b/devtools/client/debugger/src/workers/parser/tests/getSymbols.spec.js new file mode 100644 index 0000000000..6a7cccce49 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/getSymbols.spec.js @@ -0,0 +1,49 @@ +/* eslint max-nested-callbacks: ["error", 4]*/ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { formatSymbols } from "../utils/formatSymbols"; +import { populateSource, populateOriginalSource } from "./helpers"; +import cases from "jest-in-case"; + +cases( + "Parser.getSymbols", + ({ name, file, original, type }) => { + const source = original + ? populateOriginalSource(file, type) + : populateSource(file, type); + + expect(formatSymbols(source.id)).toMatchSnapshot(); + }, + [ + { name: "es6", file: "es6", original: true }, + { name: "func", file: "func", original: true }, + { name: "function names", file: "functionNames", original: true }, + { name: "math", file: "math" }, + { name: "proto", file: "proto" }, + { name: "class", file: "class", original: true }, + { name: "var", file: "var" }, + { name: "expression", file: "expression" }, + { name: "allSymbols", file: "allSymbols" }, + { name: "call sites", file: "call-sites" }, + { name: "call expression", file: "callExpressions" }, + { name: "object expressions", file: "object-expressions" }, + { name: "optional chaining", file: "optional-chaining" }, + { name: "private fields", file: "private-fields" }, + { + name: "finds symbols in an html file", + file: "parseScriptTags", + type: "html", + }, + { name: "component", file: "component", original: true }, + { + name: "react component", + file: "frameworks/reactComponent", + original: true, + }, + { name: "flow", file: "flow", original: true }, + { name: "jsx", file: "jsx", original: true }, + { name: "destruct", file: "destructuring" }, + ] +); diff --git a/devtools/client/debugger/src/workers/parser/tests/helpers/index.js b/devtools/client/debugger/src/workers/parser/tests/helpers/index.js new file mode 100644 index 0000000000..47c358ae66 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/helpers/index.js @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import fs from "fs"; +import path from "path"; + +import { makeMockSourceAndContent } from "../../../../utils/test-mockup"; +import { setSource } from "../../sources"; +import * as asyncValue from "../../../../utils/async-value"; + +export function getFixture(name, type = "js") { + return fs.readFileSync( + path.join(__dirname, `../fixtures/${name}.${type}`), + "utf8" + ); +} + +function getSourceContent(name, type = "js") { + const text = getFixture(name, type); + let contentType = "text/javascript"; + if (type === "html") { + contentType = "text/html"; + } else if (type === "vue") { + contentType = "text/vue"; + } else if (type === "ts") { + contentType = "text/typescript"; + } else if (type === "tsx") { + contentType = "text/typescript-jsx"; + } + + return { + type: "text", + value: text, + contentType, + }; +} + +export function getSource(name, type) { + const { value: text, contentType } = getSourceContent(name, type); + + return makeMockSourceAndContent(undefined, name, contentType, text); +} + +export function populateSource(name, type) { + const { content, ...source } = getSource(name, type); + setSource({ + id: source.id, + text: content.value, + contentType: content.contentType, + isWasm: false, + }); + return { + ...source, + content: asyncValue.fulfilled(content), + }; +} + +export function getOriginalSource(name, type) { + return getOriginalSourceWithContent(name, type); +} + +export function getOriginalSourceWithContent(name, type) { + const { value: text, contentType } = getSourceContent(name, type); + + return makeMockSourceAndContent( + undefined, + `${name}/originalSource-1`, + contentType, + text + ); +} + +export function populateOriginalSource(name, type) { + const { content, ...source } = getOriginalSourceWithContent(name, type); + setSource({ + id: source.id, + text: content.value, + contentType: content.contentType, + isWasm: false, + }); + return { + ...source, + content: asyncValue.fulfilled(content), + }; +} diff --git a/devtools/client/debugger/src/workers/parser/tests/mapBindings.spec.js b/devtools/client/debugger/src/workers/parser/tests/mapBindings.spec.js new file mode 100644 index 0000000000..8c23ab5873 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/mapBindings.spec.js @@ -0,0 +1,161 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import mapExpressionBindings from "../mapBindings"; +import { parseConsoleScript } from "../utils/ast"; +import cases from "jest-in-case"; + +const prettier = require("prettier"); + +function format(code) { + return prettier.format(code, { semi: false, parser: "babel" }); +} + +function excludedTest({ name, expression, bindings = [] }) { + const safeExpression = mapExpressionBindings( + expression, + parseConsoleScript(expression), + bindings + ); + expect(format(safeExpression)).toEqual(format(expression)); +} + +function includedTest({ name, expression, newExpression, bindings }) { + const safeExpression = mapExpressionBindings( + expression, + parseConsoleScript(expression), + bindings + ); + expect(format(safeExpression)).toEqual(format(newExpression)); +} + +describe("mapExpressionBindings", () => { + cases("included cases", includedTest, [ + { + name: "single declaration", + expression: "const a = 2; let b = 3; var c = 4;", + newExpression: "self.a = 2; self.b = 3; self.c = 4;", + }, + { + name: "multiple declarations", + expression: "const a = 2, b = 3", + newExpression: "self.a = 2; self.b = 3", + }, + { + name: "declaration with separate assignment", + expression: "let a; a = 2;", + newExpression: "self.a = void 0; self.a = 2;", + }, + { + name: "multiple declarations with no assignment", + expression: "let a = 2, b;", + newExpression: "self.a = 2; self.b = void 0;", + }, + { + name: "local bindings become assignments", + bindings: ["a"], + expression: "var a = 2;", + newExpression: "a = 2;", + }, + { + name: "assignments", + expression: "a = 2;", + newExpression: "self.a = 2;", + }, + { + name: "assignments with +=", + expression: "a += 2;", + newExpression: "self.a += 2;", + }, + { + name: "destructuring (objects)", + expression: "const { a } = {}; ", + newExpression: "({ a: self.a } = {})", + }, + { + name: "destructuring (arrays)", + expression: " var [a, ...foo] = [];", + newExpression: "([self.a, ...self.foo] = [])", + }, + { + name: "destructuring (declarations)", + expression: "var {d,e} = {}, {f} = {}; ", + newExpression: `({ d: self.d, e: self.e } = {}); + ({ f: self.f } = {}) + `, + }, + { + name: "destructuring & declaration", + expression: "const { a } = {}; var b = 3", + newExpression: `({ a: self.a } = {}); + self.b = 3 + `, + }, + { + name: "destructuring assignment", + expression: "[a] = [3]", + newExpression: "[self.a] = [3]", + }, + { + name: "destructuring assignment (declarations)", + expression: "[a] = [3]; var b = 4", + newExpression: "[self.a] = [3];\n self.b = 4", + }, + ]); + + cases("excluded cases", excludedTest, [ + { name: "local variables", expression: "function a() { var b = 2}" }, + { name: "functions", expression: "function a() {}" }, + { name: "classes", expression: "class a {}" }, + + { name: "with", expression: "with (obj) {var a = 2;}" }, + { + name: "with & declaration", + expression: "with (obj) {var a = 2;}; ; var b = 3", + }, + { + name: "hoisting", + expression: "{ const h = 3; }", + }, + { + name: "assignments", + bindings: ["a"], + expression: "a = 2;", + }, + { + name: "identifier", + expression: "a", + }, + ]); + + cases("cases that we should map in the future", excludedTest, [ + { name: "blocks (IF)", expression: "if (true) { var a = 3; }" }, + { + name: "hoisting", + expression: "{ var g = 5; }", + }, + { + name: "for loops bindings", + expression: "for (let foo = 4; false;){}", + }, + ]); + + cases("cases that we shouldn't map in the future", includedTest, [ + { + name: "window properties", + expression: "var innerHeight = 3; var location = 5;", + newExpression: "self.innerHeight = 3; self.location = 5;", + }, + { + name: "self declaration", + expression: "var self = 3", + newExpression: "self.self = 3", + }, + { + name: "self assignment", + expression: "self = 3", + newExpression: "self.self = 3", + }, + ]); +}); diff --git a/devtools/client/debugger/src/workers/parser/tests/mapExpression.spec.js b/devtools/client/debugger/src/workers/parser/tests/mapExpression.spec.js new file mode 100644 index 0000000000..27cc86b039 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/mapExpression.spec.js @@ -0,0 +1,785 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import mapExpression from "../mapExpression"; +import { format } from "prettier"; +import cases from "jest-in-case"; + +function test({ + expression, + newExpression, + bindings, + mappings, + shouldMapBindings, + expectedMapped, + parseExpression = true, +}) { + const res = mapExpression(expression, mappings, bindings, shouldMapBindings); + + if (parseExpression) { + expect( + format(res.expression, { + parser: "babel", + }) + ).toEqual(format(newExpression, { parser: "babel" })); + } else { + expect(res.expression).toEqual(newExpression); + } + + expect(res.mapped).toEqual(expectedMapped); +} + +function formatAwait(body) { + return `(async () => { ${body} })();`; +} + +describe("mapExpression", () => { + cases("mapExpressions", test, [ + { + name: "await", + expression: "await a()", + newExpression: formatAwait("return a()"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (multiple statements)", + expression: "const x = await a(); x + x", + newExpression: formatAwait("self.x = await a(); return x + x;"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (inner)", + expression: "async () => await a();", + newExpression: "async () => await a();", + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (multiple awaits)", + expression: "const x = await a(); await b(x)", + newExpression: formatAwait("self.x = await a(); return b(x);"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (assignment)", + expression: "let x = await sleep(100, 2)", + newExpression: formatAwait("return (self.x = await sleep(100, 2))"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (destructuring)", + expression: "const { a, c: y } = await b()", + newExpression: formatAwait( + "return ({ a: self.a, c: self.y } = await b())" + ), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (array destructuring)", + expression: "const [a, y] = await b();", + newExpression: formatAwait("return ([self.a, self.y] = await b())"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (mixed destructuring)", + expression: "const [{ a }] = await b();", + newExpression: formatAwait("return ([{ a: self.a }] = await b())"), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (destructuring, multiple statements)", + expression: "const { a, c: y } = await b(), { x } = await y()", + newExpression: formatAwait(` + ({ a: self.a, c: self.y } = await b()) + return ({ x: self.x } = await y()); + `), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (destructuring, bindings)", + expression: "const { a, c: y } = await b();", + newExpression: formatAwait("return ({ a, c: y } = await b())"), + bindings: ["a", "y"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (array destructuring, bindings)", + expression: "const [a, y] = await b();", + newExpression: formatAwait("return ([a, y] = await b())"), + bindings: ["a", "y"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (mixed destructuring, bindings)", + expression: "const [{ a }] = await b();", + newExpression: formatAwait("return ([{ a }] = await b())"), + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (destructuring with defaults, bindings)", + expression: "const { c, a = 5 } = await b();", + newExpression: formatAwait("return ({ c: self.c, a = 5 } = await b())"), + bindings: ["a", "y"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (array destructuring with defaults, bindings)", + expression: "const [a, y = 10] = await b();", + newExpression: formatAwait("return ([a, y = 10] = await b())"), + bindings: ["a", "y"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (mixed destructuring with defaults, bindings)", + expression: "const [{ c = 5 }, a = 5] = await b();", + newExpression: formatAwait( + "return ([ { c: self.c = 5 }, a = 5] = await b())" + ), + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (nested destructuring, bindings)", + expression: "const { a, c: { y } } = await b();", + newExpression: formatAwait(` + return ({ + a, + c: { y } + } = await b()); + `), + bindings: ["a", "y"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (nested destructuring with defaults)", + expression: "const { a, c: { y = 5 } = {} } = await b();", + newExpression: formatAwait(`return ({ + a: self.a, + c: { y: self.y = 5 } = {}, + } = await b()); + `), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (very nested destructuring with defaults)", + expression: + "const { a, c: { y: { z = 10, b } = { b: 5 } } } = await b();", + newExpression: formatAwait(` + return ({ + a: self.a, + c: { + y: { z: self.z = 10, b: self.b } = { + b: 5 + } + } + } = await b()); + `), + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: true, + originalExpression: false, + }, + }, + { + name: "await (with SyntaxError)", + expression: "await new Promise())", + newExpression: formatAwait("await new Promise())"), + parseExpression: false, + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, let assignment)", + expression: "let a = await 123;", + newExpression: `let a; + + (async () => { + return a = await 123; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, var assignment)", + expression: "var a = await 123;", + newExpression: `var a; + + (async () => { + return a = await 123; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, const assignment)", + expression: "const a = await 123;", + newExpression: `let a; + + (async () => { + return a = await 123; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, multiple assignments)", + expression: "let a = 1, b, c = 3; b = await 123; a + b + c", + newExpression: `let a, b, c; + + (async () => { + a = 1; + c = 3; + b = await 123; + return a + b + c; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, object destructuring)", + expression: "let {a, b, c} = await x;", + newExpression: `let a, b, c; + + (async () => { + return ({a, b, c} = await x); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, object destructuring with rest)", + expression: "let {a, ...rest} = await x;", + newExpression: `let a, rest; + + (async () => { + return ({a, ...rest} = await x); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, object destructuring with renaming and default)", + expression: "let {a: hello, b, c: world, d: $ = 4} = await x;", + newExpression: `let hello, b, world, $; + + (async () => { + return ({a: hello, b, c: world, d: $ = 4} = await x); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, nested object destructuring + renaming + default)", + expression: `let { + a: hello, c: { y: { z = 10, b: bill, d: [e, f = 20] }} + } = await x; z;`, + newExpression: `let hello, z, bill, e, f; + + (async () => { + ({ a: hello, c: { y: { z = 10, b: bill, d: [e, f = 20] }}} = await x); + return z; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, array destructuring)", + expression: "let [a, b, c] = await x; c;", + newExpression: `let a, b, c; + + (async () => { + [a, b, c] = await x; + return c; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, array destructuring with default)", + expression: "let [a, b = 1, c = 2] = await x; c;", + newExpression: `let a, b, c; + + (async () => { + [a, b = 1, c = 2] = await x; + return c; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, array destructuring with default and rest)", + expression: "let [a, b = 1, c = 2, ...rest] = await x; rest;", + newExpression: `let a, b, c, rest; + + (async () => { + [a, b = 1, c = 2, ...rest] = await x; + return rest; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, nested array destructuring with default)", + expression: "let [a, b = 1, [c = 2, [d = 3, e = 4]]] = await x; c;", + newExpression: `let a, b, c, d, e; + + (async () => { + [a, b = 1, [c = 2, [d = 3, e = 4]]] = await x; + return c; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (no bindings, dynamic import)", + expression: ` + var {rainbowLog} = await import("./cool-module.js"); + rainbowLog("dynamic");`, + newExpression: `var rainbowLog; + + (async () => { + ({rainbowLog} = await import("./cool-module.js")); + return rainbowLog("dynamic"); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (nullish coalesce operator)", + expression: "await x; true ?? false", + newExpression: `(async () => { + await x; + return true ?? false; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (optional chaining operator)", + expression: "await x; x?.y?.z", + newExpression: `(async () => { + await x; + return x?.y?.z; + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (async function declaration with nullish coalesce operator)", + expression: "async function coalesce(x) { await x; return x ?? false; }", + newExpression: + "async function coalesce(x) { await x; return x ?? false; }", + shouldMapBindings: false, + expectedMapped: { + await: false, + bindings: false, + originalExpression: false, + }, + }, + { + name: "await (async function declaration with optional chaining operator)", + expression: "async function chain(x) { await x; return x?.y?.z; }", + newExpression: "async function chain(x) { await x; return x?.y?.z; }", + shouldMapBindings: false, + expectedMapped: { + await: false, + bindings: false, + originalExpression: false, + }, + }, + { + // check that variable declaration in for loop is not put outside of the async iife + name: "await (for loop)", + expression: "for (let i=0;i<2;i++) {}; var b = await 1;", + newExpression: `var b; + + (async () => { + for (let i=0;i<2;i++) {} + + return (b = await 1); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + // check that variable declaration in for-in loop is not put outside of the async iife + name: "await (for..in loop)", + expression: "for (let i in {}) {}; var b = await 1;", + newExpression: `var b; + + (async () => { + for (let i in {}) {} + + return (b = await 1); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + // check that variable declaration in for-of loop is not put outside of the async iife + name: "await (for..of loop)", + expression: "for (let i of []) {}; var b = await 1;", + newExpression: `var b; + + (async () => { + for (let i of []) {} + + return (b = await 1); + })()`, + shouldMapBindings: false, + expectedMapped: { + await: true, + bindings: false, + originalExpression: false, + }, + }, + { + name: "simple", + expression: "a", + newExpression: "a", + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: false, + originalExpression: false, + }, + }, + { + name: "mappings", + expression: "a", + newExpression: "_a", + bindings: [], + mappings: { + a: "_a", + }, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: false, + originalExpression: true, + }, + }, + { + name: "declaration", + expression: "var a = 3;", + newExpression: "self.a = 3", + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "declaration + destructuring", + expression: "var { a } = { a: 3 };", + newExpression: "({ a: self.a } = {\n a: 3 \n})", + bindings: [], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings", + expression: "var a = 3;", + newExpression: "a = 3", + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings + destructuring", + expression: "var { a } = { a: 3 };", + newExpression: "({ a } = { \n a: 3 \n })", + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings + destructuring + rest", + expression: "var { a, ...foo } = {}", + newExpression: "({ a, ...self.foo } = {})", + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings + array destructuring + rest", + expression: "var [a, ...foo] = []", + newExpression: "([a, ...self.foo] = [])", + bindings: ["a"], + mappings: {}, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings + mappings", + expression: "a = 3;", + newExpression: "self.a = 3", + bindings: ["_a"], + mappings: { a: "_a" }, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings + mappings + destructuring", + expression: "var { a } = { a: 4 }", + newExpression: "({ a: self.a } = {\n a: 4 \n})", + bindings: ["_a"], + mappings: { a: "_a" }, + shouldMapBindings: true, + expectedMapped: { + await: false, + bindings: true, + originalExpression: false, + }, + }, + { + name: "bindings without mappings", + expression: "a = 3;", + newExpression: "a = 3", + bindings: [], + mappings: { a: "_a" }, + shouldMapBindings: false, + expectedMapped: { + await: false, + bindings: false, + originalExpression: false, + }, + }, + { + name: "object destructuring + bindings without mappings", + expression: "({ a } = {});", + newExpression: "({ a: _a } = {})", + bindings: [], + mappings: { a: "_a" }, + shouldMapBindings: false, + expectedMapped: { + await: false, + bindings: false, + originalExpression: true, + }, + }, + ]); +}); diff --git a/devtools/client/debugger/src/workers/parser/tests/mapOriginalExpression.spec.js b/devtools/client/debugger/src/workers/parser/tests/mapOriginalExpression.spec.js new file mode 100644 index 0000000000..028c86b5fe --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/mapOriginalExpression.spec.js @@ -0,0 +1,93 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import mapExpression from "../mapExpression"; +import { format } from "prettier"; + +const formatOutput = output => + format(output, { + parser: "babel", + }); + +const mapOriginalExpression = (expression, mappings) => + mapExpression(expression, mappings, [], false, false).expression; + +describe("mapOriginalExpression", () => { + it("simple", () => { + const generatedExpression = mapOriginalExpression("a + b;", { + a: "foo", + b: "bar", + }); + expect(generatedExpression).toEqual("foo + bar;"); + }); + + it("this", () => { + const generatedExpression = mapOriginalExpression("this.prop;", { + this: "_this", + }); + expect(generatedExpression).toEqual("_this.prop;"); + }); + + it("member expressions", () => { + const generatedExpression = mapOriginalExpression("a + b", { + a: "_mod.foo", + b: "_mod.bar", + }); + expect(generatedExpression).toEqual("_mod.foo + _mod.bar;"); + }); + + it("block", () => { + // todo: maybe wrap with parens () + const generatedExpression = mapOriginalExpression("{a}", { + a: "_mod.foo", + b: "_mod.bar", + }); + expect(generatedExpression).toEqual("{\n _mod.foo;\n}"); + }); + + it("skips codegen with no mappings", () => { + const generatedExpression = mapOriginalExpression("a + b", { + a: "a", + c: "_c", + }); + expect(generatedExpression).toEqual("a + b"); + }); + + it("object destructuring", () => { + const generatedExpression = mapOriginalExpression("({ a } = { a: 4 })", { + a: "_mod.foo", + }); + + expect(formatOutput(generatedExpression)).toEqual( + formatOutput("({ a: _mod.foo } = {\n a: 4 \n})") + ); + }); + + it("nested object destructuring", () => { + const generatedExpression = mapOriginalExpression( + "({ a: { b, c } } = { a: 4 })", + { + a: "_mod.foo", + b: "_mod.bar", + } + ); + + expect(formatOutput(generatedExpression)).toEqual( + formatOutput("({ a: { b: _mod.bar, c } } = {\n a: 4 \n})") + ); + }); + + it("shadowed bindings", () => { + const generatedExpression = mapOriginalExpression( + "window.thing = function fn(){ var a; a; b; }; a; b; ", + { + a: "_a", + b: "_b", + } + ); + expect(generatedExpression).toEqual( + "window.thing = function fn() {\n var a;\n a;\n _b;\n};\n\n_a;\n_b;" + ); + }); +}); diff --git a/devtools/client/debugger/src/workers/parser/tests/sources.spec.js b/devtools/client/debugger/src/workers/parser/tests/sources.spec.js new file mode 100644 index 0000000000..e84ae4ad22 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/sources.spec.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSource } from "../sources"; + +describe("sources", () => { + it("fail getSource", () => { + const sourceId = "some.nonexistent.source.id"; + expect(() => { + getSource(sourceId); + }).toThrow(); + }); +}); diff --git a/devtools/client/debugger/src/workers/parser/tests/validate.spec.js b/devtools/client/debugger/src/workers/parser/tests/validate.spec.js new file mode 100644 index 0000000000..e7edefe472 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/tests/validate.spec.js @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { hasSyntaxError } from "../validate"; + +describe("has syntax error", () => { + it("should return false", () => { + expect(hasSyntaxError("foo")).toEqual(false); + }); + + it("should return the error object for the invalid expression", () => { + expect(hasSyntaxError("foo)(")).toMatchSnapshot(); + }); +}); diff --git a/devtools/client/debugger/src/workers/parser/utils/ast.js b/devtools/client/debugger/src/workers/parser/utils/ast.js new file mode 100644 index 0000000000..2adbcd9c7c --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/ast.js @@ -0,0 +1,225 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import parseScriptTags from "parse-script-tags"; +import * as babelParser from "@babel/parser"; +import * as t from "@babel/types"; +import { getSource } from "../sources"; + +let ASTs = new Map(); + +function _parse(code, opts) { + return babelParser.parse(code, { + ...opts, + tokens: true, + }); +} + +const sourceOptions = { + generated: { + sourceType: "unambiguous", + tokens: true, + plugins: [ + "classStaticBlock", + "classPrivateProperties", + "classPrivateMethods", + "classProperties", + "objectRestSpread", + "optionalChaining", + "privateIn", + "nullishCoalescingOperator", + ], + }, + original: { + sourceType: "unambiguous", + tokens: true, + plugins: [ + "jsx", + "flow", + "doExpressions", + "optionalChaining", + "nullishCoalescingOperator", + "decorators-legacy", + "objectRestSpread", + "classStaticBlock", + "classPrivateProperties", + "classPrivateMethods", + "classProperties", + "exportDefaultFrom", + "exportNamespaceFrom", + "asyncGenerators", + "functionBind", + "functionSent", + "dynamicImport", + "react-jsx", + ], + }, +}; + +export function parse(text, opts) { + let ast = {}; + if (!text) { + return ast; + } + + try { + ast = _parse(text, opts); + } catch (error) { + console.error(error); + } + + return ast; +} + +// Custom parser for parse-script-tags that adapts its input structure to +// our parser's signature +function htmlParser({ source, line }) { + return parse(source, { startLine: line, ...sourceOptions.generated }); +} + +const VUE_COMPONENT_START = /^\s* + p !== "flow" && + p !== "decorators" && + p !== "decorators2" && + (p !== "jsx" || contentType.match(/typescript-jsx/)) + ), + "decorators-legacy", + "typescript", + ], + }; + ast = parse(source.text, options); + } + + ASTs.set(source.id, ast); + return ast; +} + +export function clearASTs() { + ASTs = new Map(); +} + +export function traverseAst(sourceId, visitor, state) { + const ast = getAst(sourceId); + if (!ast || !Object.keys(ast).length) { + return null; + } + + t.traverse(ast, visitor, state); + return ast; +} + +export function hasNode(rootNode, predicate) { + try { + t.traverse(rootNode, { + enter: (node, ancestors) => { + if (predicate(node, ancestors)) { + throw new Error("MATCH"); + } + }, + }); + } catch (e) { + if (e.message === "MATCH") { + return true; + } + } + return false; +} + +export function replaceNode(ancestors, node) { + const parent = ancestors[ancestors.length - 1]; + + if (typeof parent.index === "number") { + if (Array.isArray(node)) { + parent.node[parent.key].splice(parent.index, 1, ...node); + } else { + parent.node[parent.key][parent.index] = node; + } + } else { + parent.node[parent.key] = node; + } +} diff --git a/devtools/client/debugger/src/workers/parser/utils/contains.js b/devtools/client/debugger/src/workers/parser/utils/contains.js new file mode 100644 index 0000000000..ed4cb31c1d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/contains.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +function startsBefore(a, b) { + let before = a.start.line < b.line; + if (a.start.line === b.line) { + before = + a.start.column >= 0 && b.column >= 0 ? a.start.column <= b.column : true; + } + return before; +} + +function endsAfter(a, b) { + let after = a.end.line > b.line; + if (a.end.line === b.line) { + after = + a.end.column >= 0 && b.column >= 0 ? a.end.column >= b.column : true; + } + return after; +} + +export function containsPosition(a, b) { + return startsBefore(a, b) && endsAfter(a, b); +} + +export function containsLocation(a, b) { + return containsPosition(a, b.start) && containsPosition(a, b.end); +} diff --git a/devtools/client/debugger/src/workers/parser/utils/formatSymbols.js b/devtools/client/debugger/src/workers/parser/utils/formatSymbols.js new file mode 100644 index 0000000000..3bcf37e7c4 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/formatSymbols.js @@ -0,0 +1,65 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSymbols } from "../getSymbols"; + +function formatLocation(loc) { + if (!loc) { + return ""; + } + + const { start, end } = loc; + const startLoc = `(${start.line}, ${start.column})`; + const endLoc = `(${end.line}, ${end.column})`; + + return `[${startLoc}, ${endLoc}]`; +} + +function summarize(symbol) { + if (typeof symbol == "boolean") { + return symbol ? "true" : "false"; + } + + const loc = formatLocation(symbol.location); + const params = symbol.parameterNames + ? `(${symbol.parameterNames.join(", ")})` + : ""; + const expression = symbol.expression || ""; + const klass = symbol.klass || ""; + const name = symbol.name == undefined ? "" : symbol.name; + const names = symbol.specifiers ? symbol.specifiers.join(", ") : ""; + const values = symbol.values ? symbol.values.join(", ") : ""; + const index = symbol.index ? symbol.index : ""; + + return `${loc} ${expression} ${name}${params} ${klass} ${names} ${values} ${index}`.trim(); // eslint-disable-line max-len +} +const bools = ["hasJsx", "hasTypes"]; +const strings = ["framework"]; +function formatBool(name, symbols) { + return `${name}: ${symbols[name] ? "true" : "false"}`; +} + +function formatString(name, symbols) { + return `${name}: ${symbols[name]}`; +} + +function formatKey(name, symbols) { + if (bools.includes(name)) { + return formatBool(name, symbols); + } + + if (strings.includes(name)) { + return formatString(name, symbols); + } + + return `${name}:\n${symbols[name].map(summarize).join("\n")}`; +} + +export function formatSymbols(sourceId) { + const symbols = getSymbols(sourceId); + + return Object.keys(symbols) + .map(name => formatKey(name, symbols)) + .join("\n\n"); +} diff --git a/devtools/client/debugger/src/workers/parser/utils/getFunctionName.js b/devtools/client/debugger/src/workers/parser/utils/getFunctionName.js new file mode 100644 index 0000000000..1fe85a5c69 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/getFunctionName.js @@ -0,0 +1,96 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import * as t from "@babel/types"; + +// Perform ES6's anonymous function name inference for all +// locations where static analysis is possible. +// eslint-disable-next-line complexity +export default function getFunctionName(node, parent) { + if (t.isIdentifier(node.id)) { + return node.id.name; + } + + if ( + t.isObjectMethod(node, { computed: false }) || + t.isClassMethod(node, { computed: false }) || + t.isClassPrivateMethod(node) + ) { + const { key } = node; + + if (t.isIdentifier(key)) { + return key.name; + } + if (t.isStringLiteral(key)) { + return key.value; + } + if (t.isNumericLiteral(key)) { + return `${key.value}`; + } + + if (t.isPrivateName(key)) { + return `#${key.id.name}`; + } + } + + if ( + t.isObjectProperty(parent, { computed: false, value: node }) || + // TODO: Babylon 6 doesn't support computed class props. It is included + // here so that it is most flexible. Once Babylon 7 is used, this + // can change to use computed: false like ObjectProperty. + (t.isClassProperty(parent, { value: node }) && !parent.computed) || + (t.isClassPrivateProperty(parent, { value: node }) && !parent.computed) + ) { + const { key } = parent; + + if (t.isIdentifier(key)) { + return key.name; + } + if (t.isStringLiteral(key)) { + return key.value; + } + if (t.isNumericLiteral(key)) { + return `${key.value}`; + } + + if (t.isPrivateName(key)) { + return `#${key.id.name}`; + } + } + + if (t.isAssignmentExpression(parent, { operator: "=", right: node })) { + if (t.isIdentifier(parent.left)) { + return parent.left.name; + } + + // This case is not supported in standard ES6 name inference, but it + // is included here since it is still a helpful case during debugging. + if (t.isMemberExpression(parent.left, { computed: false })) { + return parent.left.property.name; + } + } + + if ( + t.isAssignmentPattern(parent, { right: node }) && + t.isIdentifier(parent.left) + ) { + return parent.left.name; + } + + if ( + t.isVariableDeclarator(parent, { init: node }) && + t.isIdentifier(parent.id) + ) { + return parent.id.name; + } + + if ( + t.isExportDefaultDeclaration(parent, { declaration: node }) && + t.isFunctionDeclaration(node) + ) { + return "default"; + } + + return "anonymous"; +} diff --git a/devtools/client/debugger/src/workers/parser/utils/helpers.js b/devtools/client/debugger/src/workers/parser/utils/helpers.js new file mode 100644 index 0000000000..0850ea678c --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/helpers.js @@ -0,0 +1,230 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import * as t from "@babel/types"; +import generate from "@babel/generator"; + +export function isFunction(node) { + return ( + t.isFunction(node) || + t.isArrowFunctionExpression(node) || + t.isObjectMethod(node) || + t.isClassMethod(node) + ); +} + +export function isAwaitExpression(path) { + const { node, parent } = path; + return ( + t.isAwaitExpression(node) || + t.isAwaitExpression(parent.init) || + t.isAwaitExpression(parent) + ); +} + +export function isYieldExpression(path) { + const { node, parent } = path; + return ( + t.isYieldExpression(node) || + t.isYieldExpression(parent.init) || + t.isYieldExpression(parent) + ); +} + +export function isObjectShorthand(parent) { + if (!t.isObjectProperty(parent)) { + return false; + } + + if (parent.value && parent.value.left) { + return ( + parent.value.type === "AssignmentPattern" && + parent.value.left.type === "Identifier" + ); + } + + return ( + parent.value && + parent.key.start == parent.value.start && + parent.key.loc.identifierName === parent.value.loc.identifierName + ); +} + +export function getObjectExpressionValue(node) { + const { value } = node; + + if (t.isIdentifier(value)) { + return value.name; + } + + if (t.isCallExpression(value) || t.isFunctionExpression(value)) { + return ""; + } + const code = generate(value).code; + + const shouldWrap = t.isObjectExpression(value); + return shouldWrap ? `(${code})` : code; +} + +export function getCode(node) { + return generate(node).code; +} + +export function getComments(ast) { + if (!ast || !ast.comments) { + return []; + } + return ast.comments.map(comment => ({ + name: comment.location, + location: comment.loc, + })); +} + +export function getSpecifiers(specifiers) { + if (!specifiers) { + return []; + } + + return specifiers.map(specifier => specifier.local?.name); +} + +export function isComputedExpression(expression) { + return /^\[/m.test(expression); +} + +export function getMemberExpression(root) { + function _getMemberExpression(node, expr) { + if (t.isMemberExpression(node)) { + expr = [node.property.name].concat(expr); + return _getMemberExpression(node.object, expr); + } + + if (t.isCallExpression(node)) { + return []; + } + + if (t.isThisExpression(node)) { + return ["this"].concat(expr); + } + + return [node.name].concat(expr); + } + + const expr = _getMemberExpression(root, []); + return expr.join("."); +} + +export function getVariables(dec) { + if (!dec.id) { + return []; + } + + if (t.isArrayPattern(dec.id)) { + if (!dec.id.elements) { + return []; + } + + // NOTE: it's possible that an element is empty or has several variables + // e.g. const [, a] = arr + // e.g. const [{a, b }] = 2 + return dec.id.elements + .filter(Boolean) + .map(element => ({ + name: t.isAssignmentPattern(element) + ? element.left.name + : element.name || element.argument?.name, + location: element.loc, + })) + .filter(({ name }) => name); + } + + return [ + { + name: dec.id.name, + location: dec.loc, + }, + ]; +} + +export function getPatternIdentifiers(pattern) { + let items = []; + if (t.isObjectPattern(pattern)) { + items = pattern.properties.map(({ value }) => value); + } + + if (t.isArrayPattern(pattern)) { + items = pattern.elements; + } + + return getIdentifiers(items); +} + +function getIdentifiers(items) { + let ids = []; + items.forEach(function (item) { + if (t.isObjectPattern(item) || t.isArrayPattern(item)) { + ids = ids.concat(getPatternIdentifiers(item)); + } else if (t.isIdentifier(item)) { + const { start, end } = item.loc; + ids.push({ + name: item.name, + expression: item.name, + location: { start, end }, + }); + } + }); + return ids; +} + +// Top Level checks the number of "body" nodes in the ancestor chain +// if the node is top-level, then it shoul only have one body. +export function isTopLevel(ancestors) { + return ancestors.filter(ancestor => ancestor.key == "body").length == 1; +} + +export function nodeLocationKey(a) { + const { start, end } = a.location; + return `${start.line}:${start.column}:${end.line}:${end.column}`; +} + +export function getFunctionParameterNames(path) { + if (path.node.params != null) { + return path.node.params.map(param => { + if (param.type !== "AssignmentPattern") { + return param.name; + } + + // Parameter with default value + if ( + param.left.type === "Identifier" && + param.right.type === "Identifier" + ) { + return `${param.left.name} = ${param.right.name}`; + } else if ( + param.left.type === "Identifier" && + param.right.type === "StringLiteral" + ) { + return `${param.left.name} = ${param.right.value}`; + } else if ( + param.left.type === "Identifier" && + param.right.type === "ObjectExpression" + ) { + return `${param.left.name} = {}`; + } else if ( + param.left.type === "Identifier" && + param.right.type === "ArrayExpression" + ) { + return `${param.left.name} = []`; + } else if ( + param.left.type === "Identifier" && + param.right.type === "NullLiteral" + ) { + return `${param.left.name} = null`; + } + + return null; + }); + } + return []; +} diff --git a/devtools/client/debugger/src/workers/parser/utils/inferClassName.js b/devtools/client/debugger/src/workers/parser/utils/inferClassName.js new file mode 100644 index 0000000000..09d25f275d --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/inferClassName.js @@ -0,0 +1,93 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import * as t from "@babel/types"; + +// the function class is inferred from a call like +// createClass or extend +function fromCallExpression(callExpression) { + const allowlist = ["extend", "createClass"]; + const { callee } = callExpression.node; + if (!callee) { + return null; + } + + const name = t.isMemberExpression(callee) + ? callee.property.name + : callee.name; + + if (!allowlist.includes(name)) { + return null; + } + + const variable = callExpression.findParent(p => + t.isVariableDeclarator(p.node) + ); + if (variable) { + return variable.node.id.name; + } + + const assignment = callExpression.findParent(p => + t.isAssignmentExpression(p.node) + ); + + if (!assignment) { + return null; + } + + const { left } = assignment.node; + + if (left.name) { + return name; + } + + if (t.isMemberExpression(left)) { + return left.property.name; + } + + return null; +} + +// the function class is inferred from a prototype assignment +// e.g. TodoClass.prototype.render = function() {} +function fromPrototype(assignment) { + const { left } = assignment.node; + if (!left) { + return null; + } + + if ( + t.isMemberExpression(left) && + left.object && + t.isMemberExpression(left.object) && + left.object.property.identifier === "prototype" + ) { + return left.object.object.name; + } + + return null; +} + +// infer class finds an appropriate class for functions +// that are defined inside of a class like thing. +// e.g. `class Foo`, `TodoClass.prototype.foo`, +// `Todo = createClass({ foo: () => {}})` +export function inferClassName(path) { + const classDeclaration = path.findParent(p => t.isClassDeclaration(p.node)); + if (classDeclaration) { + return classDeclaration.node.id.name; + } + + const callExpression = path.findParent(p => t.isCallExpression(p.node)); + if (callExpression) { + return fromCallExpression(callExpression); + } + + const assignment = path.findParent(p => t.isAssignmentExpression(p.node)); + if (assignment) { + return fromPrototype(assignment); + } + + return null; +} diff --git a/devtools/client/debugger/src/workers/parser/utils/simple-path.js b/devtools/client/debugger/src/workers/parser/utils/simple-path.js new file mode 100644 index 0000000000..c167103566 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/simple-path.js @@ -0,0 +1,147 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +export default function createSimplePath(ancestors) { + if (ancestors.length === 0) { + return null; + } + + // Slice the array because babel-types traverse may continue mutating + // the ancestors array in later traversal logic. + return new SimplePath(ancestors.slice()); +} + +/** + * Mimics @babel/traverse's NodePath API in a simpler fashion that isn't as + * heavy, but still allows the ease of passing paths around to process nested + * AST structures. + */ +class SimplePath { + _index; + _ancestors; + _ancestor; + + _parentPath; + + constructor(ancestors, index = ancestors.length - 1) { + if (index < 0 || index >= ancestors.length) { + console.error(ancestors); + throw new Error("Created invalid path"); + } + + this._ancestors = ancestors; + this._ancestor = ancestors[index]; + this._index = index; + } + + get parentPath() { + let path = this._parentPath; + if (path === undefined) { + if (this._index === 0) { + path = null; + } else { + path = new SimplePath(this._ancestors, this._index - 1); + } + this._parentPath = path; + } + + return path; + } + + get parent() { + return this._ancestor.node; + } + + get node() { + const { node, key, index } = this._ancestor; + + if (typeof index === "number") { + return node[key][index]; + } + + return node[key]; + } + + get key() { + return this._ancestor.key; + } + + set node(replacement) { + if (this.type !== "Identifier") { + throw new Error( + "Replacing anything other than leaf nodes is undefined behavior " + + "in t.traverse()" + ); + } + + const { node, key, index } = this._ancestor; + if (typeof index === "number") { + node[key][index] = replacement; + } else { + node[key] = replacement; + } + } + + get type() { + return this.node.type; + } + + get inList() { + return typeof this._ancestor.index === "number"; + } + + get containerIndex() { + const { index } = this._ancestor; + + if (typeof index !== "number") { + throw new Error("Cannot get index of non-array node"); + } + + return index; + } + + get depth() { + return this._index; + } + + replace(node) { + this.node = node; + } + + find(predicate) { + for (let path = this; path; path = path.parentPath) { + if (predicate(path)) { + return path; + } + } + return null; + } + + findParent(predicate) { + if (!this.parentPath) { + throw new Error("Cannot use findParent on root path"); + } + + return this.parentPath.find(predicate); + } + + getSibling(offset) { + const { node, key, index } = this._ancestor; + + if (typeof index !== "number") { + throw new Error("Non-array nodes do not have siblings"); + } + + const container = node[key]; + + const siblingIndex = index + offset; + if (siblingIndex < 0 || siblingIndex >= container.length) { + return null; + } + + return new SimplePath( + this._ancestors.slice(0, -1).concat([{ node, key, index: siblingIndex }]) + ); + } +} diff --git a/devtools/client/debugger/src/workers/parser/utils/tests/ast.spec.js b/devtools/client/debugger/src/workers/parser/utils/tests/ast.spec.js new file mode 100644 index 0000000000..e8d2964205 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/utils/tests/ast.spec.js @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getAst } from "../ast"; +import { setSource } from "../../sources"; +import cases from "jest-in-case"; + +import { makeMockSourceAndContent } from "../../../../utils/test-mockup"; + +const astKeys = [ + "type", + "start", + "end", + "loc", + "errors", + "program", + "comments", + "tokens", +]; + +cases( + "ast.getAst", + ({ name }) => { + const source = makeMockSourceAndContent(undefined, "foo", name, "2"); + setSource({ + id: source.id, + text: source.content.value || "", + contentType: source.content.contentType, + isWasm: false, + }); + const ast = getAst("foo"); + expect(ast && Object.keys(ast)).toEqual(astKeys); + }, + [ + { name: "text/javascript" }, + { name: "application/javascript" }, + { name: "application/x-javascript" }, + { name: "text/jsx" }, + ] +); diff --git a/devtools/client/debugger/src/workers/parser/validate.js b/devtools/client/debugger/src/workers/parser/validate.js new file mode 100644 index 0000000000..d01e76668a --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/validate.js @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { parseScript } from "./utils/ast"; + +export function hasSyntaxError(input) { + try { + parseScript(input); + return false; + } catch (e) { + return `${e.name} : ${e.message}`; + } +} diff --git a/devtools/client/debugger/src/workers/parser/worker.js b/devtools/client/debugger/src/workers/parser/worker.js new file mode 100644 index 0000000000..caa49cd482 --- /dev/null +++ b/devtools/client/debugger/src/workers/parser/worker.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { getSymbols, clearSymbols } from "./getSymbols"; +import { clearASTs } from "./utils/ast"; +import getScopes, { clearScopes } from "./getScopes"; +import { setSource, clearSources } from "./sources"; +import findOutOfScopeLocations from "./findOutOfScopeLocations"; +import { hasSyntaxError } from "./validate"; +import mapExpression from "./mapExpression"; + +import { workerHandler } from "../../../../shared/worker-utils"; + +function clearState() { + clearASTs(); + clearScopes(); + clearSources(); + clearSymbols(); +} + +self.onmessage = workerHandler({ + findOutOfScopeLocations, + getSymbols, + getScopes, + clearState, + hasSyntaxError, + mapExpression, + setSource, +}); diff --git a/devtools/client/debugger/src/workers/pretty-print/LICENSE.md b/devtools/client/debugger/src/workers/pretty-print/LICENSE.md new file mode 100644 index 0000000000..cc8e9a752c --- /dev/null +++ b/devtools/client/debugger/src/workers/pretty-print/LICENSE.md @@ -0,0 +1,23 @@ +Copyright (c) 2013, Nick Fitzgerald +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/devtools/client/debugger/src/workers/pretty-print/index.js b/devtools/client/debugger/src/workers/pretty-print/index.js new file mode 100644 index 0000000000..4b151b39e4 --- /dev/null +++ b/devtools/client/debugger/src/workers/pretty-print/index.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { WorkerDispatcher } from "devtools/client/shared/worker-utils"; + +const WORKER_URL = + "resource://devtools/client/debugger/dist/pretty-print-worker.js"; + +export class PrettyPrintDispatcher extends WorkerDispatcher { + constructor(jestUrl) { + super(jestUrl || WORKER_URL); + } + + #prettyPrintTask = this.task("prettyPrint"); + #prettyPrintInlineScriptTask = this.task("prettyPrintInlineScript"); + #getSourceMapForTask = this.task("getSourceMapForTask"); + + prettyPrint(options) { + return this.#prettyPrintTask(options); + } + + prettyPrintInlineScript(options) { + return this.#prettyPrintInlineScriptTask(options); + } + + getSourceMap(taskId) { + return this.#getSourceMapForTask(taskId); + } +} diff --git a/devtools/client/debugger/src/workers/pretty-print/moz.build b/devtools/client/debugger/src/workers/pretty-print/moz.build new file mode 100644 index 0000000000..b7223ac81a --- /dev/null +++ b/devtools/client/debugger/src/workers/pretty-print/moz.build @@ -0,0 +1,10 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "index.js", +) diff --git a/devtools/client/debugger/src/workers/pretty-print/pretty-fast.js b/devtools/client/debugger/src/workers/pretty-print/pretty-fast.js new file mode 100644 index 0000000000..44b07f4eda --- /dev/null +++ b/devtools/client/debugger/src/workers/pretty-print/pretty-fast.js @@ -0,0 +1,1178 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* eslint-disable complexity */ + +var acorn = require("acorn"); +var sourceMap = require("source-map"); +const NEWLINE_CODE = 10; + +export function prettyFast(input, options) { + return new PrettyFast(options).getPrettifiedCodeAndSourceMap(input); +} + +// If any of these tokens are seen before a "[" token, we know that "[" token +// is the start of an array literal, rather than a property access. +// +// The only exception is "}", which would need to be disambiguated by +// parsing. The majority of the time, an open bracket following a closing +// curly is going to be an array literal, so we brush the complication under +// the rug, and handle the ambiguity by always assuming that it will be an +// array literal. +const PRE_ARRAY_LITERAL_TOKENS = new Set([ + "typeof", + "void", + "delete", + "case", + "do", + "=", + "in", + "of", + "...", + "{", + "*", + "/", + "%", + "else", + ";", + "++", + "--", + "+", + "-", + "~", + "!", + ":", + "?", + ">>", + ">>>", + "<<", + "||", + "&&", + "<", + ">", + "<=", + ">=", + "instanceof", + "&", + "^", + "|", + "==", + "!=", + "===", + "!==", + ",", + "}", +]); + +// If any of these tokens are seen before a "{" token, we know that "{" token +// is the start of an object literal, rather than the start of a block. +const PRE_OBJECT_LITERAL_TOKENS = new Set([ + "typeof", + "void", + "delete", + "=", + "in", + "of", + "...", + "*", + "/", + "%", + "++", + "--", + "+", + "-", + "~", + "!", + ">>", + ">>>", + "<<", + "<", + ">", + "<=", + ">=", + "instanceof", + "&", + "^", + "|", + "==", + "!=", + "===", + "!==", +]); + +class PrettyFast { + /** + * @param {Object} options: Provides configurability of the pretty printing. + * @param {String} options.url: The URL string of the ugly JS code. + * @param {String} options.indent: The string to indent code by. + * @param {SourceMapGenerator} options.sourceMapGenerator: An optional sourceMapGenerator + * the mappings will be added to. + * @param {Boolean} options.prefixWithNewLine: When true, the pretty printed code will start + * with a line break + * @param {Integer} options.originalStartLine: The line the passed script starts at (1-based). + * This is used for inline scripts where we need to account for the lines + * before the script tag + * @param {Integer} options.originalStartColumn: The column the passed script starts at (1-based). + * This is used for inline scripts where we need to account for the position + * of the script tag within the line. + * @param {Integer} options.generatedStartLine: The line where the pretty printed script + * will start at (1-based). This is used for pretty printing HTML file, + * where we might have handle previous inline scripts that impact the + * position of this script. + */ + constructor(options = {}) { + // The level of indents deep we are. + this.#indentLevel = 0; + this.#indentChar = options.indent; + + // We will handle mappings between ugly and pretty printed code in this SourceMapGenerator. + this.#sourceMapGenerator = + options.sourceMapGenerator || + new sourceMap.SourceMapGenerator({ + file: options.url, + }); + + this.#file = options.url; + this.#hasOriginalStartLine = "originalStartLine" in options; + this.#hasOriginalStartColumn = "originalStartColumn" in options; + this.#hasGeneratedStartLine = "generatedStartLine" in options; + this.#originalStartLine = options.originalStartLine; + this.#originalStartColumn = options.originalStartColumn; + this.#generatedStartLine = options.generatedStartLine; + this.#prefixWithNewLine = options.prefixWithNewLine; + } + + /* options */ + #indentChar; + #indentLevel; + #file; + #hasOriginalStartLine; + #hasOriginalStartColumn; + #hasGeneratedStartLine; + #originalStartLine; + #originalStartColumn; + #prefixWithNewLine; + #generatedStartLine; + #sourceMapGenerator; + + /* internals */ + + // Whether or not we added a newline on after we added the previous token. + #addedNewline = false; + // Whether or not we added a space after we added the previous token. + #addedSpace = false; + #currentCode = ""; + #currentLine = 1; + #currentColumn = 0; + // The tokens parsed by acorn. + #tokenQueue; + // The index of the current token in this.#tokenQueue. + #currentTokenIndex; + // The previous token we added to the pretty printed code. + #previousToken; + // Stack of token types/keywords that can affect whether we want to add a + // newline or a space. We can make that decision based on what token type is + // on the top of the stack. For example, a comma in a parameter list should + // be followed by a space, while a comma in an object literal should be + // followed by a newline. + // + // Strings that go on the stack: + // + // - "{" + // - "{\n" + // - "(" + // - "(\n" + // - "[" + // - "[\n" + // - "do" + // - "?" + // - "switch" + // - "case" + // - "default" + // + // The difference between "[" and "[\n" (as well as "{" and "{\n", and "(" and "(\n") + // is that "\n" is used when we are treating (curly) brackets/parens as line delimiters + // and should increment and decrement the indent level when we find them. + // "[" can represent either a property access (e.g. `x["hi"]`), or an empty array literal + // "{" only represents an empty object literals + // "(" can represent lots of different things (wrapping expression, if/loop condition, function call, …) + #stack = []; + + /** + * @param {String} input: The ugly JS code we want to pretty print. + * @returns {Object} + * An object with the following properties: + * - code: The pretty printed code string. + * - map: A SourceMapGenerator instance. + */ + getPrettifiedCodeAndSourceMap(input) { + // Add the initial new line if needed + if (this.#prefixWithNewLine) { + this.#write("\n"); + } + + // Pass through acorn's tokenizer and append tokens and comments into a + // single queue to process. For example, the source file: + // + // foo + // // a + // // b + // bar + // + // After this process, tokenQueue has the following token stream: + // + // [ foo, '// a', '// b', bar] + this.#tokenQueue = this.#getTokens(input); + + for (let i = 0, len = this.#tokenQueue.length; i < len; i++) { + this.#currentTokenIndex = i; + const token = this.#tokenQueue[i]; + const nextToken = this.#tokenQueue[i + 1]; + this.#handleToken(token, nextToken); + + // Acorn's tokenizer re-uses tokens, so we have to copy the previous token on + // every iteration. We follow acorn's lead here, and reuse the previousToken + // object the same way that acorn reuses the token object. This allows us + // to avoid allocations and minimize GC pauses. + if (!this.#previousToken) { + this.#previousToken = { loc: { start: {}, end: {} } }; + } + this.#previousToken.start = token.start; + this.#previousToken.end = token.end; + this.#previousToken.loc.start.line = token.loc.start.line; + this.#previousToken.loc.start.column = token.loc.start.column; + this.#previousToken.loc.end.line = token.loc.end.line; + this.#previousToken.loc.end.column = token.loc.end.column; + this.#previousToken.type = token.type; + this.#previousToken.value = token.value; + } + + return { code: this.#currentCode, map: this.#sourceMapGenerator }; + } + + /** + * Write a pretty printed string to the prettified string and for tokens, add their + * mapping to the SourceMapGenerator. + * + * @param String str + * The string to be added to the result. + * @param Number line + * The line number the string came from in the ugly source. + * @param Number column + * The column number the string came from in the ugly source. + * @param Boolean isToken + * Set to true when writing tokens, so we can differentiate them from the + * whitespace we add. + */ + #write(str, line, column, isToken) { + this.#currentCode += str; + if (isToken) { + this.#sourceMapGenerator.addMapping({ + source: this.#file, + // We need to swap original and generated locations, as the prettified text should + // be seen by the sourcemap service as the "original" one. + generated: { + // originalStartLine is 1-based, and here we just want to offset by a number of + // lines, so we need to decrement it + line: this.#hasOriginalStartLine + ? line + (this.#originalStartLine - 1) + : line, + // We only need to adjust the column number if we're looking at the first line, to + // account for the html text before the opening + * ``` + * + * We want the text to start on a new line, so prepend a line break, so we get + * something like: + * + * ``` + * + * ``` + */ + prefixWithNewLine: true, + originalStartLine, + originalStartColumn, + generatedStartLine, + }); + + // When a taskId was passed, we only return the pretty printed text. + // The source map should be retrieved with getSourceMapForTask. + return code; +} + +/** + * Get the source map for a pretty-print task + * + * @param {Integer} taskId: The taskId that was used to call prettyPrint + * @returns {Object} A source map object + */ +function getSourceMapForTask(taskId) { + if (!sourceMapGeneratorByTaskId.has(taskId)) { + return null; + } + + const taskSourceMapGenerator = sourceMapGeneratorByTaskId.get(taskId); + sourceMapGeneratorByTaskId.delete(taskId); + return taskSourceMapGenerator.toJSON(); +} + +self.onmessage = workerHandler({ + prettyPrint, + prettyPrintInlineScript, + getSourceMapForTask, +}); diff --git a/devtools/client/debugger/src/workers/search/get-matches.js b/devtools/client/debugger/src/workers/search/get-matches.js new file mode 100644 index 0000000000..972dea6818 --- /dev/null +++ b/devtools/client/debugger/src/workers/search/get-matches.js @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import assert from "../../utils/assert"; +import buildQuery from "../../utils/build-query"; + +export default function getMatches(query, text, options) { + if (!query || !text || !options) { + return []; + } + const regexQuery = buildQuery(query, options, { + isGlobal: true, + }); + const matchedLocations = []; + const lines = text.split("\n"); + for (let i = 0; i < lines.length; i++) { + let singleMatch; + const line = lines[i]; + while ((singleMatch = regexQuery.exec(line)) !== null) { + // Flow doesn't understand the test above. + if (!singleMatch) { + throw new Error("no singleMatch"); + } + + matchedLocations.push({ + line: i, + ch: singleMatch.index, + match: singleMatch[0], + }); + + // When the match is an empty string the regexQuery.lastIndex will not + // change resulting in an infinite loop so we need to check for this and + // increment it manually in that case. See issue #7023 + if (singleMatch[0] === "") { + assert( + !regexQuery.unicode, + "lastIndex++ can cause issues in unicode mode" + ); + regexQuery.lastIndex++; + } + } + } + return matchedLocations; +} diff --git a/devtools/client/debugger/src/workers/search/index.js b/devtools/client/debugger/src/workers/search/index.js new file mode 100644 index 0000000000..928bbf50e6 --- /dev/null +++ b/devtools/client/debugger/src/workers/search/index.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import { WorkerDispatcher } from "devtools/client/shared/worker-utils"; + +const WORKER_URL = "resource://devtools/client/debugger/dist/search-worker.js"; + +export class SearchDispatcher extends WorkerDispatcher { + constructor(jestUrl) { + super(jestUrl || WORKER_URL); + } + + getMatches = this.task("getMatches"); + + findSourceMatches = this.task("findSourceMatches"); +} diff --git a/devtools/client/debugger/src/workers/search/moz.build b/devtools/client/debugger/src/workers/search/moz.build new file mode 100644 index 0000000000..b7223ac81a --- /dev/null +++ b/devtools/client/debugger/src/workers/search/moz.build @@ -0,0 +1,10 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +DIRS += [] + +CompiledModules( + "index.js", +) diff --git a/devtools/client/debugger/src/workers/search/project-search.js b/devtools/client/debugger/src/workers/search/project-search.js new file mode 100644 index 0000000000..f3751b57c4 --- /dev/null +++ b/devtools/client/debugger/src/workers/search/project-search.js @@ -0,0 +1,70 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Maybe reuse file search's functions? + +import getMatches from "./get-matches"; + +export function findSourceMatches(content, queryText, options) { + if (queryText == "") { + return []; + } + + const text = content.value; + const lines = text.split("\n"); + + return getMatches(queryText, text, options).map(({ line, ch, match }) => { + const { value, matchIndex } = truncateLine(lines[line], ch); + return { + line: line + 1, + column: ch, + + matchIndex, + match, + value, + }; + }); +} + +// This is used to find start of a word, so that cropped string look nice +const startRegex = /([ !@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?])/g; +// Similarly, find +const endRegex = new RegExp( + [ + "([ !@#$%^&*()_+-=[]{};':\"\\|,.<>/?])", + '[^ !@#$%^&*()_+-=[]{};\':"\\|,.<>/?]*$"/', + ].join("") +); +// For texts over 100 characters this truncates the text (for display) +// around the context of the matched text. +function truncateLine(text, column) { + if (text.length < 100) { + return { + matchIndex: column, + value: text, + }; + } + + // Initially take 40 chars left to the match + const offset = Math.max(column - 40, 0); + // 400 characters should be enough to figure out the context of the match + const truncStr = text.slice(offset, column + 400); + let start = truncStr.search(startRegex); + let end = truncStr.search(endRegex); + + if (start > column) { + // No word separator found before the match, so we take all characters + // before the match + start = -1; + } + if (end < column) { + end = truncStr.length; + } + const value = truncStr.slice(start + 1, end); + + return { + matchIndex: column - start - offset - 1, + value, + }; +} diff --git a/devtools/client/debugger/src/workers/search/tests/get-matches.spec.js b/devtools/client/debugger/src/workers/search/tests/get-matches.spec.js new file mode 100644 index 0000000000..7b2da92d43 --- /dev/null +++ b/devtools/client/debugger/src/workers/search/tests/get-matches.spec.js @@ -0,0 +1,99 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import getMatches from "../get-matches"; + +describe("search", () => { + describe("getMatches", () => { + it("gets basic string match", () => { + const text = "the test string with test in it multiple times test."; + const query = "test"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: false, + }); + expect(matchLocations).toHaveLength(3); + }); + + it("gets basic string match case-sensitive", () => { + const text = "the Test string with test in it multiple times test."; + const query = "Test"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: false, + }); + expect(matchLocations).toHaveLength(1); + }); + + it("gets whole word string match", () => { + const text = "the test string test in it multiple times whoatestthe."; + const query = "test"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: true, + regexMatch: false, + }); + expect(matchLocations).toHaveLength(2); + }); + + it("gets regex match", () => { + const text = "the test string test in it multiple times whoatestthe."; + const query = "(\\w+)\\s+(\\w+)"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: true, + }); + expect(matchLocations).toHaveLength(4); + }); + + it("it doesnt fail on empty data", () => { + const text = ""; + const query = ""; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: true, + }); + expect(matchLocations).toHaveLength(0); + }); + + it("fails gracefully when the line is too long", () => { + const text = Array(100002).join("x"); + const query = "query"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: true, + }); + expect(matchLocations).toHaveLength(0); + }); + + // regression test for #6896 + it("doesn't crash on the regex 'a*'", () => { + const text = "abc"; + const query = "a*"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: true, + }); + expect(matchLocations).toHaveLength(4); + }); + + // regression test for #6896 + it("doesn't crash on the regex '^'", () => { + const text = "012"; + const query = "^"; + const matchLocations = getMatches(query, text, { + caseSensitive: true, + wholeWord: false, + regexMatch: true, + }); + expect(matchLocations).toHaveLength(1); + }); + }); +}); diff --git a/devtools/client/debugger/src/workers/search/worker.js b/devtools/client/debugger/src/workers/search/worker.js new file mode 100644 index 0000000000..b452697516 --- /dev/null +++ b/devtools/client/debugger/src/workers/search/worker.js @@ -0,0 +1,9 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +import getMatches from "./get-matches"; +import { findSourceMatches } from "./project-search"; +import { workerHandler } from "../../../../shared/worker-utils"; + +self.onmessage = workerHandler({ getMatches, findSourceMatches }); diff --git a/devtools/client/debugger/test/mochitest/browser.ini b/devtools/client/debugger/test/mochitest/browser.ini new file mode 100644 index 0000000000..91d898715e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser.ini @@ -0,0 +1,297 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +skip-if = + os == 'linux' && debug && bits == 32 + asan # Frequent failures when opening tabs due to OOM issues, bug 1760260 +support-files = + examples/* + integration-tests/* + head.js + shared-head.js + !/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js + !/devtools/client/inspector/test/head.js + !/devtools/client/inspector/test/shared-head.js + !/devtools/client/shared/test/shared-head.js + !/devtools/client/shared/test/telemetry-test-helpers.js + !/devtools/client/shared/test/highlighter-test-actor.js + !/devtools/client/webconsole/test/browser/shared-head.js +prefs = + # Disable randomly spawning processes during tests. + # After enabling windowless service workers, a process spawning + # will trigger an update of the service workers list which can + # fail the test if it occurs during shutdown (unhandled promise + # rejection). + dom.ipc.processPrelaunch.enabled=false + # This pref has to be set before the process starts + devtools.debugger.features.javascript-tracing=true + +# Integration tests: +[browser_dbg-integration-reloading-compressed-sourcemaps.js] +[browser_dbg-integration-reloading-uncompressed-sourcemaps.js] + +# Feature tests: +[browser_dbg-features-asm.js] +[browser_dbg-features-breakable-lines.js] +[browser_dbg-features-breakable-positions.js] +skip-if = + win11_2009 # Bug 1798331 +[browser_dbg-features-breakpoints.js] +[browser_dbg-features-source-tree.js] +[browser_dbg-features-browser-toolbox-source-tree.js] +skip-if = + asan # Bug 1591064 + win10_2004 # Bug 1767702 + win11_2009 # Bug 1798331 +[browser_dbg-features-source-text-content.js] +[browser_dbg-features-tabs.js] +[browser_dbg-features-wasm.js] + +# Other tests: +[browser_dbg-asyncstacks.js] +[browser_dbg-audiocontext.js] +[browser_dbg-async-stepping.js] +[browser_dbg-sourcemapped-breakpoint-console.js] +skip-if = (os == "win" && ccov) # Bug 1453549 +[browser_dbg-xhr-breakpoints.js] +[browser_dbg-xhr-run-to-completion.js] +[browser_dbg-scroll-run-to-completion.js] +[browser_dbg-source-pragma.js] +[browser_dbg-sourcemapped-scopes.js] +# Bug 1441545, 1536253 - very slow on debug +skip-if = ccov || debug || tsan || (verify && debug && (os == 'linux')) +[browser_dbg-sourcemapped-stepping.js] +skip-if = true # original stepping is currently disabled +[browser_dbg-sourcemapped-toggle.js] +[browser_dbg-sourcemapped-preview.js] +skip-if = os == "win" # Bug 1448523, Bug 1448450 +[browser_dbg-breaking.js] +[browser_dbg-breaking-from-console.js] +skip-if = debug # Window leaks: bug 1575332 +[browser_dbg-breakpoints.js] +[browser_dbg-breakpoints-actions.js] +[browser_dbg-breakpoints-columns.js] +[browser_dbg-breakpoints-cond.js] +[browser_dbg-breakpoints-cond-shortcut.js] +[browser_dbg-breakpoints-cond-source-maps.js] +[browser_dbg-breakpoints-debugger-statement.js] +[browser_dbg-breakpoints-duplicate-functions.js] +[browser_dbg-breakpoints-in-evaled-sources.js] +[browser_dbg-breakpoints-list.js] +[browser_dbg-breakpoints-popup.js] +skip-if = + (os == 'linux' && debug) || tsan # Bug 1750199 + apple_catalina && !debug # Bug 1767705 +[browser_dbg-continue-to-here.js] +[browser_dbg-continue-to-here-click.js] +skip-if = os == "win" +[browser_dbg-breakpoints-reloading-with-source-changes.js] +[browser_dbg-breakpoints-reloading.js] +[browser_dbg-breakpoints-same-file-per-target.js] +[browser_dbg-breakpoints-scroll-to-log.js] +[browser_dbg-breakpoints-sourcemap-with-sections.js] +[browser_dbg-breakpoint-skipping.js] +[browser_dbg-breakpoint-skipping-console.js] +[browser_dbg-call-stack.js] +[browser_dbg-dom-mutation-breakpoints-fission.js] +[browser_dbg-dom-mutation-breakpoints.js] +[browser_dbg-scopes.js] +[browser_dbg-backgroundtask-debugging.js] +skip-if = + asan # Bug 1591064 +[browser_dbg-chrome-create.js] +skip-if = (verify && !debug && (os == 'linux')) +[browser_dbg-command-click.js] +[browser_dbg-console.js] +[browser_dbg-console-async.js] +[browser_dbg-console-eval.js] +[browser_dbg-console-link.js] +[browser_dbg-console-map-bindings.js] +[browser_dbg-content-script-sources.js] +skip-if = (os == "win" && ccov) # Bug 1424154 +[browser_dbg-debug-line.js] +[browser_dbg-debugger-buttons.js] +[browser_dbg-editor-gutter.js] +[browser_dbg-eager-eval-skip-pause.js] +[browser_dbg-editor-exception.js] +[browser_dbg-editor-mode.js] +[browser_dbg-editor-scroll.js] +[browser_dbg-editor-select.js] +[browser_dbg-editor-highlight.js] +[browser_dbg-ember-quickstart.js] +skip-if = debug # Window leaks: bug 1575332 +[browser_dbg-expressions.js] +[browser_dbg-expressions-error.js] +[browser_dbg-expressions-focus.js] +[browser_dbg-expressions-thread.js] +skip-if = !fission # threads panel only shows remote frame when fission is enabled. +[browser_dbg-expressions-watch.js] +[browser_dbg-extension-inspectedWindow-debugger-statement.js] +[browser_dbg-fission-frame-breakpoint.js] +[browser_dbg-fission-frame-pause-exceptions.js] +[browser_dbg-fission-frame-sources.js] +[browser_dbg-fission-project-search.js] +[browser_dbg-fission-switch-target.js] +[browser_dbg-go-to-line.js] +[browser_dbg-highlights-calls.js] +[browser_dbg-html-breakpoints.js] +skip-if = (os == 'linux' && debug) || tsan # Bug 1802862 +[browser_dbg-iframes.js] +[browser_dbg-inline-cache.js] +skip-if = ccov && os == 'win' # Bug 1443132 +[browser_dbg-inline-preview.js] +skip-if = true # bug 1607636 +[browser_dbg-inline-exceptions.js] +[browser_dbg-inspector-integration.js] +[browser_dbg-keyboard-navigation.js] +[browser_dbg-keyboard-shortcuts-modal.js] +[browser_dbg-keyboard-shortcuts.js] +[browser_dbg-layout-changes.js] +[browser_dbg-link-reload.js] +skip-if = + os == 'linux' && asan # Bug 1715866 + os == 'win' && bits == 64 # Bug 1715866 +[browser_dbg-overrides.js] +[browser_dbg-log-events.js] +[browser_dbg-log-point-mapping.js] +[browser_dbg-log-points.js] +[browser_dbg-log-points-workers.js] +[browser_dbg-outline.js] +[browser_dbg-outline-focus.js] +skip-if = verify +[browser_dbg-outline-pretty.js] +[browser_dbg-outline-filter.js] +[browser_dbg-pause-exceptions.js] +skip-if = !debug && (os == "win" && os_version == "6.1") # Bug 1456441 +[browser_dbg-pause-on-next.js] +[browser_dbg-pause-ux.js] +skip-if = os == "win" +[browser_dbg-paused-overlay-iframe.js] +[browser_dbg-paused-overlay-loading.js] +[browser_dbg-paused-overlay.js] +[browser_dbg-navigation-when-paused.js] +[browser_dbg-navigation.js] +skip-if = (verify && debug && (os == 'mac')) || (os == 'linux' && debug && bits == 64) || (os == 'mac' && debug) # Bug 1307249 +[browser_dbg-no-duplicate-breakpoints-on-frame-reload.js] +[browser_dbg-minified.js] +[browser_dbg-pretty-print.js] +[browser_dbg-pretty-print-breakpoints-columns.js] +[browser_dbg-pretty-print-breakpoints-delete.js] +[browser_dbg-pretty-print-breakpoints.js] +[browser_dbg-pretty-print-console.js] +[browser_dbg-pretty-print-inline-scripts.js] +[browser_dbg-pretty-print-paused.js] +[browser_dbg-pretty-print-sourcemap.js] +[browser_dbg-pretty-print-paused-anonymous.js] +[browser_dbg-pretty-print-flow.js] +[browser_dbg-preview-getter.js] +[browser_dbg-preview.js] +skip-if = + os == "win" + (os == "linux" && !asan && !debug && !swgl && !ccov) +[browser_dbg-preview-frame.js] +skip-if = os == "win" +[browser_dbg-preview-module.js] +skip-if = os == "win" +[browser_dbg-preview-source-maps.js] +skip-if = os == "win" +[browser_dbg-react-jsx.js] +[browser_dbg-returnvalues.js] +[browser_dbg-reloading.js] +skip-if = true +[browser_dbg-pause-points.js] +[browser_dbg-scopes-mutations.js] +[browser_dbg-search-file-retains-query.js] +skip-if = os == "win" # Bug 1393121 +[browser_dbg-search-file.js] +skip-if = os == "win" # Bug 1393121 +[browser_dbg-search-file-paused.js] +skip-if = os == "win" # Bug 1393121 +[browser_dbg-quick-open.js] +skip-if = + os == "win" + os == 'linux' && bits == 64 && debug # Bug 1721999 +[browser_dbg-blackbox-all.js] +[browser_dbg-blackbox-original.js] +[browser_dbg-blackbox.js] +[browser_dbg-state-based-panels.js] +[browser_dbg-sourcemaps.js] +[browser_dbg-sourcemaps-breakpoints.js] +[browser_dbg-sourcemaps-disabled.js] +[browser_dbg-sourcemaps-ignorelist.js] +[browser_dbg-sourcemaps-indexed.js] +skip-if = os == "win" || (verify) # Bug 1434792 +[browser_dbg-sourcemaps-redirect.js] +[browser_dbg-sourcemaps-reloading.js] +[browser_dbg-sourcemaps-reloading-quickly.js] +[browser_dbg-sourcemaps2.js] +[browser_dbg-sourcemaps3.js] +[browser_dbg-sourcemaps-bogus.js] +skip-if = os == 'linux' && !asan # bug 1447118 +[browser_dbg-stepping.js] +skip-if = debug || (verify && (os == 'win')) || (os == "win" && os_version == "6.1") +[browser_dbg-step-in-uninitialized.js] +[browser_dbg-tabs.js] +[browser_dbg-tabs-keyboard.js] +skip-if = os == "win" +[browser_dbg-tabs-pretty-print.js] +[browser_dbg-tabs-without-urls.js] +[browser_dbg-tabs-without-urls-selected.js] +[browser_dbg-toggling-tools.js] +[browser_dbg-react-app.js] +skip-if = + os == "win" + os == "linux" && tsan # Bug 1813196 +[browser_dbg-windowless-workers.js] +[browser_dbg-windowless-workers-early-breakpoint.js] +[browser_dbg-worker-exception.js] +[browser_dbg-windowless-service-workers-reload.js] +skip-if = !serviceworker_e10s # parent intercept mode required. +[browser_dbg-windowless-service-workers.js] +skip-if = + !serviceworker_e10s # parent intercept mode is needed bug 1588154. Bug 1613543, the test consistently timeouts on Linux coverage builds and WR debug builds. + (os == 'linux' && (ccov || (!swgl && debug))) + os == "linux" && bits == 64 && debug # Bug 1732486 +[browser_dbg-worker-scopes.js] +[browser_dbg-event-handler.js] +[browser_dbg-event-breakpoints-fission.js] +[browser_dbg-event-breakpoints.js] +[browser_dbg-eval-throw.js] +[browser_dbg-sourceURL-breakpoint.js] +[browser_dbg-old-breakpoint.js] +skip-if = os == "linux" || os == "mac" #Bug 1644044 +[browser_dbg-idb-run-to-completion.js] +[browser_dbg-inline-script-offset.js] +[browser_dbg-scopes-duplicated.js] +[browser_dbg-scopes-xrays.js] +[browser_dbg-merge-scopes.js] +[browser_dbg-message-run-to-completion.js] +[browser_dbg-remember-expanded-scopes.js] +[browser_dbg-bfcache.js] +[browser_dbg-gc-breakpoint-positions.js] +[browser_dbg-gc-sources.js] +[browser_dbg-watchpoints.js] +skip-if = true # Bug 1814093 +[browser_dbg-browser-toolbox-unselected-pause.js] +skip-if = + asan # Bug 1591064 + os == "win" && fission && debug # intermittent on fission, Bug 1720165 - test timed out +[browser_dbg-browser-toolbox-workers.js] +skip-if = asan || !nightly_build || fission # Bug 1591064, parent intercept mode is needed bug 1588154, Disable frequent fission intermittents Bug 1675020 +[browser_dbg-wrong-fetch.js] +[browser_dbg-worker-module.js] +[browser_dbg-worker-nested.js] +[browser_dbg-step-in-navigate.js] +[browser_dbg-settings-disable-javascript.js] +[browser_dbg-restart-frame.js] +[browser_dbg-many-breakpoints-same-line.js] +[browser_dbg-unselected-pause.js] +[browser_dbg-slow-script.js] +[browser_dbg-project-root.js] +[browser_dbg-project-search.js] +[browser_dbg-sources-project-search.js] +[browser_dbg-javascript-tracer.js] +[browser_dbg-es-module-worker.js] +[browser_dbg-ua-widgets.js] +[browser_dbg-custom-formatters.js] +[browser_dbg-reducer-cleanup-on-target-removal.js] diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-async-stepping.js b/devtools/client/debugger/test/mochitest/browser_dbg-async-stepping.js new file mode 100644 index 0000000000..d04783d666 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-async-stepping.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests async stepping will step over await statements + +"use strict"; + +add_task(async function test() { + const dbg = await initDebugger("doc-async.html", "async.js"); + + await selectSource(dbg, "async.js"); + await addBreakpoint(dbg, "async.js", 8); + invokeInTab("main"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 8); + + await stepOver(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "async.js").id, 9); + + await assertBreakpoint(dbg, 8); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-asyncstacks.js b/devtools/client/debugger/test/mochitest/browser_dbg-asyncstacks.js new file mode 100644 index 0000000000..f99eb66496 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-asyncstacks.js @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that async stacks include the async separator + +"use strict"; + +add_task(async function () { + pushPref("devtools.debugger.features.async-captured-stacks", true); + const dbg = await initDebugger("doc-frames-async.html"); + + invokeInTab("main"); + await waitForPaused(dbg); + + is(findElement(dbg, "frame", 1).innerText, "sleep\ndoc-frames-async.html:13"); + is( + findElement(dbg, "frame", 2).innerText, + "async\nmain\ndoc-frames-async.html:17" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-audiocontext.js b/devtools/client/debugger/test/mochitest/browser_dbg-audiocontext.js new file mode 100644 index 0000000000..f77fedbe2a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-audiocontext.js @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test the AudioContext are paused and resume appropriately when using the +// debugger. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-audiocontext.html"); + + await invokeInTab("myFunction"); + await invokeInTab("suspendAC"); + invokeInTab("debuggerStatement"); + await waitForPaused(dbg); + await resume(dbg); + await invokeInTab("checkACState"); + ok(true, "No AudioContext state transition are caused by the debugger"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js b/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js new file mode 100644 index 0000000000..c22c3bb49b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-backgroundtask-debugging.js @@ -0,0 +1,151 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Tests that `--backgroundtask` debugging works. + * + * This test is subtle. We launch a `--backgroundtask` with `--jsdebugger` and + * `--wait-for-jsdebugger` within the test. The background task infrastructure + * launches a browser toolbox, and the test connects to that browser toolbox + * instance. The test drives the instance, verifying that the automatically + * placed breakpoint paused execution. It then closes the browser toolbox, + * which resumes the execution and the task exits. + * + * In the future, it would be nice to change the task's running environment, for + * example by redefining a failing exit code to exit code 0. Attempts to do + * this have so far not been robust in automation. + */ + +"use strict"; + +requestLongerTimeout(4); + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js", + this +); + +const { BackgroundTasksTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/BackgroundTasksTestUtils.sys.mjs" +); +BackgroundTasksTestUtils.init(this); +const do_backgroundtask = BackgroundTasksTestUtils.do_backgroundtask.bind( + BackgroundTasksTestUtils +); + +add_task(async function test_backgroundtask_debugger() { + // In this test, the background task infrastructure launches the browser + // toolbox. The browser toolbox profile prefs are taken from the default + // profile (which is the standard place for background tasks to look for + // task-specific configuration). The current test profile will be + // considered the default profile by the background task apparatus, so this + // is how we configure the browser toolbox profile prefs. + // + // These prefs are not set for the background task under test directly: the + // relevant prefs are set in the background task defaults. + await pushPref("devtools.chrome.enabled", true); + await pushPref("devtools.debugger.remote-enabled", true); + await pushPref("devtools.browsertoolbox.enable-test-server", true); + await pushPref("devtools.debugger.prompt-connection", false); + + // Before we start the background task, the preference file must be flushed to disk. + Services.prefs.savePrefFile(null); + + // This invokes the test-only background task `BackgroundTask_jsdebugger.jsm`. + const p = do_backgroundtask("jsdebugger", { + extraArgs: [`--jsdebugger`, "--wait-for-jsdebugger"], + extraEnv: { + // Force the current test profile to be considered the default profile. + MOZ_BACKGROUNDTASKS_DEFAULT_PROFILE_PATH: Services.dirsvc.get( + "ProfD", + Ci.nsIFile + ).path, + }, + }); + + ok(true, "Launched background task"); + + const existingProcessClose = async () => { + const exitCode = await p; + return { exitCode }; + }; + const ToolboxTask = await initBrowserToolboxTask({ existingProcessClose }); + + await ToolboxTask.importFunctions({ + checkEvaluateInTopFrame, + evaluateInTopFrame, + createDebuggerContext, + expandAllScopes, + findElement, + findElementWithSelector, + getSelector, + getThreadContext, + getVisibleSelectedFrameLine, + isPaused, + resume, + stepOver, + toggleObjectInspectorNode, + toggleScopeNode, + waitForElement, + waitForLoadedScopes, + waitForPaused, + waitForResumed, + waitForSelectedSource, + waitForState, + waitUntil, + createLocation, + log: (msg, data) => + console.log(`${msg} ${!data ? "" : JSON.stringify(data)}`), + info: (msg, data) => + console.info(`${msg} ${!data ? "" : JSON.stringify(data)}`), + }); + + // ToolboxTask.spawn passes input arguments by stringify-ing them via string + // concatenation. But functions do not survive this process, so we manually + // recreate (in the toolbox process) the single function the `expandAllScopes` + // invocation in this test needs. + await ToolboxTask.spawn(selectors, async _selectors => { + this.selectors = _selectors; + this.selectors.scopeNode = i => + `.scopes-list .tree-node:nth-child(${i}) .object-label`; + }); + + // The debugger should automatically be selected. + await ToolboxTask.spawn(null, async () => { + await waitUntil(() => gToolbox.currentToolId == "jsdebugger"); + }); + ok(true, "Debugger selected"); + + // The debugger should automatically pause. + await ToolboxTask.spawn(null, async () => { + try { + /* global gToolbox */ + // Wait for the debugger to finish loading. + await gToolbox.getPanelWhenReady("jsdebugger"); + + const dbg = createDebuggerContext(gToolbox); + + // Scopes are supposed to be automatically expanded, but with + // `setBreakpointOnLoad` that doesn't seem to be happening. Explicitly + // expand scopes so that they are expanded for `waitForPaused`. + await expandAllScopes(dbg); + + await waitForPaused(dbg); + + if (!gToolbox.isHighlighted("jsdebugger")) { + throw new Error("Debugger not highlighted"); + } + } catch (e) { + console.log("Caught exception in spawn", e); + throw e; + } + }); + ok(true, "Paused in backgroundtask script"); + + // If we `resume`, then the task completes and the Browser Toolbox exits, + // which isn't handled cleanly by `spawn`, resulting in a test time out. This + // closes the toolbox "from the inside", which continues execution. The test + // then waits for the background task to terminate with exit code 0. + await ToolboxTask.destroy(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-bfcache.js b/devtools/client/debugger/test/mochitest/browser_dbg-bfcache.js new file mode 100644 index 0000000000..d66bd294bc --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-bfcache.js @@ -0,0 +1,98 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test the debugger when navigating using the BFCache. + +"use strict"; + +PromiseTestUtils.allowMatchingRejectionsGlobally(/Connection closed/); + +add_task(async function () { + info("Run test with bfcacheInParent DISABLED"); + await pushPref("fission.bfcacheInParent", false); + await testSourcesOnNavigation(); + await testDebuggerPauseStateOnNavigation(); + + // bfcacheInParent only works if sessionHistoryInParent is enable + // so only test it if both settings are enabled. + if (Services.appinfo.sessionHistoryInParent) { + info("Run test with bfcacheInParent ENABLED"); + await pushPref("fission.bfcacheInParent", true); + await testSourcesOnNavigation(); + await testDebuggerPauseStateOnNavigation(); + } +}); + +async function testSourcesOnNavigation() { + info( + "Test that sources appear in the debugger when navigating using the BFCache" + ); + const dbg = await initDebugger("doc-bfcache1.html"); + + await navigate(dbg, "doc-bfcache2.html", "doc-bfcache2.html"); + + invokeInTab("goBack"); + await waitForSources(dbg, "doc-bfcache1.html"); + + invokeInTab("goForward"); + await waitForSources(dbg, "doc-bfcache2.html"); + ok(true, "Found sources after BFCache navigations"); + + await dbg.toolbox.closeToolbox(); +} + +async function testDebuggerPauseStateOnNavigation() { + info("Test the debugger pause state when navigating using the BFCache"); + + info("Open debugger on the first page"); + const dbg = await initDebugger("doc-bfcache1.html"); + + await addBreakpoint(dbg, "doc-bfcache1.html", 4); + + info("Navigate to the second page"); + await navigate(dbg, "doc-bfcache2.html"); + await waitForSources(dbg, "doc-bfcache2.html"); + + info("Navigate back to the first page (which should resurect from bfcache)"); + await goBack(`${EXAMPLE_URL}doc-bfcache1.html`); + await waitForSources(dbg, "doc-bfcache1.html"); + + // We paused when navigation back to bfcache1.html + // The previous navigation will prevent the page from completing its load. + // And we will do the same with this reload, which will pause page load + // and we will navigate forward and never complete the reload page load. + info("Reload the first page (which was in bfcache)"); + await reloadWhenPausedBeforePageLoaded(dbg); + await waitForPaused(dbg); + + ok(dbg.toolbox.isHighlighted("jsdebugger"), "Debugger is highlighted"); + + info( + "Navigate forward to the second page (which should also coming from bfcache)" + ); + await goForward(`${EXAMPLE_URL}doc-bfcache2.html`); + + await waitUntil(() => !dbg.toolbox.isHighlighted("jsdebugger")); + ok(true, "Debugger is not highlighted"); + + dbg.toolbox.closeToolbox(); +} + +async function goBack(expectedUrl) { + const onLocationChange = BrowserTestUtils.waitForLocationChange( + gBrowser, + expectedUrl + ); + gBrowser.goBack(); + await onLocationChange; +} + +async function goForward(expectedUrl) { + const onLocationChange = BrowserTestUtils.waitForLocationChange( + gBrowser, + expectedUrl + ); + gBrowser.goForward(); + await onLocationChange; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-all.js b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-all.js new file mode 100644 index 0000000000..8080d3c145 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-all.js @@ -0,0 +1,215 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This contains tests for +// 1) The context menu items that blackboxes multiple files in the Sources Panel. +// Checks if submenu works correctly for options: +// - 'Un/Blackbox files in this group' +// - 'Un/Blackbox files outside this group' +// - 'Un/Blackbox files in this directory' +// - 'Un/Blackbox files outside this directory' +// 2) The context menu item to hide/show the blackboxed files. + +"use strict"; + +const SOURCE_FILES = { + nestedSource: "nested-source.js", + codeReload1: "code_reload_1.js", +}; + +const NODE_SELECTORS = { + nodeBlackBoxAll: "#node-blackbox-all", + nodeBlackBoxAllInside: "#node-blackbox-all-inside", + nodeUnBlackBoxAllInside: "#node-unblackbox-all-inside", + nodeBlackBoxAllOutside: "#node-blackbox-all-outside", + nodeUnBlackBoxAllOutside: "#node-unblackbox-all-outside", +}; + +add_task(async function testBlackBoxOnMultipleFiles() { + const dbg = await initDebugger( + "doc-blackbox-all.html", + SOURCE_FILES.nestedSource, + SOURCE_FILES.codeReload1 + ); + + // Expand the SourceTree and wait for all sources to be visible, + // so that we can assert the visible state of blackboxing in the source tree. + await waitForSourcesInSourceTree(dbg, Object.values(SOURCE_FILES)); + + info("Loads the source file and sets a breakpoint at line 2."); + await selectSource(dbg, SOURCE_FILES.nestedSource); + await addBreakpoint(dbg, SOURCE_FILES.nestedSource, 2); + + info("Selecting the source will highlight it and expand the tree down to it"); + await waitForAllElements(dbg, "sourceTreeFolderNode", 3); + const sourceTreeFolderNodeEls = findAllElements(dbg, "sourceTreeFolderNode"); + const sourceTreeRootNodeEl = findElement(dbg, "sourceTreeRootNode"); + + info("Blackbox files in this directory."); + rightClickEl(dbg, sourceTreeFolderNodeEls[1]); + await waitForContextMenu(dbg); + await openContextMenuSubmenu(dbg, NODE_SELECTORS.nodeBlackBoxAll); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeBlackBoxAllInside, + "Ignore files in this directory" + ); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeBlackBoxAllOutside, + "Ignore files outside this directory" + ); + selectContextMenuItem(dbg, NODE_SELECTORS.nodeBlackBoxAllInside); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + await waitForBlackboxCount(dbg, 1); + await waitForRequestsToSettle(dbg); + + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.nestedSource, true); + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.codeReload1, false); + + info("The invoked function is blackboxed and the debugger does not pause."); + invokeInTab("computeSomething"); + assertNotPaused(dbg); + + info("Unblackbox files outside this directory."); + rightClickEl(dbg, sourceTreeFolderNodeEls[2]); + await waitForContextMenu(dbg); + await openContextMenuSubmenu(dbg, NODE_SELECTORS.nodeBlackBoxAll); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeBlackBoxAllInside, + "Ignore files in this directory" + ); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeUnBlackBoxAllOutside, + "Unignore files outside this directory" + ); + selectContextMenuItem(dbg, NODE_SELECTORS.nodeUnBlackBoxAllOutside); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + await waitForBlackboxCount(dbg, 0); + await waitForRequestsToSettle(dbg); + info("Wait for any breakpoints in the source to get enabled"); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.nestedSource, false); + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.codeReload1, false); + + info("All sources are unblackboxed and the debugger pauses on line 2."); + invokeInTab("computeSomething"); + await waitForPaused(dbg); + await resume(dbg); + + info("Blackbox files in this group."); + rightClickEl(dbg, sourceTreeRootNodeEl); + await waitForContextMenu(dbg); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeBlackBoxAllInside, + "Ignore files in this group" + ); + selectContextMenuItem(dbg, NODE_SELECTORS.nodeBlackBoxAllInside); + await waitForBlackboxCount(dbg, 2); + await waitForRequestsToSettle(dbg); + + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.nestedSource, true); + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.codeReload1, true); + + info("Unblackbox files in this group."); + rightClickEl(dbg, sourceTreeRootNodeEl); + await waitForContextMenu(dbg); + await assertContextMenuLabel( + dbg, + NODE_SELECTORS.nodeUnBlackBoxAllInside, + "Unignore files in this group" + ); + selectContextMenuItem(dbg, NODE_SELECTORS.nodeUnBlackBoxAllInside); + await waitForBlackboxCount(dbg, 0); + await waitForRequestsToSettle(dbg); + + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.nestedSource, false); + assertSourceNodeIsBlackBoxed(dbg, SOURCE_FILES.codeReload1, false); +}); + +add_task(async function testHideAndShowBlackBoxedFiles() { + Services.prefs.setBoolPref("devtools.debugger.hide-ignored-sources", false); + + const dbg = await initDebugger( + "doc-blackbox-all.html", + SOURCE_FILES.nestedSource, + SOURCE_FILES.codeReload1 + ); + + await waitForSourcesInSourceTree(dbg, Object.values(SOURCE_FILES)); + await selectSource(dbg, SOURCE_FILES.nestedSource); + clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + info("Assert and click the hide ignored files button in the settings menu"); + await toggleDebbuggerSettingsMenuItem(dbg, { + className: ".debugger-settings-menu-item-hide-ignored-sources", + isChecked: false, + }); + + info("Wait until ignored sources are no longer visible"); + await waitUntil( + () => !findSourceNodeWithText(dbg, SOURCE_FILES.nestedSource) + ); + + is( + Services.prefs.getBoolPref("devtools.debugger.hide-ignored-sources"), + true, + "Hide ignored files is enabled" + ); + + is( + dbg.win.document.querySelector(".source-list-footer").innerText, + "Ignored sources are hidden.\nShow all sources", + "Notification is visible with the correct message" + ); + + info("Assert that newly ignored files are automatically hidden"); + await selectSource(dbg, SOURCE_FILES.codeReload1); + await triggerSourceTreeContextMenu( + dbg, + findSourceNodeWithText(dbg, SOURCE_FILES.codeReload1), + "#node-menu-blackbox" + ); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + await waitUntil(() => !findSourceNodeWithText(dbg, SOURCE_FILES.codeReload1)); + + info("Show the hidden ignored files using the button in the notification"); + clickElementWithSelector(dbg, ".source-list-footer button"); + + info("Wait until ignored sources are visible"); + await waitUntil(() => findSourceNodeWithText(dbg, SOURCE_FILES.nestedSource)); + + is( + Services.prefs.getBoolPref("devtools.debugger.hide-ignored-sources"), + false, + "Hide ignored files is disabled" + ); + + ok( + !document.querySelector(".source-list-footer"), + "Notification is no longer visible" + ); +}); + +function waitForBlackboxCount(dbg, count) { + return waitForState( + dbg, + state => Object.keys(dbg.selectors.getBlackBoxRanges()).length === count + ); +} + +function assertSourceNodeIsBlackBoxed(dbg, sourceFilename, shouldBeBlackBoxed) { + const treeItem = findSourceNodeWithText(dbg, sourceFilename); + ok(treeItem, `Found tree item for ${sourceFilename}`); + is( + !!treeItem.querySelector(".img.blackBox"), + shouldBeBlackBoxed, + `${sourceFilename} is ${shouldBeBlackBoxed ? "" : "not"} blackboxed` + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-original.js b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-original.js new file mode 100644 index 0000000000..c1bf46da7f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox-original.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This source map does not have source contents, so it's fetched separately + +"use strict"; + +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger( + "doc-sourcemaps3.html", + "bundle.js", + "sorted.js", + "test.js" + ); + dbg.actions.toggleMapScopes(); + + const sortedSrc = findSource(dbg, "sorted.js"); + await selectSource(dbg, sortedSrc); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + const sourceTab = findElementWithSelector(dbg, ".source-tab.active"); + ok( + sourceTab.querySelector(".img.blackBox"), + "Source tab has a blackbox icon" + ); + + const treeItem = findElementWithSelector(dbg, ".tree-node.focused"); + ok( + treeItem.querySelector(".img.blackBox"), + "Source tree item has a blackbox icon" + ); + + // breakpoint at line 38 in sorted + await addBreakpoint(dbg, sortedSrc, 38); + // invoke test + invokeInTab("test"); + // should not pause + assertNotPaused(dbg); + + // unblackbox + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + + // click on test + invokeInTab("test"); + // should pause + await waitForPaused(dbg); + + ok(true, "blackbox works"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-blackbox.js b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox.js new file mode 100644 index 0000000000..9542473408 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-blackbox.js @@ -0,0 +1,742 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test covers all the blackboxing functionality relating to a selected +// source open in the debugger editor. + +"use strict"; + +requestLongerTimeout(5); + +const contextMenuItems = { + ignoreSource: { selector: "#node-menu-blackbox", label: "Ignore source" }, + unignoreSource: { selector: "#node-menu-blackbox", label: "Unignore source" }, + ignoreLines: { selector: "#node-menu-blackbox-lines", label: "Ignore lines" }, + unignoreLines: { + selector: "#node-menu-blackbox-lines", + label: "Unignore lines", + }, + ignoreLine: { selector: "#node-menu-blackbox-line", label: "Ignore line" }, + unignoreLine: { + selector: "#node-menu-blackbox-line", + label: "Unignore line", + }, +}; + +const SOURCE_IS_FULLY_IGNORED = "source"; +const SOURCE_LINES_ARE_IGNORED = "line"; +const SOURCE_IS_NOT_IGNORED = "none"; + +// Tests basic functionality for blackbox source and blackbox single and multiple lines +add_task(async function testAllBlackBox() { + // using the doc-command-click.html as it has a simple js file we can use + // testing. + const file = "simple4.js"; + const dbg = await initDebugger("doc-command-click.html", file); + + const source = findSource(dbg, file); + + await selectSource(dbg, source); + + await addBreakpoint(dbg, file, 8); + + await testBlackBoxSource(dbg, source); + await testBlackBoxMultipleLines(dbg, source); + await testBlackBoxSingleLine(dbg, source); +}); + +// Test that the blackboxed lines are persisted accross reloads and still work accordingly. +add_task(async function testBlackBoxOnReload() { + const file = "simple4.js"; + const dbg = await initDebugger("doc-command-click.html", file); + + const source = findSource(dbg, file); + + await selectSource(dbg, source); + + // Adding 2 breakpoints in funcB() and funcC() which + // would be hit in order. + await addBreakpoint(dbg, file, 8); + await addBreakpoint(dbg, file, 12); + + info("Reload without any blackboxing to make all necesary postions are hit"); + const onReloaded = reload(dbg, file); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 8); + await resume(dbg); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 12); + await resumeAndWaitForPauseCounter(dbg); + + info("Wait for reload to complete after resume"); + await onReloaded; + + assertNotPaused(dbg); + + info("Ignoring line 2 using the gutter context menu"); + await openContextMenuInDebugger(dbg, "gutter", 2); + await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); + + info("Ignoring line 7 to 9 using the editor context menu"); + await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 9 }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + const onReloaded2 = reload(dbg, file); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 12); + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded2; + + assertNotPaused(dbg); + + info( + "Check that the expected blackbox context menu state is correct across reload" + ); + + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 2, + nonBlackBoxedLine: 4, + blackBoxedLines: [7, 9], + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 2, + nonBlackBoxedLine: 4, + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); +}); + +add_task(async function testBlackBoxOnToolboxRestart() { + const dbg = await initDebugger("doc-command-click.html", "simple4.js"); + const source = findSource(dbg, "simple4.js"); + + await selectSource(dbg, source); + + const onReloaded = reload(dbg, "simple4.js"); + await waitForPaused(dbg); + + info("Assert it paused at the debugger statement"); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + await onReloaded; + + info("Ignoring line 2 using the gutter context menu"); + await openContextMenuInDebugger(dbg, "gutter", 2); + await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); + + await reloadBrowser(); + // Wait a little bit incase of a pause + await wait(1000); + + info("Assert that the debugger no longer pauses on the debugger statement"); + assertNotPaused(dbg); + + info("Close the toolbox"); + await dbg.toolbox.closeToolbox(); + + info("Reopen the toolbox on the debugger"); + const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger"); + const dbg2 = createDebuggerContext(toolbox); + await waitForSelectedSource(dbg2, findSource(dbg2, "simple4.js")); + + await reloadBrowser(); + // Wait a little incase of a pause + await wait(1000); + + info("Assert that debbuger still does not pause on the debugger statement"); + assertNotPaused(dbg2); +}); + +async function testBlackBoxSource(dbg, source) { + info("Start testing blackboxing the whole source"); + + info("Assert the blackbox context menu items before any blackboxing is done"); + // When the source is not blackboxed there are no blackboxed lines + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackBoxedLines: null, + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: null, + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), + }); + + info( + "Blackbox the whole simple4.js source file using the editor context menu" + ); + await openContextMenuInDebugger(dbg, "CodeMirrorLines"); + await selectBlackBoxContextMenuItem(dbg, "blackbox"); + + info("Assert that all lines in the source are styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: true }); + + info("Assert that the source tree for simple4.js has the ignored style"); + const node = findSourceNodeWithText(dbg, "simple4.js"); + ok( + node.querySelector(".blackboxed"), + "simple4.js node does not have the ignored style" + ); + + invokeInTab("funcA"); + + info( + "The debugger statement on line 2 and the breakpoint on line 8 should not be hit" + ); + assertNotPaused(dbg); + + info("Assert the blackbox context menu items after blackboxing is done"); + // When the whole source is blackboxed there are no nonBlackboxed lines + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 2, + nonBlackBoxedLine: null, + blackBoxedLines: [3, 5], + nonBlackBoxedLines: null, + blackboxedSourceState: SOURCE_IS_FULLY_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 2, + nonBlackBoxedLine: null, + blackboxedSourceState: SOURCE_IS_FULLY_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); + + info("Unblackbox the whole source using the sourcetree context menu"); + rightClickEl(dbg, findSourceNodeWithText(dbg, "simple4.js")); + await waitForContextMenu(dbg); + await selectBlackBoxContextMenuItem(dbg, "blackbox"); + + info("Assert that all lines in the source are un-styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { hasBlackboxedLinesClass: false }); + + info( + "Assert that the source tree for simple4.js does not have the ignored style" + ); + const nodeAfterBlackbox = findSourceNodeWithText(dbg, "simple4.js"); + ok( + !nodeAfterBlackbox.querySelector(".blackboxed"), + "simple4.js node still has the ignored style" + ); + + invokeInTab("funcA"); + + info("assert the pause at the debugger statement on line 2"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + + info("assert the pause at the breakpoint set on line 8"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 8); + await resumeAndWaitForPauseCounter(dbg); + + assertNotPaused(dbg); + + // When the source is not blackboxed there are no blackboxed lines + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackBoxedLines: null, + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: null, + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); +} + +async function testBlackBoxMultipleLines(dbg, source) { + info("Blackbox lines 7 to 13 using the editor content menu items"); + await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 13 }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 3, + blackBoxedLines: [7, 9], + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 3, + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); + + info("Assert that the ignored lines are styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [7, 13], + hasBlackboxedLinesClass: true, + }); + + info("Assert that the source tree for simple4.js has the ignored style"); + const node = findSourceNodeWithText(dbg, "simple4.js"); + + ok( + node.querySelector(".blackboxed"), + "simple4.js node does not have the ignored style" + ); + + invokeInTab("funcA"); + + info("assert the pause at the debugger statement on line 2"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resumeAndWaitForPauseCounter(dbg); + + info( + "The breakpoint set on line 8 should not get hit as its within the blackboxed range" + ); + assertNotPaused(dbg); + + info("Unblackbox lines 7 to 13"); + await selectEditorLinesAndOpenContextMenu(dbg, { startLine: 7, endLine: 13 }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackBoxedLines: null, + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackboxedSourceState: SOURCE_IS_NOT_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: null, + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); + + info("Assert that the un-ignored lines are no longer have the style"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [7, 13], + hasBlackboxedLinesClass: false, + }); + + info( + "Assert that the source tree for simple4.js does not have the ignored style" + ); + const nodeAfterBlackbox = findSourceNodeWithText(dbg, "simple4.js"); + ok( + !nodeAfterBlackbox.querySelector(".blackboxed"), + "simple4.js still has the ignored style" + ); + + invokeInTab("funcA"); + + // assert the pause at the debugger statement on line 2 + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + + // assert the pause at the breakpoint set on line 8 + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 8); + await resumeAndWaitForPauseCounter(dbg); + + assertNotPaused(dbg); +} + +async function testBlackBoxSingleLine(dbg, source) { + info("Black box line 2 of funcA() with the debugger statement"); + await openContextMenuInDebugger(dbg, "gutter", 2); + await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); + + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 2, + nonBlackBoxedLine: 4, + blackBoxedLines: null, + nonBlackBoxedLines: [3, 4], + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: null, + nonBlackBoxedLine: 4, + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple4.js"), + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); + + info("Assert that the ignored line 2 is styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [2], + hasBlackboxedLinesClass: true, + }); + + info("Black box line 4 of funcC() with the debugger statement"); + await openContextMenuInDebugger(dbg, "gutter", 4); + await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); + + info("Assert that the ignored line 4 is styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [4], + hasBlackboxedLinesClass: true, + }); + + invokeInTab("funcA"); + + // assert the pause at the breakpoint set on line 8 + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 8); + await resumeAndWaitForPauseCounter(dbg); + + assertNotPaused(dbg); + + info("Un-blackbox line 2 of funcA()"); + selectEditorLines(dbg, 2, 2); + await openContextMenuInDebugger(dbg, "CodeMirrorLines"); + await selectBlackBoxContextMenuItem(dbg, "blackbox-line"); + + await assertEditorBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 4, + nonBlackBoxedLine: 3, + blackBoxedLines: null, + nonBlackBoxedLines: [11, 12], + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertGutterBlackBoxBoxContextMenuItems(dbg, { + blackboxedLine: 4, + nonBlackBoxedLine: 3, + blackboxedSourceState: SOURCE_LINES_ARE_IGNORED, + }); + + await assertSourceTreeBlackBoxBoxContextMenuItems(dbg, { + blackBoxedSourceTreeNode: null, + nonBlackBoxedSourceTreeNode: findSourceNodeWithText(dbg, "simple2.js"), + }); + + info("Assert that the un-ignored line 2 is styled correctly"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [2], + hasBlackboxedLinesClass: false, + }); + + invokeInTab("funcA"); + + // assert the pause at the debugger statement on line 2 + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + + // assert the pause at the breakpoint set on line 8 + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 8); + await resume(dbg); + + assertNotPaused(dbg); +} + +// Resume and wait for the thread context's `pauseCounter` to get +// updated. +async function resumeAndWaitForPauseCounter(dbg) { + const prevThreadPauseCounter = getThreadContext(dbg).pauseCounter; + await resume(dbg); + return waitFor( + () => getThreadContext(dbg).pauseCounter > prevThreadPauseCounter + ); +} + +async function assertContextMenuDisabled(dbg, selector, shouldBeDisabled) { + const item = await waitFor(() => findContextMenu(dbg, selector)); + is( + item.disabled, + shouldBeDisabled, + `The the context menu item is ${ + shouldBeDisabled ? "disabled" : "not disabled" + }` + ); +} + +/** + * Asserts that the gutter blackbox context menu items which are visible are correct + * @params {Object} dbg + * @params {Array} testFixtures + * Details needed for the assertion. Any blackboxed/nonBlackboxed lines + * and any blackboxed/nonBlackboxed sources + */ +async function assertGutterBlackBoxBoxContextMenuItems(dbg, testFixtures) { + const { blackboxedLine, nonBlackBoxedLine, blackboxedSourceState } = + testFixtures; + if (blackboxedLine) { + info( + "Asserts that the gutter context menu items when clicking on the gutter of a blackboxed line" + ); + const popup = await openContextMenuInDebugger( + dbg, + "gutter", + blackboxedLine + ); + // When the whole source is blackboxed the the gutter visually shows `ignore line` + // but it is disabled indicating that individual lines cannot be nonBlackboxed. + const item = + blackboxedSourceState == SOURCE_IS_FULLY_IGNORED + ? contextMenuItems.ignoreLine + : contextMenuItems.unignoreLine; + + await assertContextMenuLabel(dbg, item.selector, item.label); + await assertContextMenuDisabled( + dbg, + item.selector, + blackboxedSourceState == SOURCE_IS_FULLY_IGNORED + ); + await closeContextMenu(dbg, popup); + } + + if (nonBlackBoxedLine) { + info( + "Asserts that the gutter context menu items when clicking on the gutter of a nonBlackboxed line" + ); + const popup = await openContextMenuInDebugger( + dbg, + "gutter", + nonBlackBoxedLine + ); + const item = contextMenuItems.ignoreLine; + await assertContextMenuLabel(dbg, item.selector, item.label); + await assertContextMenuDisabled(dbg, item.selector, false); + await closeContextMenu(dbg, popup); + } +} + +/** + * Asserts that the source tree blackbox context menu items which are visible are correct + * @params {Object} dbg + * @params {Array} testFixtures + * Details needed for the assertion. Any blackboxed/nonBlackboxed sources + */ +async function assertSourceTreeBlackBoxBoxContextMenuItems(dbg, testFixtures) { + const { blackBoxedSourceTreeNode, nonBlackBoxedSourceTreeNode } = + testFixtures; + if (blackBoxedSourceTreeNode) { + info( + "Asserts that the source tree blackbox context menu items when clicking on a blackboxed source tree node" + ); + rightClickEl(dbg, blackBoxedSourceTreeNode); + const popup = await waitForContextMenu(dbg); + const item = contextMenuItems.unignoreSource; + await assertContextMenuLabel(dbg, item.selector, item.label); + await closeContextMenu(dbg, popup); + } + + if (nonBlackBoxedSourceTreeNode) { + info( + "Asserts that the source tree blackbox context menu items when clicking on an un-blackboxed sorce tree node" + ); + rightClickEl(dbg, nonBlackBoxedSourceTreeNode); + const popup = await waitForContextMenu(dbg); + const _item = contextMenuItems.ignoreSource; + await assertContextMenuLabel(dbg, _item.selector, _item.label); + await closeContextMenu(dbg, popup); + } +} + +/** + * Asserts that the editor blackbox context menu items which are visible are correct + * @params {Object} dbg + * @params {Array} testFixtures + * Details needed for the assertion. Any blackboxed/nonBlackboxed lines + * and any blackboxed/nonBlackboxed sources + */ +async function assertEditorBlackBoxBoxContextMenuItems(dbg, testFixtures) { + const { + blackboxedLine, + nonBlackBoxedLine, + blackBoxedLines, + nonBlackBoxedLines, + blackboxedSourceState, + } = testFixtures; + + if (blackboxedLine) { + info( + "Asserts the editor blackbox context menu items when right-clicking on a single blackboxed line" + ); + const popup = await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: blackboxedLine, + }); + + const expectedContextMenuItems = [contextMenuItems.unignoreSource]; + + if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { + expectedContextMenuItems.push(contextMenuItems.unignoreLine); + } + + for (const expectedContextMenuItem of expectedContextMenuItems) { + info( + "Checking context menu item " + + expectedContextMenuItem.selector + + " with label " + + expectedContextMenuItem.label + ); + await assertContextMenuLabel( + dbg, + expectedContextMenuItem.selector, + expectedContextMenuItem.label + ); + } + await closeContextMenu(dbg, popup); + } + + if (nonBlackBoxedLine) { + info( + "Asserts the editor blackbox context menu items when right-clicking on a single non-blackboxed line" + ); + const popup = await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: nonBlackBoxedLine, + }); + + const expectedContextMenuItems = [ + blackboxedSourceState == SOURCE_IS_NOT_IGNORED + ? contextMenuItems.ignoreSource + : contextMenuItems.unignoreSource, + contextMenuItems.ignoreLine, + ]; + + for (const expectedContextMenuItem of expectedContextMenuItems) { + info( + "Checking context menu item " + + expectedContextMenuItem.selector + + " with label " + + expectedContextMenuItem.label + ); + await assertContextMenuLabel( + dbg, + expectedContextMenuItem.selector, + expectedContextMenuItem.label + ); + } + await closeContextMenu(dbg, popup); + } + + if (blackBoxedLines) { + info( + "Asserts the editor blackbox context menu items when right-clicking on multiple blackboxed lines" + ); + const popup = await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: blackBoxedLines[0], + endLine: blackBoxedLines[1], + }); + + const expectedContextMenuItems = [contextMenuItems.unignoreSource]; + + if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { + expectedContextMenuItems.push(contextMenuItems.unignoreLines); + } + + for (const expectedContextMenuItem of expectedContextMenuItems) { + info( + "Checking context menu item " + + expectedContextMenuItem.selector + + " with label " + + expectedContextMenuItem.label + ); + await assertContextMenuLabel( + dbg, + expectedContextMenuItem.selector, + expectedContextMenuItem.label + ); + } + await closeContextMenu(dbg, popup); + } + + if (nonBlackBoxedLines) { + info( + "Asserts the editor blackbox context menu items when right-clicking on multiple non-blackboxed lines" + ); + const popup = await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: nonBlackBoxedLines[0], + endLine: nonBlackBoxedLines[1], + }); + + const expectedContextMenuItems = [ + blackboxedSourceState == SOURCE_IS_NOT_IGNORED + ? contextMenuItems.ignoreSource + : contextMenuItems.unignoreSource, + ]; + + if (blackboxedSourceState !== SOURCE_IS_FULLY_IGNORED) { + expectedContextMenuItems.push(contextMenuItems.ignoreLines); + } + + for (const expectedContextMenuItem of expectedContextMenuItems) { + info( + "Checking context menu item " + + expectedContextMenuItem.selector + + " with label " + + expectedContextMenuItem.label + ); + await assertContextMenuLabel( + dbg, + expectedContextMenuItem.selector, + expectedContextMenuItem.label + ); + } + await closeContextMenu(dbg, popup); + } +} + +/** + * Selects a range of lines + * @param {Object} dbg + * @param {Number} startLine + * @param {Number} endLine + */ +function selectEditorLines(dbg, startLine, endLine) { + getCM(dbg).setSelection( + { line: startLine - 1, ch: 0 }, + { line: endLine, ch: 0 } + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breaking-from-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-breaking-from-console.js new file mode 100644 index 0000000000..3a29506002 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breaking-from-console.js @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests that `debugger` statements are hit before the debugger even +// initializes and it properly highlights the right location in the +// debugger. + +add_task(async function () { + const url = `${EXAMPLE_URL}doc-script-switching.html`; + const toolbox = await openNewTabAndToolbox(url, "webconsole"); + + // Type "debugger" into console + const wrapper = toolbox.getPanel("webconsole").hud.ui.wrapper; + const onSelected = toolbox.once("jsdebugger-selected"); + wrapper.dispatchEvaluateExpression("debugger"); + + // Wait for the debugger to be selected and make sure it's paused + await onSelected; + is(toolbox.threadFront.state, "paused"); + + // Create a dbg context + const dbg = createDebuggerContext(toolbox); + + // Make sure the thread is paused in the right source and location + await waitForPaused(dbg); + const selectedSource = dbg.selectors.getSelectedSource(); + ok( + !selectedSource.url, + "The selected source is the console evaluation and doesn't have a URL" + ); + is(getCM(dbg).getValue(), "debugger"); + assertPausedAtSourceAndLine(dbg, selectedSource.id, 1); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breaking.js b/devtools/client/debugger/test/mochitest/browser_dbg-breaking.js new file mode 100644 index 0000000000..59594aea07 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breaking.js @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests the breakpoints are hit in various situations. + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + const { + selectors: { getSelectedSource }, + } = dbg; + + await selectSource(dbg, "doc-scripts.html"); + + // Make sure we can set a top-level breakpoint and it will be hit on + // reload. + await addBreakpoint(dbg, "doc-scripts.html", 21); + + const onReloaded = reload(dbg, "doc-scripts.html"); + + await waitForPaused(dbg); + + let whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is(whyPaused, "Paused on breakpoint"); + + assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-scripts.html").id, 21); + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; + + info("Create an eval script that pauses itself."); + invokeInTab("doEval"); + await waitForPaused(dbg); + const source = getSelectedSource(); + ok(!source.url, "It is an eval source"); + assertPausedAtSourceAndLine(dbg, source.id, 2); + + whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is(whyPaused, "Paused on debugger statement"); + + await resume(dbg); + + await addBreakpoint(dbg, source, 5); + invokeInTab("evaledFunc"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 5); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping-console.js new file mode 100644 index 0000000000..73acdce3c1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping-console.js @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Test that debugger statements are skipped when + * skip pausing is enabled. + */ + +"use strict"; + +add_task(async function () { + const toolbox = await initPane("doc-scripts.html", "webconsole", [ + ["devtools.debugger.skip-pausing", true], + ]); + await navigateTo(`${EXAMPLE_URL}doc-debugger-statements.html`); + + await hasConsoleMessage({ toolbox }, "done!"); + ok(true, "We reached the end"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping.js new file mode 100644 index 0000000000..c766a0e549 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoint-skipping.js @@ -0,0 +1,87 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Tests toggling the skip pausing button and + * invoking functions without pausing. + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + await selectSource(dbg, "simple3.js"); + + info("Adding a breakpoint should remove the skipped pausing state"); + await skipPausing(dbg); + await waitForState(dbg, state => dbg.selectors.getSkipPausing()); + await addBreakpoint(dbg, "simple3.js", 2); + await waitForState(dbg, state => !dbg.selectors.getSkipPausing()); + invokeInTab("simple"); + await waitForPaused(dbg); + ok(true, "The breakpoint has been hit after a breakpoint was created"); + await resume(dbg); + + info("Toggling a breakpoint should remove the skipped pausing state"); + // First disable the breakpoint to ensure skip pausing gets turned off + // during a disable + await skipPausing(dbg); + await disableBreakpoint(dbg, 0); + await waitForState(dbg, state => !dbg.selectors.getSkipPausing()); + // Then re-enable the breakpoint to ensure skip pausing gets turned off + // during an enable + await skipPausing(dbg); + await waitForState(dbg, state => dbg.selectors.getSkipPausing()); + toggleBreakpoint(dbg, 0); + await waitForState(dbg, state => !dbg.selectors.getSkipPausing()); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + invokeInTab("simple"); + await waitForPaused(dbg); + ok(true, "The breakpoint has been hit after skip pausing was disabled"); + await resume(dbg); + + info("Disabling a breakpoint should remove the skipped pausing state"); + await addBreakpoint(dbg, "simple3.js", 3); + await skipPausing(dbg); + await disableBreakpoint(dbg, 0); + await waitForState(dbg, state => !dbg.selectors.getSkipPausing()); + invokeInTab("simple"); + await waitForPaused(dbg); + ok(true, "The breakpoint has been hit after skip pausing was disabled again"); + await resume(dbg); + + info("Removing a breakpoint should remove the skipped pause state"); + toggleBreakpoint(dbg, 0); + await skipPausing(dbg); + const source = findSource(dbg, "simple3.js"); + removeBreakpoint(dbg, source.id, 3); + const wait = waitForDispatch(dbg.store, "TOGGLE_SKIP_PAUSING"); + await waitForState(dbg, state => !dbg.selectors.getSkipPausing()); + await wait; + invokeInTab("simple"); + await waitForPaused(dbg); + // Unfortunately required as the test harness throws if preview doesn't + // complete before the end of the test. + await waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + ok(true, "Breakpoint is hit after a breakpoint was removed"); + await resume(dbg); +}); + +function skipPausing(dbg) { + clickElementWithSelector(dbg, ".command-bar-skip-pausing"); + return waitForState(dbg, state => dbg.selectors.getSkipPausing()); +} + +function toggleBreakpoint(dbg, index) { + const breakpoints = findAllElements(dbg, "breakpointItems"); + const bp = breakpoints[index]; + const input = bp.querySelector("input"); + input.click(); +} + +async function disableBreakpoint(dbg, index) { + const disabled = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + toggleBreakpoint(dbg, index); + await disabled; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-actions.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-actions.js new file mode 100644 index 0000000000..900c55e7fa --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-actions.js @@ -0,0 +1,84 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests to see if we can trigger a breakpoint action via the context menu +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple2.js"); + await selectSource(dbg, "simple2.js"); + await waitForSelectedSource(dbg, "simple2.js"); + + await addBreakpoint(dbg, "simple2.js", 3); + + await openFirstBreakpointContextMenu(dbg); + // select "Remove breakpoint" + selectContextMenuItem(dbg, selectors.breakpointContextMenu.remove); + + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() === 0); + ok(true, "successfully removed the breakpoint"); +}); + +// Tests "disable others", "enable others" and "remove others" context actions +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + await selectSource(dbg, "simple1.js"); + await waitForSelectedSource(dbg, "simple1.js"); + + await addBreakpoint(dbg, "simple1.js", 4); + await addBreakpoint(dbg, "simple1.js", 5); + await addBreakpoint(dbg, "simple1.js", 6); + + await openFirstBreakpointContextMenu(dbg); + // select "Disable Others" + let dispatched = waitForDispatch(dbg.store, "SET_BREAKPOINT", 2); + selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableOthers); + await waitForState(dbg, state => + dbg.selectors + .getBreakpointsList() + .every(bp => (bp.location.line !== 4) === bp.disabled) + ); + await dispatched; + ok(true, "breakpoint at 4 is the only enabled breakpoint"); + + await openFirstBreakpointContextMenu(dbg); + // select "Disable All" + dispatched = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + selectContextMenuItem(dbg, selectors.breakpointContextMenu.disableAll); + await waitForState(dbg, state => + dbg.selectors.getBreakpointsList().every(bp => bp.disabled) + ); + await dispatched; + ok(true, "all breakpoints are disabled"); + + await openFirstBreakpointContextMenu(dbg); + // select "Enable Others" + dispatched = waitForDispatch(dbg.store, "SET_BREAKPOINT", 2); + selectContextMenuItem(dbg, selectors.breakpointContextMenu.enableOthers); + await waitForState(dbg, state => + dbg.selectors + .getBreakpointsList() + .every(bp => (bp.location.line === 4) === bp.disabled) + ); + await dispatched; + ok(true, "all breakpoints except line 1 are enabled"); + + await openFirstBreakpointContextMenu(dbg); + // select "Remove Others" + dispatched = waitForDispatch(dbg.store, "REMOVE_BREAKPOINT", 2); + selectContextMenuItem(dbg, selectors.breakpointContextMenu.removeOthers); + await waitForState( + dbg, + state => + dbg.selectors.getBreakpointsList().length === 1 && + dbg.selectors.getBreakpointsList()[0].location.line === 4 + ); + await dispatched; + ok(true, "remaining breakpoint should be on line 4"); +}); + +async function openFirstBreakpointContextMenu(dbg) { + rightClickElement(dbg, "breakpointItem", 2); + await waitForContextMenu(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-columns.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-columns.js new file mode 100644 index 0000000000..2caf8f9142 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-columns.js @@ -0,0 +1,131 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + await selectSource(dbg, "long.js"); + + info("1. Add a column breakpoint on line 32"); + await enableFirstBreakpoint(dbg); + + info("2. Click on the second breakpoint on line 32"); + await enableSecondBreakpoint(dbg); + + info("3. Disable second breakpoint using shift-click"); + await shiftClickDisable(dbg); + + info("4. Re-enable second breakpoint using shift-click"); + await shiftClickEnable(dbg); + + info("5. Add a condition to the first breakpoint"); + await setConditionalBreakpoint(dbg, 0, "foo"); + + info("6. Add a log to the first breakpoint"); + await setLogPoint(dbg, 0, "bar"); + + info("7. Disable the first breakpoint"); + await disableBreakpoint(dbg, 0); + + info("8. Remove the first breakpoint"); + await removeFirstBreakpoint(dbg); + + info("9. Add a condition to the second breakpoint"); + await setConditionalBreakpoint(dbg, 1, "foo2"); + + info("10. Test removing the breakpoints by clicking in the gutter"); + await removeAllBreakpoints(dbg, 32, 0); +}); + +async function enableFirstBreakpoint(dbg) { + getCM(dbg).setCursor({ line: 32, ch: 0 }); + await addBreakpoint(dbg, "long.js", 32); + const bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + + ok(bpMarkers.length === 2, "2 column breakpoints"); + assertClass(bpMarkers[0], "active"); + assertClass(bpMarkers[1], "active", false); +} + +async function enableSecondBreakpoint(dbg) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + + bpMarkers[1].click(); + await waitForBreakpointCount(dbg, 2); + + bpMarkers = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[1], "active"); + await waitForAllElements(dbg, "breakpointItems", 2); +} + +// disable active column bp with shift-click. +async function shiftClickDisable(dbg) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + shiftClickElement(dbg, "columnBreakpoints"); + bpMarkers = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[0], "disabled"); +} + +// re-enable disabled column bp with shift-click. +async function shiftClickEnable(dbg) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + shiftClickElement(dbg, "columnBreakpoints"); + bpMarkers = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[0], "active"); +} + +async function setConditionalBreakpoint(dbg, index, condition) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + rightClickEl(dbg, bpMarkers[index]); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, selectors.addConditionItem); + await typeInPanel(dbg, condition); + await waitForCondition(dbg, condition); + + bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[index], "has-condition"); +} + +async function setLogPoint(dbg, index, expression) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + rightClickEl(dbg, bpMarkers[index]); + await waitForContextMenu(dbg); + + selectContextMenuItem(dbg, selectors.addLogItem); + await typeInPanel(dbg, expression); + await waitForLog(dbg, expression); + + bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[index], "has-log"); +} + +async function disableBreakpoint(dbg, index) { + rightClickElement(dbg, "columnBreakpoints"); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, selectors.disableItem); + + await waitForState(dbg, state => { + const bp = dbg.selectors.getBreakpointsList()[index]; + return bp.disabled; + }); + + const bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[0], "disabled"); +} + +async function removeFirstBreakpoint(dbg) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + + bpMarkers[0].click(); + bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[0], "active", false); +} + +async function removeAllBreakpoints(dbg, line, count) { + await clickGutter(dbg, 32); + await waitForBreakpointCount(dbg, 0); + + ok(!findAllElements(dbg, "columnBreakpoints").length); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-shortcut.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-shortcut.js new file mode 100644 index 0000000000..7976a091a9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-shortcut.js @@ -0,0 +1,147 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test opening conditional panel using keyboard shortcut. +// Should access the closest breakpoint to a passed in cursorPosition. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "long.js"); + + await selectSource(dbg, "long.js"); + await waitForSelectedSource(dbg, "long.js"); + + info( + "toggle conditional panel with shortcut: no breakpoints, default cursorPosition" + ); + pressKey(dbg, "toggleCondPanel"); + await waitForConditionalPanelFocus(dbg); + ok( + !!getConditionalPanel(dbg, 1), + "conditional panel panel is open on line 1" + ); + is( + dbg.selectors.getConditionalPanelLocation().line, + 1, + "conditional panel location is line 1" + ); + info("close conditional panel"); + pressKey(dbg, "Escape"); + + info( + "toggle conditional panel with shortcut: cursor on line 32, no breakpoints" + ); + // codemirror editor offset: cursorPosition will be line + 1, column + 1 + getCM(dbg).setCursor({ line: 31, ch: 1 }); + pressKey(dbg, "toggleCondPanel"); + + await waitForConditionalPanelFocus(dbg); + ok( + !!getConditionalPanel(dbg, 32), + "conditional panel panel is open on line 32" + ); + is( + dbg.selectors.getConditionalPanelLocation().line, + 32, + "conditional panel location is line 32" + ); + info("close conditional panel"); + pressKey(dbg, "Escape"); + + info("add active column breakpoint on line 32 and set cursorPosition"); + await enableFirstBreakpoint(dbg); + getCM(dbg).setCursor({ line: 31, ch: 1 }); + info( + "toggle conditional panel with shortcut and add condition to first breakpoint" + ); + setConditionalBreakpoint(dbg, "1"); + await waitForCondition(dbg, 1); + const firstBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 2); + is( + firstBreakpoint.options.condition, + "1", + "first breakpoint created with condition using shortcut" + ); + + info("set cursor at second breakpoint position and activate breakpoint"); + getCM(dbg).setCursor({ line: 31, ch: 25 }); + + await enableSecondBreakpoint(dbg); + info( + "toggle conditional panel with shortcut and add condition to second breakpoint" + ); + setConditionalBreakpoint(dbg, "2"); + await waitForCondition(dbg, 2); + const secondBreakpoint = findColumnBreakpoint(dbg, "long.js", 32, 26); + is( + secondBreakpoint.options.condition, + "2", + "second breakpoint created with condition using shortcut" + ); + + info( + "set cursor position near first breakpoint, toggle conditional panel and edit breakpoint" + ); + getCM(dbg).setCursor({ line: 31, ch: 7 }); + info("toggle conditional panel and edit condition using shortcut"); + setConditionalBreakpoint(dbg, "2"); + ok( + !!waitForCondition(dbg, "12"), + "breakpoint closest to cursor position has been edited" + ); + + info("close conditional panel"); + pressKey(dbg, "Escape"); + + info( + "set cursor position near second breakpoint, toggle conditional panel and edit breakpoint" + ); + getCM(dbg).setCursor({ line: 31, ch: 21 }); + info("toggle conditional panel and edit condition using shortcut"); + setConditionalBreakpoint(dbg, "3"); + ok( + !!waitForCondition(dbg, "13"), + "breakpoint closest to cursor position has been edited" + ); +}); + +// from test/mochitest/browser_dbg-breakpoints-cond-source-maps.js +function getConditionalPanel(dbg, line) { + return getCM(dbg).doc.getLineHandle(line - 1).widgets[0]; +} + +// from devtools browser_dbg-breakpoints-cond-source-maps.js +async function waitForConditionalPanelFocus(dbg) { + await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA"); +} + +// from browser_dbg-breakpoints-columns.js +async function enableFirstBreakpoint(dbg) { + getCM(dbg).setCursor({ line: 32, ch: 0 }); + await addBreakpoint(dbg, "long.js", 32); + const bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + + ok(bpMarkers.length === 2, "2 column breakpoints"); + assertClass(bpMarkers[0], "active"); + assertClass(bpMarkers[1], "active", false); +} + +async function enableSecondBreakpoint(dbg) { + let bpMarkers = await waitForAllElements(dbg, "columnBreakpoints"); + + bpMarkers[1].click(); + await waitForBreakpointCount(dbg, 2); + + bpMarkers = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpMarkers[1], "active"); + await waitForAllElements(dbg, "breakpointItems", 2); +} + +// modified method from browser_dbg-breakpoints-columns.js +// use shortcut to open conditional panel. +function setConditionalBreakpoint(dbg, condition) { + pressKey(dbg, "toggleCondPanel"); + typeInPanel(dbg, condition); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-source-maps.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-source-maps.js new file mode 100644 index 0000000000..3e9a9d5087 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond-source-maps.js @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Confirms that a conditional panel is opened at the +// correct location in generated files. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemaps.html", "entry.js"); + + await selectSource(dbg, "bundle.js"); + getCM(dbg).scrollIntoView({ line: 55, ch: 0 }); + + await setLogPoint(dbg, 55); + await waitForConditionalPanelFocus(dbg); + ok( + !!getConditionalPanel(dbg, 55), + "conditional panel panel is open on line 55" + ); + is( + dbg.selectors.getConditionalPanelLocation().line, + 55, + "conditional panel location is line 55" + ); +}); + +async function setLogPoint(dbg, index) { + const gutterEl = await getEditorLineGutter(dbg, index); + rightClickEl(dbg, gutterEl); + await waitForContextMenu(dbg); + selectContextMenuItem( + dbg, + `${selectors.addLogItem},${selectors.editLogItem}` + ); +} + +async function waitForConditionalPanelFocus(dbg) { + await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA"); +} + +function getConditionalPanel(dbg, line) { + return getCM(dbg).doc.getLineHandle(line - 1).widgets[0]; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond.js new file mode 100644 index 0000000000..9a3f5f5611 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-cond.js @@ -0,0 +1,136 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple2.js"); + + await selectSource(dbg, "simple2.js"); + await waitForSelectedSource(dbg, "simple2.js"); + + info("Set condition `1`"); + await setConditionalBreakpoint(dbg, 5, "1"); + await waitForCondition(dbg, 1); + + let bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, "1", "breakpoint is created with the condition"); + await assertConditionBreakpoint(dbg, 5); + + info("Edit the conditional breakpoint set above"); + await setConditionalBreakpoint(dbg, 5, "2"); + await waitForCondition(dbg, 12); + + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, "12", "breakpoint is created with the condition"); + await assertConditionBreakpoint(dbg, 5); + + info("Hit 'Enter' when the cursor is in the conditional statement"); + rightClickElement(dbg, "gutter", 5); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, `${selectors.editConditionItem}`); + await waitForConditionalPanelFocus(dbg); + pressKey(dbg, "Left"); + pressKey(dbg, "Enter"); + await waitForCondition(dbg, 12); + + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, "12", "Hit 'Enter' doesn't add a new line"); + + info("Hit 'Alt+Enter' when the cursor is in the conditional statement"); + rightClickElement(dbg, "gutter", 5); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, `${selectors.editConditionItem}`); + await waitForConditionalPanelFocus(dbg); + pressKey(dbg, "Left"); + pressKey(dbg, "AltEnter"); + pressKey(dbg, "Enter"); + await waitForCondition(dbg, "1\n2"); + + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, "1\n2", "Hit 'Alt+Enter' adds a new line"); + + clickElement(dbg, "gutter", 5); + await waitForDispatch(dbg.store, "REMOVE_BREAKPOINT"); + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp, undefined, "breakpoint was removed"); + await assertNoBreakpoint(dbg, 5); + + info("Adding a condition to a breakpoint"); + clickElement(dbg, "gutter", 5); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + await setConditionalBreakpoint(dbg, 5, "1"); + await waitForCondition(dbg, 1); + + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, "1", "breakpoint is created with the condition"); + await assertConditionBreakpoint(dbg, 5); + + info("Double click the conditional breakpoint in secondary pane"); + dblClickElement(dbg, "conditionalBreakpointInSecPane"); + is( + dbg.win.document.activeElement.tagName, + "TEXTAREA", + "The textarea of conditional breakpoint panel is focused" + ); + + info("Click the conditional breakpoint in secondary pane"); + await clickElement(dbg, "conditionalBreakpointInSecPane"); + const conditonalPanel = findElement(dbg, "conditionalPanel"); + is(conditonalPanel, null, "The conditional breakpoint panel is closed"); + + rightClickElement(dbg, "breakpointItem", 2); + await waitForContextMenu(dbg); + info('select "remove condition"'); + selectContextMenuItem(dbg, selectors.breakpointContextMenu.removeCondition); + await waitForBreakpointWithoutCondition(dbg, "simple2.js", 5); + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.condition, null, "breakpoint condition removed"); + + info('Add "log point"'); + await setLogPoint(dbg, 5, "44"); + await waitForLog(dbg, 44); + await assertLogBreakpoint(dbg, 5); + + bp = findBreakpoint(dbg, "simple2.js", 5); + is(bp.options.logValue, "44", "breakpoint condition removed"); + + await altClickElement(dbg, "gutter", 6); + bp = await waitForBreakpoint(dbg, "simple2.js", 6); + is(bp.options.logValue, "displayName", "logPoint has default value"); + + info("Double click the logpoint in secondary pane"); + dblClickElement(dbg, "logPointInSecPane"); + is( + dbg.win.document.activeElement.tagName, + "TEXTAREA", + "The textarea of logpoint panel is focused" + ); + + info("Click the logpoint in secondary pane"); + await clickElement(dbg, "logPointInSecPane"); + const logPointPanel = findElement(dbg, "logPointPanel"); + is(logPointPanel, null, "The logpoint panel is closed"); +}); + +function waitForBreakpointWithoutCondition(dbg, url, line) { + return waitForState(dbg, () => { + const bp = findBreakpoint(dbg, url, line); + return bp && !bp.options.condition; + }); +} + +async function setConditionalBreakpoint(dbg, index, condition) { + // Make this work with either add or edit menu items + const { addConditionItem, editConditionItem } = selectors; + const selector = `${addConditionItem},${editConditionItem}`; + rightClickElement(dbg, "gutter", index); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, selector); + typeInPanel(dbg, condition); +} + +async function waitForConditionalPanelFocus(dbg) { + await waitFor(() => dbg.win.document.activeElement.tagName === "TEXTAREA"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-debugger-statement.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-debugger-statement.js new file mode 100644 index 0000000000..3f1f08a949 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-debugger-statement.js @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test enabling and disabling a debugger statement using editor context menu + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pause-points.html", "pause-points.js"); + await selectSource(dbg, "pause-points.js"); + await waitForSelectedSource(dbg, "pause-points.js"); + + info("Disable the first debugger statement on line 12 by gutter menu"); + rightClickElement(dbg, "gutter", 12); + await waitForContextMenu(dbg); + selectContextMenuItem( + dbg, + selectors.breakpointContextMenu.disableDbgStatement + ); + await waitForCondition(dbg, "false"); + + let bp = findBreakpoint(dbg, "pause-points.js", 12); + is( + bp.options.condition, + "false", + "The debugger statement has a conditional breakpoint with 'false' as statement" + ); + + info("Enable the previously disabled debugger statement by gutter menu"); + rightClickElement(dbg, "gutter", 12); + await waitForContextMenu(dbg); + selectContextMenuItem( + dbg, + selectors.breakpointContextMenu.enableDbgStatement + ); + await waitForBreakpointWithoutCondition(dbg, "pause-points.js", 12, 0); + + bp = findBreakpoint(dbg, "pause-points.js", 12); + is(bp.options.condition, null, "The conditional statement is removed"); + + info("Enable the breakpoint for the second debugger statement on line 12"); + let bpElements = await waitForAllElements(dbg, "columnBreakpoints"); + ok(bpElements.length === 2, "2 column breakpoints"); + assertClass(bpElements[0], "active"); + assertClass(bpElements[1], "active", false); + + bpElements[1].click(); + await waitForBreakpointCount(dbg, 2); + bpElements = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpElements[1], "active"); + + info("Disable the second debugger statement by breakpoint menu"); + rightClickEl(dbg, bpElements[1]); + await waitForContextMenu(dbg); + selectContextMenuItem( + dbg, + selectors.breakpointContextMenu.disableDbgStatement + ); + await waitForCondition(dbg, "false"); + + bp = findBreakpoints(dbg, "pause-points.js", 12)[1]; + is( + bp.options.condition, + "false", + "The second debugger statement has a conditional breakpoint with 'false' as statement" + ); + + info("Enable the second debugger statement by breakpoint menu"); + bpElements = findAllElements(dbg, "columnBreakpoints"); + assertClass(bpElements[1], "has-condition"); + rightClickEl(dbg, bpElements[1]); + await waitForContextMenu(dbg); + selectContextMenuItem( + dbg, + selectors.breakpointContextMenu.enableDbgStatement + ); + await waitForBreakpointWithoutCondition(dbg, "pause-points.js", 12, 1); + + bp = findBreakpoints(dbg, "pause-points.js", 12)[1]; + is(bp.options.condition, null, "The conditional statement is removed"); +}); + +function waitForBreakpointWithoutCondition(dbg, url, line, index) { + return waitForState(dbg, () => { + const bp = findBreakpoints(dbg, url, line)[index]; + return bp && !bp.options.condition; + }); +} + +function findBreakpoints(dbg, url, line) { + const source = findSource(dbg, url); + return dbg.selectors.getBreakpointsForSource(source.id, line); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-duplicate-functions.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-duplicate-functions.js new file mode 100644 index 0000000000..bb1fa3d64b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-duplicate-functions.js @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests to make sure we do not accidentally slide the breakpoint up to the first +// function with the same name in the file. +// TODO: Likely to remove this test when removing the breakpoint sliding functionality + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-duplicate-functions.html", + "doc-duplicate-functions.html" + ); + let source = findSource(dbg, "doc-duplicate-functions.html"); + + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 21); + + await reload(dbg, "doc-duplicate-functions.html"); + + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() == 1); + + const firstBreakpoint = dbg.selectors.getBreakpointsList()[0]; + is(firstBreakpoint.location.line, 21, "Breakpoint is on line 21"); + + // Make sure the breakpoint set on line 19 gets hit + await invokeInTab("b"); + invokeInTab("func"); + await waitForPaused(dbg); + + source = findSource(dbg, "doc-duplicate-functions.html"); + assertPausedAtSourceAndLine(dbg, source.id, 21); + await assertBreakpoint(dbg, 21); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-in-evaled-sources.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-in-evaled-sources.js new file mode 100644 index 0000000000..a4569dbfda --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-in-evaled-sources.js @@ -0,0 +1,92 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// this evaled source includes a "debugger" statement so that it gets +// automatically opened in the debugger when it is executed. +// We wrap it in a setTimeout to avoid errors in the webconsole actor which +// would still be processing the outcome of the evaluation after we destroy +// the thread actor. + +"use strict"; + +const EVALED_SOURCE_TEXT = `setTimeout(function() { + debugger; + console.log("SECOND LINE"); +}, 10)`; + +/** + * Check against blank debugger panel issues when attempting to restore + * breakpoints set in evaled sources (Bug 1720512). + * + * The STRs triggering this bug require to: + * - set a valid breakpoint on a regular source + * - then set a breakpoint on an evaled source + * - close and reopen the debugger + * + * This test will follow those STRs while also performing a few additional + * checks (eg verify breakpoints can be hit at various stages of the test). + */ +add_task(async function () { + info("Open the debugger and set a breakpoint on a regular script"); + const dbg = await initDebugger("doc-scripts.html"); + await selectSource(dbg, "doc-scripts.html"); + await addBreakpoint(dbg, "doc-scripts.html", 21); + + info("Switch to the console and evaluate a source with a debugger statement"); + const { hud } = await dbg.toolbox.selectTool("webconsole"); + const onSelected = dbg.toolbox.once("jsdebugger-selected"); + await hud.ui.wrapper.dispatchEvaluateExpression(EVALED_SOURCE_TEXT); + + info("Wait for the debugger to be selected"); + await onSelected; + + info("Wait for the debugger to be paused on the debugger statement"); + await waitForPaused(dbg); + + is( + getCM(dbg).getValue(), + EVALED_SOURCE_TEXT, + "The debugger is showing the evaled source" + ); + + const evaledSource = dbg.selectors.getSelectedSource(); + assertPausedAtSourceAndLine(dbg, evaledSource.id, 2); + + info("Add a breakpoint in the evaled source"); + await addBreakpoint(dbg, evaledSource, 3); + + info("Resume and check that we hit the breakpoint"); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, evaledSource.id, 3); + + info("Close the toolbox"); + await dbg.toolbox.closeToolbox(); + + info("Reopen the toolbox on the debugger"); + const toolbox2 = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger"); + const dbg2 = createDebuggerContext(toolbox2); + + // The initial regression tested here led to a blank debugger, + // if we can see the doc-scripts.html source, this already means the debugger + // is functional. + await waitForSources(dbg2, "doc-scripts.html"); + + // Wait until codeMirror is rendered before reloading the debugger. + await waitFor(() => findElement(dbg2, "codeMirror")); + + info("Reload to check if we hit the breakpoint added in doc-scripts.html"); + const onReloaded = reload(dbg2); + + await waitForDispatch(dbg2.store, "NAVIGATE"); + await waitForSelectedSource(dbg2, "doc-scripts.html"); + await waitForPaused(dbg2); + + const scriptSource = dbg2.selectors.getSelectedSource(); + assertPausedAtSourceAndLine(dbg2, scriptSource.id, 21); + await resume(dbg2); + + info("Wait for reload to complete after resume"); + await onReloaded; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-list.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-list.js new file mode 100644 index 0000000000..369f755e79 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-list.js @@ -0,0 +1,189 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Testing displaying breakpoints in the breakpoints list and the tooltip +// shows the source url. + +"use strict"; + +add_task(async function testBreakpointsListForMultipleTargets() { + const dbg = await initDebugger( + "doc_dbg-fission-frame-sources.html", + "simple1.js", + "simple2.js" + ); + + info("Add breakpoint to the source (simple1.js) in the main thread"); + await selectSource(dbg, "simple1.js"); + const source1 = findSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 5); + + info("Add breakpoint to the source (simple2.js) in the frame"); + await selectSource(dbg, "simple2.js"); + const source2 = findSource(dbg, "simple2.js"); + await addBreakpoint(dbg, "simple2.js", 3); + + const breakpointHeadings = findAllElements(dbg, "breakpointHeadings"); + const breakpointItems = findAllElements(dbg, "breakpointItems"); + + is( + breakpointHeadings.length, + 2, + "The breakpoint list shows two breakpoints sources" + ); + is( + breakpointItems.length, + 2, + "The breakpoint list shows only two breakpoints" + ); + + is( + breakpointHeadings[0].title, + source1.url, + "The breakpoint heading tooltip shows the source info for the first breakpoint" + ); + is( + breakpointHeadings[0].textContent, + "simple1.js", + "The info displayed for the breakpoint heading of the 1st breakpoint is correct" + ); + is( + breakpointItems[0].textContent, + "func();5:17", + "The info displayed for the 1st breakpoint is correct" + ); + + is( + breakpointHeadings[1].title, + source2.url, + "The breakpoint heading tooltip shows the source info for the second breakpoint" + ); + is( + breakpointHeadings[1].textContent, + "simple2.js", + "The info displayed for the breakpoint heading of the 2nd breakpoint is correct" + ); + is( + breakpointItems[1].textContent, + "return x + y;3:4", + "The info displayed for the 2nd breakpoint is correct" + ); + + await removeBreakpoint(dbg, source1.id, 5); + await removeBreakpoint(dbg, source2.id, 3); +}); + +add_task(async function testBreakpointsListForOriginalFiles() { + const dbg = await initDebugger("doc-sourcemaps.html", "entry.js"); + + info("Add breakpoint to the entry.js (original source)"); + await selectSource(dbg, "entry.js"); + const source = findSource(dbg, "entry.js"); + await addBreakpoint(dbg, "entry.js", 5); + + const breakpointHeadings = findAllElements(dbg, "breakpointHeadings"); + const breakpointItems = findAllElements(dbg, "breakpointItems"); + + is( + breakpointHeadings.length, + 1, + "The breakpoint list shows one breakpoints sources" + ); + is( + breakpointItems.length, + 1, + "The breakpoint list shows only one breakpoints" + ); + + is( + breakpointHeadings[0].title, + source.url, + "The breakpoint heading tooltip shows the source info for the first breakpoint" + ); + is( + breakpointHeadings[0].textContent, + "entry.js", + "The info displayed for the breakpoint heading of the 1st breakpoint is correct" + ); + is( + breakpointItems[0].textContent, + "output(times2(1));5", + "The info displayed for the 1st breakpoint is correct" + ); + + await removeBreakpoint(dbg, source.id, 5); +}); + +add_task(async function testBreakpointsListForIgnoredLines() { + const dbg = await initDebugger("doc-sourcemaps.html", "entry.js"); + + info("Add breakpoint to the entry.js (original source)"); + await selectSource(dbg, "entry.js"); + await addBreakpoint(dbg, "entry.js", 5); + + info("Ignoring line 5 to 6 which has a breakpoint already set"); + await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: 5, + endLine: 6, + }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + info("Assert the breakpoint on the ignored line"); + let breakpointItems = findAllElements(dbg, "breakpointItems"); + is( + breakpointItems[0].textContent, + "output(times2(1));5", + "The info displayed for the 1st breakpoint is correct" + ); + const firstBreakpointCheck = breakpointItems[0].querySelector("input"); + ok( + firstBreakpointCheck.disabled, + "The first breakpoint checkbox on an ignored line is disabled" + ); + ok( + !firstBreakpointCheck.checked, + "The first breakpoint on an ignored line is not checked" + ); + + info("Ignoring line 8 to 9 which currently has not breakpoint"); + await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: 8, + endLine: 9, + }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + await addBreakpointViaGutter(dbg, 9); + + breakpointItems = findAllElements(dbg, "breakpointItems"); + is( + breakpointItems[1].textContent, + "output(times2(3));9", + "The info displayed for the 2nd breakpoint is correct" + ); + const secondBreakpointCheck = breakpointItems[1].querySelector("input"); + ok( + secondBreakpointCheck.disabled, + "The second breakpoint checkbox on an ignored line is disabled" + ); + ok( + !secondBreakpointCheck.checked, + "The second breakpoint on an ignored line is not checked" + ); + + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + + info("Assert that both breakpoints are now enabled"); + breakpointItems = findAllElements(dbg, "breakpointItems"); + [...breakpointItems].forEach(breakpointItem => { + const check = breakpointItem.querySelector("input"); + ok( + !check.disabled, + "The breakpoint checkbox on the unignored line is enabled" + ); + ok(check.checked, "The breakpoint on the unignored line is checked"); + }); + + await dbg.toolbox.closeToolbox(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js new file mode 100644 index 0000000000..0c55538a49 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-popup.js @@ -0,0 +1,250 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Verify that we hit breakpoints on popups + +"use strict"; + +const TEST_URI = "https://example.org/document-builder.sjs?html=main page"; +const POPUP_URL = `https://example.com/document-builder.sjs?html=${escape(`popup for breakpoints + +`)}`; +const POPUP_DEBUGGER_STATEMENT_URL = `https://example.com/document-builder.sjs?html=${escape(`popup with debugger; + +`)}`; + +function isPopupPaused(popupBrowsingContext) { + return SpecialPowers.spawn(popupBrowsingContext, [], function (url) { + return content.wrappedJSObject.paused; + }); +} + +async function openPopup(popupUrl, browser = gBrowser.selectedBrowser) { + const onPopupTabSelected = BrowserTestUtils.waitForEvent( + gBrowser.tabContainer, + "TabSelect" + ); + const popupBrowsingContext = await SpecialPowers.spawn( + browser, + [popupUrl], + function (url) { + const popup = content.open(url); + return popup.browsingContext; + } + ); + await onPopupTabSelected; + is( + gBrowser.selectedBrowser.browsingContext, + popupBrowsingContext, + "The popup is the selected tab" + ); + return popupBrowsingContext; +} + +async function closePopup(browsingContext) { + const onPreviousTabSelected = BrowserTestUtils.waitForEvent( + gBrowser.tabContainer, + "TabSelect" + ); + await SpecialPowers.spawn(browsingContext, [], function () { + content.close(); + }); + await onPreviousTabSelected; +} + +add_task(async function testPausedByBreakpoint() { + await pushPref("devtools.popups.debug", true); + + info("Test breakpoints set in popup scripts"); + const dbg = await initDebuggerWithAbsoluteURL(TEST_URI); + + info("Open the popup in order to be able to set a breakpoint"); + const firstPopupBrowsingContext = await openPopup(POPUP_URL); + + await waitForSource(dbg, POPUP_URL); + const source = findSource(dbg, POPUP_URL); + + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 4); + + info("Now close and reopen the popup"); + await closePopup(firstPopupBrowsingContext); + + info("Re-open the popup"); + const popupBrowsingContext = await openPopup(POPUP_URL); + await waitForPaused(dbg); + is( + await isPopupPaused(popupBrowsingContext), + true, + "The popup is really paused" + ); + + await waitForSource(dbg, POPUP_URL); + assertPausedAtSourceAndLine(dbg, source.id, 4); + + await resume(dbg); + is( + await isPopupPaused(popupBrowsingContext), + false, + "The popup resumed its execution" + ); +}); + +add_task(async function testPausedByDebuggerStatement() { + info("Test debugger statements in popup scripts"); + const dbg = await initDebuggerWithAbsoluteURL(TEST_URI); + + info("Open a popup with a debugger statement"); + const popupBrowsingContext = await openPopup(POPUP_DEBUGGER_STATEMENT_URL); + await waitForPaused(dbg); + is( + await isPopupPaused(popupBrowsingContext), + true, + "The popup is really paused" + ); + + const source = findSource(dbg, POPUP_DEBUGGER_STATEMENT_URL); + assertPausedAtSourceAndLine(dbg, source.id, 4); + + await resume(dbg); + is( + await isPopupPaused(popupBrowsingContext), + false, + "The popup resumed its execution" + ); +}); + +add_task(async function testPausedInTwoPopups() { + info("Test being paused in two popup at the same time"); + const dbg = await initDebuggerWithAbsoluteURL(TEST_URI); + + info("Open the popup in order to be able to set a breakpoint"); + const browser = gBrowser.selectedBrowser; + const popupBrowsingContext = await openPopup(POPUP_URL); + + await waitForSource(dbg, POPUP_URL); + const source = findSource(dbg, POPUP_URL); + + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 4); + + info("Now close and reopen the popup"); + await closePopup(popupBrowsingContext); + + info("Open a first popup which will hit the breakpoint"); + const firstPopupBrowsingContext = await openPopup(POPUP_URL); + await waitForPaused(dbg); + const { targetCommand } = dbg.commands; + const firstTarget = targetCommand + .getAllTargets([targetCommand.TYPES.FRAME]) + .find(targetFront => targetFront.url == POPUP_URL); + is( + firstTarget.browsingContextID, + firstPopupBrowsingContext.id, + "The popup target matches the popup BrowsingContext" + ); + const firstThread = (await firstTarget.getFront("thread")).actorID; + is( + dbg.selectors.getCurrentThread(), + firstThread, + "The popup thread is automatically selected on pause" + ); + is( + await isPopupPaused(firstPopupBrowsingContext), + true, + "The first popup is really paused" + ); + + info("Open a second popup which will also hit the breakpoint"); + let onAvailable; + const onNewTarget = new Promise(resolve => { + onAvailable = ({ targetFront }) => { + if ( + targetFront.url == POPUP_URL && + targetFront.browsingContextID != firstPopupBrowsingContext.id + ) { + targetCommand.unwatchTargets({ + types: [targetCommand.TYPES.FRAME], + onAvailable, + }); + resolve(targetFront); + } + }; + }); + await targetCommand.watchTargets({ + types: [targetCommand.TYPES.FRAME], + onAvailable, + }); + const secondPopupBrowsingContext = await openPopup(POPUP_URL, browser); + info("Wait for second popup's target"); + const popupTarget = await onNewTarget; + is( + popupTarget.browsingContextID, + secondPopupBrowsingContext.id, + "The new target matches the popup WindowGlobal" + ); + const secondThread = (await popupTarget.getFront("thread")).actorID; + await waitForPausedThread(dbg, secondThread); + is( + dbg.selectors.getCurrentThread(), + secondThread, + "The second popup thread is automatically selected on pause" + ); + is( + await isPopupPaused(secondPopupBrowsingContext), + true, + "The second popup is really paused" + ); + + info("Resume the execution of the second popup"); + await resume(dbg); + is( + await isPopupPaused(secondPopupBrowsingContext), + false, + "The second popup resumed its execution" + ); + is( + await isPopupPaused(firstPopupBrowsingContext), + true, + "The first popup is still paused" + ); + + info("Resume the execution of the first popup"); + await dbg.actions.selectThread(getContext(dbg), firstThread); + await resume(dbg); + is( + await isPopupPaused(firstPopupBrowsingContext), + false, + "The first popup resumed its execution" + ); +}); + +add_task(async function testClosingOriginalTab() { + info( + "Test closing the toolbox on the original tab while the popup is kept open" + ); + const dbg = await initDebuggerWithAbsoluteURL(TEST_URI); + await dbg.toolbox.selectTool("webconsole"); + + info("Open a popup"); + const originalTab = gBrowser.selectedTab; + await openPopup("about:blank"); + await wait(1000); + const popupTab = gBrowser.selectedTab; + gBrowser.selectedTab = originalTab; + info("Close the toolbox from the original tab"); + await dbg.toolbox.closeToolbox(); + await wait(1000); + info("Re-select the popup"); + gBrowser.selectedTab = popupTab; + await wait(1000); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading-with-source-changes.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading-with-source-changes.js new file mode 100644 index 0000000000..a95599a2b4 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading-with-source-changes.js @@ -0,0 +1,186 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This tests breakpoints resyncing when source content changes +// after reload. +"use strict"; + +const httpServer = createTestHTTPServer(); +httpServer.registerContentType("html", "text/html"); +httpServer.registerContentType("js", "application/javascript"); + +httpServer.registerPathHandler( + "/doc-breakpoint-reload.html", + (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + + + `); + } +); + +let views = 0; +httpServer.registerPathHandler("/script.js", (request, response) => { + response.setHeader("Content-Type", "application/javascript"); + // The script contents to serve on reload of script.js. Each relaod + // cycles through the script content. + const content = [ + // CONTENT 1: Source content with 1 function + // The breakpoint will be set on line 3 (i.e with the `return` statement) + `function bar() { + const prefix = "long"; + return prefix + "bar"; +} +console.log(bar());`, + + // CONTENT 2: Source content with 2 functions, where the breakpoint is now in a + // different function though the line does not change. + `function foo() { + const prefix = "long"; + return prefix + "foo"; +} + +function bar() { + const prefix = "long"; + return prefix + "bar"; +} +console.log(bar(), foo());`, + + // CONTENT 3: Source content with comments and 1 function, where the breakpoint is + // is now at a line with comments (non-breakable line). + `// This is a random comment which is here +// to move the function a couple of lines +// down, making sure the breakpoint is on +// a non-breakable line. +function bar() { + const prefix = "long"; + return prefix + "bar"; +} +console.log(bar());`, + + // CONTENT 4: Source content with just a comment where the line which the breakpoint + // is supposed to be on no longer exists. + `// one line comment`, + ]; + + response.write(content[views % content.length]); + views++; +}); + +const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`; + +add_task(async function testBreakpointInFunctionRelocation() { + info("Start test for relocation of breakpoint set in a function"); + const dbg = await initDebuggerWithAbsoluteURL( + `${BASE_URL}doc-breakpoint-reload.html`, + "script.js" + ); + + let source = findSource(dbg, "script.js"); + await selectSource(dbg, source); + + info("Add breakpoint in bar()"); + await addBreakpoint(dbg, source, 3); + + info( + "Assert the text content on line 3 to make sure the breakpoint was set in bar()" + ); + assertTextContentOnLine(dbg, 3, 'return prefix + "bar";'); + + info("Check that only one breakpoint is set in the reducer"); + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + + info("Check that only one breakpoint is set on the server"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "Only one breakpoint exists on the server" + ); + + info( + "Reload should change the source content to CONTENT 2 i.e 2 functions foo() and bar()" + ); + const onReloaded = reload(dbg); + await waitForPaused(dbg); + + source = findSource(dbg, "script.js"); + + info("Assert that the breakpoint pauses on line 3"); + assertPausedAtSourceAndLine(dbg, source.id, 3); + + info("Assert that the breakpoint is visible on line 3"); + await assertBreakpoint(dbg, 3); + + info("Assert the text content on line 3 to make sure we are paused in foo()"); + assertTextContentOnLine(dbg, 3, 'return prefix + "foo";'); + + info("Check that only one breakpoint currently exists in the reducer"); + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + + info("Check that only one breakpoint exist on the server"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "Only one breakpoint exists on the server" + ); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; + + info( + "Reload should change the source content to CONTENT 3 i.e comments and 1 function bar()" + ); + await reload(dbg); + await waitForSelectedSource(dbg, "script.js"); + + await assertNotPaused(dbg); + + info( + "Assert that the breakpoint is not visible on line 3 which is a non-breakable line" + ); + await assertNoBreakpoint(dbg, 3); + + info("Check that no breakpoint exists in the reducer"); + is(dbg.selectors.getBreakpointCount(), 0, "Breakpoint has been removed"); + + // See comment on line 175 + info("Check that one breakpoint exists on the server"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "Breakpoint has been removed on the server" + ); + + info( + "Reload should change the source content to CONTENT 4 which is just a one comment line" + ); + await reload(dbg); + await waitForSelectedSource(dbg, "script.js"); + + // There will initially be zero breakpoints, but wait to make sure none are + // installed while syncing. + await wait(1000); + assertNotPaused(dbg); + + info("Assert that the source content is one comment line"); + assertTextContentOnLine(dbg, 1, "// one line comment"); + + info("Check that no breakpoint still exists in the reducer"); + is(dbg.selectors.getBreakpointCount(), 0, "No breakpoint exists"); + + // Breakpoints do not get removed in this situation, to support breakpoints in + // inline sources which load and get hit progressively. See the browser_dbg-breakpoints-reloading.js + // test for this behaviour. + info("Check that one breakpoint exists on the server"); + is( + dbg.client.getServerBreakpointsList().length, + 1, + "One breakpoint exists on the server" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading.js new file mode 100644 index 0000000000..ca953445ba --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-reloading.js @@ -0,0 +1,124 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests breakpoints syncing when reloading + +"use strict"; + +requestLongerTimeout(3); + +// Tests that a breakpoint set is correctly synced after reload +// and gets hit correctly. +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js", "long.js"); + + await selectSource(dbg, "simple1.js"); + + // Setting 2 breakpoints, one on line 61 which is expected + // to get hit, while the other on line 56 which is not expected + // to get hit, but to assert that it correctly set after reload. + await addBreakpointViaGutter(dbg, 61); + await addBreakpointViaGutter(dbg, 56); + + await selectSource(dbg, "long.js"); + + await addBreakpointViaGutter(dbg, 1); + + const onReloaded = reload(dbg); + await waitForPaused(dbg); + + info("Assert that the source is not long.js"); + // Adding this is redundant but just to make it explicit that we + // make sure long.js should not exist yet + assertSourceDoesNotExist(dbg, "long.js"); + + const source = findSource(dbg, "simple1.js"); + + await assertPausedAtSourceAndLine(dbg, source.id, 61); + + info("The breakpoint for long.js does not exist yet"); + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() == 2); + + // The breakpoints are available once their corresponding source + // has been processed. Let's assert that all the breakpoints for + // simple1.js have been restored. + await assertBreakpoint(dbg, 56); + await assertBreakpoint(dbg, 61); + + await resume(dbg); + await waitForPaused(dbg); + + const source2 = findSource(dbg, "long.js"); + + await assertPausedAtSourceAndLine(dbg, source2.id, 1); + + info("All 3 breakpoints from simple1.js and long.js still exist"); + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() == 3); + + await assertBreakpoint(dbg, 1); + + await resume(dbg); + + info("Wait for reload to complete after resume"); + await onReloaded; + + // remove breakpoints so they do not affect other + // tests. + await removeBreakpoint(dbg, source.id, 56); + await removeBreakpoint(dbg, source.id, 61); + await removeBreakpoint(dbg, source2.id, 1); + + await dbg.toolbox.closeToolbox(); +}); + +// Test that pending breakpoints are installed in inline scripts as they are +// sent to the client. +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "doc-scripts.html"); + + await selectSource(dbg, "doc-scripts.html"); + await addBreakpointViaGutter(dbg, 22); + await addBreakpointViaGutter(dbg, 27); + + const onReloaded = reload(dbg, "doc-scripts.html"); + await waitForPaused(dbg); + + const source = findSource(dbg, "doc-scripts.html"); + + await assertPausedAtSourceAndLine(dbg, source.id, 22); + + info("Only the breakpoint for the first inline script should exist"); + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() == 1); + + await assertBreakpoint(dbg, 22); + + // The second breakpoint we added is in a later inline script, and won't + // appear until after we have resumed from the first breakpoint and the + // second inline script has been created. + await assertNoBreakpoint(dbg, 27); + + await resume(dbg); + await waitForPaused(dbg); + + info("All 2 breakpoints from both inline scripts still exist"); + await waitForState(dbg, state => dbg.selectors.getBreakpointCount() == 2); + + await assertPausedAtSourceAndLine(dbg, source.id, 27); + await assertBreakpoint(dbg, 27); + + await resume(dbg); + + info("Wait for reload to complete after resume"); + await onReloaded; + + await removeBreakpoint(dbg, source.id, 22); + await removeBreakpoint(dbg, source.id, 27); + + await dbg.toolbox.closeToolbox(); +}); + +function assertSourceDoesNotExist(dbg, url) { + const source = findSource(dbg, url, { silent: true }); + ok(!source, `Source for ${url} does not exist`); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-same-file-per-target.js b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-same-file-per-target.js new file mode 100644 index 0000000000..08918c235f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-breakpoints-same-file-per-target.js @@ -0,0 +1,114 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests shows that breakpoints per url feature works in the debugger. + +"use strict"; + +add_task(async function () { + // This test fails with server side target switching disabled + if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) { + return; + } + + const dbg = await initDebugger( + "doc_dbg-same-source-distinct-threads.html", + "same-script.js" + ); + + // There is one source but 3 source actors. One per same-script.js instance, + // one "); + + // The debugger should automatically be selected. + await ToolboxTask.spawn(null, async () => { + /* global gToolbox */ + await waitUntil(() => gToolbox.currentToolId == "jsdebugger"); + }); + ok(true, "Debugger selected"); + + // The debugger should pause. + await ToolboxTask.spawn(null, async () => { + // Wait for the debugger to finish loading. + await gToolbox.getPanelWhenReady("jsdebugger"); + + const dbg = createDebuggerContext(gToolbox); + await waitForPaused(dbg); + if (!gToolbox.isHighlighted("jsdebugger")) { + throw new Error("Debugger not highlighted"); + } + }); + ok(true, "Paused in new tab"); + + await ToolboxTask.destroy(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js new file mode 100644 index 0000000000..f08feb4ba9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-browser-toolbox-workers.js @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that all kinds of workers show up properly in the multiprocess browser +// toolbox. + +"use strict"; + +requestLongerTimeout(4); + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js", + this +); + +add_task(async function () { + await pushPref("devtools.browsertoolbox.scope", "everything"); + await pushPref("dom.serviceWorkers.enabled", true); + await pushPref("dom.serviceWorkers.testing.enabled", true); + + const ToolboxTask = await initBrowserToolboxTask(); + await ToolboxTask.importFunctions({ + waitUntil, + waitForAllTargetsToBeAttached, + }); + + await addTab(`${EXAMPLE_URL}doc-all-workers.html`); + + await ToolboxTask.spawn(null, async () => { + /* global gToolbox */ + await gToolbox.selectTool("jsdebugger"); + const dbg = gToolbox.getCurrentPanel().panelWin.dbg; + + await waitUntil(() => { + const threads = dbg.selectors.getThreads(); + function hasWorker(workerName) { + // eslint-disable-next-line max-nested-callbacks + return threads.some(({ name }) => name == workerName); + } + return ( + hasWorker("simple-worker.js") && + hasWorker("shared-worker.js") && + hasWorker("service-worker.sjs") + ); + }); + + await waitForAllTargetsToBeAttached(gToolbox.commands.targetCommand); + }); + ok(true, "All workers appear in browser toolbox debugger"); + + invokeInTab("unregisterServiceWorker"); + + await ToolboxTask.destroy(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js b/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js new file mode 100644 index 0000000000..6b557cb24f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-call-stack.js @@ -0,0 +1,115 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Ignore strange errors when shutting down. +PromiseTestUtils.allowMatchingRejectionsGlobally(/No such actor/); + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + const found = findElement(dbg, "callStackBody"); + is(found, null, "Call stack is hidden"); + + invokeInTab("firstCall"); + await waitForPaused(dbg); + ok(isFrameSelected(dbg, 1, "secondCall"), "the first frame is selected"); + + const button = toggleButton(dbg); + ok(!button, "toggle button shouldn't be there"); +}); + +add_task(async function () { + const dbg = await initDebugger("doc-frames.html"); + + invokeInTab("startRecursion"); + await waitForPaused(dbg); + ok(isFrameSelected(dbg, 1, "recurseA"), "the first frame is selected"); + + // check to make sure that the toggle button isn't there + let button = toggleButton(dbg); + let frames = findAllElements(dbg, "frames"); + is(button.innerText, "Expand rows", "toggle button should be 'expand'"); + is(frames.length, 7, "There should be at most seven frames"); + + button.click(); + + button = toggleButton(dbg); + frames = findAllElements(dbg, "frames"); + is(button.innerText, "Collapse rows", "toggle button should be collapsed"); + is(frames.length, 22, "All of the frames should be shown"); + await waitForSelectedSource(dbg, "frames.js"); +}); + +add_task(async function () { + const url = createMockAngularPage(); + const tab = await addTab(url); + info("Open debugger"); + const toolbox = await openToolboxForTab(tab, "jsdebugger"); + const dbg = createDebuggerContext(toolbox); + + const found = findElement(dbg, "callStackBody"); + is(found, null, "Call stack is hidden"); + + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("button.pause").click(); + }); + + await waitForPaused(dbg); + const $group = findElementWithSelector(dbg, ".frames .frames-group"); + is( + $group.querySelector(".badge").textContent, + "2", + "Group has expected badge" + ); + is( + $group.querySelector(".group-description-name").textContent, + "Angular", + "Group has expected location" + ); +}); + +function toggleButton(dbg) { + const callStackBody = findElement(dbg, "callStackBody"); + return callStackBody.querySelector(".show-more"); +} + +// Create an HTTP server to simulate an angular app with anonymous functions +// and return the URL. +function createMockAngularPage() { + const httpServer = createTestHTTPServer(); + + httpServer.registerContentType("html", "text/html"); + httpServer.registerContentType("js", "application/javascript"); + + const htmlFilename = "angular-mock.html"; + httpServer.registerPathHandler( + `/${htmlFilename}`, + function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + `); + } + ); + + // Register an angular.js file in order to create a Group with anonymous functions in + // the callstack panel. + httpServer.registerPathHandler("/angular.js", function (request, response) { + response.setHeader("Content-Type", "application/javascript"); + response.write(` + document.querySelector("button.pause").addEventListener("click", () => { + (function() { + debugger; + })(); + }) + `); + }); + + const port = httpServer.identity.primaryPort; + return `http://localhost:${port}/${htmlFilename}`; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-chrome-create.js b/devtools/client/debugger/test/mochitest/browser_dbg-chrome-create.js new file mode 100644 index 0000000000..fdf3c186de --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-chrome-create.js @@ -0,0 +1,61 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Tests that a chrome debugger can be created in a new process. + */ + +"use strict"; + +// There are shutdown issues for which multiple rejections are left uncaught. +// See bug 1018184 for resolving these issues. +PromiseTestUtils.allowMatchingRejectionsGlobally(/File closed/); +PromiseTestUtils.allowMatchingRejectionsGlobally(/NS_ERROR_FAILURE/); + +// This test can be slow to run +requestLongerTimeout(5); + +const { BrowserToolboxLauncher } = ChromeUtils.importESModule( + "resource://devtools/client/framework/browser-toolbox/Launcher.sys.mjs" +); + +add_task(async function () { + await pushPref("devtools.chrome.enabled", true); + await pushPref("devtools.debugger.remote-enabled", true); + + info("Call BrowserToolboxLauncher.init"); + const [browserToolboxLauncher, process, profilePath] = await new Promise( + resolve => { + BrowserToolboxLauncher.init({ + onRun: (btl, dbgProcess, dbgProfilePath) => { + info("Browser toolbox process started successfully."); + resolve([btl, dbgProcess, dbgProfilePath]); + }, + }); + } + ); + + ok(process, "The remote debugger process was created"); + ok(process.exitCode == null, "The remote debugger process is running"); + is( + typeof process.pid, + "number", + `The remote debugger process has a proper pid (${process.pid})` + ); + + is( + profilePath, + PathUtils.join(PathUtils.profileDir, "chrome_debugger_profile"), + `The remote debugger profile has the expected path` + ); + + info("Close the browser toolbox"); + await browserToolboxLauncher.close(); + + is( + process.exitCode, + Services.appinfo.OS == "WINNT" ? -9 : -15, + "The remote debugger process died cleanly" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-command-click.js b/devtools/client/debugger/test/mochitest/browser_dbg-command-click.js new file mode 100644 index 0000000000..1f6ad49e4d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-command-click.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test checks to see if holding down the command key and clicking on function call +// will jump the debugger to that call. + +"use strict"; + +add_task(async function () { + await pushPref("devtools.debugger.features.command-click", true); + info( + "Checking to see if command click will jump the debugger to another highlighted call." + ); + const dbg = await initDebugger("doc-command-click.html", "simple4.js"); + + const source = findSource(dbg, "simple4.js"); + + await selectSource(dbg, source); + + invokeInTab("funcA"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + + pressKey(dbg, "commandKeyDown"); + await waitForDispatch(dbg.store, "HIGHLIGHT_CALLS"); + const calls = dbg.win.document.querySelectorAll(".highlight-function-calls"); + is(calls.length, 2); + + const funcB = calls[0]; + clickDOMElement(dbg, funcB); + await waitForDispatch(dbg.store, "RESUME"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 3, 2); + const nocalls = dbg.win.document.querySelectorAll( + ".highlight-function-calls" + ); + is(nocalls.length, 0); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js new file mode 100644 index 0000000000..4c669766b0 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-async.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Return a promise with a reference to jsterm, opening the split +// console if necessary. This cleans up the split console pref so +// it won't pollute other tests. + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + Services.prefs.setBoolPref( + "devtools.debugger.features.map-await-expression", + true + ); + + const dbg = await initDebugger( + "doc-script-switching.html", + "script-switching-01.js" + ); + + await selectSource(dbg, "script-switching-01.js"); + + // open the console + await getDebuggerSplitConsole(dbg); + ok(dbg.toolbox.splitConsole, "Split console is shown."); + + const webConsole = await dbg.toolbox.getPanel("webconsole"); + const wrapper = webConsole.hud.ui.wrapper; + + wrapper.dispatchEvaluateExpression(` + let sleep = async (time, v) => new Promise( + res => setTimeout(() => res(v+'!!!'), time) + ) + `); + + await hasMessageByType(dbg, "sleep", ".command"); + + wrapper.dispatchEvaluateExpression(`await sleep(200, "DONE")`); + await hasMessageByType(dbg, "DONE!!!", ".result"); +}); + +async function hasMessageByType(dbg, msg, typeSelector) { + const webConsole = await dbg.toolbox.getPanel("webconsole"); + const hud = webConsole.hud; + return waitFor( + async () => !!findMessagesByType(hud, msg, typeSelector).length + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-eval.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-eval.js new file mode 100644 index 0000000000..0e4cf793ec --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-eval.js @@ -0,0 +1,37 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that clicking the DOM node button in any ObjectInspect +// opens the Inspector panel + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple2.js"); + + await selectSource(dbg, "simple2.js", 1); + + clickElement(dbg, "CodeMirrorLines"); + await waitForElementWithSelector(dbg, ".CodeMirror-code"); + + getCM(dbg).setSelection({ line: 0, ch: 0 }, { line: 8, ch: 0 }); + + rightClickElement(dbg, "CodeMirrorLines"); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, "#node-menu-evaluate-in-console"); + + await waitForConsolePanelChange(dbg); + await hasConsoleMessage(dbg, "undefined"); +}); + +function waitForConsolePanelChange(dbg) { + const { toolbox } = dbg; + + return new Promise(resolve => { + toolbox.getPanelWhenReady("webconsole").then(() => { + ok(toolbox.webconsolePanel, "Console is shown."); + resolve(toolbox.webconsolePanel); + }); + }); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-link.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-link.js new file mode 100644 index 0000000000..3d87fdc819 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-link.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests opening the console first, clicking a link +// opens the editor at the correct location. + +"use strict"; + +add_task(async function () { + const toolbox = await initPane("doc-script-switching.html", "webconsole"); + const node = await waitForLink(toolbox, "hi"); + node.click(); + + await waitFor(() => toolbox.getPanel("jsdebugger")); + const dbg = createDebuggerContext(toolbox); + await waitForElementWithSelector(dbg, ".CodeMirror-code > .highlight-line"); + assertHighlightLocation(dbg, "script-switching-02.js", 14); +}); + +async function waitForLink(toolbox, messageText) { + return waitFor(async () => { + const [message] = await findConsoleMessages(toolbox, messageText); + if (!message) { + return false; + } + return message.querySelector(".frame-link-source"); + }); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js b/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js new file mode 100644 index 0000000000..26529a75cd --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-console-map-bindings.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + const dbg = await initDebugger("doc-strict.html"); + + await getSplitConsole(dbg); + ok(dbg.toolbox.splitConsole, "Split console is shown."); + + invokeInTab("strict", 2); + + await waitForPaused(dbg); + await evaluate(dbg, "var c = 3"); + const msg2 = await evaluate(dbg, "c"); + + is(msg2.trim(), "3"); +}); + +// Return a promise with a reference to jsterm, opening the split +// console if necessary. This cleans up the split console pref so +// it won't pollute other tests. +function getSplitConsole(dbg) { + const { toolbox } = dbg; + + if (!toolbox.splitConsole) { + pressKey(dbg, "Escape"); + } + + return new Promise(resolve => { + toolbox.getPanelWhenReady("webconsole").then(() => { + ok(toolbox.splitConsole, "Split console is shown."); + const jsterm = toolbox.getPanel("webconsole").hud.jsterm; + resolve(jsterm); + }); + }); +} + +async function evaluate(dbg, expression) { + const { toolbox } = dbg; + const { hud } = toolbox.getPanel("webconsole"); + const msg = await evaluateExpressionInConsole(hud, expression); + return msg.innerText; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-console.js new file mode 100644 index 0000000000..a725f7de43 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-console.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + const dbg = await initDebugger( + "doc-script-switching.html", + "script-switching-01.js" + ); + + await selectSource(dbg, "script-switching-01.js"); + + // open the console + await getDebuggerSplitConsole(dbg); + ok(dbg.toolbox.splitConsole, "Split console is shown."); + + // close the console + await clickElement(dbg, "codeMirror"); + // First time to focus out of text area + pressKey(dbg, "Escape"); + + // Second time to hide console + pressKey(dbg, "Escape"); + ok(!dbg.toolbox.splitConsole, "Split console is hidden."); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-content-script-sources.js b/devtools/client/debugger/test/mochitest/browser_dbg-content-script-sources.js new file mode 100644 index 0000000000..b95b08cbbb --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-content-script-sources.js @@ -0,0 +1,52 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the content scripts are listed in the source tree. + +"use strict"; + +add_task(async function () { + await pushPref("devtools.chrome.enabled", true); + const extension = await installAndStartContentScriptExtension(); + + let dbg = await initDebugger( + "doc-content-script-sources.html", + "content_script.js" + ); + await selectSource(dbg, "content_script.js"); + await closeTab(dbg, "content_script.js"); + + // Destroy the toolbox and repeat the test in a new toolbox + // and ensures that the content script is still listed. + await dbg.toolbox.destroy(); + + const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger"); + dbg = createDebuggerContext(toolbox); + await waitForSources(dbg, "content_script.js"); + await selectSource(dbg, "content_script.js"); + + await addBreakpoint(dbg, "content_script.js", 2); + + for (let i = 1; i < 3; i++) { + info(`Reloading tab (${i} time)`); + gBrowser.reloadTab(gBrowser.selectedTab); + await waitForPaused(dbg); + await waitForSelectedSource(dbg, "content_script.js"); + + await waitFor( + () => findElementWithSelector(dbg, ".sources-list .focused"), + "Source is focused" + ); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "content_script.js").id, + 2 + ); + await resume(dbg); + } + + await closeTab(dbg, "content_script.js"); + + await extension.unload(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here-click.js b/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here-click.js new file mode 100644 index 0000000000..67cbbe12ec --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here-click.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test cmd+click continuing to a line + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pause-points.html", "pause-points.js"); + await selectSource(dbg, "pause-points.js"); + await waitForSelectedSource(dbg, "pause-points.js"); + + info( + "Pause the debugger by clicking a button with a click handler containing a debugger statement" + ); + clickElementInTab("#sequences"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + ok(true, "Debugger is paused"); + + info("Cmd+click on a line and check the debugger continues to that line"); + const lineToContinueTo = 31; + const onResumed = waitForResumed(dbg); + await cmdClickLine(dbg, lineToContinueTo); + + // continuing will resume and pause again. Let's wait until we resume so we can properly + // wait for the next pause. + await onResumed; + // waitForPaused properly waits for the scopes to be available + await waitForPaused(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "pause-points.js").id, + lineToContinueTo, + 4 + ); + ok(true, "Debugger continued to the expected line"); + + info("Resume"); + await resume(dbg); + await waitForRequestsToSettle(dbg); +}); + +async function cmdClickLine(dbg, line) { + await cmdClickGutter(dbg, line); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here.js b/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here.js new file mode 100644 index 0000000000..baeef0cf8c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-continue-to-here.js @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pause-points.html", "pause-points.js"); + await selectSource(dbg, "pause-points.js"); + await waitForSelectedSource(dbg, "pause-points.js"); + + info("Test continuing to a line"); + clickElementInTab("#sequences"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + + await continueToLine(dbg, 31); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "pause-points.js").id, + 31, + 4 + ); + await resume(dbg); + + info("Test continuing to a column"); + clickElementInTab("#sequences"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + + await continueToColumn(dbg, { line: 31, ch: 7 }); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "pause-points.js").id, + 31, + 4 + ); + await resume(dbg); +}); + +async function continueToLine(dbg, line) { + rightClickElement(dbg, "gutter", line); + await waitForContextMenu(dbg); + selectContextMenuItem(dbg, selectors.editorContextMenu.continueToHere); + await waitForDispatch(dbg.store, "RESUME"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); +} + +async function continueToColumn(dbg, pos) { + await rightClickAtPos(dbg, pos); + await waitForContextMenu(dbg); + + selectContextMenuItem(dbg, selectors.editorContextMenu.continueToHere); + await waitForDispatch(dbg.store, "RESUME"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-custom-formatters.js b/devtools/client/debugger/test/mochitest/browser_dbg-custom-formatters.js new file mode 100644 index 0000000000..ac6a367f55 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-custom-formatters.js @@ -0,0 +1,158 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Check display of custom formatters in debugger. +const TEST_FILENAME = `doc_dbg-custom-formatters.html`; +const TEST_FUNCTION_NAME = "pauseWithCustomFormattedObject"; +const CUSTOM_FORMATTED_BODY = "customFormattedBody"; +const VARIABLE_NAME = "xyz"; + +add_task(async function () { + // TODO: This preference can be removed once the custom formatters feature is stable enough + await pushPref("devtools.custom-formatters", true); + await pushPref("devtools.custom-formatters.enabled", true); + + const dbg = await initDebugger(TEST_FILENAME); + await selectSource(dbg, TEST_FILENAME); + + info( + "Test that custom formatted objects are displayed as expected in the Watch Expressions panel" + ); + await addExpression(dbg, `({customFormatHeaderAndBody: "body"})`); + const expressionsElements = findAllElements(dbg, "expressionNodes"); + is(expressionsElements.length, 1); + + const customFormattedElement = expressionsElements[0]; + + const headerJsonMlNode = + customFormattedElement.querySelector(".objectBox-jsonml"); + is( + headerJsonMlNode.innerText, + "CUSTOM", + "The object is rendered with a custom formatter" + ); + + is( + customFormattedElement.querySelector(".arrow"), + null, + "The expression is not expandable…" + ); + const customFormattedElementArrow = + customFormattedElement.querySelector(".collapse-button"); + ok(customFormattedElementArrow, "… but the custom formatter is"); + + info("Expanding the Object"); + const onBodyRendered = waitFor( + () => + !!customFormattedElement.querySelector( + ".objectBox-jsonml-body-wrapper .objectBox-jsonml" + ) + ); + + customFormattedElementArrow.click(); + await onBodyRendered; + + ok( + customFormattedElement + .querySelector(".collapse-button") + .classList.contains("expanded"), + "The arrow of the node has the expected class after clicking on it" + ); + + const bodyJsonMlNode = customFormattedElement.querySelector( + ".objectBox-jsonml-body-wrapper > .objectBox-jsonml" + ); + ok(bodyJsonMlNode, "The body is custom formatted"); + is(bodyJsonMlNode?.textContent, "body", "The body text is correct"); + + info("Check that custom formatters are displayed in Scopes panel"); + + // The function has a debugger statement that will pause the debugger + invokeInTab(TEST_FUNCTION_NAME); + + info("Wait for the debugger to be paused"); + await waitForPaused(dbg); + + info( + `Check that '${VARIABLE_NAME}' is in the scopes panel and custom formatted` + ); + const index = 4; + is( + getScopeLabel(dbg, index), + VARIABLE_NAME, + `Got '${VARIABLE_NAME}' at the expected position` + ); + const scopeXElement = findElement(dbg, "scopeValue", index); + is( + scopeXElement.innerText, + "CUSTOM", + `'${VARIABLE_NAME}' is custom formatted in the scopes panel` + ); + const xArrow = scopeXElement.querySelector(".collapse-button"); + ok(xArrow, `'${VARIABLE_NAME}' is expandable`); + + info(`Expanding '${VARIABLE_NAME}'`); + const onScopeBodyRendered = waitFor( + () => + !!scopeXElement.querySelector( + ".objectBox-jsonml-body-wrapper .objectBox-jsonml" + ) + ); + + xArrow.click(); + await onScopeBodyRendered; + const scopeXBodyJsonMlNode = scopeXElement.querySelector( + ".objectBox-jsonml-body-wrapper > .objectBox-jsonml" + ); + ok(scopeXBodyJsonMlNode, "The scope item body is custom formatted"); + is( + scopeXBodyJsonMlNode?.textContent, + CUSTOM_FORMATTED_BODY, + "The scope item body text is correct" + ); + + await resume(dbg); + + info("Check that custom formatters are displayed in the Debugger tooltip"); + + // The function has a debugger statement that will pause the debugger + invokeInTab(TEST_FUNCTION_NAME); + await waitForPaused(dbg); + + await assertPreviewTextValue(dbg, 26, 16, { + expression: VARIABLE_NAME, + text: "CUSTOM", + }); + + const tooltipPopup = findElement(dbg, "previewPopup"); + + const tooltipArrow = tooltipPopup.querySelector(".collapse-button"); + ok(tooltipArrow, `'${VARIABLE_NAME}' is expandable`); + + info(`Expanding '${VARIABLE_NAME}'`); + const onTooltipBodyRendered = waitFor( + () => + !!tooltipPopup.querySelector( + ".objectBox-jsonml-body-wrapper .objectBox-jsonml" + ) + ); + + tooltipArrow.click(); + await onTooltipBodyRendered; + const tooltipBodyJsonMlNode = tooltipPopup.querySelector( + ".objectBox-jsonml-body-wrapper > .objectBox-jsonml" + ); + ok(tooltipBodyJsonMlNode, "The tooltip variable body is custom formatted"); + is( + tooltipBodyJsonMlNode?.textContent, + CUSTOM_FORMATTED_BODY, + "The tooltip variable body text is correct" + ); + + info("Close tooltip"); + dbg.actions.clearPreview(getContext(dbg)); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-debug-line.js b/devtools/client/debugger/test/mochitest/browser_dbg-debug-line.js new file mode 100644 index 0000000000..ab13a1ee50 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-debug-line.js @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test ensures zombie debug lines do not persist +// https://github.com/firefox-devtools/debugger/issues/7755 + +"use strict"; + +add_task(async function () { + // Load test files + const dbg = await initDebugger("doc-sources.html"); + await waitForSources(dbg, "simple1.js", "simple2.js"); + + // Add breakpoint to debug-line-2 + await selectSource(dbg, "simple2.js"); + await addBreakpoint(dbg, "simple2.js", 5); + + // Trigger the breakpoint ane ensure we're paused + invokeInTab("main"); + await waitForPaused(dbg); + await waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + + // Scroll element into view + findElement(dbg, "frame", 2).focus(); + + // Click the call stack to get to debugger-line-1 + const dispatched = waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + await clickElement(dbg, "frame", 2); + await dispatched; + await waitForRequestsToSettle(dbg); + await waitForSelectedSource(dbg, "simple1.js"); + + // Resume, which ends all pausing and would trigger the problem + await resume(dbg); + + // Select the source that had the initial debug line + await selectSource(dbg, "simple2.js"); + + info("Ensuring there's no zombie debug line"); + is( + findAllElements(dbg, "debugLine").length, + 0, + "Debug line no longer exists!" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-debugger-buttons.js b/devtools/client/debugger/test/mochitest/browser_dbg-debugger-buttons.js new file mode 100644 index 0000000000..c466c4865d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-debugger-buttons.js @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test debugger buttons + * 1. resume + * 2. stepOver + * 3. stepIn + * 4. stepOver to the end of a function + * 5. stepUp at the end of a function + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-debugger-statements.html"); + + const onReloaded = reload(dbg, "doc-debugger-statements.html"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 11 + ); + + info("resume"); + await clickResume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 16 + ); + + info("step over"); + await clickStepOver(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 17 + ); + + info("step into"); + await clickStepIn(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 22 + ); + + info("step over"); + await clickStepOver(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 24 + ); + + info("step out"); + await clickStepOut(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 18 + ); + + await resume(dbg); + + info("Wait for reload to complete after resume"); + await onReloaded; +}); + +function clickButton(dbg, button) { + const resumeFired = waitForDispatch(dbg.store, "COMMAND"); + clickElement(dbg, button); + return resumeFired; +} + +async function clickStepOver(dbg) { + await clickButton(dbg, "stepOver"); + return waitForPaused(dbg); +} + +async function clickStepIn(dbg) { + await clickButton(dbg, "stepIn"); + return waitForPaused(dbg); +} + +async function clickStepOut(dbg) { + await clickButton(dbg, "stepOut"); + return waitForPaused(dbg); +} + +async function clickResume(dbg) { + return clickButton(dbg, "resume"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints-fission.js b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints-fission.js new file mode 100644 index 0000000000..462ff35b67 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints-fission.js @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests dom mutation breakpoints with a remote frame. + +"use strict"; + +// Import helpers for the inspector +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js", + this +); + +/** + * The test page contains an INPUT and a BUTTON. + * + * On "click", the button will update the disabled attribute of the input. + * Updating the attribute via SpecialPowers.spawn would not trigger the DOM + * breakpoint, that's why we need the page itself to have a way of updating + * the attribute. + */ +const TEST_COM_URI = `https://example.com/document-builder.sjs?html=${encodeURI( + ` + ` +)}`; + +// Embed the example.com test page in an example.org iframe. +const TEST_URI = `https://example.org/document-builder.sjs?html= +`; + +add_task(async function () { + await pushPref("devtools.markup.mutationBreakpoints.enabled", true); + await pushPref("devtools.debugger.dom-mutation-breakpoints-visible", true); + + const { inspector, toolbox } = await openInspectorForURL(TEST_URI); + + await selectNodeInFrames(["iframe", "input"], inspector); + info("Adding DOM mutation breakpoints to body"); + const allMenuItems = openContextMenuAndGetAllItems(inspector); + + const attributeMenuItem = allMenuItems.find( + item => item.id === "node-menu-mutation-breakpoint-attribute" + ); + attributeMenuItem.click(); + + info("Switches over to the debugger pane"); + await toolbox.selectTool("jsdebugger"); + + const dbg = createDebuggerContext(toolbox); + + info("Changing attribute to trigger debugger pause"); + const frameBC = await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + function () { + return content.document.querySelector("iframe").browsingContext; + } + ); + + info("Confirms that one DOM mutation breakpoint exists"); + const mutationItem = await waitForElement(dbg, "domMutationItem"); + ok(mutationItem, "A DOM mutation breakpoint exists"); + + mutationItem.scrollIntoView(); + + info("Enabling and disabling the DOM mutation breakpoint works"); + const checkbox = mutationItem.querySelector("input"); + checkbox.click(); + await waitFor(() => !checkbox.checked); + + info("Click the button in the remote iframe, should not hit the breakpoint"); + BrowserTestUtils.synthesizeMouseAtCenter("button", {}, frameBC); + + info("Wait until the input is enabled"); + await asyncWaitUntil(() => + SpecialPowers.spawn( + frameBC, + [], + () => !content.document.querySelector("input").disabled + ) + ); + assertNotPaused(dbg, "DOM breakpoint should not have been hit"); + + info("Restore the disabled attribute"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + return SpecialPowers.spawn( + content.document.querySelector("iframe"), + [], + () => + !content.document.querySelector("input").setAttribute("disabled", "") + ); + }); + + checkbox.click(); + await waitFor(() => checkbox.checked); + + info("Click the button in the remote iframe, to trigger the breakpoint"); + BrowserTestUtils.synthesizeMouseAtCenter("button", {}, frameBC); + + info("Wait for paused"); + await waitForPaused(dbg); + info("Resume"); + await resume(dbg); + + info("Removing breakpoints works"); + dbg.win.document.querySelector(".dom-mutation-list .close-btn").click(); + await waitForAllElements(dbg, "domMutationItem", 0, true); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js new file mode 100644 index 0000000000..ca7e9bdc20 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-dom-mutation-breakpoints.js @@ -0,0 +1,170 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests adding, disble/enable, and removal of dom mutation breakpoints + +"use strict"; + +// Import helpers for the inspector +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js", + this +); + +const DMB_TEST_URL = + "https://example.com/browser/devtools/client/debugger/test/mochitest/examples/doc-dom-mutation.html"; + +async function enableMutationBreakpoints() { + await pushPref("devtools.markup.mutationBreakpoints.enabled", true); + await pushPref("devtools.debugger.dom-mutation-breakpoints-visible", true); +} + +add_task(async function () { + // Enable features + await enableMutationBreakpoints(); + info("Switches over to the inspector pane"); + + const { inspector, toolbox } = await openInspectorForURL(DMB_TEST_URL); + + { + info("Selecting the body node"); + await selectNode("body", inspector); + + info("Adding DOM mutation breakpoints to body"); + const allMenuItems = openContextMenuAndGetAllItems(inspector); + + const attributeMenuItem = allMenuItems.find( + item => item.id === "node-menu-mutation-breakpoint-attribute" + ); + attributeMenuItem.click(); + + const subtreeMenuItem = allMenuItems.find( + item => item.id === "node-menu-mutation-breakpoint-subtree" + ); + subtreeMenuItem.click(); + } + + { + info("Find and expand the shadow host."); + const hostFront = await getNodeFront("#host", inspector); + const hostContainer = inspector.markup.getContainer(hostFront); + await expandContainer(inspector, hostContainer); + + info("Expand the shadow root"); + const shadowRootContainer = hostContainer.getChildContainers()[0]; + await expandContainer(inspector, shadowRootContainer); + + info("Select the div under the shadow root"); + const divContainer = shadowRootContainer.getChildContainers()[0]; + await selectNode(divContainer.node, inspector); + + const allMenuItems = openContextMenuAndGetAllItems(inspector); + info("Adding attribute breakpoint."); + const attributeMenuItem = allMenuItems.find( + item => item.id === "node-menu-mutation-breakpoint-attribute" + ); + attributeMenuItem.click(); + } + + info("Switches over to the debugger pane"); + await toolbox.selectTool("jsdebugger"); + + const dbg = createDebuggerContext(toolbox); + + info("Confirms that one DOM mutation breakpoint exists"); + const mutationItem = await waitForElement(dbg, "domMutationItem"); + ok(mutationItem, "A DOM mutation breakpoint exists"); + + mutationItem.scrollIntoView(); + + info("Enabling and disabling the DOM mutation breakpoint works"); + const checkbox = mutationItem.querySelector("input"); + checkbox.click(); + await waitFor(() => !checkbox.checked); + checkbox.click(); + await waitFor(() => checkbox.checked); + + info("Changing attribute to trigger debugger pause"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#attribute").click(); + }); + await waitForPaused(dbg); + let whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is( + whyPaused, + `Paused on DOM mutation\nDOM Mutation: 'attributeModified'\nbody` + ); + + await resume(dbg); + + info("Changing style to trigger debugger pause"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#style-attribute").click(); + }); + await waitForPaused(dbg); + await resume(dbg); + + info("Changing attribute in shadow dom to trigger debugger pause"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#shadow-attribute").click(); + }); + await waitForPaused(dbg); + await resume(dbg); + + info("Adding element in subtree to trigger debugger pause"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#add-in-subtree").click(); + }); + await waitForPaused(dbg); + whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is( + whyPaused, + `Paused on DOM mutation\nDOM Mutation: 'subtreeModified'\nbodyAdded:div#dynamic` + ); + + await resume(dbg); + + info("Removing element in subtree to trigger debugger pause"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#remove-in-subtree").click(); + }); + await waitForPaused(dbg); + whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is( + whyPaused, + `Paused on DOM mutation\nDOM Mutation: 'subtreeModified'\nbodyRemoved:div#dynamic` + ); + + await resume(dbg); + + info("Blackboxing the source prevents debugger pause"); + await waitForSource(dbg, "dom-mutation.original.js"); + + const source = findSource(dbg, "dom-mutation.original.js"); + + await selectSource(dbg, source); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("#blackbox").click(); + }); + + await waitForPaused(dbg, "click.js"); + await resume(dbg); + + await selectSource(dbg, source); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + + info("Removing breakpoints works"); + dbg.win.document.querySelector(".dom-mutation-list .close-btn").click(); + await waitForAllElements(dbg, "domMutationItem", 2, true); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-eager-eval-skip-pause.js b/devtools/client/debugger/test/mochitest/browser_dbg-eager-eval-skip-pause.js new file mode 100644 index 0000000000..dcd8f4605b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-eager-eval-skip-pause.js @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that eager evaluation skips breakpoints and debugger statements + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-strict.html"); + const { hud } = await getDebuggerSplitConsole(dbg); + + await addBreakpoint(dbg, "doc-strict.html", 15); + setInputValue(hud, "strict()"); + await waitForEagerEvaluationResult(hud, `3`); + + setInputValue(hud, "debugger; 2"); + await waitForEagerEvaluationResult(hud, `2`); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-exception.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-exception.js new file mode 100644 index 0000000000..9f6ff306a0 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-exception.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the editor does not crash when closing a tab (using the contextmenu) + +"use strict"; + +add_task(async function testEditorExceptionClose() { + const dbg = await initDebugger("doc-exceptions.html", "exceptions.js"); + await selectSource(dbg, "exceptions.js"); + is(countTabs(dbg), 1, "Tab for the exceptions.js source is open"); + await openActiveTabContextMenuAndSelectCloseTabItem(dbg); + is(countTabs(dbg), 0, "All tabs are closed"); +}); + +async function openActiveTabContextMenuAndSelectCloseTabItem(dbg) { + const waitForOpen = waitForContextMenu(dbg); + info(`Open the current active tab context menu`); + rightClickElement(dbg, "activeTab"); + await waitForOpen; + const wait = waitForDispatch(dbg.store, "CLOSE_TAB"); + info(`Select the close tab context menu item`); + selectContextMenuItem(dbg, `#node-menu-close-tab`); + return wait; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-gutter.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-gutter.js new file mode 100644 index 0000000000..1653d9195b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-gutter.js @@ -0,0 +1,144 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the breakpoint gutter and making sure breakpoint icons exist +// correctly + +"use strict"; + +// FIXME bug 1524374 removing breakpoints in this test can cause uncaught +// rejections and make bug 1512742 permafail. +PromiseTestUtils.allowMatchingRejectionsGlobally(/NS_ERROR_NOT_INITIALIZED/); + +add_task(async function testGutterBreakpoints() { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + const source = findSource(dbg, "simple1.js"); + + await selectSource(dbg, source); + + // Make sure that clicking the gutter creates a breakpoint icon. + await clickGutter(dbg, 4); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + await assertBreakpoint(dbg, 4); + + // Make sure clicking at the same place removes the icon. + await clickGutter(dbg, 4); + await waitForDispatch(dbg.store, "REMOVE_BREAKPOINT"); + is(dbg.selectors.getBreakpointCount(), 0, "No breakpoints exist"); + await assertNoBreakpoint(dbg, 4); +}); + +add_task(async function testGutterBreakpointsInIgnoredSource() { + info( + "Ensure clicking on gutter to add breakpoint should not un-ignore source" + ); + const dbg = await initDebugger("doc-sourcemaps3.html"); + dbg.actions.toggleMapScopes(); + await waitForSources(dbg, "bundle.js", "sorted.js", "test.js"); + + info("Ignore the source"); + await selectSource(dbg, findSource(dbg, "sorted.js")); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + // invoke test + invokeInTab("test"); + + // wait to make sure no pause has occured + await wait(1000); + assertNotPaused(dbg); + + info("Ensure gutter breakpoint gets set with click"); + await clickGutter(dbg, 4); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + + info("Assert that the `Enable breakpoint` context menu item is disabled"); + const popup = await openContextMenuInDebugger(dbg, "gutter", 4); + await assertContextMenuItemDisabled( + dbg, + "#node-menu-enable-breakpoint", + true + ); + await closeContextMenu(dbg, popup); + + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + await assertBreakpoint(dbg, 4); + is( + findBreakpoint(dbg, "sorted.js", 4).disabled, + true, + "The breakpoint in the ignored source looks disabled" + ); + + invokeInTab("test"); + + await wait(1000); + assertNotPaused(dbg); + + ok(true, "source is still blackboxed"); +}); + +add_task(async function testGutterBreakpointsForSourceWithIgnoredLines() { + info( + "Asserts that adding a breakpoint to the gutter of an un-ignored line does not un-ignore other ranges in the source" + ); + const dbg = await initDebugger("doc-sourcemaps3.html"); + await waitForSources(dbg, "bundle.js", "sorted.js", "test.js"); + + await selectSource(dbg, findSource(dbg, "sorted.js")); + + info("Ignoring line 17 to 21 using the editor context menu"); + await selectEditorLinesAndOpenContextMenu(dbg, { + startLine: 17, + endLine: 21, + }); + await selectBlackBoxContextMenuItem(dbg, "blackbox-lines"); + + info("Set breakpoint on an un-ignored line"); + await clickGutter(dbg, 4); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + + info("Assert that the `Disable breakpoint` context menu item is enabled"); + const popup = await openContextMenuInDebugger(dbg, "gutter", 4); + await assertContextMenuItemDisabled( + dbg, + "#node-menu-disable-breakpoint", + false + ); + await closeContextMenu(dbg, popup); + + info("Assert that the lines 17 to 21 are still ignored"); + assertIgnoredStyleInSourceLines(dbg, { + lines: [17, 21], + hasBlackboxedLinesClass: true, + }); + + info( + "Asserts that adding a breakpoint to the gutter of an ignored line creates a disabled breakpoint" + ); + info("Set breakpoint on an ignored line"); + await clickGutter(dbg, 19); + await waitForDispatch(dbg.store, "SET_BREAKPOINT"); + + info("Assert that the `Enable breakpoint` context menu item is disabled"); + const popup2 = await openContextMenuInDebugger(dbg, "gutter", 19); + await assertContextMenuItemDisabled( + dbg, + "#node-menu-enable-breakpoint", + true + ); + await closeContextMenu(dbg, popup2); + + info("Assert that the breakpoint on the line 19 is visually disabled"); + is( + findBreakpoint(dbg, "sorted.js", 19).disabled, + true, + "The breakpoint on an ignored line is disabled" + ); +}); + +async function assertContextMenuItemDisabled(dbg, selector, expectedState) { + const item = await waitFor(() => findContextMenu(dbg, selector)); + is(item.disabled, expectedState, "The context menu item is disabled"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-highlight.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-highlight.js new file mode 100644 index 0000000000..4fd5a6be40 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-highlight.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the editor will always highight the right line, no +// matter if the source text doesn't exist yet or even if the source +// doesn't exist. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "long.js"); + const { + selectors: { getSettledSourceTextContent }, + } = dbg; + + // The source itself doesn't even exist yet, and using + // `selectSourceURL` will set a pending request to load this source + // and highlight a specific line. + + await selectSource(dbg, "long.js", 66); + + // TODO: revisit highlighting lines when the debugger opens + // assertHighlightLocation(dbg, "long.js", 66); + + info("Select line 16 and make sure the editor scrolled."); + await selectSource(dbg, "long.js", 16); + await waitForElementWithSelector(dbg, ".CodeMirror-code > .highlight-line"); + assertHighlightLocation(dbg, "long.js", 16); + + info("Select several locations and check that we have one highlight"); + await selectSource(dbg, "long.js", 17); + await selectSource(dbg, "long.js", 18); + assertHighlightLocation(dbg, "long.js", 18); + + // Test jumping to a line in a source that exists but hasn't been + // loaded yet. + info("Select an unloaded source"); + selectSource(dbg, "simple1.js", 6); + + // Make sure the source is in the loading state, wait for it to be + // fully loaded, and check the highlighted line. + const simple1 = findSource(dbg, "simple1.js"); + const location = createLocation({ source: simple1 }); + is(getSettledSourceTextContent(location), null); + + await waitForSelectedSource(dbg, "simple1.js"); + ok(getSettledSourceTextContent(location).value.value); + assertHighlightLocation(dbg, "simple1.js", 6); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-mode.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-mode.js new file mode 100644 index 0000000000..6cec2e1dbf --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-mode.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the editor sets the correct mode for different file +// types + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + + await selectSource(dbg, "simple1.js"); + is(dbg.getCM().getOption("mode").name, "javascript", "Mode is correct"); + + await selectSource(dbg, "doc-scripts.html"); + is(dbg.getCM().getOption("mode").name, "htmlmixed", "Mode is correct"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-scroll.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-scroll.js new file mode 100644 index 0000000000..a6f6394ee8 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-scroll.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the editor keeps proper scroll position per document +// while also moving to the correct location upon pause/breakpoint selection + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // This test runs too slowly on linux debug. I'd like to figure out + // which is the slowest part of this and make it run faster, but to + // fix a frequent failure allow a longer timeout. + const dbg = await initDebugger("doc-editor-scroll.html"); + + // Set the initial breakpoint. + await selectSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 26); + + const cm = getCM(dbg); + + info("Open long file, scroll down to line below the fold"); + await selectSource(dbg, "long.js"); + cm.scrollTo(0, 600); + + info("Ensure vertical scroll is the same after switching documents"); + await selectSource(dbg, "simple1.js"); + is(cm.getScrollInfo().top, 0); + await selectSource(dbg, "long.js"); + is(cm.getScrollInfo().top, 600); + + info("Trigger a pause, click on a frame, ensure the right line is selected"); + invokeInTab("doNamedEval"); + await waitForPaused(dbg); + findElement(dbg, "frame", 1).focus(); + await clickElement(dbg, "frame", 1); + ok(cm.getScrollInfo().top != 0, "frame scrolled down to correct location"); + + info("Navigating while paused, goes to the correct location"); + await selectSource(dbg, "long.js"); + is(cm.getScrollInfo().top, 600); + + info("Open new source, ensure it's at 0 scroll"); + await selectSource(dbg, "frames.js"); + is(cm.getScrollInfo().top, 0); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-editor-select.js b/devtools/client/debugger/test/mochitest/browser_dbg-editor-select.js new file mode 100644 index 0000000000..f5002f864f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-editor-select.js @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the editor highlights the correct location when the +// debugger pauses + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // This test runs too slowly on linux debug. I'd like to figure out + // which is the slowest part of this and make it run faster, but to + // fix a frequent failure allow a longer timeout. + const dbg = await initDebugger("doc-scripts.html"); + + info("Set the initial breakpoint."); + await selectSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 4); + + info("Call the function that we set a breakpoint in."); + invokeInTab("main"); + await waitForPaused(dbg); + await waitForSelectedSource(dbg, "simple1.js"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 4); + + info("Step into another file."); + await stepOver(dbg); + await stepIn(dbg); + await waitForSelectedSource(dbg, "simple2.js"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 3); + + info("Step out to the initial file."); + await stepOut(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple1.js").id, 6); + await resume(dbg); + + info("Make sure that the editor scrolls to the paused location."); + const longSrc = findSource(dbg, "long.js"); + await selectSource(dbg, "long.js"); + await addBreakpoint(dbg, longSrc, 66); + + invokeInTab("testModel"); + await waitForPaused(dbg); + await waitForSelectedSource(dbg, "long.js"); + + assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 66); + ok( + isVisibleInEditor(dbg, findElement(dbg, "breakpoint")), + "Breakpoint is visible" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-ember-quickstart.js b/devtools/client/debugger/test/mochitest/browser_dbg-ember-quickstart.js new file mode 100644 index 0000000000..c8ef196da7 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-ember-quickstart.js @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("ember/quickstart/dist/"); + dbg.actions.toggleMapScopes(); + + await invokeWithBreakpoint( + dbg, + "mapTestFunction", + "router.js", + { line: 13, column: 2 }, + async () => { + await assertScopes(dbg, [ + "Module", + ["config", "{\u2026}"], + "EmberRouter:Class()", + "Router:Class()", + ]); + } + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js b/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js new file mode 100644 index 0000000000..93123187e1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-es-module-worker.js @@ -0,0 +1,75 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that we can debug workers using ES Modules. + +"use strict"; + +const httpServer = createTestHTTPServer(); +httpServer.registerContentType("html", "text/html"); +httpServer.registerContentType("js", "application/javascript"); + +httpServer.registerPathHandler(`/`, function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + `); +}); + +httpServer.registerPathHandler("/worker.js", function (request, response) { + response.setHeader("Content-Type", "application/javascript"); + response.write(` + onmessage = () => { + console.log("breakpoint line"); + postMessage("resume"); + } + `); +}); +const port = httpServer.identity.primaryPort; +const TEST_URL = `http://localhost:${port}/`; +const WORKER_URL = TEST_URL + "worker.js"; + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL(TEST_URL); + + // Note that the following APIs only returns the additional threads + await waitForThreadCount(dbg, 1); + const threads = dbg.selectors.getThreads(); + is(threads.length, 1, "Got the page and the worker threads"); + is(threads[0].name, WORKER_URL, "Thread name is correct"); + + const source = findSource(dbg, "worker.js"); + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 3); + + info("Call worker code to trigger the breakpoint"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + content.wrappedJSObject.worker.postMessage("foo"); + }); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 3); + assertTextContentOnLine(dbg, 3, `console.log("breakpoint line");`); + + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + // Create a Promise which will resolve once the worker resumes and send a message + // Hold the promise on window, so that a following task can use it. + content.onWorkerResumed = new Promise( + resolve => (content.wrappedJSObject.worker.onmessage = resolve) + ); + }); + + await resume(dbg); + + info("Wait for the worker to resume its execution and send a message"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async () => { + ok( + content.onWorkerResumed, + "The promise created by the previous task exists" + ); + await content.onWorkerResumed; + ok(true, "The worker resumed its execution"); + }); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-eval-throw.js b/devtools/client/debugger/test/mochitest/browser_dbg-eval-throw.js new file mode 100644 index 0000000000..803037d921 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-eval-throw.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that exceptions thrown while evaluating code will pause at the point the +// exception was generated when pausing on uncaught exceptions. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-eval-throw.html"); + await togglePauseOnExceptions(dbg, true, true); + + invokeInTab("evaluateException"); + await waitForPaused(dbg); + const source = dbg.selectors.getSelectedSource(); + ok(!source.url, "Selected source should not have a URL"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints-fission.js b/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints-fission.js new file mode 100644 index 0000000000..072b840a14 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints-fission.js @@ -0,0 +1,81 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests early event breakpoints and event breakpoints in a remote frame. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-event-breakpoints-fission.html", + "event-breakpoints.js" + ); + + await selectSource(dbg, "event-breakpoints.js"); + await waitForSelectedSource(dbg, "event-breakpoints.js"); + + await dbg.actions.addEventListenerBreakpoints([ + "event.mouse.click", + "event.xhr.load", + "timer.timeout.set", + ]); + + info("Assert early timeout event breakpoint gets hit"); + const waitForReload = reloadBrowser(); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-event-breakpoints-fission.html").id, + 17 + ); + await resume(dbg); + + await waitForReload; + + info("Assert event breakpoints work in remote frame"); + await invokeAndAssertBreakpoints(dbg); + + info("reload the iframe"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => + content.wrappedJSObject.reloadIframe() + ); + info("Assert event breakpoints work in remote frame after reload"); + await invokeAndAssertBreakpoints(dbg); +}); + +async function invokeAndAssertBreakpoints(dbg) { + invokeInTabRemoteFrame("clickHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "event-breakpoints.js").id, + 12 + ); + await resume(dbg); + + invokeInTabRemoteFrame("xhrHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "event-breakpoints.js").id, + 20 + ); + await resume(dbg); +} + +async function invokeInTabRemoteFrame(fnc, ...args) { + info(`Invoking in tab remote frame: ${fnc}(${args.map(uneval).join(",")})`); + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [fnc, args], + function (_fnc, _args) { + return SpecialPowers.spawn( + content.document.querySelector("iframe"), + [_fnc, _args], + (__fnc, __args) => content.wrappedJSObject[__fnc](...__args) + ); + } + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints.js new file mode 100644 index 0000000000..416a9bb43f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-event-breakpoints.js @@ -0,0 +1,294 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + await pushPref("apz.scrollend-event.content.enabled", true); + + const dbg = await initDebugger( + "doc-event-breakpoints.html", + "event-breakpoints.js" + ); + await selectSource(dbg, "event-breakpoints.js"); + await waitForSelectedSource(dbg, "event-breakpoints.js"); + const eventBreakpointsSource = findSource(dbg, "event-breakpoints.js"); + + // We want to set each breakpoint individually to test adding/removing breakpoints, see Bug 1748589. + await toggleEventBreakpoint(dbg, "Mouse", "event.mouse.click"); + + invokeInTab("clickHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12); + + const whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is( + whyPaused, + `Paused on event breakpoint\nDOM 'click' event`, + "whyPaused does state that the debugger is paused as a result of a click event breakpoint" + ); + await resume(dbg); + + await toggleEventBreakpoint(dbg, "XHR", "event.xhr.load"); + invokeInTab("xhrHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 20); + await resume(dbg); + + await toggleEventBreakpoint(dbg, "Timer", "timer.timeout.set"); + await toggleEventBreakpoint(dbg, "Timer", "timer.timeout.fire"); + invokeInTab("timerHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 27); + await resume(dbg); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 28); + await resume(dbg); + + await toggleEventBreakpoint(dbg, "Script", "script.source.firstStatement"); + invokeInTab("evalHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "eval-test.js").id, 2); + await resume(dbg); + + await toggleEventBreakpoint(dbg, "Control", "event.control.focusin"); + await toggleEventBreakpoint(dbg, "Control", "event.control.focusout"); + invokeOnElement("#focus-text", "focus"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 43); + await resume(dbg); + + // wait for focus-out event to fire + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 48); + await resume(dbg); + + info("Deselect focus events"); + // We need to give the input focus to test composition, but we don't want the + // focus breakpoints to fire. + await toggleEventBreakpoint(dbg, "Control", "event.control.focusin"); + await toggleEventBreakpoint(dbg, "Control", "event.control.focusout"); + + // TODO: Enable this block when you fix bug 1466596 or bug 1690827 + /* + await toggleEventBreakpoint( + dbg, + "Keyboard", + "event.keyboard.compositionstart" + ); + invokeOnElement("#focus-text", "focus"); + + info("Type some characters during composition"); + invokeComposition(); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 53); + await resume(dbg); + + info("Deselect compositionstart and select compositionupdate"); + await toggleEventBreakpoint( + dbg, + "Keyboard", + "event.keyboard.compositionstart" + ); + await toggleEventBreakpoint( + dbg, + "Keyboard", + "event.keyboard.compositionupdate" + ); + + invokeOnElement("#focus-text", "focus"); + + info("Type some characters during composition"); + invokeComposition(); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 58); + await resume(dbg); + + info("Deselect compositionupdate and select compositionend"); + await toggleEventBreakpoint( + dbg, + "Keyboard", + "event.keyboard.compositionupdate" + ); + await toggleEventBreakpoint(dbg, "Keyboard", "event.keyboard.compositionend"); + invokeOnElement("#focus-text", "focus"); + + info("Type some characters during composition"); + invokeComposition(); + + info("Commit the composition"); + EventUtils.synthesizeComposition({ + type: "compositioncommitasis", + key: { key: "KEY_Enter" }, + }); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 63); + await resume(dbg); + */ + + info(`Check that breakpoint can be set on "scrollend"`); + await toggleEventBreakpoint(dbg, "Control", "event.control.scrollend"); + + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + content.scrollTo({ top: 20, behavior: "smooth" }); + }); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 68); + await resume(dbg); + + info("Check that the click event breakpoint is still enabled"); + invokeInTab("clickHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12); + await resume(dbg); + + info("Check that disabling an event breakpoint works"); + await toggleEventBreakpoint(dbg, "Mouse", "event.mouse.click"); + invokeInTab("clickHandler"); + // wait for a bit to make sure the debugger do not pause + await wait(100); + assertNotPaused(dbg); + + info("Check that we can re-enable event breakpoints"); + await toggleEventBreakpoint(dbg, "Mouse", "event.mouse.click"); + invokeInTab("clickHandler"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, eventBreakpointsSource.id, 12); + await resume(dbg); + + info( + "Test that we don't pause on event breakpoints when source is blackboxed." + ); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + invokeInTab("clickHandler"); + // wait for a bit to make sure the debugger do not pause + await wait(100); + assertNotPaused(dbg); + + invokeInTab("xhrHandler"); + // wait for a bit to make sure the debugger do not pause + await wait(100); + assertNotPaused(dbg); + + invokeInTab("timerHandler"); + // wait for a bit to make sure the debugger do not pause + await wait(100); + assertNotPaused(dbg); + + // Cleanup - unblackbox the source + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); +}); + +add_task(async function checkUnavailableEvents() { + await pushPref("apz.scrollend-event.content.enabled", false); + + const dbg = await initDebugger( + "doc-event-breakpoints.html", + "event-breakpoints.js" + ); + await selectSource(dbg, "event-breakpoints.js"); + await waitForSelectedSource(dbg, "event-breakpoints.js"); + + is( + await getEventBreakpointCheckbox(dbg, "Control", "event.control.scrollend"), + null, + `"scrollend" item is not displayed when "apz.scrollend-event.content.enabled" is false` + ); +}); + +function getEventListenersPanel(dbg) { + return findElementWithSelector(dbg, ".event-listeners-pane .event-listeners"); +} + +async function toggleEventBreakpoint( + dbg, + eventBreakpointGroup, + eventBreakpointName +) { + const eventCheckbox = await getEventBreakpointCheckbox( + dbg, + eventBreakpointGroup, + eventBreakpointName + ); + eventCheckbox.scrollIntoView(); + info(`Toggle ${eventBreakpointName} breakpoint`); + const onEventListenersUpdate = waitForDispatch( + dbg.store, + "UPDATE_EVENT_LISTENERS" + ); + eventCheckbox.click(); + await onEventListenersUpdate; +} + +async function getEventBreakpointCheckbox( + dbg, + eventBreakpointGroup, + eventBreakpointName +) { + if (!getEventListenersPanel(dbg)) { + // Event listeners panel is collapse, expand it + findElementWithSelector( + dbg, + `.event-listeners-pane ._header .arrow` + ).click(); + await waitFor(() => getEventListenersPanel(dbg)); + } + + const groupCheckbox = findElementWithSelector( + dbg, + `input[value="${eventBreakpointGroup}"]` + ); + const groupEl = groupCheckbox.closest(".event-listener-group"); + let groupEventsUl = groupEl.querySelector("ul"); + if (!groupEventsUl) { + info( + `Expand ${eventBreakpointGroup} and wait for the sub list to be displayed` + ); + groupEl.querySelector(".event-listener-expand").click(); + groupEventsUl = await waitFor(() => groupEl.querySelector("ul")); + } + + return findElementWithSelector(dbg, `input[value="${eventBreakpointName}"]`); +} + +async function invokeOnElement(selector, action) { + await SpecialPowers.focus(gBrowser.selectedBrowser); + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [selector, action], + (_selector, _action) => { + content.document.querySelector(_selector)[_action](); + } + ); +} + +// TODO: Enable this function when you fix bug 1466596 or bug 1690827 +/* +function invokeComposition() { + const string = "ex"; + EventUtils.synthesizeCompositionChange({ + composition: { + string, + clauses: [ + { + length: string.length, + attr: Ci.nsITextInputProcessor.ATTR_RAW_CLAUSE, + }, + ], + }, + caret: { start: string.length, length: 0 }, + key: { key: string[string.length - 1] }, + }); +} +*/ diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-event-handler.js b/devtools/client/debugger/test/mochitest/browser_dbg-event-handler.js new file mode 100644 index 0000000000..10acc9f118 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-event-handler.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that pausing within an event handler on an element does *not* show the +// HTML page containing that element. It should show a sources tab containing +// just the handler's text instead. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-event-handler.html"); + + invokeInTab("synthesizeClick"); + await waitForPaused(dbg); + const source = dbg.selectors.getSelectedSource(); + ok(!source.url, "Selected source should not have a URL"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-expressions-error.js b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-error.js new file mode 100644 index 0000000000..af54bc1a92 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-error.js @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * test pausing on an errored watch expression + * assert that you can: + * 1. resume + * 2. still evalutate expressions + * 3. expand properties + */ + +"use strict"; + +const EXPRESSION_SELECTORS = { + plusIcon: ".watch-expressions-pane button.plus", + input: "input.input-expression", +}; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + await togglePauseOnExceptions(dbg, true, true); + + // add a good expression, 2 bad expressions, and another good one + info(`Adding location`); + await addExpression(dbg, "location"); + await addExpression(dbg, "foo.bar"); + await addExpression(dbg, "foo.batt"); + await addExpression(dbg, "2"); + // check the value of + is(getWatchExpressionValue(dbg, 2), "(unavailable)"); + is(getWatchExpressionValue(dbg, 3), "(unavailable)"); + is(getWatchExpressionValue(dbg, 4), "2"); + + await toggleExpressionNode(dbg, 1); + is(findAllElements(dbg, "expressionNodes").length, 37); +}); + +async function addExpression(dbg, input) { + const plusIcon = findElementWithSelector(dbg, EXPRESSION_SELECTORS.plusIcon); + if (plusIcon) { + plusIcon.click(); + } + + const evaluation = waitForDispatch(dbg.store, "EVALUATE_EXPRESSION"); + findElementWithSelector(dbg, EXPRESSION_SELECTORS.input).focus(); + type(dbg, input); + pressKey(dbg, "Enter"); + await evaluation; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-expressions-focus.js b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-focus.js new file mode 100644 index 0000000000..07054fd80f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-focus.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Ensures the input is displayed and focused when "+" is clicked + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + info(">> Close the panel"); + clickElementWithSelector(dbg, ".watch-expressions-pane ._header"); + + info(">> Click + to add the new expression"); + await waitForElementWithSelector( + dbg, + ".watch-expressions-pane ._header .plus" + ); + clickElementWithSelector(dbg, ".watch-expressions-pane ._header .plus"); + + info(">> Ensure element gets focused"); + await waitForElementWithSelector(dbg, ".expression-input-container.focused"); + + info(">> Ensure the element is focused"); + is( + dbg.win.document.activeElement.classList.contains("input-expression"), + true + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-expressions-thread.js b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-thread.js new file mode 100644 index 0000000000..2d4dc94c9a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-thread.js @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test the watch expressions update when selecting a different thread in the thread panel. + */ + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`; +const TEST_ORG_IFRAME_URI = `${URL_ROOT_ORG_SSL}examples/doc_dbg-fission-frame-sources-frame.html`; +const DATA_URI = "data:text/html,foo"; + +add_task(async function () { + // Load a test page with a remote frame and wait for both sources to be visible. + // simple1.js is imported by the main page. simple2.js comes from the frame. + const dbg = await initDebuggerWithAbsoluteURL( + TEST_COM_URI, + "simple1.js", + "simple2.js" + ); + + const threadsPaneEl = await waitForElementWithSelector( + dbg, + ".threads-pane .header-label" + ); + + await waitForElement(dbg, "threadsPaneItems"); + const threadsEl = findAllElements(dbg, "threadsPaneItems"); + is(threadsEl.length, 2, "There are two threads in the thread panel"); + const [mainThreadEl, remoteThreadEl] = threadsEl; + is( + mainThreadEl.textContent, + "Main Thread", + "first thread displayed is the main thread" + ); + is( + remoteThreadEl.textContent, + "Test remote frame sources", + "second thread displayed is the remote thread" + ); + + await addExpression(dbg, "document.location.href"); + + is( + getWatchExpressionValue(dbg, 1), + JSON.stringify(TEST_COM_URI), + "expression is evaluated on the expected thread" + ); + + info( + "Select the remote frame thread and check that the expression is updated" + ); + let onExpressionsEvaluated = waitForDispatch( + dbg.store, + "EVALUATE_EXPRESSIONS" + ); + remoteThreadEl.click(); + await onExpressionsEvaluated; + + is( + getWatchExpressionValue(dbg, 1), + JSON.stringify(TEST_ORG_IFRAME_URI), + "expression is evaluated on the remote origin thread" + ); + + info("Select the main thread again and check that the expression is updated"); + onExpressionsEvaluated = waitForDispatch(dbg.store, "EVALUATE_EXPRESSIONS"); + mainThreadEl.click(); + await onExpressionsEvaluated; + + is( + getWatchExpressionValue(dbg, 1), + JSON.stringify(TEST_COM_URI), + "expression is evaluated on the main thread again" + ); + + // close the threads pane so following test don't have it open + threadsPaneEl.click(); + + await navigateToAbsoluteURL(dbg, DATA_URI); + + is( + getWatchExpressionValue(dbg, 1), + JSON.stringify(DATA_URI), + "The location.host expression is updated after a navigaiton" + ); + + await addExpression(dbg, "document.title"); + + is( + getWatchExpressionValue(dbg, 2), + `"foo"`, + "We can add expressions after a navigation" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-expressions-watch.js b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-watch.js new file mode 100644 index 0000000000..5f2c6aba40 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-expressions-watch.js @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test the watch expressions "refresh" button: + * - hidden when no expression is available + * - visible with one or more expressions + * - updates expressions values after clicking on it + * - disappears when all expressions are removed + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + invokeInTab("firstCall"); + await waitForPaused(dbg); + + ok( + !getRefreshExpressionsElement(dbg), + "No refresh button is displayed when there are no watch expressions" + ); + + await addExpression(dbg, "someVariable"); + + ok( + getRefreshExpressionsElement(dbg), + "Refresh button is displayed after adding a watch expression" + ); + + is( + getWatchExpressionLabel(dbg, 1), + "someVariable", + "Watch expression was added" + ); + is( + getWatchExpressionValue(dbg, 1), + "(unavailable)", + "Watch expression has no value" + ); + + info("Switch to the console and update the value of the watched variable"); + const { hud } = await dbg.toolbox.selectTool("webconsole"); + await evaluateExpressionInConsole(hud, "var someVariable = 1"); + + info("Switch back to the debugger"); + await dbg.toolbox.selectTool("jsdebugger"); + + is( + getWatchExpressionLabel(dbg, 1), + "someVariable", + "Watch expression is still available" + ); + is( + getWatchExpressionValue(dbg, 1), + "(unavailable)", + "Watch expression still has no value" + ); + + info( + "Click on the watch expression refresh button and wait for the " + + "expression to update." + ); + const refreshed = waitForDispatch(dbg.store, "EVALUATE_EXPRESSIONS"); + await clickElement(dbg, "expressionRefresh"); + await refreshed; + + is( + getWatchExpressionLabel(dbg, 1), + "someVariable", + "Watch expression is still available" + ); + is( + getWatchExpressionValue(dbg, 1), + "1", + "Watch expression value has been updated" + ); + + await deleteExpression(dbg, "someVariable"); + + ok( + !getRefreshExpressionsElement(dbg), + "The refresh button is no longer displayed after removing watch expressions" + ); +}); + +function getRefreshExpressionsElement(dbg) { + return findElement(dbg, "expressionRefresh", 1); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-expressions.js b/devtools/client/debugger/test/mochitest/browser_dbg-expressions.js new file mode 100644 index 0000000000..44dcd81f43 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-expressions.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * tests the watch expressions component + * 1. add watch expressions + * 2. edit watch expressions + * 3. delete watch expressions + * 4. expanding properties when not paused + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + invokeInTab("firstCall"); + await waitForPaused(dbg); + + await addExpression(dbg, "f"); + is(getWatchExpressionLabel(dbg, 1), "f"); + is(getWatchExpressionValue(dbg, 1), "(unavailable)"); + + await editExpression(dbg, "oo"); + is(getWatchExpressionLabel(dbg, 1), "foo()"); + + // There is no "value" element for functions. + assertEmptyValue(dbg, 1); + + await addExpression(dbg, "location"); + is(getWatchExpressionLabel(dbg, 2), "location"); + ok(getWatchExpressionValue(dbg, 2).includes("Location"), "has a value"); + + // can expand an expression + await toggleExpressionNode(dbg, 2); + + is(findAllElements(dbg, "expressionNodes").length, 35); + is(dbg.selectors.getExpressions(dbg.store.getState()).length, 2); + + await deleteExpression(dbg, "foo"); + await deleteExpression(dbg, "location"); + is(findAllElements(dbg, "expressionNodes").length, 0); + is(dbg.selectors.getExpressions(dbg.store.getState()).length, 0); + + // Test expanding properties when the debuggee is active + // Wait for full evaluation of the expressions in order to avoid having + // mixed up code between the location being removed and the one being re-added + const evaluated = waitForDispatch(dbg.store, "EVALUATE_EXPRESSIONS"); + await resume(dbg); + await evaluated; + + await addExpression(dbg, "location"); + is(dbg.selectors.getExpressions(dbg.store.getState()).length, 1); + + is(findAllElements(dbg, "expressionNodes").length, 1); + + await toggleExpressionNode(dbg, 1); + is(findAllElements(dbg, "expressionNodes").length, 34); + + await deleteExpression(dbg, "location"); + is(findAllElements(dbg, "expressionNodes").length, 0); +}); + +function assertEmptyValue(dbg, index) { + const value = findElement(dbg, "expressionValue", index); + if (value) { + is(value.innerText, ""); + return; + } + + is(value, null); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-extension-inspectedWindow-debugger-statement.js b/devtools/client/debugger/test/mochitest/browser_dbg-extension-inspectedWindow-debugger-statement.js new file mode 100644 index 0000000000..790b0366b9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-extension-inspectedWindow-debugger-statement.js @@ -0,0 +1,88 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that web extensions' inspectedWindow.eval() doesn't break debugger/console + +"use strict"; + +// Test debugger statement in page, with devtools opened to debugger panel +add_task(async function () { + const extension = await installAndStartExtension(); + + const dbg = await initDebugger("doc-scripts.html"); + + await extension.awaitMessage("loaded"); + + info("Evaluating debugger statement in page"); + const evalFinished = invokeInTab("nestedC"); + await waitForPaused(dbg); + + info("resuming once"); + await resume(dbg); + + // bug 1728290: WebExtension target used to trigger the thread actor and also pause a second time on the debugger statement. + // This would prevent the evaluation from completing. + info("waiting for invoked function to complete"); + await evalFinished; + + await closeTabAndToolbox(); + await extension.unload(); +}); + +// Test debugger statement in webconsole +add_task(async function () { + const extension = await installAndStartExtension(); + + // Test again with debugger panel closed + const toolbox = await openNewTabAndToolbox( + EXAMPLE_URL + "doc-scripts.html", + "webconsole" + ); + await extension.awaitMessage("loaded"); + + info("Evaluating debugger statement in console"); + const onSelected = toolbox.once("jsdebugger-selected"); + const evalFinished = invokeInTab("nestedC"); + + await onSelected; + const dbg = createDebuggerContext(toolbox); + await waitForPaused(dbg); + + info("resuming once"); + await resume(dbg); + + await evalFinished; + + await closeTabAndToolbox(); + await extension.unload(); +}); + +async function installAndStartExtension() { + async function devtools_page() { + await globalThis.browser.devtools.inspectedWindow.eval(""); + globalThis.browser.test.sendMessage("loaded"); + } + + const extension = ExtensionTestUtils.loadExtension({ + manifest: { + devtools_page: "devtools_page.html", + }, + files: { + "devtools_page.html": ` + + + + + + + + `, + "devtools_page.js": devtools_page, + }, + }); + + await extension.startup(); + + return extension; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-asm.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-asm.js new file mode 100644 index 0000000000..15c7737072 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-asm.js @@ -0,0 +1,92 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test covers all specifics of debugging ASM.js files. + * + * ASM.js is a subset of the Javascript syntax. + * Thanks to these limitations, the JS engine is able to compile this code + * into machine instructions and execute it faster. + * + * When the DevTools are opened, ThreadConfiguration's `observeAsmJS` is set to true, + * which sets DebuggerAPI's `allowUnobservedAsmJS` to false, + * which disables the compilation of ASM.js files and make them run as regular JS code. + * Thus, allowing to debug them as regular JS code. + * + * This behavior introduces some limitations when opening the debugger against + * and already loaded page. The ASM.js file won't be debuggable. + */ + +"use strict"; + +add_task(async function () { + // Load the test page before opening the debugger + // and also force a GC before opening the debugger + // so that ASM.js is fully garbaged collected. + // Otherwise on debug builds, the thread actor is able to intermittently + // retrieve the ASM.js sources and retrieve the breakable lines. + const tab = await addTab(EXAMPLE_URL + "doc-asm.html"); + await SpecialPowers.spawn(tab.linkedBrowser, [], function () { + Cu.forceGC(); + }); + const toolbox = await openToolboxForTab(tab, "jsdebugger"); + const dbg = createDebuggerContext(toolbox); + + // There is the legit and the spurious wasm source (see following comment) + await waitForSourcesInSourceTree(dbg, ["doc-asm.html", "asm.js", "asm.js"]); + is(dbg.selectors.getSourceCount(), 3, "There are only three sources"); + + const legitSource = findSource(dbg, EXAMPLE_URL + "asm.js"); + ok( + legitSource.url.startsWith("https://"), + "We got the legit source that works, not the spurious WASM one" + ); + is(legitSource.isWasm, false, "ASM.js sources are *not* flagged as WASM"); + + // XXX Bug 1759573 - There is a spurious wasm source reported which is broken + // and ideally shouldn't exists at all in UI. + // The Thread Actor is notified by the Debugger API about a WASM + // source when calling Debugger.findSources in ThreadActor.addAllSources. + const wasmUrl = "wasm:" + legitSource.url; + ok( + sourceExists(dbg, wasmUrl), + `There is a spurious wasm:// source displayed: ${wasmUrl}` + ); + + await selectSource(dbg, legitSource); + + assertTextContentOnLine(dbg, 7, "return 1 | 0;"); + + info( + "Before reloading, ThreadConfiguration's 'observedAsmJS' was false while the page was loading" + ); + info( + "So that we miss info about the ASM sources and lines are not breakables" + ); + assertLineIsBreakable(dbg, legitSource.url, 7, false); + + info("Reload and assert that ASM.js file are then debuggable"); + await reload(dbg, "doc-asm.html", "asm.js"); + + info("After reloading, ASM lines are breakable"); + // Ensure selecting the source before asserting breakable lines + // otherwise the gutter may not be yet updated + await selectSource(dbg, "asm.js"); + assertLineIsBreakable(dbg, legitSource.url, 7, true); + + await waitForSourcesInSourceTree(dbg, ["doc-asm.html", "asm.js"]); + is(dbg.selectors.getSourceCount(), 2, "There is only the two sources"); + + assertTextContentOnLine(dbg, 7, "return 1 | 0;"); + + await addBreakpoint(dbg, "asm.js", 7); + invokeInTab("runAsm"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "asm.js").id, 7); + await assertBreakpoint(dbg, 7); + + await removeBreakpoint(dbg, findSource(dbg, "asm.js").id, 7); + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-lines.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-lines.js new file mode 100644 index 0000000000..872530025f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-lines.js @@ -0,0 +1,92 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const testServer = createVersionizedHttpTestServer( + "examples/sourcemaps-reload-uncompressed" +); +const TEST_URL = testServer.urlFor("index.html"); + +// Assert the behavior of the gutter that grays out non-breakable lines +add_task(async function testBreakableLinesOverReloads() { + const dbg = await initDebuggerWithAbsoluteURL( + TEST_URL, + "index.html", + "script.js", + "original.js" + ); + + info("Assert breakable lines of the first html page load"); + await assertBreakableLines(dbg, "index.html", 78, [ + ...getRange(16, 17), + 21, + ...getRange(24, 25), + 30, + 36, + ]); + + info("Assert breakable lines of the first original source file, original.js"); + // The length of original.js is longer than the test file + // because the sourcemap replaces the content of the original file + // and appends a few lines with a "WEBPACK FOOTER" comment + // All the appended lines are empty lines or comments, so none of them are breakable. + await assertBreakableLines(dbg, "original.js", 15, [ + ...getRange(1, 3), + 5, + ...getRange(8, 10), + ]); + + info("Assert breakable lines of the simple first load of script.js"); + await assertBreakableLines(dbg, "script.js", 9, [1, 5, 7, 8, 9]); + + info("Assert breakable lines of the first iframe page load"); + await assertBreakableLines(dbg, "iframe.html", 30, [ + ...getRange(16, 17), + ...getRange(22, 23), + ]); + + info( + "Reload the page, wait for sources and assert that breakable lines get updated" + ); + testServer.switchToNextVersion(); + await reload(dbg, "index.html", "script.js", "original.js", "iframe.html"); + + // Wait for previously selected source to be re-selected after reload + // otherwise it may overlap with the next source selected by assertBreakableLines. + await waitForSelectedSource(dbg, "iframe.html"); + + info("Assert breakable lines of the more complex second load of script.js"); + await assertBreakableLines(dbg, "script.js", 23, [2, ...getRange(13, 23)]); + + info("Assert breakable lines of the second html page load"); + await assertBreakableLines(dbg, "index.html", 33, [25, 27]); + + info("Assert breakable lines of the second orignal file"); + // See first assertion about original.js, + // the size of original.js doesn't match the size of the test file + await assertBreakableLines(dbg, "original.js", 18, [ + ...getRange(1, 3), + ...getRange(8, 11), + 13, + ]); + + await selectSource(dbg, "iframe.html"); + // When EFT is disabled, iframe.html is a regular source and the right content is displayed + if (isEveryFrameTargetEnabled()) { + is( + getCM(dbg).getValue(), + `Error: Incorrect contents fetched, please reload.` + ); + } + /** + * Bug 1762381 - Can't assert breakable lines yet, because the iframe page content fails loading + + info("Assert breakable lines of the second iframe page load"); + await assertBreakableLines(dbg, "iframe.html", 27, [ + ...getRange(15, 17), + ...getRange(21, 23), + ]); + */ +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-positions.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-positions.js new file mode 100644 index 0000000000..b1e13f6cd7 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakable-positions.js @@ -0,0 +1,284 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const testServer = createVersionizedHttpTestServer( + "examples/sourcemaps-reload-uncompressed" +); +const TEST_URL = testServer.urlFor("index.html"); + +// getTokenFromPosition pauses 0.5s for each line, +// so this test is quite slow to complete +requestLongerTimeout(4); + +/** + * Cover the breakpoints positions/columns: + * - assert that the UI displayed markers in CodeMirror next to each breakable columns, + * - assert the data in the reducers about the breakable columns. + * + * Note that it doesn't assert that the breakpoint can be hit. + * It only verify data integrity and the UI. + */ +add_task(async function testBreakableLinesOverReloads() { + const dbg = await initDebuggerWithAbsoluteURL( + TEST_URL, + "index.html", + "script.js", + "original.js" + ); + + info("Assert breakable lines of the first html page load"); + await assertBreakablePositions(dbg, "index.html", 78, [ + { line: 16, columns: [6, 14] }, + { line: 17, columns: [] }, + { line: 21, columns: [12, 20, 48] }, + { line: 24, columns: [12, 20] }, + { line: 25, columns: [] }, + { line: 30, columns: [] }, + { line: 36, columns: [] }, + ]); + + info("Pretty print first html page load and assert breakable lines"); + await prettyPrint(dbg); + await assertBreakablePositions(dbg, "index.html:formatted", 87, [ + { line: 16, columns: [0, 8] }, + { line: 22, columns: [0, 8, 35] }, + { line: 27, columns: [0, 8] }, + { line: 28, columns: [] }, + { line: 36, columns: [] }, + ]); + await closeTab(dbg, "index.html:formatted"); + + info("Assert breakable lines of the first original source file, original.js"); + // The length of original.js is longer than the test file + // because the sourcemap replaces the content of the original file + // and appends a few lines with a "WEBPACK FOOTER" comment + // All the appended lines are empty lines or comments, so none of them are breakable. + await assertBreakablePositions(dbg, "original.js", 15, [ + { line: 1, columns: [] }, + { line: 2, columns: [2, 9, 32] }, + { line: 3, columns: [] }, + { line: 5, columns: [] }, + { line: 8, columns: [2, 8] }, + { line: 9, columns: [2, 10] }, + { line: 10, columns: [] }, + ]); + + info("Assert breakable lines of the simple first load of script.js"); + await assertBreakablePositions(dbg, "script.js", 9, [ + { line: 1, columns: [0, 8] }, + { line: 5, columns: [2, 10] }, + { line: 7, columns: [2, 9] }, + { line: 8, columns: [] }, + { line: 9, columns: [] }, + ]); + + info("Pretty print first load of script.js and assert breakable lines"); + await prettyPrint(dbg); + await assertBreakablePositions(dbg, "script.js:formatted", 8, [ + { line: 1, columns: [0, 8] }, + { line: 4, columns: [2, 10] }, + { line: 6, columns: [2, 9] }, + { line: 7, columns: [] }, + ]); + await closeTab(dbg, "script.js:formatted"); + + info( + "Reload the page, wait for sources and assert that breakable lines get updated" + ); + testServer.switchToNextVersion(); + await reload(dbg, "index.html", "script.js", "original.js"); + + info("Assert breakable lines of the more complex second load of script.js"); + await assertBreakablePositions(dbg, "script.js", 23, [ + { line: 2, columns: [0, 8] }, + { line: 13, columns: [4, 12] }, + { line: 14, columns: [] }, + { line: 15, columns: [] }, + { line: 16, columns: [] }, + { line: 17, columns: [] }, + { line: 18, columns: [2, 10] }, + { line: 19, columns: [] }, + { line: 20, columns: [] }, + { line: 21, columns: [] }, + { line: 22, columns: [] }, + { line: 23, columns: [] }, + ]); + + info("Pretty print first load of script.js and assert breakable lines"); + await prettyPrint(dbg); + await assertBreakablePositions(dbg, "script.js:formatted", 23, [ + { line: 2, columns: [0, 8] }, + { line: 13, columns: [4, 12] }, + { line: 14, columns: [] }, + { line: 15, columns: [] }, + { line: 16, columns: [] }, + { line: 17, columns: [] }, + { line: 18, columns: [2, 10] }, + { line: 19, columns: [] }, + { line: 20, columns: [] }, + { line: 21, columns: [] }, + { line: 22, columns: [] }, + ]); + await closeTab(dbg, "script.js:formatted"); + + info("Assert breakable lines of the second html page load"); + await assertBreakablePositions(dbg, "index.html", 33, [ + { line: 25, columns: [6, 14] }, + { line: 27, columns: [] }, + ]); + + info("Pretty print second html page load and assert breakable lines"); + await prettyPrint(dbg); + await assertBreakablePositions(dbg, "index.html:formatted", 33, [ + { line: 25, columns: [0, 8] }, + ]); + await closeTab(dbg, "index.html:formatted"); + + info("Assert breakable lines of the second orignal file"); + // See first assertion about original.js, + // the size of original.js doesn't match the size of the test file + await assertBreakablePositions(dbg, "original.js", 18, [ + { line: 1, columns: [] }, + { line: 2, columns: [2, 9, 32] }, + { line: 3, columns: [] }, + { line: 8, columns: [] }, + { line: 9, columns: [2, 8] }, + { line: 10, columns: [2, 10] }, + { line: 11, columns: [] }, + { line: 13, columns: [] }, + ]); +}); + +async function assertBreakablePositions( + dbg, + file, + numberOfLines, + breakablePositions +) { + await selectSource(dbg, file); + is( + getCM(dbg).lineCount(), + numberOfLines, + `We show the expected number of lines in CodeMirror for ${file}` + ); + for (let line = 1; line <= numberOfLines; line++) { + info(`Asserting line #${line}`); + const positions = breakablePositions.find( + position => position.line == line + ); + // If we don't have any position, only assert that the line isn't breakable + if (!positions) { + assertLineIsBreakable(dbg, file, line, false); + continue; + } + const { columns } = positions; + // Otherwise, set a breakpoint on the line to ensure we force fetching the breakable columns per line + // (this is only fetch on-demand) + await addBreakpointViaGutter(dbg, line); + await assertBreakpoint(dbg, line); + const source = findSource(dbg, file); + + // If there is no column breakpoint, skip all further assertions + // Last lines of inline script are reported as breakable lines and selectors reports + // one breakable column, but, we don't report any available column breakpoint for them. + if (!columns.length) { + // So, only ensure that the really is no marker on this line + const lineElement = await getTokenFromPosition(dbg, { line, ch: -1 }); + const columnMarkers = lineElement.querySelectorAll(".column-breakpoint"); + is( + columnMarkers.length, + 0, + `There is no breakable columns on line ${line}` + ); + await removeBreakpoint(dbg, source.id, line); + continue; + } + + const selectorPositions = dbg.selectors.getBreakpointPositionsForSource( + source.id + ); + ok(selectorPositions, "Selector returned positions"); + const selectorPositionsForLine = selectorPositions[line]; + ok(selectorPositionsForLine, "Selector returned positions for the line"); + is( + selectorPositionsForLine.length, + columns.length, + "Selector has the expected number of breakable columns" + ); + for (const selPos of selectorPositionsForLine) { + is( + selPos.location.line, + line, + "Selector breakable column has the right line" + ); + ok( + columns.includes(selPos.location.column), + `Selector breakable column has an expected column (${ + selPos.location.column + } in ${JSON.stringify(columns)}) for line ${line}` + ); + is( + selPos.location.sourceId, + source.id, + "Selector breakable column has the right sourceId" + ); + is( + selPos.location.sourceUrl, + source.url, + "Selector breakable column has the right sourceUrl" + ); + } + + const tokenElement = await getTokenFromPosition(dbg, { line, ch: -1 }); + const lineElement = tokenElement.closest(".CodeMirror-line"); + // Those are the breakpoint chevron we click on to set a breakpoint on a given column + const columnMarkers = [ + ...lineElement.querySelectorAll(".column-breakpoint"), + ]; + is( + columnMarkers.length, + columns.length, + "Got the expeced number of column markers" + ); + + // The first breakable column received the line breakpoint when calling addBreakpoint() + const firstColumn = columns.shift(); + ok( + findColumnBreakpoint(dbg, file, line, firstColumn), + `The first column ${firstColumn} has a breakpoint automatically` + ); + columnMarkers.shift(); + + for (const column of columns) { + ok( + !findColumnBreakpoint(dbg, file, line, column), + `Before clicking on the marker, the column ${column} was not having a breakpoint` + ); + const marker = columnMarkers.shift(); + const onSetBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + marker.click(); + await onSetBreakpoint; + ok( + findColumnBreakpoint(dbg, file, line, column), + `Was able to set column breakpoint for ${file} @ ${line}:${column}` + ); + + const onRemoveBreakpoint = waitForDispatch( + dbg.store, + "REMOVE_BREAKPOINT" + ); + marker.click(); + await onRemoveBreakpoint; + + ok( + !findColumnBreakpoint(dbg, file, line, column), + `Removed the just-added column breakpoint` + ); + } + + await removeBreakpoint(dbg, source.id, line); + } +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakpoints.js new file mode 100644 index 0000000000..6cd3354cff --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-breakpoints.js @@ -0,0 +1,72 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +/** + * Assert that breakpoints and stepping works in various conditions + */ + +const testServer = createVersionizedHttpTestServer( + "examples/sourcemaps-reload-uncompressed" +); +const TEST_URL = testServer.urlFor("index.html"); + +add_task( + async function testSteppingFromOriginalToGeneratedAndAnotherOriginal() { + const dbg = await initDebuggerWithAbsoluteURL( + TEST_URL, + "index.html", + "script.js", + "original.js" + ); + + await selectSource(dbg, "original.js"); + await addBreakpoint(dbg, "original.js", 8); + assertBreakpointSnippet(dbg, 1, "await nonSourceMappedFunction();"); + + info("Test pausing on an original source"); + invokeInTab("foo"); + await waitForPaused(dbg, "original.js"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 8); + + info("Then stepping into a generated source"); + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 5); + + info("Stepping another time within the same generated source"); + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 7); + + info("And finally stepping into another original source"); + await stepIn(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "removed-original.js").id, + 4 + ); + + info("Walk up the stack backward, until we resume execution"); + await stepIn(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "removed-original.js").id, + 5 + ); + + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "script.js").id, 8); + + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 9); + + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "original.js").id, 10); + + // We can't use the `stepIn` helper as this last step will resume + // and the helper is expecting to pause again + await dbg.actions.stepIn(getThreadContext(dbg)); + await assertNotPaused(dbg); + } +); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-browser-toolbox-source-tree.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-browser-toolbox-source-tree.js new file mode 100644 index 0000000000..fa321f5f43 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-browser-toolbox-source-tree.js @@ -0,0 +1,122 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test focuses on the SourceTree component, within the browser toolbox. + */ + +"use strict"; + +requestLongerTimeout(2); + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/framework/browser-toolbox/test/helpers-browser-toolbox.js", + this +); + +// Test that the Web extension name is shown in source tree rather than +// the extensions internal UUID. This checks both the web toolbox and the +// browser toolbox. +add_task(async function testSourceTreeNamesForWebExtensions() { + await pushPref("devtools.chrome.enabled", true); + await pushPref("devtools.browsertoolbox.scope", "everything"); + const extension = await installAndStartContentScriptExtension(); + + const dbg = await initDebugger("doc-content-script-sources.html"); + await waitForSourcesInSourceTree(dbg, [], { + noExpand: true, + }); + + is( + getSourceTreeLabel(dbg, 2), + "Test content script extension", + "Test content script extension is labeled properly" + ); + + await dbg.toolbox.closeToolbox(); + await extension.unload(); + + // Make sure the toolbox opens with the debugger selected. + await pushPref("devtools.browsertoolbox.panel", "jsdebugger"); + + const ToolboxTask = await initBrowserToolboxTask(); + await ToolboxTask.importFunctions({ + createDebuggerContext, + waitUntil, + findSourceNodeWithText, + findAllElements, + getSelector, + findAllElementsWithSelector, + assertSourceTreeNode, + }); + + await ToolboxTask.spawn(selectors, async _selectors => { + this.selectors = _selectors; + }); + + await ToolboxTask.spawn(null, async () => { + try { + /* global gToolbox */ + // Wait for the debugger to finish loading. + await gToolbox.getPanelWhenReady("jsdebugger"); + const dbgx = createDebuggerContext(gToolbox); + let rootNodeForExtensions = null; + await waitUntil(() => { + rootNodeForExtensions = findSourceNodeWithText(dbgx, "extension"); + return !!rootNodeForExtensions; + }); + // Find the root node for extensions and expand it if needed + if ( + !!rootNodeForExtensions && + !rootNodeForExtensions.querySelector(".arrow.expanded") + ) { + rootNodeForExtensions.querySelector(".arrow").click(); + } + + // Assert that extensions are displayed in the source tree + // with their extension name. + await assertSourceTreeNode(dbgx, "Picture-In-Picture"); + await assertSourceTreeNode(dbgx, "Form Autofill"); + + const threadLabels = [...findAllElements(dbgx, "sourceTreeThreads")].map( + el => { + return el.textContent; + } + ); + is( + threadLabels[0], + "Main Thread", + "The first thread is always the main thread" + ); + let lastPID = -1, + lastThreadLabel = ""; + for (let i = 1; i < threadLabels.length; i++) { + const label = threadLabels[i]; + if (label.startsWith("(pid ")) { + ok( + !lastThreadLabel, + "We should only have content process threads first after the main thread" + ); + const pid = parseInt(label.match(/pid (\d+)\)/)[1], 10); + ok( + pid >= lastPID, + `The content process threads are sorted by incremental PID ${pid} > ${lastPID}` + ); + lastPID = pid; + } else { + ok( + label.localeCompare(lastThreadLabel) >= 0, + `Worker thread labels are sorted alphabeticaly: ${label} vs ${lastThreadLabel}` + ); + lastThreadLabel = label; + } + } + } catch (e) { + console.log("Caught exception in spawn", e); + throw e; + } + }); + + await ToolboxTask.destroy(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-source-text-content.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-source-text-content.js new file mode 100644 index 0000000000..e8bb9875b3 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-source-text-content.js @@ -0,0 +1,565 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test focus on asserting the source content displayed in CodeMirror + * when we open a source from the SourceTree (or by any other means). + * + * The source content is being fetched from the server only on-demand. + * The main shortcoming is about sources being GC-ed. This only happens + * when we open the debugger on an already loaded page. + * When we (re)load a page while the debugger is opened, sources are never GC-ed. + * There are also specifics related to HTML page having inline scripts. + * Also, as this data is fetched on-demand, there is a loading prompt + * being displayed while the source is being fetched from the server. + */ + +"use strict"; + +const httpServer = createTestHTTPServer(); +const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`; +const loadCounts = {}; + +/** + * Simple tests, asserting that we correctly display source text content in CodeMirror + */ +const NAMED_EVAL_CONTENT = `function namedEval() {}; console.log('eval script'); //# sourceURL=named-eval.js`; +const NEW_FUNCTION_CONTENT = + "console.log('new function'); //# sourceURL=new-function.js"; +const INDEX_PAGE_CONTENT = ` + + + + + + + + + + + + + `; +const IFRAME_CONTENT = ` + + + + + + + + + `; + +httpServer.registerPathHandler("/index.html", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(INDEX_PAGE_CONTENT); +}); + +httpServer.registerPathHandler("/normal-script.js", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setHeader("Content-Type", "application/javascript"); + response.write(`console.log("normal script")`); +}); +httpServer.registerPathHandler( + "/slow-loading-script.js", + (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.processAsync(); + // eslint-disable-next-line mozilla/no-arbitrary-setTimeout + setTimeout(function () { + response.setHeader("Content-Type", "application/javascript"); + response.write(`console.log("slow loading script")`); + response.finish(); + }, 1000); + } +); +httpServer.registerPathHandler("/http-error-script.js", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setStatusLine(request.httpVersion, 404, "Not found"); + response.write(`console.log("http error")`); +}); +httpServer.registerPathHandler("/same-url.js", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + const sameUrlLoadCount = loadCounts[request.path]; + // Prevents gecko from cache this request in order to force fetching + // a new, distinct content for each usage of this URL + response.setHeader("Cache-Control", "no-store"); + response.setHeader("Content-Type", "application/javascript"); + response.write(`console.log("same url #${sameUrlLoadCount}")`); +}); +httpServer.registerPathHandler("/iframe.html", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setHeader("Content-Type", "text/html"); + response.write(IFRAME_CONTENT); +}); +add_task(async function testSourceTextContent() { + const dbg = await initDebuggerWithAbsoluteURL("about:blank"); + + const waitForSources = [ + "index.html", + "normal-script.js", + "slow-loading-script.js", + "same-url.js", + "new-function.js", + ]; + + // With fission and EFT disabled, the structure of the source tree changes + // as there is no iframe thread and all the iframe sources are loaded under the + // Main thread, so nodes will be in different positions in the tree. + const noFissionNoEFT = !isFissionEnabled() && !isEveryFrameTargetEnabled(); + + if (noFissionNoEFT) { + waitForSources.push("iframe.html", "named-eval.js"); + } + + // Load the document *once* the debugger is opened + // in order to avoid having any source being GC-ed. + await navigateToAbsoluteURL(dbg, BASE_URL + "index.html", ...waitForSources); + + await selectSourceFromSourceTree( + dbg, + "new-function.js", + noFissionNoEFT ? 6 : 5, + "Select `new-function.js`" + ); + is( + getCM(dbg).getValue(), + `function anonymous(\n) {\n${NEW_FUNCTION_CONTENT}\n}` + ); + + await selectSourceFromSourceTree( + dbg, + "normal-script.js", + noFissionNoEFT ? 7 : 6, + "Select `normal-script.js`" + ); + is(getCM(dbg).getValue(), `console.log("normal script")`); + + await selectSourceFromSourceTree( + dbg, + "slow-loading-script.js", + noFissionNoEFT ? 9 : 8, + "Select `slow-loading-script.js`" + ); + is(getCM(dbg).getValue(), `console.log("slow loading script")`); + + await selectSourceFromSourceTree( + dbg, + "index.html", + noFissionNoEFT ? 4 : 3, + "Select `index.html`" + ); + is(getCM(dbg).getValue(), INDEX_PAGE_CONTENT); + + await selectSourceFromSourceTree( + dbg, + "named-eval.js", + noFissionNoEFT ? 5 : 4, + "Select `named-eval.js`" + ); + is(getCM(dbg).getValue(), NAMED_EVAL_CONTENT); + + await selectSourceFromSourceTree( + dbg, + "same-url.js", + noFissionNoEFT ? 8 : 7, + "Select `same-url.js` in the Main Thread" + ); + + is( + getCM(dbg).getValue(), + `console.log("same url #1")`, + "We get an arbitrary content for same-url, the first loaded one" + ); + + const sameUrlSource = findSource(dbg, "same-url.js"); + const sourceActors = dbg.selectors.getSourceActorsForSource(sameUrlSource.id); + + if (isFissionEnabled() || isEveryFrameTargetEnabled()) { + const mainThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == "Main Thread"); + + is( + sourceActors.filter(actor => actor.thread == mainThread.actor).length, + 3, + "same-url.js is loaded 3 times in the main thread" + ); + + info(`Close the same-url.js from Main Thread`); + await closeTab(dbg, "same-url.js"); + + info("Click on the iframe tree node to show sources in the iframe"); + await clickElement(dbg, "sourceDirectoryLabel", 9); + await waitForSourcesInSourceTree( + dbg, + [ + "index.html", + "named-eval.js", + "normal-script.js", + "slow-loading-script.js", + "same-url.js", + "iframe.html", + "same-url.js", + "new-function.js", + ], + { + noExpand: true, + } + ); + + await selectSourceFromSourceTree( + dbg, + "same-url.js", + 12, + "Select `same-url.js` in the iframe" + ); + + is( + getCM(dbg).getValue(), + `console.log("same url #3")`, + "We get the expected content for same-url.js in the iframe" + ); + + const iframeThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == `${BASE_URL}iframe.html`); + is( + sourceActors.filter(actor => actor.thread == iframeThread.actor).length, + 1, + "same-url.js is loaded one time in the iframe thread" + ); + } else { + // There is no iframe thread when fission is off + const mainThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == "Main Thread"); + + is( + sourceActors.filter(actor => actor.thread == mainThread.actor).length, + 4, + "same-url.js is loaded 4 times in the main thread without fission" + ); + } + + info(`Close the same-url.js from the iframe`); + await closeTab(dbg, "same-url.js"); + + info("Click on the worker tree node to show sources in the worker"); + + await clickElement(dbg, "sourceDirectoryLabel", noFissionNoEFT ? 10 : 13); + + const workerSources = [ + "index.html", + "named-eval.js", + "normal-script.js", + "slow-loading-script.js", + "same-url.js", + "iframe.html", + "same-url.js", + "new-function.js", + ]; + + if (!noFissionNoEFT) { + workerSources.push("same-url.js"); + } + + await waitForSourcesInSourceTree(dbg, workerSources, { + noExpand: true, + }); + + await selectSourceFromSourceTree( + dbg, + "same-url.js", + noFissionNoEFT ? 12 : 15, + "Select `same-url.js` in the worker" + ); + + is( + getCM(dbg).getValue(), + `console.log("same url #4")`, + "We get the expected content for same-url.js worker" + ); + + const workerThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == `${BASE_URL}same-url.js`); + + is( + sourceActors.filter(actor => actor.thread == workerThread.actor).length, + 1, + "same-url.js is loaded one time in the worker thread" + ); + + await selectSource(dbg, "iframe.html"); + is(getCM(dbg).getValue(), IFRAME_CONTENT); + + ok( + !sourceExists(dbg, "http-error-script.js"), + "scripts with HTTP error code do not appear in the source list" + ); + + const onNewSource = waitForDispatch(dbg.store, "ADD_SOURCES"); + invokeInTab("breakInNewFunction"); + await waitForPaused(dbg); + const { sources } = await onNewSource; + is(sources.length, 1, "Got a unique source related to new Function source"); + const newFunctionSource = sources[0]; + // We acknowledge the function header as well as the new line in the first argument + assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 4, 0); + is(getCM(dbg).getValue(), "function anonymous(a\n,b\n) {\ndebugger;\n}"); + await resume(dbg); + + // As we are loading the page while the debugger is already opened, + // none of the resources are loaded twice. + is(loadCounts["/index.html"], 1, "We loaded index.html only once"); + is( + loadCounts["/normal-script.js"], + 1, + "We loaded normal-script.js only once" + ); + is( + loadCounts["/slow-loading-script.js"], + 1, + "We loaded slow-loading-script.js only once" + ); + is( + loadCounts["/same-url.js"], + 4, + "We loaded same-url.js in 4 distinct ways (the named eval doesn't count)" + ); + // For some reason external to the debugger, we issue two requests to scripts having http error codes. + // These two requests are done before opening the debugger. + is( + loadCounts["/http-error-script.js"], + 2, + "We loaded http-error-script.js twice, only before the debugger is opened" + ); +}); + +/** + * In this test, we force a GC before loading DevTools. + * So that Spidermonkey will no longer have access to the sources + * and another request should be issues to load the source text content. + */ +const GARBAGED_PAGE_CONTENT = ` + + + + + + `; + +httpServer.registerPathHandler( + "/garbaged-collected.html", + (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(GARBAGED_PAGE_CONTENT); + } +); + +httpServer.registerPathHandler("/garbaged-script.js", (request, response) => { + loadCounts[request.path] = (loadCounts[request.path] || 0) + 1; + response.setHeader("Content-Type", "application/javascript"); + response.write(`console.log("garbaged script ${loadCounts[request.path]}")`); +}); +add_task(async function testGarbageCollectedSourceTextContent() { + const tab = await addTab(BASE_URL + "garbaged-collected.html"); + is( + loadCounts["/garbaged-collected.html"], + 1, + "The HTML page is loaded once before opening the DevTools" + ); + is( + loadCounts["/garbaged-script.js"], + 1, + "The script is loaded once before opening the DevTools" + ); + + // Force freeing both the HTML page and script in memory + // so that the debugger has to fetch source content from http cache. + await SpecialPowers.spawn(tab.linkedBrowser, [], () => { + Cu.forceGC(); + }); + + const toolbox = await openToolboxForTab(tab, "jsdebugger"); + const dbg = createDebuggerContext(toolbox); + await waitForSources(dbg, "garbaged-collected.html", "garbaged-script.js"); + + await selectSource(dbg, "garbaged-script.js"); + // XXX Bug 1758454 - Source content of GC-ed script can be wrong! + // Even if we have to issue a new HTTP request for this source, + // we should be using HTTP cache and retrieve the first served version which + // is the one that actually runs in the page! + // We should be displaying `console.log("garbaged script 1")`, + // but instead, a new HTTP request is dispatched and we get a new content. + is(getCM(dbg).getValue(), `console.log("garbaged script 2")`); + + await selectSource(dbg, "garbaged-collected.html"); + is(getCM(dbg).getValue(), GARBAGED_PAGE_CONTENT); + + is( + loadCounts["/garbaged-collected.html"], + 2, + "We loaded the html page once as we haven't tried to display it in the debugger (2)" + ); + is( + loadCounts["/garbaged-script.js"], + 2, + "We loaded the garbaged script twice as we lost its content" + ); +}); + +/** + * Test failures when trying to open the source text content. + * + * In this test we load an html page + * - with inline source (so that it shows up in the debugger) + * - it first loads fine so that it shows up + * - initDebuggerWithAbsoluteURL will first load the document before the debugger + * - so the debugger will have to fetch the html page content via a network request + * - the test page will return a connection reset error on the second load attempt + */ +let loadCount = 0; +httpServer.registerPathHandler( + "/200-then-connection-reset.html", + (request, response) => { + loadCount++; + if (loadCount > 1) { + response.seizePower(); + response.bodyOutPutStream.close(); + response.finish(); + return; + } + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(``); + } +); +add_task(async function testFailingHtmlSource() { + info("Test failure in retrieving html page sources"); + + // initDebuggerWithAbsoluteURL will first load the document once before the debugger, + // then the debugger will have to fetch the html page content via a network request + // therefore the test page will encounter a connection reset error on the second load attempt + const dbg = await initDebuggerWithAbsoluteURL( + BASE_URL + "200-then-connection-reset.html", + "200-then-connection-reset.html" + ); + + // We can't select the HTML page as its source content isn't fetched + // (waitForSelectedSource doesn't resolve) + // Note that it is important to load the page *before* opening the page + // so that the thread actor has to request the page content and will fail + const source = findSource(dbg, "200-then-connection-reset.html"); + await dbg.actions.selectLocation( + getContext(dbg), + createLocation({ source }), + { keepContext: false } + ); + + ok( + getCM(dbg).getValue().includes("Could not load the source"), + "Display failure error" + ); +}); + +/** + * In this test we try to reproduce the "Loading..." message. + * This may happen when opening an HTML source that was loaded *before* + * opening DevTools. The thread actor will have to issue a new HTTP request + * to load the source content. + */ +let loadCount2 = 0; +let slowLoadingPageResolution = null; +httpServer.registerPathHandler( + "/slow-loading-page.html", + (request, response) => { + loadCount2++; + if (loadCount2 > 1) { + response.processAsync(); + slowLoadingPageResolution = function () { + response.write( + `` + ); + response.finish(); + }; + return; + } + response.write( + `` + ); + } +); +add_task(async function testLoadingHtmlSource() { + info("Test loading progress of html page sources"); + const dbg = await initDebuggerWithAbsoluteURL( + BASE_URL + "slow-loading-page.html", + "slow-loading-page.html" + ); + + const onSelected = selectSource(dbg, "slow-loading-page.html"); + await waitFor( + () => getCM(dbg).getValue() == `Loading…`, + "Wait for the source to be displayed as loading" + ); + + info("Wait for a second HTTP request to be made for the html page"); + await waitFor( + () => slowLoadingPageResolution, + "Wait for the html page to be queried a second time" + ); + is( + getCM(dbg).getValue(), + `Loading…`, + "The source is still loading until we release the network request" + ); + + slowLoadingPageResolution(); + info("Wait for the source to be fully selected and loaded"); + await onSelected; + + // Note that, even if the thread actor triggers a new HTTP request, + // it will use the HTTP cache and retrieve the first request content. + // This is actually relevant as that's the source that actually runs in the page! + // + // XXX Bug 1758458 - the source content is wrong. + // We should be seeing the whole HTML page content, + // whereas we only see the inline source text content. + is(getCM(dbg).getValue(), `console.log("slow-loading-page:first-load");`); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-source-tree.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-source-tree.js new file mode 100644 index 0000000000..320e157b70 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-source-tree.js @@ -0,0 +1,554 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test focuses on the SourceTree component, where we display all debuggable sources. + * + * The first two tests expand the tree via manual DOM events (first with clicks and second with keys). + * `waitForSourcesInSourceTree()` is a key assertion method. Passing `{noExpand: true}` + * is important to avoid automatically expand the source tree. + * + * The following tests depend on auto-expand and only assert all the sources possibly displayed + */ + +"use strict"; + +const testServer = createVersionizedHttpTestServer( + "examples/sourcemaps-reload-uncompressed" +); +const TEST_URL = testServer.urlFor("index.html"); + +/** + * This test opens the SourceTree manually via click events on the nested source, + * and then adds a source dynamically and asserts it is visible. + */ +add_task(async function testSimpleSourcesWithManualClickExpand() { + const dbg = await initDebugger( + "doc-sources.html", + "simple1.js", + "simple2.js", + "nested-source.js", + "long.js" + ); + + // Expand nodes and make sure more sources appear. + is( + getSourceTreeLabel(dbg, 1), + "Main Thread", + "Main thread is labeled properly" + ); + info("Before interacting with the source tree, no source are displayed"); + await waitForSourcesInSourceTree(dbg, [], { noExpand: true }); + await clickElement(dbg, "sourceDirectoryLabel", 3); + info( + "After clicking on the directory, all sources but the nested ones are displayed" + ); + await waitForSourcesInSourceTree( + dbg, + ["doc-sources.html", "simple1.js", "simple2.js", "long.js"], + { noExpand: true } + ); + + await clickElement(dbg, "sourceDirectoryLabel", 4); + info( + "After clicking on the nested directory, the nested source is also displayed" + ); + await waitForSourcesInSourceTree( + dbg, + [ + "doc-sources.html", + "simple1.js", + "simple2.js", + "long.js", + "nested-source.js", + ], + { noExpand: true } + ); + + const selected = waitForDispatch(dbg.store, "SET_SELECTED_LOCATION"); + await clickElement(dbg, "sourceNode", 5); + await selected; + await waitForSelectedSource(dbg, "nested-source.js"); + + // Ensure the source file clicked is now focused + await waitForElementWithSelector(dbg, ".sources-list .focused"); + + const selectedSource = dbg.selectors.getSelectedSource().url; + ok(selectedSource.includes("nested-source.js"), "nested-source is selected"); + await assertNodeIsFocused(dbg, 5); + + // Make sure new sources appear in the list. + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + const script = content.document.createElement("script"); + script.src = "math.min.js"; + content.document.body.appendChild(script); + }); + + info("After adding math.min.js, we got a new source displayed"); + await waitForSourcesInSourceTree( + dbg, + [ + "doc-sources.html", + "simple1.js", + "simple2.js", + "long.js", + "nested-source.js", + "math.min.js", + ], + { noExpand: true } + ); + is( + getSourceNodeLabel(dbg, 8), + "math.min.js", + "math.min.js - The dynamic script exists" + ); + + info("Assert that nested-source.js is still the selected source"); + await assertNodeIsFocused(dbg, 5); + + info("Test the copy to clipboard context menu"); + const mathMinTreeNode = findSourceNodeWithText(dbg, "math.min.js"); + await triggerSourceTreeContextMenu( + dbg, + mathMinTreeNode, + "#node-menu-copy-source" + ); + const clipboardData = SpecialPowers.getClipboardData("text/plain"); + is( + clipboardData, + EXAMPLE_URL + "math.min.js", + "The clipboard content is the selected source URL" + ); + + info("Test the download file context menu"); + // Before trigerring the menu, mock the file picker + const MockFilePicker = SpecialPowers.MockFilePicker; + MockFilePicker.init(window); + const nsiFile = FileUtils.getFile("TmpD", [ + `export_source_content_${Date.now()}.log`, + ]); + MockFilePicker.setFiles([nsiFile]); + const path = nsiFile.path; + + await triggerSourceTreeContextMenu( + dbg, + mathMinTreeNode, + "#node-menu-download-file" + ); + + info("Wait for the downloaded file to be fully saved to disk"); + await BrowserTestUtils.waitForCondition(() => IOUtils.exists(path)); + await BrowserTestUtils.waitForCondition(async () => { + const { size } = await IOUtils.stat(path); + return size > 0; + }); + const buffer = await IOUtils.read(path); + const savedFileContent = new TextDecoder().decode(buffer); + + const mathMinRequest = await fetch(EXAMPLE_URL + "math.min.js"); + const mathMinContent = await mathMinRequest.text(); + + is( + savedFileContent, + mathMinContent, + "The downloaded file has the expected content" + ); + + dbg.toolbox.closeToolbox(); +}); + +/** + * Test keyboard arrow behaviour on the SourceTree with a nested folder + * that we manually expand/collapse via arrow keys. + */ +add_task(async function testSimpleSourcesWithManualKeyShortcutsExpand() { + const dbg = await initDebugger( + "doc-sources.html", + "simple1.js", + "simple2.js", + "nested-source.js", + "long.js" + ); + + // Before clicking on the source label, no source is displayed + await waitForSourcesInSourceTree(dbg, [], { noExpand: true }); + await clickElement(dbg, "sourceDirectoryLabel", 3); + // Right after, all sources, but the nested one are displayed + await waitForSourcesInSourceTree( + dbg, + ["doc-sources.html", "simple1.js", "simple2.js", "long.js"], + { noExpand: true } + ); + + // Right key on open dir + await pressKey(dbg, "Right"); + await assertNodeIsFocused(dbg, 3); + + // Right key on closed dir + await pressKey(dbg, "Right"); + await assertNodeIsFocused(dbg, 4); + + // Left key on a open dir + await pressKey(dbg, "Left"); + await assertNodeIsFocused(dbg, 4); + + // Down key on a closed dir + await pressKey(dbg, "Down"); + await assertNodeIsFocused(dbg, 4); + + // Right key on a source + // We are focused on the nested source and up to this point we still display only the 4 initial sources + await waitForSourcesInSourceTree( + dbg, + ["doc-sources.html", "simple1.js", "simple2.js", "long.js"], + { noExpand: true } + ); + await pressKey(dbg, "Right"); + await assertNodeIsFocused(dbg, 4); + // Now, the nested source is also displayed + await waitForSourcesInSourceTree( + dbg, + [ + "doc-sources.html", + "simple1.js", + "simple2.js", + "long.js", + "nested-source.js", + ], + { noExpand: true } + ); + + // Down key on a source + await pressKey(dbg, "Down"); + await assertNodeIsFocused(dbg, 5); + + // Go to bottom of tree and press down key + await pressKey(dbg, "Down"); + await pressKey(dbg, "Down"); + await assertNodeIsFocused(dbg, 6); + + // Up key on a source + await pressKey(dbg, "Up"); + await assertNodeIsFocused(dbg, 5); + + // Left key on a source + await pressKey(dbg, "Left"); + await assertNodeIsFocused(dbg, 4); + + // Left key on a closed dir + // We are about to close the nested folder, the nested source is about to disappear + await waitForSourcesInSourceTree( + dbg, + [ + "doc-sources.html", + "simple1.js", + "simple2.js", + "long.js", + "nested-source.js", + ], + { noExpand: true } + ); + await pressKey(dbg, "Left"); + // And it disappeared + await waitForSourcesInSourceTree( + dbg, + ["doc-sources.html", "simple1.js", "simple2.js", "long.js"], + { noExpand: true } + ); + await pressKey(dbg, "Left"); + await assertNodeIsFocused(dbg, 3); + + // Up Key at the top of the source tree + await pressKey(dbg, "Up"); + await assertNodeIsFocused(dbg, 2); + dbg.toolbox.closeToolbox(); +}); + +/** + * Tests that the source tree works with all the various types of sources + * coming from the integration test page. + * + * Also assert a few extra things on sources with query strings: + * - they can be pretty printed, + * - quick open matches them, + * - you can set breakpoint on them. + */ +add_task(async function testSourceTreeOnTheIntegrationTestPage() { + // We open against a blank page and only then navigate to the test page + // so that sources aren't GC-ed before opening the debugger. + // When we (re)load a page while the debugger is opened, the debugger + // will force all sources to be held in memory. + const dbg = await initDebuggerWithAbsoluteURL("about:blank"); + + await navigateToAbsoluteURL( + dbg, + TEST_URL, + "index.html", + "script.js", + "test-functions.js", + "query.js?x=1", + "query.js?x=2", + "query2.js?y=3", + "bundle.js", + "original.js", + "replaced-bundle.js", + "removed-original.js", + "named-eval.js" + ); + + info("Verify source tree content"); + await waitForSourcesInSourceTree(dbg, INTEGRATION_TEST_PAGE_SOURCES); + + info("Verify Thread Source Items"); + const mainThreadItem = findSourceTreeThreadByName(dbg, "Main Thread"); + ok(mainThreadItem, "Found the thread item for the main thread"); + ok( + mainThreadItem.querySelector("span.img.window"), + "The thread has the window icon" + ); + + info( + "Assert the number of sources and source actors for the same-url.sjs sources" + ); + const sameUrlSource = findSource(dbg, "same-url.sjs"); + ok(sameUrlSource, "Found same-url.js in the main thread"); + + const sourceActors = dbg.selectors.getSourceActorsForSource(sameUrlSource.id); + + const mainThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == "Main Thread"); + + is( + sourceActors.filter(actor => actor.thread == mainThread.actor).length, + // When EFT is disabled the iframe's source is meld into the main target + isEveryFrameTargetEnabled() ? 3 : 4, + "same-url.js is loaded 3 times in the main thread" + ); + + if (isEveryFrameTargetEnabled()) { + const iframeThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == testServer.urlFor("iframe.html")); + + is( + sourceActors.filter(actor => actor.thread == iframeThread.actor).length, + 1, + "same-url.js is loaded one time in the iframe thread" + ); + } + + const workerThread = dbg.selectors + .getAllThreads() + .find(thread => thread.name == testServer.urlFor("same-url.sjs")); + + is( + sourceActors.filter(actor => actor.thread == workerThread.actor).length, + 1, + "same-url.js is loaded one time in the worker thread" + ); + + const workerThreadItem = findSourceTreeThreadByName(dbg, "same-url.sjs"); + ok(workerThreadItem, "Found the thread item for the worker"); + ok( + workerThreadItem.querySelector("span.img.worker"), + "The thread has the worker icon" + ); + + info("Verify source icons"); + assertSourceIcon(dbg, "index.html", "file"); + assertSourceIcon(dbg, "script.js", "javascript"); + assertSourceIcon(dbg, "query.js?x=1", "javascript"); + assertSourceIcon(dbg, "original.js", "javascript"); + // Framework icons are only displayed when we parse the source, + // which happens when we select the source + assertSourceIcon(dbg, "react-component-module.js", "javascript"); + await selectSource(dbg, "react-component-module.js"); + assertSourceIcon(dbg, "react-component-module.js", "react"); + + info("Verify blackbox source icon"); + await selectSource(dbg, "script.js"); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + assertSourceIcon(dbg, "script.js", "blackBox"); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + assertSourceIcon(dbg, "script.js", "javascript"); + + info("Assert the content of the named eval"); + await selectSource(dbg, "named-eval.js"); + assertTextContentOnLine(dbg, 3, `console.log("named-eval");`); + + info("Assert that nameless eval don't show up in the source tree"); + invokeInTab("breakInEval"); + await waitForPaused(dbg); + await waitForSourcesInSourceTree(dbg, INTEGRATION_TEST_PAGE_SOURCES); + await resume(dbg); + + info("Assert the content of sources with query string"); + await selectSource(dbg, "query.js?x=1"); + const tab = findElement(dbg, "activeTab"); + is(tab.innerText, "query.js?x=1", "Tab label is query.js?x=1"); + assertTextContentOnLine( + dbg, + 1, + `function query() {console.log("query x=1");}` + ); + await addBreakpoint(dbg, "query.js?x=1", 1); + assertBreakpointHeading(dbg, "query.js?x=1", 0); + + // pretty print the source and check the tab text + clickElement(dbg, "prettyPrintButton"); + await waitForSource(dbg, "query.js?x=1:formatted"); + await waitForSelectedSource(dbg, "query.js?x=1:formatted"); + assertSourceIcon(dbg, "query.js?x=1", "prettyPrint"); + + const prettyTab = findElement(dbg, "activeTab"); + is(prettyTab.innerText, "query.js?x=1", "Tab label is query.js?x=1"); + ok(prettyTab.querySelector(".img.prettyPrint")); + assertBreakpointHeading(dbg, "query.js?x=1", 0); + assertTextContentOnLine(dbg, 1, `function query() {`); + // Note the replacements of " by ' here: + assertTextContentOnLine(dbg, 2, `console.log('query x=1');`); + + // assert quick open works with queries + pressKey(dbg, "quickOpen"); + type(dbg, "query.js?x"); + + // There can be intermediate updates in the results, + // so wait for the final expected value + await waitFor(async () => { + const resultItem = findElement(dbg, "resultItems"); + if (!resultItem) { + return false; + } + return resultItem.innerText.includes("query.js?x=1"); + }, "Results include the source with the query string"); + dbg.toolbox.closeToolbox(); +}); + +/** + * Verify that Web Extension content scripts appear only when + * devtools.chrome.enabled is set to true and that they get + * automatically re-selected on page reload. + */ +add_task(async function testSourceTreeWithWebExtensionContentScript() { + const extension = await installAndStartContentScriptExtension(); + + info("Without the chrome preference, the content script doesn't show up"); + await pushPref("devtools.chrome.enabled", false); + let dbg = await initDebugger("doc-content-script-sources.html"); + // Let some time for unexpected source to appear + await wait(1000); + await waitForSourcesInSourceTree(dbg, []); + await dbg.toolbox.closeToolbox(); + + info("With the chrome preference, the content script shows up"); + await pushPref("devtools.chrome.enabled", true); + const toolbox = await openToolboxForTab(gBrowser.selectedTab, "jsdebugger"); + dbg = createDebuggerContext(toolbox); + await waitForSourcesInSourceTree(dbg, ["content_script.js"]); + await selectSource(dbg, "content_script.js"); + ok( + findElementWithSelector(dbg, ".sources-list .focused"), + "Source is focused" + ); + + const contentScriptGroupItem = findSourceNodeWithText( + dbg, + "Test content script extension" + ); + ok(contentScriptGroupItem, "Found the group item for the content script"); + ok( + contentScriptGroupItem.querySelector("span.img.extension"), + "The group has the extension icon" + ); + assertSourceIcon(dbg, "content_script.js", "javascript"); + + for (let i = 1; i < 3; i++) { + info( + `Reloading tab (${i} time), the content script should always be reselected` + ); + gBrowser.reloadTab(gBrowser.selectedTab); + await waitForSelectedSource(dbg, "content_script.js"); + ok( + findElementWithSelector(dbg, ".sources-list .focused"), + "Source is focused" + ); + } + await dbg.toolbox.closeToolbox(); + + await extension.unload(); +}); + +add_task(async function testSourceTreeWithEncodedPaths() { + const httpServer = createTestHTTPServer(); + httpServer.registerContentType("html", "text/html"); + httpServer.registerContentType("js", "application/javascript"); + + httpServer.registerPathHandler("/index.html", function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + + + +

Encoded scripts paths

+ + `); + }); + httpServer.registerPathHandler( + encodeURI("/my folder/my file.js"), + function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript", false); + response.write(`const x = 42`); + } + ); + httpServer.registerPathHandler( + "/malformedUri.js", + function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript", false); + response.write(`const y = "malformed"`); + } + ); + const port = httpServer.identity.primaryPort; + + const dbg = await initDebuggerWithAbsoluteURL( + `http://localhost:${port}/index.html`, + "my file.js" + ); + + await waitForSourcesInSourceTree(dbg, ["my file.js", "malformedUri.js?%"]); + ok( + true, + "source name are decoded in the tree, and malformed uri source are displayed" + ); + is( + // We don't have any specific class on the folder item, so let's target the folder + // icon next sibling, which is the directory label. + findElementWithSelector(dbg, ".sources-panel .node .folder + .label") + .innerText, + "my folder", + "folder name is decoded in the tree" + ); +}); + +/** + * Assert the location displayed in the breakpoint list, in the right sidebar. + * + * @param {Object} dbg + * @param {String} label + * The expected displayed location + * @param {Number} index + * The position of the breakpoint in the list to verify + */ +function assertBreakpointHeading(dbg, label, index) { + const breakpointHeading = findAllElements(dbg, "breakpointHeadings")[index] + .innerText; + is(breakpointHeading, label, `Breakpoint heading is ${label}`); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-tabs.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-tabs.js new file mode 100644 index 0000000000..7aedb868e6 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-tabs.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test focuses on the Tabs component, where we display all opened sources. + */ + +"use strict"; + +const testServer = createVersionizedHttpTestServer( + "examples/sourcemaps-reload-uncompressed" +); +const TEST_URL = testServer.urlFor("index.html"); + +add_task(async function () { + // We open against a blank page and only then navigate to the test page + // so that sources aren't GC-ed before opening the debugger. + // When we (re)load a page while the debugger is opened, the debugger + // will force all sources to be held in memory. + const dbg = await initDebuggerWithAbsoluteURL("about:blank"); + + await navigateToAbsoluteURL(dbg, TEST_URL, ...INTEGRATION_TEST_PAGE_SOURCES); + + info("Wait for all sources to be displayed in the source tree"); + let displayedSources; + await waitFor(() => { + displayedSources = dbg.selectors.getDisplayedSourcesList(); + return displayedSources.length == INTEGRATION_TEST_PAGE_SOURCES.length; + }, "Got the expected number of sources from the selectors"); + + // Open each visible source in tabs + const uniqueUrls = new Set(); + for (const source of displayedSources) { + info(`Opening '${source.url}'`); + await selectSource(dbg, source); + uniqueUrls.add(source.url); + } + + // Some sources are loaded from the same URL and only one tab will be opened for them + is(countTabs(dbg), uniqueUrls.size, "Got a tab for each distinct source URL"); + + await reload(dbg, ...INTEGRATION_TEST_PAGE_SOURCES); + + await waitFor( + () => countTabs(dbg) == uniqueUrls.size, + "Wait for tab count to be fully restored" + ); + + is( + countTabs(dbg), + uniqueUrls.size, + "Still get the same number of tabs after reload" + ); + + for (const source of displayedSources) { + info(`Closing '${source.url}'`); + await closeTab(dbg, source); + } + + is(countTabs(dbg), 0, "All tabs are closed"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-features-wasm.js b/devtools/client/debugger/test/mochitest/browser_dbg-features-wasm.js new file mode 100644 index 0000000000..e7d4ee17d0 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-features-wasm.js @@ -0,0 +1,168 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This test covers all specifics of debugging WASM/WebAssembly files. + * + * WebAssembly is a binary file format for the Web. + * The binary files are loaded by Gecko and machine code runs. + * In order to debug them ThreadConfiguration's `observeWasm` is set to true, + * only once the debugger is opened. This will set DebuggerAPI's `allowUnobservedWasm` to false. + * Then, the engine will compute a different machine code with debugging instruction. + * This will use a lot more memory, but allow debugger to set breakpoint and break on WASM sources. + * + * This behavior introduces some limitations when opening the debugger against + * and already loaded page. The WASM file won't be debuggable. + */ + +"use strict"; + +add_task(async function () { + // Load the test page before opening the debugger so that WASM are built + // without debugging instructions. Opening the console still doesn't enable debugging instructions. + const tab = await addTab(EXAMPLE_URL + "doc-wasm-sourcemaps.html"); + const toolbox = await openToolboxForTab(tab, "webconsole"); + + // Reload once again, while the console is opened. + // When opening the debugger, it will still miss the source content. + // To see the sources, we have to reload while the debugger has been opened. + await reloadBrowser(); + + await toolbox.selectTool("jsdebugger"); + const dbg = createDebuggerContext(toolbox); + + // When opening against an already loaded page, WASM source loading doesn't work + // And because of that we don't see sourcemap/original files. + await waitForSourcesInSourceTree(dbg, [ + "doc-wasm-sourcemaps.html", + "fib.wasm", + ]); + is(dbg.selectors.getSourceCount(), 2, "There are only these two sources"); + + const source = findSource(dbg, "fib.wasm"); + is(source.isWasm, true, "The original source is flagged as Wasm source"); + + // Note that there is no point in asserting breakable lines, + // as we aren't fetching any source. + await dbg.actions.selectLocation( + getContext(dbg), + createLocation({ source }), + { keepContext: false } + ); + is(getCM(dbg).getValue(), `Please refresh to debug this module`); + + info("Reload and assert that WASM files are then debuggable"); + await reload(dbg, "doc-wasm-sourcemaps.html", "fib.wasm", "fib.c"); + + info("After reloading, original file lines are breakable"); + // Ensure selecting the source before asserting breakable lines + // otherwise the gutter may not be yet updated + await selectSource(dbg, "fib.c"); + assertLineIsBreakable(dbg, source.url, 14, true); + + await waitForSourcesInSourceTree(dbg, [ + "doc-wasm-sourcemaps.html", + "fib.wasm", + "fib.c", + ]); + is(dbg.selectors.getSourceCount(), 3, "There is all these 3 sources"); + // (even if errno_location.c is still not functional) + + // The line in the original C file, where the for() loop starts + const breakpointLine = 12; + assertTextContentOnLine(dbg, breakpointLine, "for (i = 0; i < n; i++) {"); + + info("Register and trigger a breakpoint from the original source in C"); + await addBreakpoint(dbg, "fib.c", breakpointLine); + invokeInTab("runWasm"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "fib.c").id, breakpointLine); + await assertBreakpoint(dbg, breakpointLine); + // Capture the generated location line, so that we can better report + // when the binary code changed later in this test + const frames = dbg.selectors.getCurrentThreadFrames(); + const generatedLine = frames[0].generatedLocation.line; + + assertFirstFrameTitleAndLocation(dbg, "(wasmcall)", "fib.c"); + + await removeBreakpoint(dbg, findSource(dbg, "fib.c").id, breakpointLine); + await resume(dbg); + + info( + "Now register and trigger the same breakpoint from the binary source file" + ); + const binarySource = findSource(dbg, "fib.wasm"); + + // There is two lines, the hexadecimal one is the "virtual line" displayed in the gutter. + // While the decimal one is the line where the line appear in CodeMirror. + // So while we set the breakpoint on the decimal line in CodeMirror gutter, + // internaly, the engine sets the breakpoint on the "virtual line". + const virtualBinaryLine = 0x11a; + is( + "0x" + virtualBinaryLine.toString(16), + "0x" + generatedLine.toString(16), + "The hardcoded binary line matches the mapped location when we set the breakpoint on the original line. If you rebuilt the binary, you may just need to update the virtualBinaryLine variable to the new location." + ); + const binaryLine = + dbg.wasmOffsetToLine(binarySource.id, virtualBinaryLine) + 1; + + // We can't use selectSource here because binary source won't have symbols loaded + // (getSymbols(source) selector will be false) + await dbg.actions.selectLocation( + getContext(dbg), + createLocation({ source: binarySource }), + { keepContext: false } + ); + + assertLineIsBreakable(dbg, binarySource.url, binaryLine, true); + + await addBreakpoint(dbg, binarySource, virtualBinaryLine); + invokeInTab("runWasm"); + + // We can't use waitForPaused test helper as the text content isn't displayed correctly + // so only assert that we are in paused state. + await waitForPaused(dbg); + // We don't try to assert paused line as there is two types of line in wasm + assertPausedAtSourceAndLine(dbg, binarySource.id, virtualBinaryLine); + + // Switch to original source + info( + "Manually switch to original C source as we set the breakpoint on binary source, we paused on it" + ); + await dbg.actions.jumpToMappedSelectedLocation(getContext(dbg)); + + // But once we switch to original source, we should have the original text content and be able + // to do all classic assertions for paused state. + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "fib.c").id, breakpointLine); + + info("Reselect the binary source"); + await dbg.actions.selectLocation( + getContext(dbg), + createLocation({ source: binarySource }), + { keepContext: false } + ); + + assertFirstFrameTitleAndLocation(dbg, "(wasmcall)", "fib.wasm"); + + // We can't use this method as it uses internaly the breakpoint line, which isn't the line in CodeMirror + // assertPausedAtSourceAndLine(dbg, binarySource.id, binaryLine); + await assertBreakpoint(dbg, binaryLine); + + await removeBreakpoint(dbg, binarySource.id, virtualBinaryLine); + await resume(dbg); +}); + +function assertFirstFrameTitleAndLocation(dbg, title, location) { + const frames = findAllElements(dbg, "frames"); + const firstFrameTitle = frames[0].querySelector(".title").textContent; + is(firstFrameTitle, title, "First frame title is the expected one"); + const firstFrameLocation = frames[0].querySelector(".location").textContent; + is( + firstFrameLocation.includes(location), + true, + `First frame location '${firstFrameLocation}' includes '${location}'` + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-breakpoint.js b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-breakpoint.js new file mode 100644 index 0000000000..783b86f80c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-breakpoint.js @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`; + +add_task(async function () { + // Load a test page with a remote frame: + // simple1.js is imported by the main page. simple2.js comes from the remote frame. + const dbg = await initDebuggerWithAbsoluteURL( + TEST_COM_URI, + "simple1.js", + "simple2.js" + ); + const { + selectors: { getSelectedSource }, + } = dbg; + + // Add breakpoint within the iframe, which is hit early on load + await selectSource(dbg, "simple2.js"); + await addBreakpoint(dbg, "simple2.js", 7); + + const onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + info("Reload the page to hit the breakpoint on load"); + const onReloaded = reload(dbg); + await onBreakpoint; + await waitForSelectedSource(dbg, "simple2.js"); + + ok( + getSelectedSource().url.includes("simple2.js"), + "Selected source is simple2.js" + ); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7); + + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 7); + + // We can't used `stepIn` helper as this last step will resume + // and the helper is expecting to pause again + await dbg.actions.stepIn(getThreadContext(dbg)); + assertNotPaused(dbg, "Stepping in two times resumes"); + + info("Wait for reload to complete after resume"); + await onReloaded; + + await dbg.toolbox.closeToolbox(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-pause-exceptions.js b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-pause-exceptions.js new file mode 100644 index 0000000000..8a76831e8c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-pause-exceptions.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-pause-exceptions.html`; +// Tests Pause on exceptions in remote iframes + +add_task(async function () { + // Load a test page with a remote iframe + const dbg = await initDebuggerWithAbsoluteURL(TEST_COM_URI); + + info("Test pause on exceptions ignoring caught exceptions"); + await togglePauseOnExceptions(dbg, true, false); + + let onReloaded = reload(dbg); + await waitForPaused(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id, + 17 + ); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; + + info("Test pause on exceptions including caught exceptions"); + await togglePauseOnExceptions(dbg, true, true); + + onReloaded = reload(dbg); + await waitForPaused(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id, + 13 + ); + + await resume(dbg); + await waitForPaused(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc_dbg-fission-frame-pause-exceptions.html").id, + 17 + ); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-sources.js b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-sources.js new file mode 100644 index 0000000000..b40058a7dd --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-fission-frame-sources.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`; + +add_task(async function () { + // Simply load a test page with a remote frame and wait for both sources to + // be visible. + // simple1.js is imported by the main page. simple2.js comes from the frame. + const dbg = await initDebuggerWithAbsoluteURL( + TEST_COM_URI, + "simple1.js", + "simple2.js" + ); + + const rootNodes = dbg.win.document.querySelectorAll( + selectors.sourceTreeRootNode + ); + + info("Expands the main root node"); + await expandAllSourceNodes(dbg, rootNodes[0]); + + // We need to assert the actual DOM nodes in the source tree, because the + // state can contain simple1.js and simple2.js, but only show one of them. + info("Waiting for simple1.js from example.com (parent page)"); + await waitUntil(() => findSourceNodeWithText(dbg, "simple1.js")); + + // If fission or EFT is enabled, the second source is under another root node. + if (isFissionEnabled() || isEveryFrameTargetEnabled()) { + is( + rootNodes.length, + 2, + "Found 2 sourceview root nodes when iframe has dedicated target" + ); + + info("Expands the remote frame root node"); + await expandAllSourceNodes(dbg, rootNodes[1]); + } + + info("Waiting for simple2.js from example.org (frame)"); + await waitUntil(() => findSourceNodeWithText(dbg, "simple2.js")); + + await dbg.toolbox.closeToolbox(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-fission-project-search.js b/devtools/client/debugger/test/mochitest/browser_dbg-fission-project-search.js new file mode 100644 index 0000000000..7a781c8451 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-fission-project-search.js @@ -0,0 +1,52 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`; + +// Testing project search for remote frames. +add_task(async function () { + // Load page and wait for sources. simple.js is loaded from + // the top-level document in the dot com domain, while simple2.js + // is loaded from the remote frame in the dot org domain + const dbg = await initDebuggerWithAbsoluteURL( + TEST_COM_URI, + "simple1.js", + "simple2.js" + ); + + pressKey(dbg, "projectSearch"); + type(dbg, "foo"); + pressKey(dbg, "Enter"); + + await waitForState(dbg, state => state.projectTextSearch.status === "DONE"); + + const fileResults = findAllElements(dbg, "projectSearchFileResults"); + const matches = findAllElements(dbg, "projectSearchExpandedResults"); + + is(fileResults.length, 2, "Two results found"); + is(matches.length, 6, "Total no of matches found"); + + // Asserts that we find a matches in the js file included in the top-level document + assertFileResult("simple1.js", 5); + // Asserts that we find the match in the js file included + assertFileResult("simple2.js", 1); + + function assertFileResult(fileMatched, noOfMatches) { + // The results can be out of order so let find it from the collection + const match = [...fileResults].find(result => + result.querySelector(".file-path").innerText.includes(fileMatched) + ); + + ok(match, `Matches were found in ${fileMatched} file.`); + + const matchText = noOfMatches > 1 ? "matches" : "match"; + is( + match.querySelector(".matches-summary").innerText.trim(), + `(${noOfMatches} ${matchText})`, + `${noOfMatches} ${matchText} were found in ${fileMatched} file.` + ); + } +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-fission-switch-target.js b/devtools/client/debugger/test/mochitest/browser_dbg-fission-switch-target.js new file mode 100644 index 0000000000..6500942d0a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-fission-switch-target.js @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test switching for the top-level target. + +"use strict"; + +const PARENT_PROCESS_URI = "about:robots"; + +add_task(async function () { + // Start the debugger on a parent process URL + const dbg = await initDebuggerWithAbsoluteURL( + PARENT_PROCESS_URI, + "aboutRobots.js" + ); + + // Navigate to a content process URL and check that the sources tree updates + await navigate(dbg, "doc-scripts.html", "simple1.js"); + info("Wait for all sources to be in the store"); + await waitFor(() => dbg.selectors.getSourceCount() == 5); + is(dbg.selectors.getSourceCount(), 5, "5 sources are loaded."); + + // Check that you can still break after target switching. + await selectSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 4); + invokeInTab("main"); + await waitForPaused(dbg); + await waitForLoadedSource(dbg, "simple1.js"); + + await dbg.toolbox.closeToolbox(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-gc-breakpoint-positions.js b/devtools/client/debugger/test/mochitest/browser_dbg-gc-breakpoint-positions.js new file mode 100644 index 0000000000..7c46e7cacc --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-gc-breakpoint-positions.js @@ -0,0 +1,17 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that we can set breakpoints in scripts that have been GCed. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-gc-breakpoint-positions.html", + "doc-gc-breakpoint-positions.html" + ); + await selectSource(dbg, "doc-gc-breakpoint-positions.html"); + await addBreakpoint(dbg, "doc-gc-breakpoint-positions.html", 21); + ok(true, "Added breakpoint at GC'ed script location"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-gc-sources.js b/devtools/client/debugger/test/mochitest/browser_dbg-gc-sources.js new file mode 100644 index 0000000000..e4a6da536a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-gc-sources.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that we can set breakpoints in scripts that have been GCed. +// Check that breakpoints can be set in GC'ed inline scripts, and in +// generated and original sources of scripts with source maps specified either +// inline or in their HTTP response headers. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-gc-sources.html", + "doc-gc-sources.html", + "collected-bundle.js", + "collected.js", + "collected2.js" + ); + await selectSource(dbg, "doc-gc-sources.html"); + await addBreakpoint(dbg, "doc-gc-sources.html", 21); + await selectSource(dbg, "collected-bundle.js"); + await addBreakpoint(dbg, "collected-bundle.js", 31); + await selectSource(dbg, "collected.js"); + await addBreakpoint(dbg, "collected.js", 2); + await selectSource(dbg, "collected2.js"); + await addBreakpoint(dbg, "collected2.js", 2); + ok(true, "Added breakpoint in GC'ed sources"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-go-to-line.js b/devtools/client/debugger/test/mochitest/browser_dbg-go-to-line.js new file mode 100644 index 0000000000..d151d03a51 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-go-to-line.js @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test the "go to line" feature correctly responses to keyboard shortcuts. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "long.js"); + await selectSource(dbg, "long.js"); + await waitForSelectedSource(dbg, "long.js"); + + info("Test opening"); + pressKey(dbg, "goToLine"); + assertEnabled(dbg); + is( + dbg.win.document.activeElement.tagName, + "INPUT", + "The input area of 'go to line' box is focused" + ); + + info("Test closing by the same keyboard shortcut"); + pressKey(dbg, "goToLine"); + assertDisabled(dbg); + is(findElement(dbg, "searchField"), null, "The 'go to line' box is closed"); + + info("Test closing by escape"); + pressKey(dbg, "goToLine"); + assertEnabled(dbg); + + pressKey(dbg, "Escape"); + assertDisabled(dbg); + is(findElement(dbg, "searchField"), null, "The 'go to line' box is closed"); + + info("Test going to the correct line"); + pressKey(dbg, "goToLine"); + await waitForGoToLineBoxFocus(dbg); + type(dbg, "66"); + pressKey(dbg, "Enter"); + await assertLine(dbg, 66); +}); + +function assertEnabled(dbg) { + is(dbg.selectors.getQuickOpenEnabled(), true, "quickOpen enabled"); +} + +function assertDisabled(dbg) { + is(dbg.selectors.getQuickOpenEnabled(), false, "quickOpen disabled"); +} + +async function waitForGoToLineBoxFocus(dbg) { + await waitFor(() => dbg.win.document.activeElement.tagName === "INPUT"); +} + +async function assertLine(dbg, lineNumber) { + // Wait for the line to be set + await waitUntil(() => !!dbg.selectors.getSelectedLocation().line); + is( + dbg.selectors.getSelectedLocation().line, + lineNumber, + `goto line is ${lineNumber}` + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-highlights-calls.js b/devtools/client/debugger/test/mochitest/browser_dbg-highlights-calls.js new file mode 100644 index 0000000000..98319cda51 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-highlights-calls.js @@ -0,0 +1,31 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test checks to see if command button highlights and unhighlights +// calls when debugger is paused. + +"use strict"; + +add_task(async function () { + await pushPref("devtools.debugger.features.command-click", true); + const dbg = await initDebugger("doc-command-click.html", "simple4.js"); + + const source = findSource(dbg, "simple4.js"); + + await selectSource(dbg, source); + + invokeInTab("funcA"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + + pressKey(dbg, "commandKeyDown"); + await waitForDispatch(dbg.store, "HIGHLIGHT_CALLS"); + const calls = dbg.win.document.querySelectorAll(".highlight-function-calls"); + is(calls.length, 2); + pressKey(dbg, "commandKeyUp"); + const nocalls = dbg.win.document.querySelectorAll( + ".highlight-function-calls" + ); + is(nocalls.length, 0); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-html-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-html-breakpoints.js new file mode 100644 index 0000000000..aafea0d650 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-html-breakpoints.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-html-breakpoints.html"); + + await selectSource(dbg, "doc-html-breakpoints.html"); + + // Reload the page so that we know the debugger is already open and + // functional before the page loads and we start getting notifications + // about new actors being created in the page content. + await reload(dbg, "doc-html-breakpoints.html"); + + await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 8); + await addBreakpoint(dbg, "doc-html-breakpoints.html", 8); + + // Ensure that the breakpoints get added once the later scripts load. + await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 15); + await addBreakpoint(dbg, "doc-html-breakpoints.html", 15); + await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 20); + await addBreakpoint(dbg, "doc-html-breakpoints.html", 20); + + await reload(dbg, "doc-html-breakpoints.html", "simple2.js"); + + invokeInTab("test1"); + await waitForPaused(dbg); + + const htmlSource = findSource(dbg, "doc-html-breakpoints.html"); + + is(htmlSource.isHTML, true, "The html page is flagged as an html source"); + is( + findSource(dbg, "simple2.js").isHTML, + false, + "The js source is not flagged as an html source" + ); + + assertPausedAtSourceAndLine(dbg, htmlSource.id, 8); + await resume(dbg); + + await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 15); + invokeInTab("test3"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, htmlSource.id, 15); + await resume(dbg); + + await waitForBreakableLine(dbg, "doc-html-breakpoints.html", 20); + invokeInTab("test4"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, htmlSource.id, 20); + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-idb-run-to-completion.js b/devtools/client/debugger/test/mochitest/browser_dbg-idb-run-to-completion.js new file mode 100644 index 0000000000..dcd4a11463 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-idb-run-to-completion.js @@ -0,0 +1,15 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that IDB transactions are not processed at microtask checkpoints +// introduced by debugger hooks. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-idb-run-to-completion.html"); + invokeInTab("test", "doc-xhr-run-to-completion.html"); + await waitForPaused(dbg); + ok(true, "paused after successfully processing IDB transaction"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-iframes.js b/devtools/client/debugger/test/mochitest/browser_dbg-iframes.js new file mode 100644 index 0000000000..0bcc0e020f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-iframes.js @@ -0,0 +1,60 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test is taking too much time to complete on some hardware since +// release at https://bugzilla.mozilla.org/show_bug.cgi?id=1423158 + +"use strict"; + +requestLongerTimeout(3); + +/** + * Test debugging a page with iframes + * 1. pause in the main thread + * 2. pause in the iframe + */ +add_task(async function () { + const dbg = await initDebugger("doc-iframes.html"); + + // test pausing in the main thread + const onReloaded = reload(dbg); + await waitForPaused(dbg); + await waitForLoadedSource(dbg, "doc-iframes.html"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "doc-iframes.html").id, 11); + + // test pausing in the iframe + await resume(dbg); + await waitForPaused(dbg); + await waitForLoadedSource(dbg, "doc-debugger-statements.html"); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 11 + ); + + // test pausing in the iframe + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-debugger-statements.html").id, + 16 + ); + await waitFor(() => dbg.toolbox.isHighlighted("jsdebugger")); + ok(true, "Debugger is highlighted when paused"); + + if (isFissionEnabled() || isEveryFrameTargetEnabled()) { + info("Remove the iframe and wait for resume"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + const iframe = content.document.querySelector("iframe"); + iframe.remove(); + }); + await waitForResumed(dbg); + await waitFor(() => !dbg.toolbox.isHighlighted("jsdebugger")); + ok(true, "Debugger is no longer highlighted when resumed"); + + info("Wait for reload to complete after resume"); + await onReloaded; + } +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-inline-cache.js b/devtools/client/debugger/test/mochitest/browser_dbg-inline-cache.js new file mode 100644 index 0000000000..f579ddb1b9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-inline-cache.js @@ -0,0 +1,146 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Test loading inline scripts from cache: + * - Load document with inline script + * - Reload inside debugger with toolbox caching disabled + * - Reload inside debugger with toolbox caching enabled + */ + +"use strict"; + +// Breakpoint position calculations can throw when interrupted by a navigation. +PromiseTestUtils.allowMatchingRejectionsGlobally(/Resource .*? does not exist/); + +const server = createTestHTTPServer(); + +let docValue = 1; +server.registerPathHandler("/inline-cache.html", (request, response) => { + response.setHeader("Content-Type", "text/html"); + // HTTP should assume cacheable by default. + // Toolbox defaults to disabling cache for subsequent loads when open. + response.setHeader("Cache-Control", "public, max-age=3600"); + response.write(` + + + + + + `); +}); + +const SOURCE_URL = `http://localhost:${server.identity.primaryPort}/inline-cache.html`; + +add_task(async function () { + info("Load document with inline script"); + const tab = await addTab(SOURCE_URL); + info("Open debugger"); + clearDebuggerPreferences(); + const toolbox = await openToolboxForTab(tab, "jsdebugger"); + const dbg = createDebuggerContext(toolbox); + await waitForSource(dbg, "inline-cache.html"); + info("Reload tab to ensure debugger finds script"); + await reloadBrowser(); + let pageValue = await getPageValue(tab); + is(pageValue, "let x = 1;", "Content loads from network, has doc value 1"); + await waitForSource(dbg, "inline-cache.html"); + await selectSource(dbg, "inline-cache.html"); + await waitForLoadedSource(dbg, "inline-cache.html"); + let dbgValue = findSourceContent(dbg, "inline-cache.html"); + info(`Debugger text: ${dbgValue.value}`); + ok( + dbgValue.value.includes(pageValue), + "Debugger loads from cache, gets value 1 like page" + ); + + info("Disable HTTP cache for page"); + await toolbox.commands.targetConfigurationCommand.updateConfiguration({ + cacheDisabled: true, + }); + makeChanges(); + + info("Reload inside debugger with toolbox caching disabled (attempt 1)"); + await reloadBrowser(); + pageValue = await getPageValue(tab); + is(pageValue, "let x = 2;", "Content loads from network, has doc value 2"); + await waitForLoadedSource(dbg, "inline-cache.html"); + dbgValue = findSourceContent(dbg, "inline-cache.html"); + + info(`Debugger text: ${dbgValue.value}`); + ok( + dbgValue.value.includes(pageValue), + "Debugger loads from network, gets value 2 like page" + ); + + makeChanges(); + + info("Reload inside debugger with toolbox caching disabled (attempt 2)"); + await reloadBrowser(); + pageValue = await getPageValue(tab); + is(pageValue, "let x = 3;", "Content loads from network, has doc value 3"); + await waitForLoadedSource(dbg, "inline-cache.html"); + dbgValue = findSourceContent(dbg, "inline-cache.html"); + info(`Debugger text: ${dbgValue.value}`); + ok( + dbgValue.value.includes(pageValue), + "Debugger loads from network, gets value 3 like page" + ); + + info("Enable HTTP cache for page"); + await toolbox.commands.targetConfigurationCommand.updateConfiguration({ + cacheDisabled: false, + }); + makeChanges(); + + // Even though the HTTP cache is now enabled, Gecko sets the VALIDATE_ALWAYS flag when + // reloading the page. So, it will always make a request to the server for the main + // document contents. + + info("Reload inside debugger with toolbox caching enabled (attempt 1)"); + await reloadBrowser(); + pageValue = await getPageValue(tab); + is(pageValue, "let x = 4;", "Content loads from network, has doc value 4"); + await waitForLoadedSource(dbg, "inline-cache.html"); + dbgValue = findSourceContent(dbg, "inline-cache.html"); + info(`Debugger text: ${dbgValue.value}`); + ok( + dbgValue.value.includes(pageValue), + "Debugger loads from cache, gets value 4 like page" + ); + + makeChanges(); + + info("Reload inside debugger with toolbox caching enabled (attempt 2)"); + await reloadBrowser(); + pageValue = await getPageValue(tab); + is(pageValue, "let x = 5;", "Content loads from network, has doc value 5"); + await waitForLoadedSource(dbg, "inline-cache.html"); + await waitForSelectedSource(dbg, "inline-cache.html"); + dbgValue = findSourceContent(dbg, "inline-cache.html"); + info(`Debugger text: ${dbgValue.value}`); + ok( + dbgValue.value.includes(pageValue), + "Debugger loads from cache, gets value 5 like page" + ); + + await toolbox.destroy(); + await removeTab(tab); +}); + +/** + * This is meant to simulate the developer editing the inline source and saving. + * Effectively, we change the source during the test at specific controlled points. + */ +function makeChanges() { + docValue++; +} + +function getPageValue(tab) { + return SpecialPowers.spawn(tab.linkedBrowser, [], function () { + return content.document.querySelector("script").textContent.trim(); + }); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-inline-exceptions.js b/devtools/client/debugger/test/mochitest/browser_dbg-inline-exceptions.js new file mode 100644 index 0000000000..a7ae02cb61 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-inline-exceptions.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test checks the appearance of an inline exception +// and the content of the exception tooltip. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-exceptions.html"); + await selectSource(dbg, "exceptions.js"); + + info("Hovers over the inline exception mark text."); + await assertPreviewTextValue(dbg, 85, 10, { + text: 'TypeError: "abc".push is not a function', + }); + await closePreviewAtPos(dbg, 85, 10); + + const excLineEls = findAllElementsWithSelector(dbg, ".line-exception"); + const excTextMarkEls = findAllElementsWithSelector( + dbg, + ".mark-text-exception" + ); + + is(excLineEls.length, 1, "The editor has one exception line"); + is(excTextMarkEls.length, 1, "One token is marked as an exception."); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-inline-preview.js b/devtools/client/debugger/test/mochitest/browser_dbg-inline-preview.js new file mode 100644 index 0000000000..54946f2109 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-inline-preview.js @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test checking inline preview feature + +"use strict"; + +add_task(async function () { + await pushPref("devtools.debugger.features.inline-preview", true); + + const dbg = await initDebugger( + "doc-inline-preview.html", + "inline-preview.js" + ); + await selectSource(dbg, "inline-preview.js"); + + await checkInlinePreview(dbg, "checkValues", [ + { identifier: "a:", value: '""' }, + { identifier: "b:", value: "false" }, + { identifier: "c:", value: "undefined" }, + { identifier: "d:", value: "null" }, + { identifier: "e:", value: "Array []" }, + { identifier: "f:", value: "Object { }" }, + { identifier: "obj:", value: "Object { foo: 1 }" }, + { + identifier: "bs:", + value: "Array(101) [ {…}, {…}, {…}, … ]", + }, + ]); + + await checkInlinePreview(dbg, "columnWise", [ + { identifier: "c:", value: '"c"' }, + { identifier: "a:", value: '"a"' }, + { identifier: "b:", value: '"b"' }, + ]); + + // Check that referencing an object property previews the property, not the + // object (bug 1599917) + await checkInlinePreview(dbg, "objectProperties", [ + { identifier: "obj:", value: 'Object { hello: "world", a: {…} }' }, + { identifier: "obj.hello:", value: '"world"' }, + { identifier: "obj.a.b:", value: '"c"' }, + ]); + + await checkInlinePreview(dbg, "classProperties", [ + { identifier: "i:", value: "2" }, + { identifier: "self:", value: `Object { x: 1, #privateVar: 2 }` }, + ]); + + // Checks that open in inspector button works in inline preview + invokeInTab("btnClick"); + await checkInspectorIcon(dbg); + + const { toolbox } = dbg; + await toolbox.selectTool("jsdebugger"); + + await waitForPaused(dbg); + + // Check preview of event ( event.target should be clickable ) + // onBtnClick function in inline-preview.js + await checkInspectorIcon(dbg); +}); + +async function checkInlinePreview(dbg, fnName, inlinePreviews) { + invokeInTab(fnName); + + await waitForAllElements(dbg, "inlinePreviewLabels", inlinePreviews.length); + + const labels = findAllElements(dbg, "inlinePreviewLabels"); + const values = findAllElements(dbg, "inlinePreviewValues"); + + inlinePreviews.forEach((inlinePreview, index) => { + const { identifier, value } = inlinePreview; + is( + labels[index].innerText, + identifier, + `${identifier} in ${fnName} has correct inline preview label` + ); + is( + values[index].innerText, + value, + `${identifier} in ${fnName} has correct inline preview value` + ); + }); + + await resume(dbg); +} + +async function checkInspectorIcon(dbg) { + await waitForElement(dbg, "inlinePreviewOpenInspector"); + + const { toolbox } = dbg; + const node = findElement(dbg, "inlinePreviewOpenInspector"); + + // Ensure hovering over button highlights the node in content pane + const view = node.ownerDocument.defaultView; + const onNodeHighlight = toolbox.getHighlighter().waitForHighlighterShown(); + + EventUtils.synthesizeMouseAtCenter(node, { type: "mousemove" }, view); + + const { nodeFront } = await onNodeHighlight; + is(nodeFront.displayName, "button", "The correct node was highlighted"); + + // Ensure panel changes when button is clicked + const onInspectorPanelLoad = waitForInspectorPanelChange(dbg); + node.click(); + await onInspectorPanelLoad; + + await resume(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-inline-script-offset.js b/devtools/client/debugger/test/mochitest/browser_dbg-inline-script-offset.js new file mode 100644 index 0000000000..b0473d21e1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-inline-script-offset.js @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that breakpoints work when set in inline scripts that do not start at column 0. + +"use strict"; + +const TEST_PAGE = "doc-inline-script-offset.html"; + +add_task(async function () { + const dbg = await initDebugger(TEST_PAGE); + await selectSource(dbg, TEST_PAGE); + + // Ensure that breakable lines are correct when loading against an already loaded page + await assertBreakableLines(dbg, TEST_PAGE, 16, [ + ...getRange(3, 5), + ...getRange(11, 13), + 15, + ]); + + await reload(dbg, TEST_PAGE); + + // Also verify they are fine after reload + await assertBreakableLines(dbg, TEST_PAGE, 16, [ + ...getRange(3, 5), + ...getRange(11, 13), + 15, + ]); + + await addBreakpoint(dbg, "doc-inline-script-offset.html", 15, 66); + + const onReloaded = reload(dbg); + await waitForPaused(dbg); + ok(true, "paused after reloading at column breakpoint"); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-inspector-integration.js b/devtools/client/debugger/test/mochitest/browser_dbg-inspector-integration.js new file mode 100644 index 0000000000..e9f2464bc6 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-inspector-integration.js @@ -0,0 +1,140 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that clicking the DOM node button in any ObjectInspect +// opens the Inspector panel + +"use strict"; + +add_task(async function () { + // Ensures the end panel is wide enough to show the inspector icon + await pushPref("devtools.debugger.end-panel-size", 600); + // Disable 3-pane inspector as it might trigger unwanted server communication. + await pushPref("devtools.inspector.three-pane-enabled", false); + + const dbg = await initDebugger("doc-script-switching.html"); + const { toolbox } = dbg; + const highlighterTestFront = await getHighlighterTestFront(toolbox); + const highlighter = toolbox.getHighlighter(); + + // Bug 1562165: the WhyPaused element is displayed for a few hundred ms when adding an + // expression, which can break synthesizeMouseAtCenter. So here we wait for the + // whyPaused element to be displayed then hidden before testing the highlight feature. + const onWhyPausedDisplayed = waitUntil(() => + dbg.win.document.querySelector(".why-paused") + ); + await addExpression(dbg, "window.document.querySelector('button')"); + // TODO: Remove when Bug 1562165 lands. + await onWhyPausedDisplayed; + // TODO: Remove when Bug 1562165 lands. + await waitUntil(() => !dbg.win.document.querySelector(".why-paused")); + + info( + "Check that hovering over DOM element highlights the node in content panel" + ); + let onNodeHighlight = highlighter.waitForHighlighterShown(); + + info("Mouseover the open in inspector button"); + const inspectorNode = await waitFor(() => findElement(dbg, "openInspector")); + const view = inspectorNode.ownerDocument.defaultView; + EventUtils.synthesizeMouseAtCenter( + inspectorNode, + { type: "mouseover" }, + view + ); + + info("Wait for highligther to be shown"); + const { nodeFront } = await onNodeHighlight; + is(nodeFront.displayName, "button", "The correct node was highlighted"); + + info("Check that moving the mouse away from the node hides the highlighter"); + let onNodeUnhighlight = highlighter.waitForHighlighterHidden(); + const nonHighlightEl = inspectorNode.closest(".object-node"); + EventUtils.synthesizeMouseAtCenter( + nonHighlightEl, + { type: "mouseover" }, + view + ); + + await onNodeUnhighlight; + isVisible = await highlighterTestFront.isHighlighting(); + is(isVisible, false, "The highlighter is not displayed anymore"); + + info("Check we don't have zombie highlighters when briefly hovering a node"); + onNodeHighlight = highlighter.waitForHighlighterShown(); + onNodeUnhighlight = highlighter.waitForHighlighterHidden(); + + // Move hover the node and then, right after, move out. + EventUtils.synthesizeMouseAtCenter( + inspectorNode, + { type: "mousemove" }, + view + ); + EventUtils.synthesizeMouseAtCenter( + nonHighlightEl, + { type: "mousemove" }, + view + ); + + await Promise.all([onNodeHighlight, onNodeUnhighlight]); + isVisible = await highlighterTestFront.isHighlighting(); + is(isVisible, false, "The highlighter is not displayed anymore - no zombie"); + + info("Ensure panel changes when button is clicked"); + // Loading the inspector panel at first, to make it possible to listen for + // new node selections + const inspector = await toolbox.loadTool("inspector"); + const onInspectorSelected = toolbox.once("inspector-selected"); + const onInspectorUpdated = inspector.once("inspector-updated"); + const onNewNode = toolbox.selection.once("new-node-front"); + + inspectorNode.click(); + + await onInspectorSelected; + await onInspectorUpdated; + const inspectorNodeFront = await onNewNode; + + ok(true, "Inspector selected and new node got selected"); + is( + inspectorNodeFront.displayName, + "button", + "The expected node was selected" + ); +}); + +add_task(async function () { + // Disable 3-pane inspector as it might trigger unwanted server communication. + await pushPref("devtools.inspector.three-pane-enabled", false); + + const dbg = await initDebugger("doc-event-handler.html"); + const { toolbox } = dbg; + + invokeInTab("synthesizeClick"); + await waitForPaused(dbg); + + findElement(dbg, "frame", 2).focus(); + await clickElement(dbg, "frame", 2); + + // Hover over the token to launch preview popup + await tryHovering(dbg, 5, 8, "popup"); + + // Click the first inspector buttom to view node in inspector + await waitForElement(dbg, "openInspector"); + + // Loading the inspector panel at first, to make it possible to listen for + // new node selections + const inspector = await toolbox.loadTool("inspector"); + + const onInspectorSelected = toolbox.once("inspector-selected"); + const onInspectorUpdated = inspector.once("inspector-updated"); + const onNewNode = toolbox.selection.once("new-node-front"); + + findElement(dbg, "openInspector").click(); + + await onInspectorSelected; + await onInspectorUpdated; + await onNewNode; + + ok(true, "Inspector selected and new node got selected"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-compressed-sourcemaps.js b/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-compressed-sourcemaps.js new file mode 100644 index 0000000000..0569d36071 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-compressed-sourcemaps.js @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This runs all integration tests against a test using sources maps + * whose generated files (bundles) are compressed. + * i.e. bundles are made of a unique line with all sources compressed into one line. + */ + +"use strict"; + +requestLongerTimeout(10); + +add_task(async function () { + const testFolder = "sourcemaps-reload-compressed"; + const isCompressed = true; + + await runAllIntegrationTests(testFolder, { + isCompressed, + }); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-uncompressed-sourcemaps.js b/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-uncompressed-sourcemaps.js new file mode 100644 index 0000000000..df07f0dc43 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-integration-reloading-uncompressed-sourcemaps.js @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This runs all integration tests against a test using sources maps + * whose generated files (bundles) are uncompressed. + * i.e. bundles are keeping the same format as original files. + */ + +"use strict"; + +requestLongerTimeout(10); + +add_task(async function () { + const testFolder = "sourcemaps-reload-uncompressed"; + const isCompressed = false; + + await runAllIntegrationTests(testFolder, { + isCompressed, + }); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-javascript-tracer.js b/devtools/client/debugger/test/mochitest/browser_dbg-javascript-tracer.js new file mode 100644 index 0000000000..535321aa37 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-javascript-tracer.js @@ -0,0 +1,226 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the Javascript Tracing feature. + +"use strict"; + +add_task(async function () { + // This is preffed off for now, so ensure turning it on + await pushPref("devtools.debugger.features.javascript-tracing", true); + + const dbg = await initDebugger("doc-scripts.html"); + + info("Enable the tracing"); + await clickElement(dbg, "trace"); + + const topLevelThread = + dbg.toolbox.commands.targetCommand.targetFront.threadFront.actorID; + info("Wait for tracing to be enabled"); + await waitForState(dbg, state => { + return dbg.selectors.getIsThreadCurrentlyTracing(topLevelThread); + }); + + ok( + dbg.toolbox.splitConsole, + "Split console is automatically opened when tracing to the console" + ); + + invokeInTab("main"); + + info("Wait for console messages for the whole trace"); + // `main` calls `foo` which calls `bar` + await hasConsoleMessage(dbg, "λ main"); + await hasConsoleMessage(dbg, "λ foo"); + await hasConsoleMessage(dbg, "λ bar"); + + const traceMessages = await findConsoleMessages(dbg.toolbox, "λ main"); + is(traceMessages.length, 1, "We got a unique trace for 'main' function call"); + const sourceLink = traceMessages[0].querySelector(".frame-link-source"); + sourceLink.click(); + info("Wait for the main function to be highlighted in the debugger"); + await waitForSelectedSource(dbg, "simple1.js"); + await waitForSelectedLocation(dbg, 1, 16); + + // Test Blackboxing + info("Clear the console from previous traces"); + const { hud } = await dbg.toolbox.getPanel("webconsole"); + hud.ui.clearOutput(); + await waitFor( + async () => !(await findConsoleMessages(dbg.toolbox, "λ main")).length, + "Wait for console to be cleared" + ); + + info( + "Now blackbox only the source where main function is (simple1.js), but foo and bar are in another module" + ); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + + info("Trigger some code from simple1 and simple2"); + invokeInTab("main"); + + info("Only methods from simple2 are logged"); + await hasConsoleMessage(dbg, "λ foo"); + await hasConsoleMessage(dbg, "λ bar"); + is( + (await findConsoleMessages(dbg.toolbox, "λ main")).length, + 0, + "Traces from simple1.js, related to main function are not logged" + ); + + info("Revert blackboxing"); + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"); + + // Test Disabling tracing + info("Disable the tracing"); + await clickElement(dbg, "trace"); + info("Wait for tracing to be disabled"); + await waitForState(dbg, state => { + return !dbg.selectors.getIsThreadCurrentlyTracing(topLevelThread); + }); + + invokeInTab("inline_script2"); + + // Let some time for the tracer to appear if we failed disabling the tracing + await wait(1000); + + const messages = await findConsoleMessages(dbg.toolbox, "inline_script2"); + is( + messages.length, + 0, + "We stopped recording traces, an the function call isn't logged in the console" + ); + + // Test Navigations + await navigate(dbg, "doc-sourcemaps2.html", "main.js", "main.min.js"); + + info("Re-enable the tracing after navigation"); + await clickElement(dbg, "trace"); + + const newTopLevelThread = + dbg.toolbox.commands.targetCommand.targetFront.threadFront.actorID; + info("Wait for tracing to be re-enabled"); + await waitForState(dbg, state => { + return dbg.selectors.getIsThreadCurrentlyTracing(newTopLevelThread); + }); + + invokeInTab("logMessage"); + + await hasConsoleMessage(dbg, "λ logMessage"); + + const traceMessages2 = await findConsoleMessages(dbg.toolbox, "λ logMessage"); + is( + traceMessages2.length, + 1, + "We got a unique trace for 'logMessage' function call" + ); + const sourceLink2 = traceMessages2[0].querySelector(".frame-link-source"); + sourceLink2.click(); + + info("Wait for the 'logMessage' function to be highlighted in the debugger"); + await waitForSelectedSource(dbg, "main.js"); + await waitForSelectedLocation(dbg, 4, 2); + ok(true, "The selected source and location is on the original file"); +}); + +add_task(async function testPersitentLogMethod() { + let dbg = await initDebugger("doc-scripts.html"); + is( + dbg.selectors.getJavascriptTracingLogMethod(), + "console", + "By default traces are logged to the console" + ); + + info("Change the log method to stdout"); + dbg.actions.setJavascriptTracingLogMethod("stdout"); + + await dbg.toolbox.closeToolbox(); + + dbg = await initDebugger("doc-scripts.html"); + is( + dbg.selectors.getJavascriptTracingLogMethod(), + "stdout", + "The new setting has been persisted" + ); + + info("Reset back to the default value"); + dbg.actions.setJavascriptTracingLogMethod("console"); +}); + +add_task(async function testPageKeyShortcut() { + // Ensures that the key shortcut emitted in the content process bubbles up to the parent process + await pushPref("test.events.async.enabled", true); + + // Fake DevTools being opened by a real user interaction. + // Tests are bypassing DevToolsStartup to open the tools by calling gDevTools directly. + // By doing so DevToolsStartup considers itself as uninitialized, + // whereas we want it to handle the key shortcut we trigger in this test. + const DevToolsStartup = Cc["@mozilla.org/devtools/startup-clh;1"].getService( + Ci.nsISupports + ).wrappedJSObject; + DevToolsStartup.initialized = true; + registerCleanupFunction(() => { + DevToolsStartup.initialized = false; + }); + + const dbg = await initDebugger("data:text/html,key-shortcut"); + + const topLevelThread = + dbg.toolbox.commands.targetCommand.targetFront.threadFront.actorID; + ok( + !dbg.selectors.getIsThreadCurrentlyTracing(topLevelThread), + "Tracing is disabled on debugger opening" + ); + + info( + "Focus the page in order to assert that the page keeps the focus when enabling the tracer" + ); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + content.focus(); + }); + await waitFor( + () => Services.focus.focusedElement == gBrowser.selectedBrowser + ); + is( + Services.focus.focusedElement, + gBrowser.selectedBrowser, + "The tab is still focused before enabling tracing" + ); + + info("Toggle ON the tracing via the key shortcut from the web page"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + EventUtils.synthesizeKey( + "VK_5", + { ctrlKey: true, shiftKey: true }, + content + ); + }); + + info("Wait for tracing to be enabled"); + await waitForState(dbg, state => { + return dbg.selectors.getIsThreadCurrentlyTracing(topLevelThread); + }); + + is( + Services.focus.focusedElement, + gBrowser.selectedBrowser, + "The tab is still focused after enabling tracing" + ); + + info("Toggle it back off, wit the same shortcut"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + EventUtils.synthesizeKey( + "VK_5", + { ctrlKey: true, shiftKey: true }, + content + ); + }); + + info("Wait for tracing to be disabled"); + await waitForState(dbg, state => { + return !dbg.selectors.getIsThreadCurrentlyTracing(topLevelThread); + }); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-navigation.js b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-navigation.js new file mode 100644 index 0000000000..21d911a2cd --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-navigation.js @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that keyboard navigation into and out of debugger code editor + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple2.js"); + const doc = dbg.win.document; + + await selectSource(dbg, "simple2.js"); + + await waitForElementWithSelector(dbg, ".CodeMirror"); + findElementWithSelector(dbg, ".CodeMirror").focus(); + + // Enter code editor + pressKey(dbg, "Enter"); + is( + findElementWithSelector(dbg, "textarea"), + doc.activeElement, + "Editor is enabled" + ); + + // Exit code editor and focus on container + pressKey(dbg, "Escape"); + is( + findElementWithSelector(dbg, ".CodeMirror"), + doc.activeElement, + "Focused on container" + ); + + // Enter code editor + pressKey(dbg, "Tab"); + is( + findElementWithSelector(dbg, "textarea"), + doc.activeElement, + "Editor is enabled" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts-modal.js b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts-modal.js new file mode 100644 index 0000000000..d293d3d56f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts-modal.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test the keyboard shortcuts modal + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL( + "data:text/html,Test keyboard shortcuts modal" + ); + + ok(!getShortcutsModal(dbg), "The shortcuts modal is hidden by default"); + + info("Open the modal with the shortcut"); + pressKeyboardShortcut(dbg); + + const el = await waitFor(() => getShortcutsModal(dbg)); + const sections = [...el.querySelectorAll(".shortcuts-section h2")].map( + h2 => h2.textContent + ); + is( + JSON.stringify(sections), + JSON.stringify(["Editor", "Stepping", "Search"]), + "The modal has the expected sections" + ); + + info("Close the modal with the shortcut"); + pressKeyboardShortcut(dbg); + await waitFor(() => !getShortcutsModal(dbg)); + ok(true, "The modal was closed"); +}); + +function getShortcutsModal(dbg) { + return findElementWithSelector(dbg, ".shortcuts-modal"); +} + +function pressKeyboardShortcut(dbg) { + EventUtils.synthesizeKey( + "/", + { + [Services.appinfo.OS === "Darwin" ? "metaKey" : "ctrlKey"]: true, + }, + dbg.win + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts.js b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts.js new file mode 100644 index 0000000000..67fa1d397e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-keyboard-shortcuts.js @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test keyboard shortcuts. + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-debugger-statements.html"); + + const onReloaded = reload(dbg); + await waitForPaused(dbg); + await waitForLoadedSource(dbg, "doc-debugger-statements.html"); + const source = findSource(dbg, "doc-debugger-statements.html"); + assertPausedAtSourceAndLine(dbg, source.id, 11); + + await pressResume(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 16); + + await pressStepOver(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 17); + + await pressStepIn(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 22); + + await pressStepOut(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 18); + + await pressStepOver(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 18); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; +}); + +function pressResume(dbg) { + pressKey(dbg, "resumeKey"); + return waitForPaused(dbg); +} + +function pressStepOver(dbg) { + pressKey(dbg, "stepOverKey"); + return waitForPaused(dbg); +} + +function pressStepIn(dbg) { + pressKey(dbg, "stepInKey"); + return waitForPaused(dbg); +} + +function pressStepOut(dbg) { + pressKey(dbg, "stepOutKey"); + return waitForPaused(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-layout-changes.js b/devtools/client/debugger/test/mochitest/browser_dbg-layout-changes.js new file mode 100644 index 0000000000..609879c7b1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-layout-changes.js @@ -0,0 +1,94 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * This if the debugger's layout is correctly modified when the toolbox's + * host changes. + */ + +"use strict"; + +requestLongerTimeout(2); + +let gDefaultHostType = Services.prefs.getCharPref("devtools.toolbox.host"); + +add_setup(async function () { + // Disable window occlusion. See bug 1733955 / bug 1779559. + if (navigator.platform.indexOf("Win") == 0) { + await SpecialPowers.pushPrefEnv({ + set: [["widget.windows.window_occlusion_tracking.enabled", false]], + }); + } +}); + +add_task(async function () { + // test is too slow on some platforms due to the number of test cases + const dbg = await initDebugger("doc-iframes.html"); + + const layouts = [ + ["vertical", "window:small"], + ["horizontal", "bottom"], + ["vertical", "right"], + ["horizontal", "window:big"], + ]; + + for (const layout of layouts) { + const [orientation, host] = layout; + await testLayout(dbg, orientation, host); + } + + ok(true, "Orientations are correct"); +}); + +async function testLayout(dbg, orientation, host) { + info(`Switching to ${host} ${orientation}.`); + + await switchHost(dbg, host); + await resizeToolboxWindow(dbg, host); + return waitForState( + dbg, + state => dbg.selectors.getOrientation() == orientation + ); +} + +function getHost(host) { + if (host.indexOf("window") == 0) { + return "window"; + } + return host; +} + +async function switchHost(dbg, hostType) { + const { toolbox } = dbg; + await toolbox.switchHost(getHost(hostType)); +} + +function resizeToolboxWindow(dbg, host) { + const { toolbox } = dbg; + const sizeOption = host.split(":")[1]; + if (!sizeOption) { + return; + } + + const win = toolbox.win.parent; + + let breakpoint = 800; + if (sizeOption == "big" && win.outerWidth <= breakpoint) { + breakpoint += 300; + } else if (sizeOption == "small" && win.outerWidth >= breakpoint) { + breakpoint -= 300; + } + resizeWindow(dbg, breakpoint); +} + +function resizeWindow(dbg, width) { + const { toolbox } = dbg; + const win = toolbox.win.parent; + win.resizeTo(width, window.screen.availHeight); +} + +registerCleanupFunction(function () { + Services.prefs.setCharPref("devtools.toolbox.host", gDefaultHostType); + gDefaultHostType = null; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js b/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js new file mode 100644 index 0000000000..c374fc6bba --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-link-reload.js @@ -0,0 +1,65 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Test reload via an href link, which refers to the same document. + * It seems to cause different codepath compared to F5. + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-reload-link.html", + "doc-reload-link.html" + ); + + info("Add a breakpoint that will be hit on reload"); + await addBreakpoint(dbg, "doc-reload-link.html", 3); + + for (let i = 0; i < 5; i++) { + const onReloaded = waitForReload(dbg.commands); + + info( + "Reload via a link, this causes special race condition different from F5" + ); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + const reloadLink = content.document.querySelector("a"); + reloadLink.click(); + }); + + info("Wait for paused\n"); + await waitForPaused(dbg); + + info("Check paused location\n"); + const source = findSource(dbg, "doc-reload-link.html"); + assertPausedAtSourceAndLine(dbg, source.id, 3); + + await resume(dbg); + + info("Wait for completion of the page load"); + // This help ensure that the page loaded correctly and prevent pending request at teardown + await onReloaded; + } +}); + +async function waitForReload(commands) { + let resolve; + const onReloaded = new Promise(r => (resolve = r)); + const { resourceCommand } = commands; + const { DOCUMENT_EVENT } = resourceCommand.TYPES; + const onAvailable = resources => { + if (resources.find(resource => resource.name == "dom-complete")) { + resourceCommand.unwatchResources([DOCUMENT_EVENT], { onAvailable }); + resolve(); + } + }; + // Wait for watchResources completion before reloading, otherwise we might miss the dom-complete event + // if watchResources is still pending while the reload already started and finished loading the document early. + await resourceCommand.watchResources([DOCUMENT_EVENT], { + onAvailable, + ignoreExistingResources: true, + }); + return onReloaded; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js new file mode 100644 index 0000000000..6ce0acbc77 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-events.js @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Tests that we can log event listeners calls + */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + const dbg = await initDebugger( + "doc-event-breakpoints.html", + "event-breakpoints.js" + ); + + await clickElement(dbg, "logEventsCheckbox"); + await dbg.actions.addEventListenerBreakpoints(["event.mouse.click"]); + clickElementInTab("#click-target"); + + await hasConsoleMessage(dbg, "click"); + await waitForRequestsToSettle(dbg); + ok(true); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js new file mode 100644 index 0000000000..f061bbbbc5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-point-mapping.js @@ -0,0 +1,44 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Tests that expressions in log points are source mapped. + */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + + const dbg = await initDebugger("doc-sourcemaps3.html", "test.js"); + dbg.actions.toggleMapScopes(); + + const source = findSource(dbg, "test.js"); + await selectSource(dbg, "test.js"); + + await getDebuggerSplitConsole(dbg); + + await addBreakpoint(dbg, "test.js", 6); + await waitForBreakpoint(dbg, "test.js", 6); + + await dbg.actions.addBreakpoint( + getContext(dbg), + createLocation({ line: 5, source }), + { logValue: "`value: ${JSON.stringify(test)}`", requiresMapping: true } + ); + await waitForBreakpoint(dbg, "test.js", 5); + + invokeInTab("test"); + + await waitForPaused(dbg); + + await hasConsoleMessage(dbg, "value:"); + const { value } = await findConsoleMessage(dbg, "value:"); + is( + value, + 'value: ["b (30)","a","b (5)","z"]', + "Variables in logpoint expression should be mapped" + ); + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js new file mode 100644 index 0000000000..aa52904d31 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-points-workers.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Tests that log points in a worker are correctly logged to the console + */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + + const dbg = await initDebugger("doc-windowless-workers.html"); + + await waitForSource(dbg, "simple-worker.js"); + await selectSource(dbg, "simple-worker.js"); + + await altClickElement(dbg, "gutter", 4); + await waitForBreakpoint(dbg, "simple-worker.js", 4); + + await getDebuggerSplitConsole(dbg); + await hasConsoleMessage(dbg, "timer"); + const { link } = await findConsoleMessage(dbg, "timer"); + is( + link, + "simple-worker.js:4:9", + "message should include the url and linenumber" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js b/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js new file mode 100644 index 0000000000..a025b58dab --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-log-points.js @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Tests that log points are correctly logged to the console + */ + +"use strict"; + +add_task(async function () { + Services.prefs.setBoolPref("devtools.toolbox.splitconsoleEnabled", true); + const dbg = await initDebugger( + "doc-script-switching.html", + "script-switching-01.js" + ); + + const source = findSource(dbg, "script-switching-01.js"); + await selectSource(dbg, "script-switching-01.js"); + + await getDebuggerSplitConsole(dbg); + + await altClickElement(dbg, "gutter", 7); + await waitForBreakpoint(dbg, "script-switching-01.js", 7); + + await dbg.actions.addBreakpoint( + getContext(dbg), + createLocation({ line: 8, source }), + { logValue: "'a', 'b', 'c'" } + ); + + invokeInTab("firstCall"); + await waitForPaused(dbg); + + await hasConsoleMessage(dbg, "a b c"); + await hasConsoleMessage(dbg, "firstCall"); + + const { link, value } = await findConsoleMessage(dbg, "a b c"); + is(link, "script-switching-01.js:8:2", "logs should have the relevant link"); + is(value, "a b c", "logs should have multiple values"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-many-breakpoints-same-line.js b/devtools/client/debugger/test/mochitest/browser_dbg-many-breakpoints-same-line.js new file mode 100644 index 0000000000..d6d1fc30c7 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-many-breakpoints-same-line.js @@ -0,0 +1,93 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test settings multiple types of breakpoints on the same line +// Only the last should be used + +"use strict"; + +// Line where we set a breakpoint in simple2.js +const BREAKPOINT_LINE = 5; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple2.js"); + + await selectSource(dbg, "simple2.js"); + await waitForSelectedSource(dbg, "simple2.js"); + + await testSimpleAndLog(dbg); + + await testLogUpdates(dbg); +}); + +async function testSimpleAndLog(dbg) { + info("Add a simple breakpoint"); + await addBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE); + + info("Add a log breakpoint, replacing the breakpoint into a logpoint"); + await setLogPoint(dbg, BREAKPOINT_LINE, "`log point ${x}`"); + await waitForLog(dbg, "`log point ${x}`"); + await assertLogBreakpoint(dbg, BREAKPOINT_LINE); + + const bp = findBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE); + is( + bp.options.logValue, + "`log point ${x}`", + "log breakpoint value is correct" + ); + + info( + "Eval foo() and trigger the breakpoints. If this freeze here, it means that the log point has been ignored." + ); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.wrappedJSObject.foo(42); + }); + + info( + "Wait for the log-point message. Only log-point breakpoint should work." + ); + + await waitForMessageByType(dbg, "log point 42", ".logPoint"); + + const source = findSource(dbg, "simple2.js"); + await removeBreakpoint(dbg, source.id, BREAKPOINT_LINE); +} + +async function testLogUpdates(dbg) { + info("Add a log breakpoint"); + await setLogPoint(dbg, BREAKPOINT_LINE, "`log point`"); + await waitForLog(dbg, "`log point`"); + await assertLogBreakpoint(dbg, BREAKPOINT_LINE); + + const bp = findBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE); + is(bp.options.logValue, "`log point`", "log breakpoint value is correct"); + + info("Edit the log breakpoint"); + await setLogPoint(dbg, BREAKPOINT_LINE, " + ` edited`"); + await waitForLog(dbg, "`log point` + ` edited`"); + await assertLogBreakpoint(dbg, BREAKPOINT_LINE); + + const bp2 = findBreakpoint(dbg, "simple2.js", BREAKPOINT_LINE); + is( + bp2.options.logValue, + "`log point` + ` edited`", + "log breakpoint value is correct" + ); + + info("Eval foo() and trigger the breakpoints"); + await SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.wrappedJSObject.foo(); + }); + + info("Wait for the log-point message. Only the edited one should appear"); + await waitForMessageByType(dbg, "log point edited", ".logPoint"); +} + +async function waitForMessageByType(dbg, msg, typeSelector) { + const webConsolePanel = await getDebuggerSplitConsole(dbg); + const hud = webConsolePanel.hud; + return waitFor( + async () => !!findMessagesByType(hud, msg, typeSelector).length + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-merge-scopes.js b/devtools/client/debugger/test/mochitest/browser_dbg-merge-scopes.js new file mode 100644 index 0000000000..7bed9fc9ea --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-merge-scopes.js @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that adjacent scopes are merged together as expected. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-merge-scopes.html"); + + invokeInTab("run"); + await waitForPaused(dbg, "doc-merge-scopes.html"); + + // Function body and function lexical scopes are merged together. + expectLabels(dbg, ["first", "", "arguments", "x", "y", "z"]); + + await resume(dbg); + await waitForPaused(dbg); + + // Function body and inner lexical scopes are not merged together. + await toggleScopeNode(dbg, 4); + expectLabels(dbg, ["Block", "", "y", "second", "arguments", "x"]); + + await resume(dbg); + await waitForPaused(dbg); + + // When there is a function body, function lexical, and inner lexical scope, + // the first two are merged together. + await toggleScopeNode(dbg, 4); + expectLabels(dbg, [ + "Block", + "", + "z", + "third", + "arguments", + "v", + "x", + "y", + ]); +}); + +function getLabel(dbg, index) { + return findElement(dbg, "scopeNode", index).innerText; +} + +function expectLabels(dbg, array) { + for (let i = 0; i < array.length; i++) { + is( + getLabel(dbg, i + 1), + array[i], + `Correct label ${array[i]} for index ${i + 1}` + ); + } +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-message-run-to-completion.js b/devtools/client/debugger/test/mochitest/browser_dbg-message-run-to-completion.js new file mode 100644 index 0000000000..a168c9233d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-message-run-to-completion.js @@ -0,0 +1,24 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that messages from postMessage calls are not delivered while paused in +// the debugger. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-message-run-to-completion.html"); + invokeInTab("test", "doc-message-run-to-completion.html"); + await waitForPaused(dbg); + let result = await dbg.client.evaluate("event.data"); + is(result.result, "first", "first message delivered in order"); + await resume(dbg); + await waitForPaused(dbg); + result = await dbg.client.evaluate("event.data"); + is(result.result, "second", "second message delivered in order"); + await resume(dbg); + await waitForPaused(dbg); + result = await dbg.client.evaluate("event.data"); + is(result.result, "third", "third message delivered in order"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-minified.js b/devtools/client/debugger/test/mochitest/browser_dbg-minified.js new file mode 100644 index 0000000000..8086dbbf46 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-minified.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests minfied + source maps. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-minified2.html", "sum.js"); + dbg.actions.toggleMapScopes(); + + await selectSource(dbg, "sum.js"); + await addBreakpoint(dbg, "sum.js", 2); + + invokeInTab("test"); + await waitForPaused(dbg); + + is(getScopeNodeLabel(dbg, 1), "sum", "check scope label"); + is(getScopeNodeLabel(dbg, 2), "first", "check scope label"); + is(getScopeNodeValue(dbg, 2), "40", "check scope value"); + is(getScopeNodeLabel(dbg, 3), "second", "check scope label"); + is(getScopeNodeValue(dbg, 3), "2", "check scope value"); + is(getScopeNodeLabel(dbg, 4), "Window", "check scope label"); +}); + +function getScopeNodeLabel(dbg, index) { + return findElement(dbg, "scopeNode", index).innerText; +} + +function getScopeNodeValue(dbg, index) { + return findElement(dbg, "scopeValue", index).innerText; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-navigation-when-paused.js b/devtools/client/debugger/test/mochitest/browser_dbg-navigation-when-paused.js new file mode 100644 index 0000000000..9af7228527 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-navigation-when-paused.js @@ -0,0 +1,42 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-navigation-when-paused.html"); + + await togglePauseOnExceptions(dbg, true, true); + + clickElementInTab("body"); + + await waitForPaused(dbg, "doc-navigation-when-paused.html"); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-navigation-when-paused.html").id, + 12 + ); + + await navigate( + dbg, + "doc-navigation-when-paused.html", + "doc-navigation-when-paused.html" + ); + + clickElementInTab("body"); + + await waitForPaused(dbg, "doc-navigation-when-paused.html"); + + // If breakpoints aren't properly ignored after navigation, this could + // potentially pause at line 9. This helper also ensures that the file + // source itself has loaded, which may not be the case if navigation cleared + // the source and nothing has sent it to the devtools client yet, as was + // the case in Bug 1581530. + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-navigation-when-paused.html").id, + 12 + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js b/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js new file mode 100644 index 0000000000..6cf5c0ec5f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-navigation.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +const SOURCES = [ + "simple1.js", + "simple2.js", + "simple3.js", + "long.js", + "doc-scripts.html", +]; + +/** + * Test navigating + * navigating while paused will reset the pause state and sources + */ +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + const { + selectors: { getSelectedSource, getIsPaused, getCurrentThread }, + } = dbg; + ok(getCurrentThread(), "We get a thread selected on debugger opening"); + + info("Pause in the first document"); + invokeInTab("firstCall"); + await waitForPaused(dbg); + + info("Navigate while being paused in the first document"); + await navigate(dbg, "doc-scripts.html", "simple1.js"); + ok( + getCurrentThread(), + "The new top level thread is selected after navigation" + ); + + info("Set a breakpoint on the second document and pause on it"); + await selectSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 4); + invokeInTab("main"); + await waitForPaused(dbg); + const source = findSource(dbg, "simple1.js"); + assertPausedAtSourceAndLine(dbg, source.id, 4); + is(countSources(dbg), 5, "5 sources are loaded."); + + await waitForRequestsToSettle(dbg); + let onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + await navigate(dbg, "doc-scripts.html", ...SOURCES); + await onBreakpoint; + is(countSources(dbg), 5, "5 sources are loaded."); + ok(!getIsPaused(getCurrentThread()), "Is not paused"); + + await waitForRequestsToSettle(dbg); + onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + await navigate(dbg, "doc-scripts.html", ...SOURCES); + await onBreakpoint; + is(countSources(dbg), 5, "5 sources are loaded."); + + info("Test that the current selected source persists across reloads"); + await selectSource(dbg, "long.js"); + + await waitForRequestsToSettle(dbg); + onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + await reload(dbg, "long.js"); + await onBreakpoint; + await waitForSelectedSource(dbg, "long.js"); + + ok(getSelectedSource().url.includes("long.js"), "Selected source is long.js"); +}); + +function countSources(dbg) { + return dbg.selectors.getSourceCount(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-no-duplicate-breakpoints-on-frame-reload.js b/devtools/client/debugger/test/mochitest/browser_dbg-no-duplicate-breakpoints-on-frame-reload.js new file mode 100644 index 0000000000..97d4eeb273 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-no-duplicate-breakpoints-on-frame-reload.js @@ -0,0 +1,101 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This tests makes sure that on reload of a remote iframe, there +// are no duplicated breakpoints. The test case relates to a specific +// issue in Bug 1728587 +"use strict"; + +add_task(async function () { + // With fission and EFT disabled all the sources are going to be under the Main Thread + // and this sceanrio becomes irrelevant + if (!isFissionEnabled() && !isEveryFrameTargetEnabled()) { + return; + } + + const dbg = await initDebugger( + "doc_dbg-fission-frame-sources.html", + "simple2.js" + ); + + info( + "Open a tab for a source in the top document to assert it doesn't disappear" + ); + await selectSource(dbg, "simple1.js"); + + info("Add breakpoint to the source (simple2.js) in the remote frame"); + await selectSource(dbg, "simple2.js"); + await addBreakpoint(dbg, "simple2.js", 3); + + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + + const source = findSource(dbg, "simple2.js"); + assertBreakpointsList(dbg, source); + + is( + countTabs(dbg), + 2, + "We see the tabs for the sources of both top and iframe documents" + ); + + const onBreakpointSet = waitForDispatch(dbg.store, "SET_BREAKPOINT"); + + info("reload the iframe"); + const iframeBrowsingContext = await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + function () { + const iframe = content.document.querySelector("iframe"); + return iframe.browsingContext; + } + ); + await SpecialPowers.spawn(iframeBrowsingContext, [], () => { + content.location.reload(); + }); + + await onBreakpointSet; + + await waitForSelectedSource(dbg, "simple2.js"); + + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint still exists"); + + const sourceAfterReload = findSource(dbg, "simple2.js"); + assertBreakpointsList(dbg, sourceAfterReload); + + is(countTabs(dbg), 2, "We still see the tabs for the two sources"); + + await removeBreakpoint(dbg, sourceAfterReload.id, 3); +}); + +function assertBreakpointsList(dbg, source) { + const breakpointHeadings = findAllElements(dbg, "breakpointHeadings"); + const breakpointItems = findAllElements(dbg, "breakpointItems"); + + is( + breakpointHeadings.length, + 1, + "The breakpoint list show one breakpoint source" + ); + is( + breakpointItems.length, + 1, + "The breakpoint list shows only one breakpoint" + ); + + is( + breakpointHeadings[0].title, + source.url, + "The info displayed for the breakpoint tooltip of the 1st breakpoint is correct" + ); + is( + breakpointHeadings[0].textContent, + "simple2.js", + "The info displayed for the breakpoint heading of the 1st breakpoint is correct" + ); + is( + breakpointItems[0].textContent, + "return x + y;3:4", + "The info displayed for the 1st breakpoint is correct" + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-old-breakpoint.js b/devtools/client/debugger/test/mochitest/browser_dbg-old-breakpoint.js new file mode 100644 index 0000000000..ad8ee830b0 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-old-breakpoint.js @@ -0,0 +1,111 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that we show a breakpoint in the UI when there is an old pending +// breakpoint with an invalid original location. + +"use strict"; + +add_task(async function () { + clearDebuggerPreferences(); + + const pending = { + bp1: { + location: { + sourceId: "", + sourceUrl: `${EXAMPLE_URL}nowhere2.js`, + line: 5, + column: 0, + }, + generatedLocation: { + sourceUrl: `${EXAMPLE_URL}simple1.js`, + line: 4, + column: 0, + }, + options: {}, + disabled: false, + }, + bp2: { + location: { + sourceId: "", + sourceUrl: `${EXAMPLE_URL}nowhere.js`, + line: 5, + column: 0, + }, + generatedLocation: { + sourceUrl: `${EXAMPLE_URL}simple3.js`, + line: 2, + column: 0, + }, + options: {}, + disabled: false, + }, + }; + asyncStorage.setItem("debugger.pending-breakpoints", pending); + + const toolbox = await openNewTabAndToolbox( + `${EXAMPLE_URL}doc-scripts.html`, + "jsdebugger" + ); + const dbg = createDebuggerContext(toolbox); + const onBreakpoint = waitForDispatch(dbg.store, "SET_BREAKPOINT", 2); + + // Pending breakpoints are installed asynchronously, keep invoking the entry + // function until the debugger pauses. + await waitUntil(() => { + invokeInTab("main"); + return isPaused(dbg); + }); + await onBreakpoint; + + ok(true, "paused at unmapped breakpoint"); + await waitForState( + dbg, + state => dbg.selectors.getBreakpointCount(state) == 2 + ); + ok(true, "unmapped breakpoints shown in UI"); +}); + +// Test that if we show a breakpoint with an old generated location, it is +// removed after we load the original source and find the new generated +// location. +add_task(async function () { + clearDebuggerPreferences(); + + const pending = { + bp1: { + location: { + sourceId: "", + sourceUrl: "webpack:///entry.js", + line: 15, + column: 0, + }, + generatedLocation: { + sourceUrl: `${EXAMPLE_URL}sourcemaps/bundle.js`, + line: 47, + column: 16, + }, + options: {}, + disabled: false, + }, + }; + asyncStorage.setItem("debugger.pending-breakpoints", pending); + + const toolbox = await openNewTabAndToolbox( + `${EXAMPLE_URL}doc-sourcemaps.html`, + "jsdebugger" + ); + const dbg = createDebuggerContext(toolbox); + + await waitForState(dbg, state => { + const bps = dbg.selectors.getBreakpointsList(state); + return ( + bps.length == 1 && + bps[0].location.sourceUrl.includes("entry.js") && + bps[0].location.line == 15 + ); + }); + ok(true, "removed old breakpoint during sync"); + await waitForRequestsToSettle(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-outline-filter.js b/devtools/client/debugger/test/mochitest/browser_dbg-outline-filter.js new file mode 100644 index 0000000000..3ce605311c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-outline-filter.js @@ -0,0 +1,82 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the outline pane fuzzy filtering of outline items + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "long.js"); + await selectSource(dbg, "long.js", 1); + findElementWithSelector(dbg, ".outline-tab").click(); + + // turn off alphetical sort if active + const alphabetizeButton = findElementWithSelector( + dbg, + ".outline-footer button" + ); + if (alphabetizeButton.className === "active") { + alphabetizeButton.click(); + } + + const outlineFilter = findElementWithSelector(dbg, ".outline-filter-input"); + ok(outlineFilter, "Outline filter is present"); + + outlineFilter.blur(); + ok( + !findElementWithSelector(dbg, ".outline-filter-input.focused"), + "does not have class focused when not focused" + ); + + outlineFilter.focus(); + ok( + findElementWithSelector(dbg, ".outline-filter-input.focused"), + "has class focused when focused" + ); + + is(getItems(dbg).length, 9, "9 items in the unfiltered list"); + + // filter all items starting with t + type(dbg, "t"); + is(getItems(dbg).length, 4, "4 items in the list after 't' filter"); + ok(getItems(dbg)[0].textContent.includes("TodoModel(key)"), "item TodoModel"); + ok( + getItems(dbg)[1].textContent.includes("toggleAll(checked)"), + "item toggleAll" + ); + ok( + getItems(dbg)[2].textContent.includes("toggle(todoToToggle)"), + "item toggle" + ); + ok(getItems(dbg)[3].textContent.includes("testModel()"), "item testModel"); + + // filter using term 'tog' + type(dbg, "og"); + is(getItems(dbg).length, 2, "2 items in the list after 'tog' filter"); + ok( + getItems(dbg)[0].textContent.includes("toggleAll(checked)"), + "item toggleAll" + ); + ok( + getItems(dbg)[1].textContent.includes("toggle(todoToToggle)"), + "item toggle" + ); + + pressKey(dbg, "Escape"); + is(getItems(dbg).length, 9, "9 items in the list after escape pressed"); + + // Ensure no action is taken when Enter key is pressed + pressKey(dbg, "Enter"); + is(getItems(dbg).length, 9, "9 items in the list after enter pressed"); + + // check that the term 'todo' includes items with todo + type(dbg, "todo"); + is(getItems(dbg).length, 2, "2 items in the list after 'todo' filter"); + ok(getItems(dbg)[0].textContent.includes("TodoModel(key)"), "item TodoModel"); + ok(getItems(dbg)[1].textContent.includes("addTodo(title)"), "item addTodo"); +}); + +function getItems(dbg) { + return findAllElements(dbg, "outlineItems"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-outline-focus.js b/devtools/client/debugger/test/mochitest/browser_dbg-outline-focus.js new file mode 100644 index 0000000000..f04a28b732 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-outline-focus.js @@ -0,0 +1,39 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that after clicking a function in edtior, outline focuses that function + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-sources.html", "long.js"); + + await selectSource(dbg, "long.js", 1); + findElementWithSelector(dbg, ".outline-tab").click(); + is(getItems(dbg).length, 9, "9 items in the outline list"); + + info("Clicking inside a function in editor should focus the outline"); + clickAtPos(dbg, { line: 15, ch: 2 }); + await waitForElementWithSelector(dbg, ".outline-list__element.focused"); + ok( + getFocusedFunction(dbg).includes("addTodo"), + "The right function is focused" + ); + + info("Clicking an empty line in the editor should unfocus the outline"); + await clickAtPos(dbg, { line: 13, ch: 2 }); + is(getFocusedNode(dbg), null, "should not exist"); +}); + +function getItems(dbg) { + return findAllElements(dbg, "outlineItems"); +} + +function getFocusedNode(dbg) { + return findElementWithSelector(dbg, ".outline-list__element.focused"); +} + +function getFocusedFunction(dbg) { + return getFocusedNode(dbg).innerText; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-outline-pretty.js b/devtools/client/debugger/test/mochitest/browser_dbg-outline-pretty.js new file mode 100644 index 0000000000..ca0d5c65c4 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-outline-pretty.js @@ -0,0 +1,30 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the length of outline functions for original and pretty printed source matches + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + + await selectSource(dbg, "simple1.js"); + findElementWithSelector(dbg, ".outline-tab").click(); + const originalSource = getItems(dbg); + + clickElement(dbg, "prettyPrintButton"); + await waitForLoadedSource(dbg, "simple1.js:formatted"); + await waitForElementWithSelector(dbg, ".outline-list"); + const prettySource = getItems(dbg); + + is( + originalSource.length, + prettySource.length, + "Length of outline functions for both prettyPrint and originalSource same" + ); +}); + +function getItems(dbg) { + return findAllElements(dbg, "outlineItems"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-outline.js b/devtools/client/debugger/test/mochitest/browser_dbg-outline.js new file mode 100644 index 0000000000..825fdc1508 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-outline.js @@ -0,0 +1,89 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that clicking a function in outline panel, the editor highlights the correct location. +// Tests that outline panel can sort functions alphabetically. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + + await selectSource(dbg, "simple1.js", 1); + + findElementWithSelector(dbg, ".outline-tab").click(); + + assertOutlineItems(dbg, [ + "λmain()", + "λdoEval()", + "λevaledFunc()", + "λdoNamedEval()", + // evaledFunc is set twice + "λevaledFunc()", + "class MyClass", + "λconstructor(a, b)", + "λtest()", + "λ#privateFunc(a, b)", + "class Klass", + "λconstructor()", + "λtest()", + ]); + + info("Click an item in outline panel"); + const item = getNthItem(dbg, 3); + item.click(); + await waitForLoadedSource(dbg, "simple1.js"); + assertHighlightLocation(dbg, "simple1.js", 15); + ok( + item.parentNode.classList.contains("focused"), + "The clicked item li is focused" + ); + + info("Sort the list"); + findElementWithSelector(dbg, ".outline-footer button").click(); + // Button becomes active to show alphabetization + is( + findElementWithSelector(dbg, ".outline-footer button").className, + "active", + "Alphabetize button is highlighted when active" + ); + + info("Check that the list was sorted as expected"); + assertOutlineItems(dbg, [ + "λdoEval()", + "λdoNamedEval()", + // evaledFunc is set twice + "λevaledFunc()", + "λevaledFunc()", + "λmain()", + "class Klass", + "λconstructor()", + "λtest()", + "class MyClass", + "λ#privateFunc(a, b)", + "λconstructor(a, b)", + "λtest()", + ]); +}); + +function assertOutlineItems(dbg, expectedItems) { + SimpleTest.isDeeply( + getItems(dbg).map(i => i.innerText.trim()), + expectedItems, + "The expected items are displayed in the outline panel" + ); +} + +function getItems(dbg) { + return Array.from( + findAllElementsWithSelector( + dbg, + ".outline-list h2, .outline-list .outline-list__element" + ) + ); +} + +function getNthItem(dbg, index) { + return findElement(dbg, "outlineItem", index); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-overrides.js b/devtools/client/debugger/test/mochitest/browser_dbg-overrides.js new file mode 100644 index 0000000000..136a11c497 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-overrides.js @@ -0,0 +1,128 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/** + * Testing the script overrides feature + */ + +"use strict"; + +const httpServer = createTestHTTPServer(); +const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`; + +httpServer.registerContentType("html", "text/html"); +httpServer.registerContentType("js", "application/javascript"); + +const testSourceContent = `function foo() { + console.log("original test script"); +}`; + +const testOverrideSourceContent = `function foo() { + console.log("overriden test script"); +} +foo(); +`; + +httpServer.registerPathHandler("/index.html", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + + + + + `); +}); + +httpServer.registerPathHandler("/test.js", (request, response) => { + response.setHeader("Content-Type", "application/javascript"); + response.write(testSourceContent); +}); + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL( + BASE_URL + "index.html", + "test.js" + ); + + await waitForSourcesInSourceTree(dbg, ["test.js"], { + noExpand: false, + }); + + info("Load and assert the content of the test.js script"); + await selectSourceFromSourceTree( + dbg, + "test.js", + 3, + "Select the `test.js` script for the tree" + ); + is( + getCM(dbg).getValue(), + testSourceContent, + "The test.js is the original source content" + ); + + info("Add a breakpoint"); + await addBreakpoint(dbg, "test.js", 2); + + info("Select test.js tree node, and add override"); + const MockFilePicker = SpecialPowers.MockFilePicker; + MockFilePicker.init(window); + const nsiFile = FileUtils.getFile("TmpD", [`test.js`]); + MockFilePicker.setFiles([nsiFile]); + const path = nsiFile.path; + + await triggerSourceTreeContextMenu( + dbg, + findSourceNodeWithText(dbg, "test.js"), + "#node-menu-overrides" + ); + + info("Wait for `test.js` to be saved to disk and re-write it"); + await BrowserTestUtils.waitForCondition(() => IOUtils.exists(path)); + await BrowserTestUtils.waitForCondition(async () => { + const { size } = await IOUtils.stat(path); + return size > 0; + }); + + await IOUtils.write( + path, + new TextEncoder().encode(testOverrideSourceContent) + ); + + info("Reload and assert `test.js` pause and it overriden source content"); + const onReloaded = reload(dbg, "test.js"); + await waitForPaused(dbg); + + assertPausedAtSourceAndLine(dbg, findSource(dbg, "test.js").id, 2); + is( + getCM(dbg).getValue(), + testOverrideSourceContent, + "The test.js is the overridden source content" + ); + + await resume(dbg); + await onReloaded; + + info("Remove override and test"); + const removed = waitForDispatch(dbg.store, "REMOVE_OVERRIDE"); + await triggerSourceTreeContextMenu( + dbg, + findSourceNodeWithText(dbg, "test.js"), + "#node-menu-overrides" + ); + await removed; + + info("Reload and assert `test.js`'s original source content"); + await reload(dbg, "test.js"); + await waitForSelectedSource(dbg, "test.js"); + + is( + getCM(dbg).getValue(), + testSourceContent, + "The test.js is the original source content" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pause-exceptions.js b/devtools/client/debugger/test/mochitest/browser_dbg-pause-exceptions.js new file mode 100644 index 0000000000..eeebb1be3d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pause-exceptions.js @@ -0,0 +1,139 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + Tests Pausing on exception + 1. skip an uncaught exception + 2. pause on an uncaught exception + 3. pause on a caught error + 4. skip a caught error +*/ + +"use strict"; + +const { PromiseTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PromiseTestUtils.sys.mjs" +); +// This is step 9 +PromiseTestUtils.allowMatchingRejectionsGlobally(/doesntExists is not defined/); + +add_task(async function () { + const dbg = await initDebugger("doc-exceptions.html", "exceptions.js"); + const source = findSource(dbg, "exceptions.js"); + + info("1. test skipping an uncaught exception"); + await uncaughtException(); + assertNotPaused(dbg); + + info("2. Test pausing on an uncaught exception"); + await togglePauseOnExceptions(dbg, true, true); + uncaughtException(); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + + const whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is(whyPaused, `Paused on exception\nunreachable`); + + await resume(dbg); + + info("2.b Test throwing the same uncaught exception pauses again"); + await togglePauseOnExceptions(dbg, true, true); + uncaughtException(); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 2); + await resume(dbg); + + info("3. Test pausing on a caught Error"); + caughtException(); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 7); + + info("3.b Test pausing in the catch statement"); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 9); + await resume(dbg); + + info("4. Test skipping a caught error"); + await togglePauseOnExceptions(dbg, true, false); + caughtException(); + + info("4.b Test pausing in the catch statement"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 9); + await resume(dbg); + + await togglePauseOnExceptions(dbg, true, true); + + info("5. Only pause once when throwing deep in the stack"); + invokeInTab("deepError"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 16); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 22); + await resume(dbg); + + info("6. Only pause once on an exception when pausing in a finally block"); + invokeInTab("deepErrorFinally"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 34); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 31); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 40); + await resume(dbg); + + info("7. Only pause once on an exception when it is rethrown from a catch"); + invokeInTab("deepErrorCatch"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 53); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 49); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 59); + await resume(dbg); + + info("8. Pause on each exception thrown while unwinding"); + invokeInTab("deepErrorThrowDifferent"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 71); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 68); + await resume(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, source.id, 77); + await resume(dbg); + + info("9. Pause in throwing new Function argument"); + const onNewSource = waitForDispatch(dbg.store, "ADD_SOURCES"); + invokeInTab("throwInNewFunctionArgument"); + await waitForPaused(dbg); + const { sources } = await onNewSource; + is(sources.length, 1, "Got a unique source related to new Function source"); + const newFunctionSource = sources[0]; + is( + newFunctionSource.url, + null, + "This new source looks like the new function one as it has no url" + ); + assertPausedAtSourceAndLine(dbg, newFunctionSource.id, 1, 0); + assertTextContentOnLine(dbg, 1, "function anonymous(f=doesntExists()"); + await resume(dbg); +}); + +function uncaughtException() { + return invokeInTab("uncaughtException").catch(() => {}); +} + +function caughtException() { + return invokeInTab("caughtException"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pause-on-next.js b/devtools/client/debugger/test/mochitest/browser_dbg-pause-on-next.js new file mode 100644 index 0000000000..27ae30983f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pause-on-next.js @@ -0,0 +1,21 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that when pause on next is selected, we pause on the next execution + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + const { + selectors: { getIsWaitingOnBreak, getCurrentThread }, + } = dbg; + + clickElement(dbg, "pause"); + await waitForState(dbg, state => getIsWaitingOnBreak(getCurrentThread())); + invokeInTab("simple"); + + await waitForPaused(dbg, "simple3"); + assertPaused(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pause-points.js b/devtools/client/debugger/test/mochitest/browser_dbg-pause-points.js new file mode 100644 index 0000000000..4ebfe08f15 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pause-points.js @@ -0,0 +1,97 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +requestLongerTimeout(2); + +async function testCase(dbg, { name, steps }) { + info(` ### Execute testCase "${name}"`); + + const { + selectors: { getTopFrame, getCurrentThread }, + } = dbg; + const locations = []; + + const recordFrame = state => { + const { line, column } = getTopFrame(getCurrentThread()).location; + locations.push([line, column]); + info(`Break on ${line}:${column}`); + }; + + info("Trigger the expected debugger statement"); + const onPaused = waitForPaused(dbg); + invokeInTab(name); + await onPaused; + recordFrame(); + + info("Start stepping over"); + for (let i = 0; i < steps.length - 1; i++) { + await dbg.actions.stepOver(getThreadContext(dbg)); + await waitForPaused(dbg); + recordFrame(); + } + + is(formatSteps(locations), formatSteps(steps), name); + + await resume(dbg); +} + +add_task(async function test() { + const dbg = await initDebugger("doc-pause-points.html", "pause-points.js"); + + await selectSource(dbg, "pause-points.js"); + await testCase(dbg, { + name: "statements", + steps: [ + [9, 2], + [10, 4], + [10, 13], + [11, 2], + [11, 21], + [12, 2], + [12, 12], + [13, 0], + ], + }); + + await testCase(dbg, { + name: "expressions", + steps: [ + [40, 2], + [41, 2], + [42, 12], + [43, 0], + ], + }); + + await testCase(dbg, { + name: "sequences", + steps: [ + [23, 2], + [25, 12], + [29, 12], + [34, 2], + [37, 0], + ], + }); + + await testCase(dbg, { + name: "flow", + steps: [ + [16, 2], + [17, 12], + [18, 10], + [19, 8], + [19, 17], + [19, 8], + [19, 17], + [19, 8], + ], + }); +}); + +function formatSteps(steps) { + return steps.map(loc => `(${loc.join(",")})`).join(", "); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pause-ux.js b/devtools/client/debugger/test/mochitest/browser_dbg-pause-ux.js new file mode 100644 index 0000000000..a8ca4b74bf --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pause-ux.js @@ -0,0 +1,52 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + + // Make sure that we can set a breakpoint on a line out of the + // viewport, and that pausing there scrolls the editor to it. + const longSrc = findSource(dbg, "long.js"); + await selectSource(dbg, "long.js"); + await addBreakpoint(dbg, longSrc, 66); + invokeInTab("testModel"); + await waitForPaused(dbg, "long.js"); + + const pauseScrollTop = getScrollTop(dbg); + + info("1. adding a breakpoint should not scroll the editor"); + getCM(dbg).scrollTo(0, 0); + await addBreakpoint(dbg, longSrc, 11); + is(getScrollTop(dbg), 0, "scroll position"); + + info("2. searching should jump to the match"); + pressKey(dbg, "fileSearch"); + type(dbg, "check"); + + const cm = getCM(dbg); + await waitFor( + () => cm.getSelection() == "check", + "Wait for actual selection in CodeMirror" + ); + is( + cm.getCursor().line, + 26, + "The line of first check occurence in long.js is selected (this is zero-based)" + ); + // The column is the end of "check", so after 'k' + is( + cm.getCursor().ch, + 51, + "The column of first check occurence in long.js is selected (this is zero-based)" + ); + + const matchScrollTop = getScrollTop(dbg); + ok(pauseScrollTop != matchScrollTop, "did not jump to debug line"); +}); + +function getScrollTop(dbg) { + return getCM(dbg).doc.scrollTop; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-iframe.js b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-iframe.js new file mode 100644 index 0000000000..5f8bcd972c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-iframe.js @@ -0,0 +1,76 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the paused overlay in a remote frame + +"use strict"; + +const TEST_COM_URI = `${URL_ROOT_COM_SSL}examples/doc_dbg-fission-frame-sources.html`; + +add_task(async function () { + info("Load a test page with a remote frame"); + // simple1.js is imported by the main page. simple2.js comes from the remote frame. + const dbg = await initDebuggerWithAbsoluteURL( + TEST_COM_URI, + "simple1.js", + "simple2.js" + ); + const { + selectors: { getSelectedSource }, + commands, + } = dbg; + + info("Add breakpoint within the iframe, in `foo` function"); + await selectSource(dbg, "simple2.js"); + await addBreakpoint(dbg, "simple2.js", 5); + + info("Call `foo` in the iframe"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + const iframe = content.document.querySelector("iframe"); + SpecialPowers.spawn(iframe, [], () => { + return content.wrappedJSObject.foo(); + }); + }); + await waitForPaused(dbg); + ok(true, "debugger is paused"); + + let highlighterTestFront; + if (isFissionEnabled() || isEveryFrameTargetEnabled()) { + // We need to retrieve the highlighterTestFront for the frame target. + const iframeTarget = commands.targetCommand + .getAllTargets([commands.targetCommand.TYPES.FRAME]) + .find(target => target.url.includes("example.org")); + highlighterTestFront = await iframeTarget.getFront("highlighterTest"); + } else { + // When fission is disabled, we don't have a dedicated target for the remote frame. + // In this case, the overlay is displayed by the top-level target anyway, so we can + // get the corresponding highlighter test front. + highlighterTestFront = await getHighlighterTestFront(dbg.toolbox); + } + + info("Check that the paused overlay is displayed"); + await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible()); + ok(true, "Paused debugger overlay is visible"); + + ok( + getSelectedSource().url.includes("simple2.js"), + "Selected source is simple2.js" + ); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "simple2.js").id, 5); + + info("Test clicking the resume button"); + await highlighterTestFront.clickPausedDebuggerOverlayButton( + "paused-dbg-resume-button" + ); + + await waitForResumed(dbg); + ok("The debugger isn't paused after clicking on the resume button"); + + await waitFor(async () => { + const visible = await highlighterTestFront.isPausedDebuggerOverlayVisible(); + return !visible; + }); + + ok(true, "The overlay is now hidden"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-loading.js b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-loading.js new file mode 100644 index 0000000000..0601a66a9c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay-loading.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that the paused overlay isn't visible after resuming if the debugger paused +// while the DOM was still loading (Bug 1678636). + +"use strict"; + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL( + "data:text/html," + ); + + info("Reload the page to hit the debugger statement while loading"); + const onReloaded = reload(dbg); + await waitForPaused(dbg); + ok(true, "We're paused"); + + info("Check that the paused overlay is displayed"); + const highlighterTestFront = await dbg.toolbox.target.getFront( + "highlighterTest" + ); + + await waitFor(async () => { + const visible = await highlighterTestFront.isPausedDebuggerOverlayVisible(); + return visible; + }); + ok(true, "Paused debugger overlay is visible"); + + info("Click the resume button"); + await highlighterTestFront.clickPausedDebuggerOverlayButton( + "paused-dbg-resume-button" + ); + + await waitForResumed(dbg); + ok("The debugger isn't paused after clicking on the resume button"); + + await waitFor(async () => { + const visible = await highlighterTestFront.isPausedDebuggerOverlayVisible(); + return !visible; + }); + + ok(true, "The overlay is now hidden"); + + info("Wait for reload to complete after resume"); + await onReloaded; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay.js b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay.js new file mode 100644 index 0000000000..1d442c5ca5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-paused-overlay.js @@ -0,0 +1,73 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the paused overlay + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + + // Sanity check + const highlighterTestFront = await getHighlighterTestFront(dbg.toolbox); + let isPausedOverlayVisible = + await highlighterTestFront.isPausedDebuggerOverlayVisible(); + is( + isPausedOverlayVisible, + false, + "The pause overlay is not visible in the beginning" + ); + + info("Create an eval script that pauses itself."); + invokeInTab("doEval"); + await waitForPaused(dbg); + + info("Check that the paused overlay is displayed"); + await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible()); + ok(true, "Paused debugger overlay is visible"); + + const pauseLine = getVisibleSelectedFrameLine(dbg); + is(pauseLine, 2, "We're paused at the expected location"); + + info("Test clicking the step over button"); + await highlighterTestFront.clickPausedDebuggerOverlayButton( + "paused-dbg-step-button" + ); + await waitFor(() => isPaused(dbg) && getVisibleSelectedFrameLine(dbg) === 4); + ok(true, "We're paused at the expected location after stepping"); + + isPausedOverlayVisible = + await highlighterTestFront.isPausedDebuggerOverlayVisible(); + is(isPausedOverlayVisible, true, "The pause overlay is still visible"); + + info("Test clicking the highlighter resume button"); + await highlighterTestFront.clickPausedDebuggerOverlayButton( + "paused-dbg-resume-button" + ); + + await waitForResumed(dbg); + ok("The debugger isn't paused after clicking on the resume button"); + + await waitFor(async () => { + const visible = await highlighterTestFront.isPausedDebuggerOverlayVisible(); + return !visible; + }); + ok(true, "The overlay is now hidden"); + + info( + "Check that the highlighter is removed when clicking on the debugger resume button" + ); + invokeInTab("doEval"); + await waitFor(() => highlighterTestFront.isPausedDebuggerOverlayVisible()); + ok(true, "Paused debugger overlay is visible again"); + + info("Click debugger UI resume button"); + const resumeButton = await waitFor(() => findElement(dbg, "resume")); + resumeButton.click(); + await waitFor(async () => { + const visible = await highlighterTestFront.isPausedDebuggerOverlayVisible(); + return !visible; + }); + ok(true, "The overlay is hidden after clicking on the resume button"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-columns.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-columns.js new file mode 100644 index 0000000000..e5dcfc4f4c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-columns.js @@ -0,0 +1,119 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that breakpoints set in the pretty printed files display and paused +// correctly. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + await prettyPrint(dbg); + + info( + "Add breakpoint in funcWithMultipleBreakableColumns, on the for-loop line" + ); + const LINE_INDEX_TO_BREAK_ON = 15; + const prettySourceFileName = "pretty.js:formatted"; + await addBreakpoint(dbg, prettySourceFileName, LINE_INDEX_TO_BREAK_ON); + const prettySource = findSource(dbg, prettySourceFileName); + + info("Check that multiple column breakpoints can be set"); + const columnBreakpointMarkers = await waitForAllElements( + dbg, + "columnBreakpoints" + ); + /* + * We're pausing on the following line, which should have those breakpoints (marked with ➤) + * + * for( ➤let i=0; ➤i < items.length; ➤i++ ) { + * + */ + is( + columnBreakpointMarkers.length, + 3, + "We have the expected numbers of possible column breakpoints" + ); + + info("Enable the second column breakpoint"); + columnBreakpointMarkers[1].click(); + await waitForBreakpointCount(dbg, 2); + await waitForAllElements(dbg, "breakpointItems", 2); + + info("Check that we do pause at expected locations"); + invokeInTab("funcWithMultipleBreakableColumns"); + + info("We pause on the first column breakpoint (before `i` init)"); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + await assertPausedAtSourceAndLine( + dbg, + prettySource.id, + LINE_INDEX_TO_BREAK_ON, + 15 + ); + await resume(dbg); + + info( + "We pause at the second column breakpoint, before the first loop iteration" + ); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + await assertPausedAtSourceAndLine( + dbg, + prettySource.id, + LINE_INDEX_TO_BREAK_ON, + 18 + ); + const assertScopesForSecondColumnBreakpoint = topBlockItems => + assertScopes(dbg, [ + "Block", + ["", "Window"], + ...topBlockItems, + "funcWithMultipleBreakableColumns", + ["arguments", "Arguments"], + ["items", "(2) […]"], + ]); + await assertScopesForSecondColumnBreakpoint([["i", "0"]]); + await resume(dbg); + + info( + "We pause at the second column breakpoint, before the second loop iteration" + ); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + await assertPausedAtSourceAndLine( + dbg, + prettySource.id, + LINE_INDEX_TO_BREAK_ON, + 18 + ); + await assertScopesForSecondColumnBreakpoint([["i", "1"]]); + await resume(dbg); + + info( + "We pause at the second column breakpoint, before we exit the loop (`items.length` is 2, so the condition will fail)" + ); + await waitForPaused(dbg); + await waitForInlinePreviews(dbg); + await assertPausedAtSourceAndLine( + dbg, + prettySource.id, + LINE_INDEX_TO_BREAK_ON, + 18 + ); + await assertScopesForSecondColumnBreakpoint([["i", "2"]]); + await resume(dbg); + + info("Remove all breakpoints"); + await clickGutter(dbg, LINE_INDEX_TO_BREAK_ON); + await waitForBreakpointCount(dbg, 0); + + ok( + !findAllElements(dbg, "columnBreakpoints").length, + "There is no column breakpoints anymore after clicking on the gutter" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-delete.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-delete.js new file mode 100644 index 0000000000..38798f2b50 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints-delete.js @@ -0,0 +1,113 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that breakpoints in pretty printed files +// are properly removed when the user deletes them on either the generated or original files. + +"use strict"; + +add_task(async function () { + info( + "Test removing the breakpoint from the minified file (generated source) works" + ); + + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + + await prettyPrint(dbg); + + await addBreakpointToPrettyPrintedFile(dbg); + + info( + `Close the pretty-printed source, so it is not automatically reopened on reload` + ); + await closeTab(dbg, "pretty.js:formatted"); + + await waitForSelectedSource(dbg, "pretty.js"); + + info( + "Assert that a equivalent breakpoint was set in pretty.js (generated source)" + ); + await assertBreakpoint(dbg, 4); + + info(`Remove the breakpoint from pretty.js (generated source)`); + await clickGutter(dbg, 4); + + await waitForBreakpointCount(dbg, 0); + + await reloadAndCheckNoBreakpointExists(dbg); +}); + +add_task(async function () { + info( + "Test removing the breakpoint from the pretty printed (original source) works" + ); + + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + + await prettyPrint(dbg); + + await addBreakpointToPrettyPrintedFile(dbg); + + info("Check that breakpoint gets added to pretty.js (generated source)"); + await selectSource(dbg, "pretty.js"); + await assertBreakpoint(dbg, 4); + + info("Close the pretty.js (generated source)"); + await closeTab(dbg, "pretty.js"); + + await waitForSelectedSource(dbg, "pretty.js:formatted"); + + info(`Remove the breakpoint from pretty.js:formatted (original source)`); + await clickGutter(dbg, 5); + + await waitForBreakpointCount(dbg, 0); + + info( + `Close the pretty-printed source, so it is not automatically reopened on reload` + ); + await closeTab(dbg, "pretty.js:formatted"); + + await reloadAndCheckNoBreakpointExists(dbg); +}); + +async function addBreakpointToPrettyPrintedFile(dbg) { + // This breakpoint would be set before the debugger statement + // and should be hit first. + info("Add breakpoint to pretty.js:formatted (original source)"); + await addBreakpoint(dbg, "pretty.js:formatted", 5); + await waitForBreakpointCount(dbg, 1); +} + +async function reloadAndCheckNoBreakpointExists(dbg) { + info("Reload and pretty print pretty.js"); + await reload(dbg, "pretty.js"); + await selectSource(dbg, "pretty.js"); + await prettyPrint(dbg); + info("Check that we do not pause on the removed breakpoint"); + invokeInTab("stuff"); + await waitForPaused(dbg); + + const sourcePretty = findSource(dbg, "pretty.js:formatted"); + info( + "Assert pause at the debugger statement in pretty.js:formatted (original source) and not the removed breakpoint" + ); + assertPausedAtSourceAndLine(dbg, sourcePretty.id, 8); + + await selectSource(dbg, "pretty.js"); + const source = findSource(dbg, "pretty.js"); + + info( + "Assert pause at the debugger statement in pretty.js (generated source) and not the removed breakpoint" + ); + assertPausedAtSourceAndLine(dbg, source.id, 6); + + info(`Confirm that pretty.js:formatted does not have any breakpoints`); + is(dbg.selectors.getBreakpointCount(), 0, "Breakpoints should be cleared"); + + await resume(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints.js new file mode 100644 index 0000000000..1c25d3e0c8 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-breakpoints.js @@ -0,0 +1,126 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that breakpoints set in the pretty printed files display and paused +// correctly. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + await prettyPrint(dbg); + + await addBreakpoint(dbg, "pretty.js:formatted", 5); + + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint is created"); + + invokeInTab("stuff"); + await waitForPaused(dbg); + + await assertBreakpointsInNonPrettyAndPrettySources(dbg); + + is( + dbg.selectors.getBreakpointCount(), + 1, + "Only one breakpoint still exists after pause " + ); + + await resume(dbg); + + info("Wait for another pause because of a debugger statement on line 8"); + await waitForPaused(dbg); + + await resume(dbg); + assertNotPaused(dbg); + + await closeTab(dbg, "pretty.js"); + await closeTab(dbg, "pretty.js:formatted"); +}); + +// Tests that breakpoints appear and work when you reload a page +// with pretty-printed files. +add_task(async function () { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + await prettyPrint(dbg); + + await addBreakpoint(dbg, "pretty.js:formatted", 5); + + info("Check that equivalent breakpoint to pretty.js (generated source)"); + await selectSource(dbg, "pretty.js"); + await assertBreakpoint(dbg, 4); + + await selectSource(dbg, "pretty.js:formatted"); + + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint exists"); + + await reload(dbg, "pretty.js", "pretty.js:formatted"); + + await waitForSelectedSource(dbg, "pretty.js:formatted"); + + invokeInTab("stuff"); + await waitForPaused(dbg); + + await assertBreakpointsInNonPrettyAndPrettySources(dbg); + + is( + dbg.selectors.getBreakpointCount(), + 1, + "Only one breakpoint still exists after reload and pause " + ); +}); + +// Test that breakpoints appear and work when set in the minified source +add_task(async function () { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await selectSource(dbg, "pretty.js"); + + info("Add breakpoint to pretty.js (generated source)"); + await addBreakpoint(dbg, "pretty.js", 4, 7); + + await prettyPrint(dbg); + + info( + "Check that equivalent breakpoint is added to pretty.js:formatted (original source)" + ); + await selectSource(dbg, "pretty.js:formatted"); + await assertBreakpoint(dbg, 5); + + is(dbg.selectors.getBreakpointCount(), 1, "Only one breakpoint created"); + + await reload(dbg, "pretty.js", "pretty.js:formatted"); + + await waitForSelectedSource(dbg, "pretty.js:formatted"); + + invokeInTab("stuff"); + await waitForPaused(dbg); + + await assertBreakpointsInNonPrettyAndPrettySources(dbg); + + is( + dbg.selectors.getBreakpointCount(), + 1, + "Only one breakpoint still exists after reload and pause " + ); +}); + +async function assertBreakpointsInNonPrettyAndPrettySources(dbg) { + info( + "Asserts breakpoint pause and display on the correct line in the pretty printed source" + ); + const prettyPrintedSource = findSource(dbg, "pretty.js:formatted"); + await assertPausedAtSourceAndLine(dbg, prettyPrintedSource.id, 5); + await assertBreakpoint(dbg, 5); + + await selectSource(dbg, "pretty.js"); + + info("Assert pause and display on the correct line in the minified source"); + const minifiedSource = findSource(dbg, "pretty.js"); + await assertPausedAtSourceAndLine(dbg, minifiedSource.id, 4, 7); + await assertBreakpoint(dbg, 4); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-console.js new file mode 100644 index 0000000000..e6aa266b26 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-console.js @@ -0,0 +1,66 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// The test has a lot of interactions between debugger and console panels which +// might take more than 30s to complete on a slow machine. + +"use strict"; + +requestLongerTimeout(2); + +// Tests that pretty-printing updates console messages. +add_task(async function () { + const dbg = await initDebugger("doc-minified.html"); + invokeInTab("arithmetic"); + + info("Switch to console and check message"); + const minifiedLink = await waitForConsoleLink( + dbg, + "arithmetic", + "math.min.js:3:73" + ); + + info("Click on the link to open the debugger"); + minifiedLink.click(); + await waitForSelectedSource(dbg, "math.min.js"); + await waitForSelectedLocation(dbg, 3); + + info("Click on pretty print button and wait for the file to be formatted"); + clickElement(dbg, "prettyPrintButton"); + await waitForSelectedSource(dbg, "math.min.js:formatted"); + + info("Switch back to console and check message"); + const formattedLink = await waitForConsoleLink( + dbg, + "arithmetic", + "math.min.js:formatted:31:24" + ); + ok(true, "Message location was updated as expected"); + + info( + "Click on the link again and check the debugger opens in formatted file" + ); + formattedLink.click(); + await selectSource(dbg, "math.min.js:formatted"); + await waitForSelectedLocation(dbg, 31); +}); + +async function waitForConsoleLink(dbg, messageText, linkText) { + const { toolbox } = dbg; + await toolbox.selectTool("webconsole"); + + return waitFor(async () => { + // Wait until the message updates. + const [message] = await findConsoleMessages(toolbox, messageText); + if (!message) { + return false; + } + const linkEl = message.querySelector(".frame-link-source"); + if (!linkEl) { + return false; + } + + return linkEl.textContent == linkText ? linkEl : false; + }); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-flow.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-flow.js new file mode 100644 index 0000000000..eb8db0b25e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-flow.js @@ -0,0 +1,78 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that loader and new tab appear when pretty printing, +// and the selected location is mapped afterwards + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { + const scriptEl = content.document.createElement("script"); + scriptEl.innerText = `(function callInPretty() { debugger; funcWithMultipleBreakableColumns() })()`; + content.document.body.append(scriptEl); + }); + + await waitForPaused(dbg); + const scriptSource = dbg.selectors.getSelectedSource(); + + info( + "Step-in to navigate to pretty.js `funcWithMultipleBreakableColumns` function" + ); + await stepOver(dbg); + await stepIn(dbg); + await waitForSelectedSource(dbg, "pretty.js"); + await waitForSelectedLocation(dbg, 9); + + is( + countTabs(dbg), + 2, + "Two tabs are opened, one for the dynamically inserted script and one for minified pretty.js" + ); + is( + dbg.selectors.getSourceCount(), + 2, + "There are 2 sources before pretty printing" + ); + await prettyPrint(dbg); + + info("Wait for the pretty printed source to be selected on a different line"); + await waitForSelectedLocation(dbg, 11); + + is(countTabs(dbg), 3, "A new tab was opened for the prettified source"); + is( + dbg.selectors.getSourceCount(), + 3, + "There are three sources after pretty printing" + ); + + info("Navigate to previous frame in call stack"); + clickElement(dbg, "frame", 2); + await waitForSelectedSource(dbg, scriptSource); + + info("Navigate back to `funcWithMultipleBreakableColumns` frame"); + clickElement(dbg, "frame", 1); + await waitForSelectedLocation(dbg, 11); + await waitForSelectedSource(dbg, "pretty.js:formatted"); + ok(true, "pretty-printed source was selected"); + + await resume(dbg); + + info("Re select the minified version"); + await selectSource(dbg, "pretty.js", 4, 8); + info("Re toggle pretty print from the minified source"); + await prettyPrint(dbg); + is(countTabs(dbg), 3, "There are stil three tabs"); + info( + "Wait for re-selecting the mapped location in the pretty printed source" + ); + await waitForSelectedLocation(dbg, 5); + is( + dbg.selectors.getSourceCount(), + 3, + "There are still 3 sources after retrying to pretty print the same source" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-inline-scripts.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-inline-scripts.js new file mode 100644 index 0000000000..2b263ad0a9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-inline-scripts.js @@ -0,0 +1,256 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests pretty-printing of HTML file and its inner scripts. + +"use strict"; + +const TEST_FILENAME = `doc-pretty-print-inline-scripts.html`; +const PRETTY_PRINTED_FILENAME = `${TEST_FILENAME}:formatted`; + +const BREAKABLE_LINE_HINT_CHAR = `➤`; + +// Import helpers for the inspector +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js", + this +); + +add_task(async function () { + const dbg = await initDebugger(TEST_FILENAME); + + await selectSource(dbg, TEST_FILENAME); + clickElement(dbg, "prettyPrintButton"); + + await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME); + const prettyPrintedSource = findSourceContent(dbg, PRETTY_PRINTED_FILENAME); + + ok(prettyPrintedSource, "Pretty-printed source exists"); + + info("Check that the HTML file was pretty-printed as expected"); + const expectedPrettyHtml = getExpectedPrettyPrintedHtml(); + is( + prettyPrintedSource.value, + // ➤ is used to indicate breakable lines, we remove them to assert the actual + // content of the editor. + expectedPrettyHtml.replaceAll(BREAKABLE_LINE_HINT_CHAR, ""), + "HTML file is pretty printed as expected" + ); + + info("Check breakable lines"); + const htmlLines = expectedPrettyHtml.split("\n"); + const expectedBreakableLines = []; + htmlLines.forEach((line, index) => { + if (line.startsWith(BREAKABLE_LINE_HINT_CHAR)) { + // Lines in the debugger are 1-based + expectedBreakableLines.push(index + 1); + } + }); + + await assertBreakableLines( + dbg, + PRETTY_PRINTED_FILENAME, + htmlLines.length, + expectedBreakableLines + ); + + info("Check that console messages are pointing to pretty-printed file"); + const { toolbox } = dbg; + await toolbox.selectTool("webconsole"); + + const { hud } = await dbg.toolbox.getPanel("webconsole"); + info("Wait until messages are sourcemapped"); + await waitFor( + () => !!findMessageByType(hud, PRETTY_PRINTED_FILENAME, ".log") + ); + + const firstMessage = await waitFor(() => + findMessageByType(hud, "User information", ".log") + ); + const firstMessageLink = firstMessage.querySelector(".frame-link-source"); + is( + firstMessageLink.innerText, + `${PRETTY_PRINTED_FILENAME}:18:8`, + "first console message has expected location" + ); + info( + "Click on the link of the first message to open the file in the debugger" + ); + firstMessageLink.click(); + await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME); + ok(true, "pretty printed file was selected in debugger…"); + await waitForSelectedLocation(dbg, 18); + ok(true, "…at the expected location"); + + info("Go back to the console to check an other message"); + await toolbox.selectTool("webconsole"); + + const secondMessage = await waitFor(() => + findMessageByType(hud, "42 yay", ".log") + ); + const secondMessageLink = secondMessage.querySelector(".frame-link-source"); + is( + secondMessageLink.innerText, + `${PRETTY_PRINTED_FILENAME}:41:12`, + "second console message has expected location" + ); + info( + "Click on the link of the second message to open the file in the debugger" + ); + secondMessageLink.click(); + await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME); + ok(true, "pretty printed file was selected in debugger…"); + await waitForSelectedLocation(dbg, 41); + ok(true, "…at the expected location"); + + info("Check that event listener popup is pointing to pretty-printed file"); + const inspector = await toolbox.selectTool("inspector"); + + const nodeFront = await getNodeFront("h1", inspector); + const markupContainer = inspector.markup.getContainer(nodeFront); + const evHolder = markupContainer.elt.querySelector( + ".inspector-badge.interactive[data-event]" + ); + const eventTooltip = inspector.markup.eventDetailsTooltip; + + info("Open event tooltip."); + EventUtils.synthesizeMouseAtCenter( + evHolder, + {}, + inspector.markup.doc.defaultView + ); + await eventTooltip.once("shown"); + ok(true, "event tooltip opened"); + // wait for filename to be sourcemapped + await waitFor(() => + eventTooltip.panel + .querySelector(".event-header") + ?.innerText.includes(PRETTY_PRINTED_FILENAME) + ); + const header = eventTooltip.panel.querySelector(".event-header"); + const headerFilename = header.querySelector( + ".event-tooltip-filename" + ).innerText; + ok( + headerFilename.endsWith(`${PRETTY_PRINTED_FILENAME}:51`), + `Location in event tooltip is the pretty printed one (${headerFilename})` + ); + info( + "Check that clicking on open debugger icon selects the pretty printed file" + ); + header.querySelector(".event-tooltip-debugger-icon").click(); + await waitForSelectedSource(dbg, PRETTY_PRINTED_FILENAME); + ok(true, "pretty printed file was selected in debugger…"); + await waitForSelectedLocation(dbg, 51); + ok(true, "…at the expected location"); +}); + +add_task(async function prettyPrintSingleLineDataUrl() { + const TEST_URL = `data:text/html,`; + const PRETTY_PRINTED_URL = `${TEST_URL}:formatted`; + const dbg = await initDebuggerWithAbsoluteURL(TEST_URL); + + await selectSource(dbg, TEST_URL); + clickElement(dbg, "prettyPrintButton"); + + const prettySource = await waitForSource(dbg, PRETTY_PRINTED_URL); + await waitForSelectedSource(dbg, prettySource); + const prettyPrintedSource = findSourceContent(dbg, PRETTY_PRINTED_URL); + + ok(prettyPrintedSource, "Pretty-printed source exists"); + + info("Check that the HTML file was pretty-printed as expected"); + const expectedPrettyHtml = ``; + is( + prettyPrintedSource.value, + expectedPrettyHtml, + "HTML file is pretty printed as expected" + ); +}); + +/** + * Return the expected pretty-printed HTML. Lines starting with ➤ indicate breakable + * lines for easier maintenance. + * + * @returns {String} + */ +function getExpectedPrettyPrintedHtml() { + return ` + + + + + + Debugger test page + + + + + + + + +

Minified

+ + + + + + +

+ + +`; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js new file mode 100644 index 0000000000..8d3771cae9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused-anonymous.js @@ -0,0 +1,148 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that pretty-printing a file with no URL works while paused. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-minified.html"); + + info("Evaluate an expression with scriptCommand.execute"); + const debuggerDone = dbg.commands.scriptCommand.execute( + `debugger; var foo; document.addEventListener("click", e => { debugger; }, {once: true})` + ); + await waitForPaused(dbg); + const evaluatedSourceId = dbg.selectors.getSelectedSourceId(); + + // This will throw if things fail to pretty-print and render properly. + info("Pretty print the source created by the evaluated expression"); + await prettyPrint(dbg); + + const prettyEvaluatedSourceFilename = + evaluatedSourceId.split("/").at(-1) + ":formatted"; + await waitForSource(dbg, prettyEvaluatedSourceFilename); + const prettySource = findSource(dbg, prettyEvaluatedSourceFilename); + + info("Check that the script was pretty-printed as expected"); + const { value: prettySourceValue } = findSourceContent(dbg, prettySource); + + is( + prettySourceValue.trim(), + `debugger; +var foo; +document.addEventListener('click', e => { + debugger; +}, { + once: true +}) +`.trim(), + "script was pretty printed as expected" + ); + + await resume(dbg); + await debuggerDone; + + info("Check if we can pause inside the pretty-printed source"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.body.click(); + }); + await waitForPaused(dbg); + await assertPausedAtSourceAndLine(dbg, prettySource.id, 4); + await resume(dbg); + + info("Check that pretty printing works in `eval`'d source"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.eval( + `setTimeout(() => {debugger;document.addEventListener("click", e => { debugger; }, {once: true})}, 100)` + ); + }); + await waitForPaused(dbg); + const evalSourceId = dbg.selectors.getSelectedSourceId(); + + // This will throw if things fail to pretty-print and render properly. + info("Pretty print the source created by the `eval` expression"); + await prettyPrint(dbg); + + const prettyEvalSourceFilename = + evalSourceId.split("/").at(-1) + ":formatted"; + await waitForSource(dbg, prettyEvalSourceFilename); + const prettyEvalSource = findSource(dbg, prettyEvalSourceFilename); + + info("Check that the script was pretty-printed as expected"); + const { value: prettyEvalSourceValue } = findSourceContent( + dbg, + prettyEvalSource + ); + + is( + prettyEvalSourceValue.trim(), + ` +setTimeout( + () => { + debugger; + document.addEventListener('click', e => { + debugger; + }, { + once: true + }) + }, + 100 +)`.trim(), + "script was pretty printed as expected" + ); + await resume(dbg); + + info("Check if we can pause inside the pretty-printed eval source"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.body.click(); + }); + await waitForPaused(dbg); + await assertPausedAtSourceAndLine(dbg, prettyEvalSource.id, 5); + await resume(dbg); + + info("Check that pretty printing works in `new Function` source"); + invokeInTab("breakInNewFunction"); + await waitForPaused(dbg); + const newFunctionSourceId = dbg.selectors.getSelectedSourceId(); + + // This will throw if things fail to pretty-print and render properly. + info("Pretty print the source created with `new Function`"); + await prettyPrint(dbg); + + const prettyNewFunctionSourceFilename = + newFunctionSourceId.split("/").at(-1) + ":formatted"; + await waitForSource(dbg, prettyNewFunctionSourceFilename); + const prettyNewFunctionSource = findSource( + dbg, + prettyNewFunctionSourceFilename + ); + + info("Check that the script was pretty-printed as expected"); + const { value: prettyNewFunctionSourceValue } = findSourceContent( + dbg, + prettyNewFunctionSource + ); + + is( + prettyNewFunctionSourceValue.trim(), + `function anonymous() { + debugger; + document.addEventListener('click', function () { + debugger; + }) +} +`.trim(), + "script was pretty printed as expected" + ); + await resume(dbg); + + info("Check if we can pause inside the pretty-printed eval source"); + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.body.click(); + }); + await waitForPaused(dbg); + await assertPausedAtSourceAndLine(dbg, prettyNewFunctionSource.id, 4); + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused.js new file mode 100644 index 0000000000..a5b9260af2 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-paused.js @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests pretty-printing a source that is currently paused. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-minified.html", "math.min.js"); + const thread = dbg.selectors.getCurrentThread(); + + await selectSource(dbg, "math.min.js"); + await addBreakpoint(dbg, "math.min.js", 2); + + invokeInTab("arithmetic"); + await waitForPaused(dbg, "math.min.js"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "math.min.js").id, 2); + + clickElement(dbg, "prettyPrintButton"); + await waitForSelectedSource(dbg, "math.min.js:formatted"); + await waitForState( + dbg, + state => dbg.selectors.getSelectedFrame(thread).location.line == 18 + ); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "math.min.js:formatted").id, + 18 + ); + await waitForBreakpoint(dbg, "math.min.js:formatted", 18); + await assertBreakpoint(dbg, 18); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-sourcemap.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-sourcemap.js new file mode 100644 index 0000000000..25d3712d32 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print-sourcemap.js @@ -0,0 +1,157 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This tests pretty-printing for sourcemapped files. + +"use strict"; + +const { LocalizationHelper } = require("resource://devtools/shared/l10n.js"); +const L10N = new LocalizationHelper( + "devtools/client/locales/debugger.properties" +); + +const httpServer = createTestHTTPServer(); +httpServer.registerContentType("html", "text/html"); +httpServer.registerContentType("js", "application/javascript"); + +httpServer.registerPathHandler( + "/doc-prettyprint-sourcemap.html", + (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + + + + + `); + } +); + +function sourceHandler(request, response) { + response.setHeader("Content-Type", "text/javascript"); + console.log(request.path.substring(1)); + response.write(`function add(a,b,k){var result=a+b;return k(result)}function sub(a,b,k){var result=a-b;return k(result)}function mul(a,b,k){var result=a*b;return k(result)}function div(a,b,k){var result=a/b;return k(result)}function arithmetic(){add(4,4,function(a){sub(a,2,function(b){mul(b,3,function(c){div(c,2,function(d){console.log("arithmetic",d)})})})})}; +//# sourceMappingURL=${request.path.substring(1)}.map`); +} + +httpServer.registerPathHandler("/js1.min.js", sourceHandler); +httpServer.registerPathHandler("/js2.min.js", sourceHandler); + +// This returns no sourcemap +httpServer.registerPathHandler("/js1.min.js.map", (request, response) => { + response.setHeader("Content-Type", "application/javascript"); + response.setStatusLine(request.httpVersion, 404, "Not found"); + response.write(`console.log("http error")`); +}); + +// This returns a sourcemap without any original source +httpServer.registerPathHandler("/js2.min.js.map", (request, response) => { + response.setHeader("Content-Type", "application/javascript"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write( + `{"version":3,"sources":[],"names":["message","document","getElementById","logMessage","console","log","value","addEventListener","logMessageButton"],"mappings":"AAAA,GAAIA,SAAUC,SAASC,eAAe,UAEtC,SAASC,cACPC,QAAQC,IAAI,eAAiBL,QAAQM,OAGvCN,QAAQO,iBAAiB,QAAS,WAChCP,QAAQM,MAAQ,IACf,MAEH,IAAIE,kBAAmBP,SAASC,eAAe,cAE/CM,kBAAiBD,iBAAiB,QAAS,WACzCJ,cACC"}` + ); +}); + +const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`; + +// Tests that the pretty-print icon is visible for source files with a sourceMappingURL +// but the linked sourcemap is not found or no original files exist. +add_task(async () => { + const dbg = await initDebuggerWithAbsoluteURL( + `${BASE_URL}doc-prettyprint-sourcemap.html`, + "doc-prettyprint-sourcemap.html", + "js1.min.js", + "js2.min.js" + ); + + info(" - Test HTML source"); + const htmlSource = findSource(dbg, "doc-prettyprint-sourcemap.html"); + await selectSource(dbg, htmlSource); + assertPrettyPrintButton(dbg, L10N.getStr("sourceTabs.prettyPrint"), false); + + info(" - Test source with sourceMappingURL but sourcemap does not exist"); + const source1 = findSource(dbg, "js1.min.js"); + await selectSource(dbg, source1); + + // The source may be reported as pretty printable while we are fetching the sourcemap, + // but once the sourcemap is reported to be failing, we no longer report to be pretty printable. + await waitFor( + () => !dbg.selectors.isSourceWithMap(source1.id), + "Wait for the selector to report the source to be source-map less" + ); + + assertPrettyPrintButton(dbg, L10N.getStr("sourceTabs.prettyPrint"), false); + + info( + " - Test source with sourceMappingURL and sourcemap but no original files" + ); + const source2 = findSource(dbg, "js2.min.js"); + await selectSource(dbg, source2); + + assertPrettyPrintButton(dbg, L10N.getStr("sourceTabs.prettyPrint"), false); + + info(" - Test an already pretty-printed source"); + info("Pretty print the script"); + clickElement(dbg, "prettyPrintButton"); + + await waitForSelectedSource(dbg, "js2.min.js:formatted"); + assertPrettyPrintButton( + dbg, + L10N.getStr("sourceFooter.prettyPrint.isPrettyPrintedMessage"), + true + ); +}); + +add_task(async () => { + const dbg = await initDebugger( + "doc-sourcemaps2.html", + "main.min.js", + "main.js" + ); + + info( + " - Test source with sourceMappingURL, sourcemap and original files exist" + ); + const source = findSource(dbg, "main.min.js"); + await selectSource(dbg, source); + + assertPrettyPrintButton( + dbg, + L10N.getStr("sourceFooter.prettyPrint.hasSourceMapMessage"), + true + ); + + info(" - Test an original source"); + const originalSource = findSource(dbg, "main.js"); + await selectSource(dbg, originalSource); + + assertPrettyPrintButton( + dbg, + L10N.getStr("sourceFooter.prettyPrint.isOriginalMessage"), + true + ); +}); + +function assertPrettyPrintButton(dbg, expectedTitle, shouldBeDisabled) { + const prettyPrintButton = findElement(dbg, "prettyPrintButton"); + ok(prettyPrintButton, "Pretty Print Button is visible"); + is( + prettyPrintButton.title, + expectedTitle, + "The pretty print button title should be correct" + ); + ok( + shouldBeDisabled ? prettyPrintButton.disabled : !prettyPrintButton.disabled, + `The pretty print button should be ${ + shouldBeDisabled ? "disabled" : "enabled" + }` + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print.js b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print.js new file mode 100644 index 0000000000..293cabb75c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-pretty-print.js @@ -0,0 +1,134 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests basic pretty-printing functionality. + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + const dbg = await initDebugger("doc-minified.html", "math.min.js"); + + await selectSource(dbg, "math.min.js", 2); + clickElement(dbg, "prettyPrintButton"); + + await waitForSelectedSource(dbg, "math.min.js:formatted"); + const ppSrc = findSource(dbg, "math.min.js:formatted"); + + ok(ppSrc, "Pretty-printed source exists"); + + // this is not implemented yet + // assertHighlightLocation(dbg, "math.min.js:formatted", 18); + // await selectSource(dbg, "math.min.js") + await addBreakpoint(dbg, ppSrc, 18); + + invokeInTab("arithmetic"); + await waitForPaused(dbg); + + assertPausedAtSourceAndLine(dbg, ppSrc.id, 18); + + await stepOver(dbg); + + assertPausedAtSourceAndLine(dbg, ppSrc.id, 39); + + await resume(dbg); + + // The pretty-print button should be disabled in the pretty-printed source. + ok( + findElement(dbg, "prettyPrintButton").disabled, + "Pretty Print Button should be disabled" + ); + + await selectSource(dbg, "math.min.js"); + await waitForSelectedSource(dbg, "math.min.js"); + + ok( + !findElement(dbg, "prettyPrintButton").disabled, + "Pretty Print Button should be enabled" + ); +}); + +add_task(async function testPrivateFields() { + // Create a source containing a class with private fields + const httpServer = createTestHTTPServer(); + httpServer.registerContentType("html", "text/html"); + httpServer.registerContentType("js", "application/javascript"); + + httpServer.registerPathHandler(`/`, function (request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + Test pretty-printing class with private fields + + `); + }); + + httpServer.registerPathHandler( + "/class-with-private-fields.js", + function (request, response) { + response.setHeader("Content-Type", "application/javascript"); + response.write(` + class MyClass { + constructor(a) { + this.#a = a;this.#b = Math.random();this.ab = this.#getAB(); + } + #a + #b = "default value" + static #someStaticPrivate + #getA() { + return this.#a; + } + #getAB() { + return this.#getA()+this. + #b + } + } + `); + } + ); + const port = httpServer.identity.primaryPort; + const TEST_URL = `http://localhost:${port}/`; + + info("Open toolbox"); + const dbg = await initDebuggerWithAbsoluteURL(TEST_URL); + + info("Select script with private fields"); + await selectSource(dbg, "class-with-private-fields.js", 2); + + info("Pretty print the script"); + clickElement(dbg, "prettyPrintButton"); + + info("Wait until the script is pretty-printed"); + await waitForSelectedSource(dbg, "class-with-private-fields.js:formatted"); + + info("Check that the script was pretty-printed as expected"); + const prettyPrintedSource = await findSourceContent( + dbg, + "class-with-private-fields.js:formatted" + ); + + is( + prettyPrintedSource.value.trim(), + ` +class MyClass { + constructor(a) { + this.#a = a; + this.#b = Math.random(); + this.ab = this.#getAB(); + } + #a + #b = 'default value' + static #someStaticPrivate + #getA() { + return this.#a; + } + #getAB() { + return this.#getA() + this.#b + } +} + `.trim(), + "script was pretty printed as expected" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview-frame.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview-frame.js new file mode 100644 index 0000000000..8ca20bce53 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview-frame.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test hovering in a selected frame + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + const found = findElement(dbg, "callStackBody"); + is(found, null, "Call stack is hidden"); + + invokeInTab("firstCall"); + await waitForPaused(dbg); + + info("Preview a variable in the second frame"); + clickElement(dbg, "frame", 2); + await waitForSelectedFrame(dbg, "firstCall"); + await assertFunctionPreview(dbg, 8, 4, "secondCall()"); + + info("Preview should still work after selecting different locations"); + const frame = dbg.selectors.getVisibleSelectedFrame(); + const inScopeLines = dbg.selectors.getInScopeLines(frame.location); + await selectSource(dbg, "script-switching-01.js"); + await assertFunctionPreview(dbg, 8, 4, "secondCall()"); + is( + dbg.selectors.getInScopeLines(frame.location), + inScopeLines, + "In scope lines" + ); +}); + +function waitForSelectedFrame(dbg, displayName) { + const { getInScopeLines, getVisibleSelectedFrame } = dbg.selectors; + return waitForState(dbg, state => { + const frame = getVisibleSelectedFrame(); + + return frame?.displayName == displayName && getInScopeLines(frame.location); + }); +} + +async function assertFunctionPreview(dbg, line, column, displayName) { + const previewEl = await tryHovering(dbg, line, column, "tooltip"); + is(previewEl.innerText, displayName); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview-getter.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview-getter.js new file mode 100644 index 0000000000..88b85b8292 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview-getter.js @@ -0,0 +1,56 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test checks if 'executing getter' in a preview correctly displays values. +// Bug 1456441 - 'execute getter' not working in Preview + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-preview-getter.html", + "preview-getter.js" + ); + + await loadAndAddBreakpoint(dbg, "preview-getter.js", 5, 4); + invokeInTab("funcA"); + await waitForPaused(dbg); + + info("Hovers over 'this' token to display the preview."); + await tryHovering(dbg, 5, 8, "previewPopup"); + + info("Invokes getter and waits for the element to be rendered"); + await clickElement(dbg, "previewPopupInvokeGetterButton"); + await waitForAllElements(dbg, "previewPopupObjectNumber", 2); + + await clickElement(dbg, "previewPopupInvokeGetterButton"); + await waitForAllElements(dbg, "previewPopupObjectObject", 3); + + const getterButtonEls = findAllElements( + dbg, + "previewPopupInvokeGetterButton" + ); + const previewObjectNumberEls = findAllElements( + dbg, + "previewPopupObjectNumber" + ); + const previewObjectObjectEls = findAllElements( + dbg, + "previewPopupObjectObject" + ); + + is(getterButtonEls.length, 0, "There are no getter buttons in the preview."); + is( + previewObjectNumberEls.length, + 2, + "Getters were invoked and two numerical values are displayed as expected." + ); + is( + previewObjectObjectEls.length, + 3, + "Getters were invoked and three object values are displayed as expected." + ); + + await closePreviewAtPos(dbg, 5, 8); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview-module.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview-module.js new file mode 100644 index 0000000000..be51ec88a4 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview-module.js @@ -0,0 +1,36 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test hovering in a script that is paused on load +// and doesn't have functions. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html"); + + const onNavigated = navigate(dbg, "doc-on-load.html"); + + // wait for `top-level.js` to load and to pause at a debugger statement + await waitForSelectedSource(dbg, "top-level.js"); + await waitForPaused(dbg); + + await assertPreviews(dbg, [ + { + line: 1, + column: 6, + expression: "obj", + fields: [ + ["foo", "1"], + ["bar", "2"], + ], + }, + ]); + + await assertPreviewTooltip(dbg, 2, 7, { result: "3", expression: "func" }); + + info("Resume and wait for full navigation of the tab"); + await resume(dbg); + await onNavigated; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview-source-maps.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview-source-maps.js new file mode 100644 index 0000000000..ddf9945ef5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview-source-maps.js @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-sourcemaps.html", + "entry.js", + "output.js", + "times2.js", + "opts.js" + ); + + await selectSource(dbg, "times2.js"); + await addBreakpoint(dbg, "times2.js", 2); + + invokeInTab("keepMeAlive"); + await waitForPaused(dbg); + await waitForSelectedSource(dbg, "times2.js"); + + info("Test previewing in the original location"); + await assertPreviews(dbg, [ + { line: 2, column: 10, result: 4, expression: "x" }, + ]); + + info("Test previewing in the generated location"); + await dbg.actions.jumpToMappedSelectedLocation(getContext(dbg)); + await waitForSelectedSource(dbg, "bundle.js"); + await assertPreviews(dbg, [ + { line: 70, column: 11, result: 4, expression: "x" }, + ]); + + info("Test that you can not preview in another original file"); + await selectSource(dbg, "output.js"); + await hoverAtPos(dbg, { line: 2, ch: 16 }); + await assertNoTooltip(dbg); +}); + +async function assertNoTooltip(dbg) { + await wait(200); + const el = findElement(dbg, "tooltip"); + is(el, null, "Tooltip should not exist"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-preview.js b/devtools/client/debugger/test/mochitest/browser_dbg-preview.js new file mode 100644 index 0000000000..3a5fe4ec5d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-preview.js @@ -0,0 +1,123 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test hovering on an object, which will show a popup and on a +// simple value, which will show a tooltip. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-preview.html", "preview.js"); + + await testPreviews(dbg, "testInline", [ + { line: 17, column: 16, expression: "obj?.prop", result: 2 }, + ]); + + await selectSource(dbg, "preview.js"); + await testBucketedArray(dbg); + + await testPreviews(dbg, "empties", [ + { line: 6, column: 9, expression: "a", result: '""' }, + { line: 7, column: 9, expression: "b", result: "false" }, + { line: 8, column: 9, expression: "c", result: "undefined" }, + { line: 9, column: 9, expression: "d", result: "null" }, + ]); + + await testPreviews(dbg, "objects", [ + { line: 27, column: 10, expression: "empty", result: "No properties" }, + { line: 28, column: 22, expression: "obj?.foo", result: 1 }, + ]); + + await testPreviews(dbg, "smalls", [ + { line: 14, column: 9, expression: "a", result: '"..."' }, + { line: 15, column: 9, expression: "b", result: "true" }, + { line: 16, column: 9, expression: "c", result: "1" }, + { + line: 17, + column: 9, + expression: "d", + fields: [["length", "0"]], + }, + ]); + + await testPreviews(dbg, "classPreview", [ + { line: 50, column: 20, expression: "this.x", result: 1 }, + { line: 50, column: 29, expression: "this.#privateVar", result: 2 }, + { + line: 50, + column: 47, + expression: "Foo.#privateStatic", + fields: [ + ["first", `"a"`], + ["second", `"b"`], + ], + }, + { + line: 51, + column: 26, + expression: "this", + fields: [ + ["x", "1"], + ["#privateVar", "2"], + ], + }, + { line: 51, column: 39, expression: "this.#privateVar", result: 2 }, + ]); + + info( + "Check that closing the preview tooltip doesn't release the underlying object actor" + ); + invokeInTab("classPreview"); + await waitForPaused(dbg); + info("Display popup a first time and hide it"); + await assertPreviews(dbg, [ + { + line: 60, + column: 7, + expression: "y", + fields: [["hello", "{…}"]], + }, + ]); + await closePreviewAtPos(dbg, 60, 7); + + info("Display the popup again and try to expand a property"); + const popupEl = await tryHovering(dbg, 60, 7, "popup"); + const nodes = popupEl.querySelectorAll(".preview-popup .node"); + const initialNodesLength = nodes.length; + nodes[0].querySelector(".arrow").click(); + await waitFor( + () => + popupEl.querySelectorAll(".preview-popup .node").length > + initialNodesLength + ); + ok(true, `"hello" was expanded`); + await resume(dbg); +}); + +async function testPreviews(dbg, fnName, previews) { + invokeInTab(fnName); + await waitForPaused(dbg); + + await assertPreviews(dbg, previews); + await resume(dbg); + + info(`Ran tests for ${fnName}`); +} + +async function testBucketedArray(dbg) { + invokeInTab("largeArray"); + await waitForPaused(dbg); + await tryHovering(dbg, 34, 10, "popup"); + const preview = dbg.selectors.getPreview(); + + is( + preview.properties.map(p => p.name).join(" "), + "[0…99] [100…100] length ", + "Popup properties are bucketed" + ); + + is(preview.properties[0].meta.endIndex, 99, "first bucket ends at 99"); + is(preview.properties[2].contents.value, 101, "length is 101"); + await resume(dbg); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-project-root.js b/devtools/client/debugger/test/mochitest/browser_dbg-project-root.js new file mode 100644 index 0000000000..e1e3c4a9ad --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-project-root.js @@ -0,0 +1,119 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// This test covers changing to a distinct "project root" +// i.e. displaying only one particular thread, domain, or directory in the Source Tree. + +"use strict"; + +const httpServer = createTestHTTPServer(); +const HOST = `localhost:${httpServer.identity.primaryPort}`; +const BASE_URL = `http://${HOST}/`; + +const INDEX_PAGE_CONTENT = ` + + + + + + + + `; + +httpServer.registerPathHandler("/index.html", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(INDEX_PAGE_CONTENT); +}); +httpServer.registerPathHandler("/root-script.js", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("console.log('root script')"); +}); +httpServer.registerPathHandler( + "/folder/folder-script.js", + (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("console.log('folder script')"); + } +); +httpServer.registerPathHandler( + "/folder/sub-folder/sub-folder-script.js", + (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write("console.log('sub folder script')"); + } +); + +const ALL_SCRIPTS = [ + "root-script.js", + "folder-script.js", + "sub-folder-script.js", +]; + +add_task(async function testProjectRoot() { + const dbg = await initDebuggerWithAbsoluteURL( + BASE_URL + "index.html", + ...ALL_SCRIPTS + ); + + await waitForSourcesInSourceTree(dbg, ALL_SCRIPTS); + + info("Select the Main Thread as project root"); + const threadItem = findSourceNodeWithText(dbg, "Main Thread"); + await setProjectRoot(dbg, threadItem); + assertRootLabel(dbg, "Main Thread"); + await waitForSourcesInSourceTree(dbg, ALL_SCRIPTS); + + info("Select the host as project root"); + const hostItem = findSourceNodeWithText(dbg, HOST); + await setProjectRoot(dbg, hostItem); + assertRootLabel(dbg, HOST); + await waitForSourcesInSourceTree(dbg, ALL_SCRIPTS); + + info("Select 'folder' as project root"); + const folderItem = findSourceNodeWithText(dbg, "folder"); + await setProjectRoot(dbg, folderItem); + assertRootLabel(dbg, "folder"); + await waitForSourcesInSourceTree(dbg, [ + "folder-script.js", + "sub-folder-script.js", + ]); + + info("Reload and see if project root is preserved"); + await reload(dbg, "folder-script.js", "sub-folder-script.js"); + assertRootLabel(dbg, "folder"); + await waitForSourcesInSourceTree(dbg, [ + "folder-script.js", + "sub-folder-script.js", + ]); + + info("Select 'sub-folder' as project root"); + const subFolderItem = findSourceNodeWithText(dbg, "sub-folder"); + await setProjectRoot(dbg, subFolderItem); + assertRootLabel(dbg, "sub-folder"); + await waitForSourcesInSourceTree(dbg, ["sub-folder-script.js"]); + + info("Clear project root"); + await clearProjectRoot(dbg); + await waitForSourcesInSourceTree(dbg, ALL_SCRIPTS); +}); + +async function setProjectRoot(dbg, treeNode) { + return triggerSourceTreeContextMenu( + dbg, + treeNode, + "#node-set-directory-root" + ); +} + +function assertRootLabel(dbg, label) { + const rootHeaderLabel = dbg.win.document.querySelector( + ".sources-clear-root-label" + ); + is(rootHeaderLabel.textContent, label); +} + +async function clearProjectRoot(dbg) { + const rootHeader = dbg.win.document.querySelector(".sources-clear-root"); + rootHeader.click(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-project-search.js b/devtools/client/debugger/test/mochitest/browser_dbg-project-search.js new file mode 100644 index 0000000000..03ac9b740c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-project-search.js @@ -0,0 +1,258 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Testing various project search features + +"use strict"; + +requestLongerTimeout(3); + +add_task(async function testProjectSearchCloseOnNavigation() { + const dbg = await initDebugger( + "doc-script-switching.html", + "script-switching-01.js" + ); + + await selectSource(dbg, "script-switching-01.js"); + + await openProjectSearch(dbg); + await doProjectSearch(dbg, "first"); + + is(dbg.selectors.getActiveSearch(), "project"); + + await navigate(dbg, "doc-scripts.html"); + + // wait for the project search to close + await waitForState(dbg, state => !dbg.selectors.getActiveSearch()); +}); + +add_task(async function testSimpleProjectSearch() { + // Start with side panel collapsed so we can assert that the project search keyboard + // shortcut will open it. + await pushPref("devtools.debugger.start-panel-collapsed", true); + + const dbg = await initDebugger( + "doc-script-switching.html", + "script-switching-01.js" + ); + + await openProjectSearch(dbg); + + ok( + !!findElementWithSelector(dbg, ".project-text-search"), + "Project search is visible" + ); + + const searchTerm = "first"; + await doProjectSearch(dbg, searchTerm); + + const queryMatch = findElement(dbg, "fileMatch").querySelector( + ".query-match" + ); + is( + queryMatch.innerText, + searchTerm, + "The highlighted text matches the search term" + ); + + info("Select a result match to open the location in the source"); + await clickElement(dbg, "fileMatch"); + await waitForSelectedSource(dbg, "script-switching-01.js"); + + info("Close start sidebar"); + const startPanelToggleButtonEl = findElementWithSelector( + dbg, + ".toggle-button.start" + ); + startPanelToggleButtonEl.click(); + await waitFor(() => startPanelToggleButtonEl.classList.contains("collapsed")); + + info("Try to open project search again"); + await openProjectSearch(dbg); + ok( + !!findElementWithSelector(dbg, ".project-text-search"), + "Project search is visible" + ); +}); + +add_task(async function testMatchesForRegexSearches() { + const dbg = await initDebugger("doc-react.html", "App.js"); + await openProjectSearch(dbg); + + type(dbg, "import .* from 'react'"); + await clickElement(dbg, "projectSearchModifiersRegexMatch"); + + await waitForSearchResults(dbg, 2); + + const queryMatch = findAllElements(dbg, "fileMatch")[1].querySelector( + ".query-match" + ); + + is( + queryMatch.innerText, + "import React, { Component } from 'react'", + "The highlighted text matches the search term" + ); + + // Turn off the regex modifier so does not break tests below + await clickElement(dbg, "projectSearchModifiersRegexMatch"); +}); + +// Test expanding search results to reveal the search matches. +add_task(async function testExpandSearchResultsToShowMatches() { + const dbg = await initDebugger("doc-react.html", "App.js"); + + await openProjectSearch(dbg); + await doProjectSearch(dbg, "we"); + + is(getExpandedResultsCount(dbg), 159); + + const collapsedNodes = findAllElements(dbg, "projectSearchCollapsed"); + is(collapsedNodes.length, 1); + + collapsedNodes[0].click(); + + is(getExpandedResultsCount(dbg), 367); +}); + +add_task(async function testSearchModifiers() { + const dbg = await initDebugger("doc-react.html", "App.js"); + + await openProjectSearch(dbg); + + await assertProjectSearchModifier( + dbg, + "projectSearchModifiersCaseSensitive", + "FIELDS", + "case sensitive", + { resultWithModifierOn: 0, resultWithModifierOff: 2 } + ); + await assertProjectSearchModifier( + dbg, + "projectSearchModifiersRegexMatch", + `\\*`, + "regex match", + { resultWithModifierOn: 12, resultWithModifierOff: 0 } + ); + await assertProjectSearchModifier( + dbg, + "projectSearchModifiersWholeWordMatch", + "so", + "whole word match", + { resultWithModifierOn: 6, resultWithModifierOff: 16 } + ); +}); + +add_task(async function testSearchExcludePatterns() { + const dbg = await initDebugger("doc-react.html", "App.js"); + + info("Search across all files"); + await openProjectSearch(dbg); + let fileResults = await doProjectSearch(dbg, "console"); + + is(fileResults.length, 5, "5 results were found"); + + let resultsFromNodeModules = [...fileResults].filter(result => + result.innerText.includes("node_modules") + ); + + is( + resultsFromNodeModules.length, + 3, + "3 results were found from node_modules" + ); + + info("Excludes search results based on multiple search patterns"); + + await clickElement(dbg, "excludePatternsInput"); + type(dbg, "App.js, main.js"); + pressKey(dbg, "Enter"); + + fileResults = await waitForSearchResults(dbg, 3); + + const resultsFromAppJS = [...fileResults].filter(result => + result.innerText.includes("App.js") + ); + + is(resultsFromAppJS.length, 0, "None of the results is from the App.js file"); + + const resultsFromMainJS = [...fileResults].filter(result => + result.innerText.includes("main.js") + ); + + is( + resultsFromMainJS.length, + 0, + "None of the results is from the main.js file" + ); + + info("Excludes search results from node modules files"); + + await clearElement(dbg, "excludePatternsInput"); + type(dbg, "**/node_modules/**"); + pressKey(dbg, "Enter"); + + fileResults = await waitForSearchResults(dbg, 2); + + resultsFromNodeModules = [...fileResults].filter(result => + result.innerText.includes("node_modules") + ); + + is( + resultsFromNodeModules.length, + 0, + "None of the results is from the node modules files" + ); + + info("Assert that the exclude pattern is persisted across reloads"); + await reloadBrowser(); + await openProjectSearch(dbg); + + const excludePatternsInputElement = await waitForElement( + dbg, + "excludePatternsInput" + ); + + is( + excludePatternsInputElement.value, + "**/node_modules/**", + "The exclude pattern for node modules is persisted accross reloads" + ); + + // Clear the fields so that it does not impact on the subsequent tests + await clearElement(dbg, "projectSearchSearchInput"); + await clearElement(dbg, "excludePatternsInput"); + pressKey(dbg, "Enter"); +}); + +async function assertProjectSearchModifier( + dbg, + searchModifierBtn, + searchTerm, + title, + expected +) { + info(`Assert ${title} search modifier`); + + type(dbg, searchTerm); + info(`Turn on the ${title} search modifier option`); + await clickElement(dbg, searchModifierBtn); + let results = await waitForSearchResults(dbg, expected.resultWithModifierOn); + is( + results.length, + expected.resultWithModifierOn, + `${results.length} results where found` + ); + + info(`Turn off the ${title} search modifier`); + await clickElement(dbg, searchModifierBtn); + + results = await waitForSearchResults(dbg, expected.resultWithModifierOff); + is( + results.length, + expected.resultWithModifierOff, + `${results.length} results where found` + ); + await clearElement(dbg, "projectSearchSearchInput"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-quick-open.js b/devtools/client/debugger/test/mochitest/browser_dbg-quick-open.js new file mode 100644 index 0000000000..1cbf02c616 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-quick-open.js @@ -0,0 +1,166 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Testing quick open + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + // Inject lots of sources to go beyond the maximum limit of displayed sources (set to 100) + const injectedSources = await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + function () { + const sources = []; + for (let i = 1; i <= 200; i++) { + const value = String(i).padStart(3, "0"); + content.eval( + `function evalSource() {}; //# sourceURL=eval-source-${value}.js` + ); + sources.push(`eval-source-${value}.js`); + } + return sources; + } + ); + await waitForSources(dbg, ...injectedSources); + + info("test opening and closing"); + await quickOpen(dbg, ""); + pressKey(dbg, "Escape"); + assertDisabled(dbg); + + info("Testing the number of results for source search"); + await quickOpen(dbg, "sw"); + await waitForResults(dbg, [undefined, undefined]); + is(resultCount(dbg), 2, "two file results"); + pressKey(dbg, "Escape"); + + // We ensure that sources after maxResult limit are visible + info("Test that first and last eval source are visible"); + await quickOpen(dbg, "eval-source-001.js"); + await waitForResults(dbg, ["eval-source-001.js"]); + is(resultCount(dbg), 1, "one file result"); + pressKey(dbg, "Escape"); + await quickOpen(dbg, "eval-source-200.js"); + await waitForResults(dbg, ["eval-source-200.js"]); + is(resultCount(dbg), 1, "one file result"); + pressKey(dbg, "Escape"); + + info("Testing source search and check to see if source is selected"); + await waitForSource(dbg, "script-switching-01.js"); + await quickOpen(dbg, "sw1"); + await waitForResults(dbg, ["script-switching-01.js"]); + is(resultCount(dbg), 1, "one file results"); + pressKey(dbg, "Enter"); + await waitForSelectedSource(dbg, "script-switching-01.js"); + + info("Test that results show tab icons"); + await quickOpen(dbg, "sw1"); + await waitForResults(dbg, ["script-switching-01.js"]); + await assertResultIsTab(dbg, 1); + pressKey(dbg, "Tab"); + + info( + "Testing arrow keys in source search and check to see if source is selected" + ); + await quickOpen(dbg, "sw2"); + await waitForResults(dbg, ["script-switching-02.js"]); + is(resultCount(dbg), 1, "one file results"); + pressKey(dbg, "Down"); + pressKey(dbg, "Enter"); + await waitForSelectedSource(dbg, "script-switching-02.js"); + + info("Testing tab closes the search"); + await quickOpen(dbg, "sw"); + await waitForResults(dbg, [undefined, undefined]); + pressKey(dbg, "Tab"); + assertDisabled(dbg); + + info("Testing function search"); + await quickOpen(dbg, "", "quickOpenFunc"); + await waitForResults(dbg, ["secondCall", "foo"]); + is(resultCount(dbg), 2, "two function results"); + + type(dbg, "@x"); + await waitForResults(dbg, []); + is(resultCount(dbg), 0, "no functions with 'x' in name"); + + pressKey(dbg, "Escape"); + assertDisabled(dbg); + + info("Testing goto line:column"); + assertLine(dbg, 0); + assertColumn(dbg, null); + await quickOpen(dbg, ":7:12"); + await waitForResults(dbg, [undefined, undefined]); + pressKey(dbg, "Enter"); + await waitForSelectedSource(dbg, "script-switching-02.js"); + assertLine(dbg, 7); + assertColumn(dbg, 12); + + info("Testing gotoSource"); + await quickOpen(dbg, "sw1:5"); + await waitForResults(dbg, ["script-switching-01.js"]); + pressKey(dbg, "Enter"); + await waitForSelectedSource(dbg, "script-switching-01.js"); + assertLine(dbg, 5); +}); + +function assertEnabled(dbg) { + is(dbg.selectors.getQuickOpenEnabled(), true, "quickOpen enabled"); +} + +function assertDisabled(dbg) { + is(dbg.selectors.getQuickOpenEnabled(), false, "quickOpen disabled"); +} + +function assertLine(dbg, lineNumber) { + is( + dbg.selectors.getSelectedLocation().line, + lineNumber, + `goto line is ${lineNumber}` + ); +} + +function assertColumn(dbg, columnNumber) { + let value = dbg.selectors.getSelectedLocation().column; + if (value === undefined) { + value = null; + } + is(value, columnNumber, `goto column is ${columnNumber}`); +} + +function resultCount(dbg) { + return findAllElements(dbg, "resultItems").length; +} + +async function quickOpen(dbg, query, shortcut = "quickOpen") { + pressKey(dbg, shortcut); + assertEnabled(dbg); + query !== "" && type(dbg, query); +} + +async function waitForResults(dbg, results) { + await waitForAllElements(dbg, "resultItems", results.length, true); + + for (let i = 0; i < results.length; ++i) { + if (results[i] !== undefined) { + await waitForElement(dbg, "resultItemName", results[i], i + 1); + } + } +} + +function findResultEl(dbg, index = 1) { + return waitForElementWithSelector(dbg, `.result-item:nth-child(${index})`); +} + +async function assertResultIsTab(dbg, index) { + const el = await findResultEl(dbg, index); + ok( + el && !!el.querySelector(".tab.result-item-icon"), + "Result should be a tab" + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-react-app.js b/devtools/client/debugger/test/mochitest/browser_dbg-react-app.js new file mode 100644 index 0000000000..16d1e361c1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-react-app.js @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-react.html", "App.js"); + dbg.actions.toggleMapScopes(); + + await selectSource(dbg, "App.js"); + await addBreakpoint(dbg, "App.js", 11); + + info("Test previewing an immutable Map inside of a react component"); + invokeInTab("clickButton"); + await waitForPaused(dbg); + + await waitForState(dbg, state => + dbg.selectors.getSelectedScopeMappings(dbg.selectors.getCurrentThread()) + ); + + await assertPreviewTextValue(dbg, 10, 22, { + text: "size: 1", + expression: "_this.fields;", + }); + + info("Verify that the file is flagged as a React module"); + const sourceTab = findElementWithSelector(dbg, ".source-tab.active"); + ok( + sourceTab.querySelector(".source-icon.react"), + "Source tab has a React icon" + ); + assertSourceIcon(dbg, "App.js", "react"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-react-jsx.js b/devtools/client/debugger/test/mochitest/browser_dbg-react-jsx.js new file mode 100644 index 0000000000..9e9f6417bd --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-react-jsx.js @@ -0,0 +1,20 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that dynamically generated + `); +}); + +httpServer.registerPathHandler("/test.js", function (request, response) { + response.setHeader("Content-Type", "application/javascript"); + response.write(` + document.addEventListener("click", function onClick(e) { + var sharedValue = {hello: "world"}; + var x = { + a: sharedValue, + b: sharedValue, + c: sharedValue, + d: { + e: { + g: sharedValue + }, + f: { + h: sharedValue + } + } + }; + debugger; + }); + `); +}); +const port = httpServer.identity.primaryPort; +const TEST_URL = `http://localhost:${port}/`; + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL(TEST_URL); + + const ready = Promise.all([ + waitForPaused(dbg), + waitForLoadedSource(dbg, "test.js"), + ]); + + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.document.querySelector("button.pause").click(); + }); + + await ready; + + checkScopesLabels( + dbg, + ` + | e + | sharedValue + | x + `, + { startIndex: 3 } + ); + + info("Expand `x` node"); + await toggleScopeNode(dbg, 6); + checkScopesLabels( + dbg, + ` + | x + | | a + | | b + | | c + | | d + `, + { startIndex: 5 } + ); + + info("Expand node `d`"); + await toggleScopeNode(dbg, 10); + checkScopesLabels( + dbg, + ` + | | d + | | | e + | | | f + `, + { startIndex: 9 } + ); + + info("Expand `f` and `e` nodes"); + await toggleScopeNode(dbg, 12); + await toggleScopeNode(dbg, 11); + checkScopesLabels( + dbg, + ` + | | d + | | | e + | | | | g + | | | | + | | | f + | | | | h + | | | | + `, + { startIndex: 9 } + ); + + info("Expand `h`, `g`, `e`, `c`, `b` and `a` nodes"); + await toggleScopeNode(dbg, 15); + await toggleScopeNode(dbg, 12); + await toggleScopeNode(dbg, 9); + await toggleScopeNode(dbg, 8); + await toggleScopeNode(dbg, 7); + + checkScopesLabels( + dbg, + ` + | x + | | a + | | | hello + | | | + | | b + | | | hello + | | | + | | c + | | | hello + | | | + | | d + | | | e + | | | | g + | | | | | hello + | | | | | + | | | | + | | | f + | | | | h + | | | | | hello + | | | | | + | | | | + `, + { startIndex: 5 } + ); + + info("Expand `e`"); + await toggleScopeNode(dbg, 4); + + info("Expand the `target` node"); + let nodes = getAllLabels(dbg); + const originalNodesCount = nodes.length; + const targetNodeIndex = nodes.indexOf("target"); + ok(targetNodeIndex > -1, "Found the target node"); + await toggleScopeNode(dbg, targetNodeIndex); + nodes = getAllLabels(dbg); + ok(nodes.length > originalNodesCount, "the target node was expanded"); + ok(nodes.includes("classList"), "classList is displayed"); + + await resume(dbg); +}); + +function getAllLabels(dbg, withIndent = false) { + return Array.from(findAllElements(dbg, "scopeNodes")).map(el => { + let text = el.innerText; + if (withIndent) { + const node = el.closest(".tree-node"); + const level = Number(node.getAttribute("aria-level")); + if (!Number.isNaN(level)) { + text = `${"| ".repeat(level - 1)}${text}`.trim(); + } + } + return text; + }); +} + +function checkScopesLabels(dbg, expected, { startIndex = 0 } = {}) { + const lines = expected + .trim() + .split("\n") + .map(line => line.trim()); + + const labels = getAllLabels(dbg, true).slice( + startIndex, + startIndex + lines.length + ); + + const format = arr => `\n${arr.join("\n")}\n`; + is(format(labels), format(lines), "got expected scope labels"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-scopes-mutations.js b/devtools/client/debugger/test/mochitest/browser_dbg-scopes-mutations.js new file mode 100644 index 0000000000..d0cb3b6035 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-scopes-mutations.js @@ -0,0 +1,93 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-mutate.html"); + + const onPaused = waitForPaused(dbg); + invokeInTab("mutate"); + await onPaused; + await waitForSelectedSource(dbg, "script-mutate"); + await waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + + is( + getScopeNodeLabel(dbg, 2), + "", + 'The second element in the scope panel is ""' + ); + is( + getScopeNodeLabel(dbg, 4), + "phonebook", + 'The fourth element in the scope panel is "phonebook"' + ); + + info("Expand `phonebook`"); + await expandNode(dbg, 4); + is( + getScopeNodeLabel(dbg, 5), + "S", + 'The fifth element in the scope panel is "S"' + ); + + info("Expand `S`"); + await expandNode(dbg, 5); + is( + getScopeNodeLabel(dbg, 6), + "sarah", + 'The sixth element in the scope panel is "sarah"' + ); + is( + getScopeNodeLabel(dbg, 7), + "serena", + 'The seventh element in the scope panel is "serena"' + ); + + info("Expand `sarah`"); + await expandNode(dbg, 6); + is( + getScopeNodeLabel(dbg, 7), + "lastName", + 'The seventh element in the scope panel is now "lastName"' + ); + is( + getScopeNodeValue(dbg, 7), + '"Doe"', + 'The "lastName" element has the expected "Doe" value' + ); + + await resume(dbg); + await waitForPaused(dbg); + await waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + + is( + getScopeNodeLabel(dbg, 2), + "", + 'The second element in the scope panel is ""' + ); + is( + getScopeNodeLabel(dbg, 4), + "phonebook", + 'The fourth element in the scope panel is "phonebook"' + ); +}); + +function getScopeNodeLabel(dbg, index) { + return findElement(dbg, "scopeNode", index).innerText; +} + +function getScopeNodeValue(dbg, index) { + return findElement(dbg, "scopeValue", index).innerText; +} + +function expandNode(dbg, index) { + const node = findElement(dbg, "scopeNode", index); + const objectInspector = node.closest(".object-inspector"); + const properties = objectInspector.querySelectorAll(".node").length; + findElement(dbg, "scopeNode", index).click(); + return waitUntil( + () => objectInspector.querySelectorAll(".node").length !== properties + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-scopes-xrays.js b/devtools/client/debugger/test/mochitest/browser_dbg-scopes-xrays.js new file mode 100644 index 0000000000..43ec77d5b3 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-scopes-xrays.js @@ -0,0 +1,67 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that xrays do not interfere with examining objects in the scopes pane. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scopes-xrays.html"); + + invokeInTab("start"); + await waitForPaused(dbg, "doc-scopes-xrays.html"); + + await toggleNode(dbg, "set"); + await toggleNode(dbg, ""); + await checkObjectNode(dbg, "0", "1"); + await toggleNode(dbg, "set"); + + await toggleNode(dbg, "weakset"); + await toggleNode(dbg, ""); + await checkObjectNode(dbg, "0", "2"); + await toggleNode(dbg, "weakset"); + + await toggleNode(dbg, "map"); + await toggleNode(dbg, ""); + await toggleNode(dbg, "0"); + await checkObjectNode(dbg, "", "3"); + await toggleNode(dbg, ""); + await checkObjectNode(dbg, "", "4"); + await toggleNode(dbg, "map"); + + await toggleNode(dbg, "weakmap"); + await toggleNode(dbg, ""); + await toggleNode(dbg, "0"); + await checkObjectNode(dbg, "", "5"); + await toggleNode(dbg, ""); + await checkObjectNode(dbg, "", "6"); + await toggleNode(dbg, "weakmap"); +}); + +function findNode(dbg, text) { + for (let index = 0; ; index++) { + const elem = findElement(dbg, "scopeNode", index); + if (elem?.innerText == text) { + return elem; + } + } +} + +function toggleNode(dbg, text) { + return toggleObjectInspectorNode(findNode(dbg, text)); +} + +function findNodeValue(dbg, text) { + for (let index = 0; ; index++) { + const elem = findElement(dbg, "scopeNode", index); + if (elem?.innerText == text) { + return findElement(dbg, "scopeValue", index).innerText; + } + } +} + +async function checkObjectNode(dbg, text, value) { + await toggleNode(dbg, text); + ok(findNodeValue(dbg, "a") == value, "object value"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-scopes.js b/devtools/client/debugger/test/mochitest/browser_dbg-scopes.js new file mode 100644 index 0000000000..0de1e32baa --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-scopes.js @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-script-switching.html"); + + const ready = Promise.all([ + waitForPaused(dbg), + waitForLoadedSource(dbg, "script-switching-02.js"), + + // MAP_FRAMES triggers a new Scopes panel render cycle, which introduces + // a race condition with the click event on the foo node. + waitForDispatch(dbg.store, "MAP_FRAMES"), + ]); + invokeInTab("firstCall"); + await ready; + + is(getLabel(dbg, 1), "secondCall"); + is(getLabel(dbg, 2), ""); + is(getLabel(dbg, 4), "foo()"); + await toggleScopeNode(dbg, 4); + is(getLabel(dbg, 5), "arguments"); + + await stepOver(dbg); + is(getLabel(dbg, 4), "foo()"); + is(getLabel(dbg, 5), "Window"); +}); + +function getLabel(dbg, index) { + return findElement(dbg, "scopeNode", index).innerText; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-scroll-run-to-completion.js b/devtools/client/debugger/test/mochitest/browser_dbg-scroll-run-to-completion.js new file mode 100644 index 0000000000..c42841f135 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-scroll-run-to-completion.js @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scroll-run-to-completion.html"); + invokeInTab("pauseOnce", "doc-scroll-run-to-completion.html"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-scroll-run-to-completion.html").id, + 20 + ); + + await checkEvaluateInTopFrame(dbg, "window.scrollBy(0, 10);", undefined); + + // checkEvaluateInTopFrame does an implicit resume for some reason. + await waitForPaused(dbg); + + const onTestPassed = once(Services.ppmm, "test passed"); + await resume(dbg); + await onTestPassed; +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-search-file-paused.js b/devtools/client/debugger/test/mochitest/browser_dbg-search-file-paused.js new file mode 100644 index 0000000000..54a493fc2d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-search-file-paused.js @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the search bar correctly responds to queries, enter, shift enter + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + info("Add a breakpoint, wait for pause"); + const source = findSource(dbg, "simple2.js"); + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 5); + invokeInTab("main"); + await waitForPaused(dbg); + + info("Starting a search for 'bar'"); + const cm = getCM(dbg); + pressKey(dbg, "fileSearch"); + is(dbg.selectors.getActiveSearch(), "file"); + const el = getFocusedEl(dbg); + type(dbg, "bar"); + await waitForSearchState(dbg); + + info("Ensuring 'bar' matches are highlighted"); + pressKey(dbg, "Enter"); + is(cm.state.search.posFrom.line, 1); + pressKey(dbg, "Enter"); + is(cm.state.search.posFrom.line, 4); + + info("Switching files via frame click"); + const frames = findAllElements(dbg, "frames"); + pressMouseDown(dbg, frames[1]); + + // Ensure that the debug line is in view, and not the first "bar" instance, + // which the user would have to scroll down for + const { top } = cm.getScrollInfo(); + is(top, 0, "First search term is not in view"); + + // Change the search term and go back to the first source in stack + info("Switching to paused file via frame click"); + pressKey(dbg, "fileSearch"); + el.value = ""; + type(dbg, "func"); + await waitForSearchState(dbg); + pressMouseDown(dbg, frames[0]); + await waitFor(() => cm.state.search.query === "func"); + + // Ensure there is a match for the new term + pressKey(dbg, "Enter"); + await waitFor(() => cm.state.search.posFrom.line === 0); + is(cm.state.search.posFrom.line, 0); + pressKey(dbg, "Enter"); + await waitFor(() => cm.state.search.posFrom.line === 1); + is(cm.state.search.posFrom.line, 1); +}); + +function getFocusedEl(dbg) { + const doc = dbg.win.document; + return doc.activeElement; +} + +function pressMouseDown(dbg, node) { + EventUtils.sendMouseEvent({ type: "mousedown" }, node, dbg.win); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-search-file-retains-query.js b/devtools/client/debugger/test/mochitest/browser_dbg-search-file-retains-query.js new file mode 100644 index 0000000000..53e9861d14 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-search-file-retains-query.js @@ -0,0 +1,40 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the search bar retains previous query on re-opening. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + const { + selectors: { getActiveSearch }, + } = dbg; + await selectSource(dbg, "simple1.js"); + + // Open search bar + pressKey(dbg, "fileSearch"); + await waitFor(() => getActiveSearch() === "file"); + is(getActiveSearch(), "file"); + + // Type a search query + type(dbg, "con"); + await waitForSearchState(dbg); + is(findElement(dbg, "fileSearchInput").value, "con"); + is(getCM(dbg).state.search.query, "con"); + + // Close the search bar + pressKey(dbg, "Escape"); + await waitFor(() => getActiveSearch() === null); + is(getActiveSearch(), null); + + // Re-open search bar + pressKey(dbg, "fileSearch"); + await waitFor(() => getActiveSearch() === "file"); + is(getActiveSearch(), "file"); + + // Test for the retained query + is(getCM(dbg).state.search.query, "con"); + is(findElement(dbg, "fileSearchInput").value, "con"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-search-file.js b/devtools/client/debugger/test/mochitest/browser_dbg-search-file.js new file mode 100644 index 0000000000..0bf438fba4 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-search-file.js @@ -0,0 +1,146 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests the search bar correctly responds to queries, enter, shift enter + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + await selectSource(dbg, "simple1.js"); + + pressKey(dbg, "fileSearch"); + is(dbg.selectors.getActiveSearch(), "file", "The search UI was opened"); + + info("Test closing and re-opening the search UI"); + pressKey(dbg, "Escape"); + is( + dbg.selectors.getActiveSearch(), + null, + "The search UI was closed when hitting Escape" + ); + + pressKey(dbg, "fileSearch"); + is(dbg.selectors.getActiveSearch(), "file", "The search UI was opened again"); + + info("Search for `con` in the script"); + type(dbg, "con"); + await waitForSearchState(dbg); + + // All the lines in the script that include `con` + const linesWithResults = [ + // const func + 4, + // const result + 5, + // constructor (in MyClass) + 42, + // constructor (in Klass) + 55, + // console.log + 62, + ]; + + await waitFor( + () => getCursorPositionLine(dbg) === linesWithResults[0], + `typing in the search input did not set the search state in expected state` + ); + + is( + getCursorPositionLine(dbg), + linesWithResults[0], + "typing in the search input initialize the search" + ); + + info("Check that pressing Enter navigates forward through the results"); + await navigateWithKey( + dbg, + "Enter", + linesWithResults[1], + "Enter moves forward in the search results" + ); + + await navigateWithKey( + dbg, + "Enter", + linesWithResults[2], + "Enter moves forward in the search results" + ); + + info( + "Check that pressing Shift+Enter navigates backward through the results" + ); + await navigateWithKey( + dbg, + "ShiftEnter", + linesWithResults[1], + "Shift+Enter moves backward in the search results" + ); + + await navigateWithKey( + dbg, + "ShiftEnter", + linesWithResults[0], + "Shift+Enter moves backward in the search results" + ); + + info( + "Check that navigating backward goes to the last result when we were at the first one" + ); + await navigateWithKey( + dbg, + "ShiftEnter", + linesWithResults.at(-1), + "Shift+Enter cycles back through the results" + ); + + info( + "Check that navigating forward goes to the first result when we were at the last one" + ); + await navigateWithKey( + dbg, + "Enter", + linesWithResults[0], + "Enter cycles forward through the results" + ); + + info("Check that changing the search term works"); + pressKey(dbg, "fileSearch"); + type(dbg, "doEval"); + + await waitFor( + () => getCursorPositionLine(dbg) === 9, + "The UI navigates to the new search results" + ); + + // selecting another source keeps search open + await selectSource(dbg, "simple2.js"); + ok(findElement(dbg, "searchField"), "Search field is still visible"); + + // search is always focused regardless of when or how it was opened + pressKey(dbg, "fileSearch"); + await clickElement(dbg, "codeMirror"); + pressKey(dbg, "fileSearch"); + is(dbg.win.document.activeElement.tagName, "INPUT", "Search field focused"); +}); + +async function navigateWithKey(dbg, key, expectedLine, assertionMessage) { + const currentLine = getCursorPositionLine(dbg); + pressKey(dbg, key); + await waitFor( + () => currentLine !== getCursorPositionLine(dbg), + `Pressing "${key}" did not change the position` + ); + + is(getCursorPositionLine(dbg), expectedLine, assertionMessage); +} + +function getCursorPositionLine(dbg) { + const cursorPosition = findElementWithSelector(dbg, ".cursor-position"); + const { innerText } = cursorPosition; + // Cursor position text has the following shape: (L, C) + // where N is the line number, and C the column number + const line = innerText.substring(1, innerText.indexOf(",")); + return parseInt(line, 10); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-settings-disable-javascript.js b/devtools/client/debugger/test/mochitest/browser_dbg-settings-disable-javascript.js new file mode 100644 index 0000000000..9b244ca4b7 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-settings-disable-javascript.js @@ -0,0 +1,49 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +requestLongerTimeout(2); + +// Tests that using the Settings menu to enable and disable JavaScript +// updates the pref properly +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple1.js"); + const menuItemClassName = ".debugger-settings-menu-item-disable-javascript"; + + info("Waiting for source to load"); + await waitForSource(dbg, "simple1.js"); + + const waitForDevToolsReload = await watchForDevToolsReload( + gBrowser.selectedBrowser + ); + info("Clicking the disable javascript button in the settings menu"); + await toggleDebbuggerSettingsMenuItem(dbg, { + className: menuItemClassName, + isChecked: false, + }); + + info("Waiting for reload triggered by disabling javascript"); + await waitForSourcesInSourceTree(dbg, [], { noExpand: true }); + + info("Wait for DevTools to be reloaded"); + await waitForDevToolsReload(); + + info( + "Clicking the disable javascript button in the settings menu to reenable JavaScript" + ); + await toggleDebbuggerSettingsMenuItem(dbg, { + className: menuItemClassName, + isChecked: true, + }); + is( + Services.prefs.getBoolPref("javascript.enabled"), + true, + "JavaScript is enabled" + ); + + info("Reloading page to ensure there are sources"); + await reload(dbg); + await waitForSource(dbg, "simple1.js"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-slow-script.js b/devtools/client/debugger/test/mochitest/browser_dbg-slow-script.js new file mode 100644 index 0000000000..d5d60c7994 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-slow-script.js @@ -0,0 +1,91 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests the slow script warning + +add_task(async function openDebuggerFirst() { + // In mochitest, the timeout is disable, so set it to a short, but non zero duration + await pushPref("dom.max_script_run_time", 1); + // Prevents having to click on the page to have the dialog to appear + await pushPref("dom.max_script_run_time.require_critical_input", false); + + const dbg = await initDebugger("doc-slow-script.html"); + + const alert = BrowserTestUtils.waitForGlobalNotificationBar( + window, + "process-hang" + ); + + info("Execute an infinite loop"); + invokeInTab("infiniteLoop"); + + info("Wait for the slow script warning"); + const notification = await alert; + + info("Click on the debug script button"); + const buttons = notification.buttonContainer.getElementsByTagName("button"); + // The first button is "stop", the second is "debug script" + buttons[1].click(); + + info("Waiting for the debugger to be paused"); + await waitForPaused(dbg); + const source = findSource(dbg, "doc-slow-script.html"); + assertPausedAtSourceAndLine(dbg, source.id, 14); + + info("Close toolbox and tab"); + await dbg.toolbox.closeToolbox(); + await removeTab(gBrowser.selectedTab); +}); + +add_task(async function openDebuggerFromDialog() { + const tab = await addTab(EXAMPLE_URL + "doc-slow-script.html"); + + const alert = BrowserTestUtils.waitForGlobalNotificationBar( + window, + "process-hang" + ); + + // /!\ Hack this attribute in order to force showing the "debug script" button + // on all channels. Otherwise it is only displayed in dev edition. + tab.linkedBrowser.browsingContext.watchedByDevTools = true; + + info("Execute an infinite loop"); + // Note that spawn will return a promise that may be rejected because of the infinite loop + // And mochitest may consider this as an error. So ignore any rejection. + SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { + content.wrappedJSObject.infiniteLoop(); + }).catch(e => {}); + + info("Wait for the slow script warning"); + const notification = await alert; + + info("Click on the debug script button"); + const buttons = notification.buttonContainer.getElementsByTagName("button"); + // The first button is "stop", the second is "debug script" + buttons[1].click(); + + info("Wait for the toolbox to appear and have the debugger initialized"); + await waitFor(async () => { + const tb = await gDevTools.getToolboxForTab(gBrowser.selectedTab); + if (tb) { + await tb.getPanelWhenReady("jsdebugger"); + return true; + } + return false; + }); + const toolbox = await gDevTools.getToolboxForTab(gBrowser.selectedTab); + ok(toolbox, "Got a toolbox"); + const dbg = createDebuggerContext(toolbox); + + info("Waiting for the debugger to be paused"); + await waitForPaused(dbg); + const source = findSource(dbg, "doc-slow-script.html"); + assertPausedAtSourceAndLine(dbg, source.id, 14); + + info("Close toolbox and tab"); + await dbg.toolbox.closeToolbox(); + await removeTab(gBrowser.selectedTab); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js b/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js new file mode 100644 index 0000000000..edca4e2b80 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-source-pragma.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +add_task(async function () { + // Disable handling of //# source(Mapping)URL= comments. + await SpecialPowers.pushPrefEnv({ + set: [["javascript.options.source_pragmas", false]], + }); + + const dbg = await initDebugger("doc-source-pragma.html"); + + // The sourceURL pragma didn't rename the source + await waitForSource(dbg, "source-pragma.js"); + const source = findSource(dbg, "source-pragma.js"); + const actors = dbg.selectors.getSourceActorsForSource(source.id); + + is(actors.length, 1, "have a single actor"); + ok( + actors[0].url.endsWith("/source-pragma.js"), + "source url was not rewritten" + ); + is(actors[0].sourceMapURL, null, "source map was not exposed"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourceURL-breakpoint.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourceURL-breakpoint.js new file mode 100644 index 0000000000..a054d4fcac --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourceURL-breakpoint.js @@ -0,0 +1,18 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that breakpoints are hit in eval'ed sources with a sourceURL property. + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-sourceURL-breakpoint.html", "my-foo.js"); + await selectSource(dbg, "my-foo.js"); + await addBreakpoint(dbg, "my-foo.js", 2); + + invokeInTab("foo"); + await waitForPaused(dbg); + + ok(true, "paused at breakpoint"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js new file mode 100644 index 0000000000..2bb4d853fe --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-breakpoint-console.js @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// This test can be really slow on debug platforms and should be split. +requestLongerTimeout(3); + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemapped.html"); + dbg.actions.toggleMapScopes(); + + await evalInConsoleAtPoint( + dbg, + "webpack3-babel6", + "eval-maps", + { line: 14, column: 4 }, + ["one === 1", "two === 4", "three === 5"] + ); + + await evalInConsoleAtPoint( + dbg, + "webpack3-babel6", + "esmodules-cjs", + { line: 18, column: 2 }, + [ + `aDefault === "a-default"`, + `anAliased === "an-original"`, + `aNamed === "a-named"`, + `aDefault2 === "a-default2"`, + `anAliased2 === "an-original2"`, + `aNamed2 === "a-named2"`, + `aDefault3 === "a-default3"`, + `anAliased3 === "an-original3"`, + `aNamed3 === "a-named3"`, + ] + ); + + await evalInConsoleAtPoint( + dbg, + "webpack3-babel6", + "shadowed-vars", + { line: 18, column: 6 }, + [`aVar === "var3"`, `aLet === "let3"`, `aConst === "const3"`] + ); + + await evalInConsoleAtPoint( + dbg, + "webpack3-babel6", + "babel-classes", + { line: 8, column: 16 }, + [`this.hasOwnProperty("bound")`] + ); +}); + +async function evalInConsoleAtPoint( + dbg, + target, + fixture, + { line, column }, + statements +) { + const url = `${target}://./${fixture}/input.js`; + const fnName = `${target}-${fixture}`.replace(/-([a-z])/g, (s, c) => + c.toUpperCase() + ); + + await invokeWithBreakpoint(dbg, fnName, url, { line, column }, async () => { + await assertConsoleEval(dbg, statements); + }); + + ok(true, `Ran tests for ${fixture} at line ${line} column ${column}`); +} + +async function assertConsoleEval(dbg, statements) { + const { hud } = await dbg.toolbox.selectTool("webconsole"); + + for (const statement of statements.values()) { + await dbg.client.evaluate(`window.TEST_RESULT = false;`); + await evaluateExpressionInConsole(hud, `TEST_RESULT = ${statement};`); + + const result = await dbg.client.evaluate(`window.TEST_RESULT`); + is(result.result, true, `'${statement}' evaluates to true`); + } +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-preview.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-preview.js new file mode 100644 index 0000000000..5034761549 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-preview.js @@ -0,0 +1,206 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests for preview through Babel's compile output. +requestLongerTimeout(3); + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemapped.html"); + dbg.actions.toggleMapScopes(); + + await testForOf(dbg); + await testShadowing(dbg); + await testImportedBindings(dbg); +}); + +async function breakpointPreviews( + dbg, + target, + fixture, + { line, column }, + previews +) { + const url = `${target}://./${fixture}/input.js`; + const fnName = `${target}-${fixture}`.replace(/-([a-z])/g, (s, c) => + c.toUpperCase() + ); + + info(`Starting ${fixture} tests`); + + await invokeWithBreakpoint(dbg, fnName, url, { line, column }, async () => { + await assertPreviews(dbg, previews); + }); + + ok(true, `Ran tests for ${fixture} at line ${line} column ${column}`); +} + +function testForOf(dbg) { + return breakpointPreviews( + dbg, + "webpack3-babel6", + "for-of", + { line: 5, column: 4 }, + [ + { + line: 5, + column: 7, + expression: "doThing", + result: "doThing(arg)", + }, + { + line: 5, + column: 13, + expression: "x", + result: "1", + }, + { + line: 8, + column: 16, + expression: "doThing", + result: "doThing(arg)", + }, + ] + ); +} + +function testShadowing(dbg) { + return breakpointPreviews( + dbg, + "webpack3-babel6", + "shadowed-vars", + { line: 18, column: 6 }, + [ + // These aren't what the user would expect, but we test them anyway since + // they reflect what this actually returns. These shadowed bindings read + // the binding closest to the current frame's scope even though their + // actual value is different. + { + line: 2, + column: 9, + expression: "aVar", + result: '"var3"', + }, + { + line: 3, + column: 9, + expression: "_aLet2;", + result: '"let3"', + }, + { + line: 4, + column: 11, + expression: "_aConst2;", + result: '"const3"', + }, + { + line: 10, + column: 11, + expression: "aVar", + result: '"var3"', + }, + { + line: 11, + column: 11, + expression: "_aLet2;", + result: '"let3"', + }, + { + line: 12, + column: 13, + expression: "_aConst2;", + result: '"const3"', + }, + + // These actually result in the values the user would expect. + { + line: 14, + column: 13, + expression: "aVar", + result: '"var3"', + }, + { + line: 15, + column: 13, + expression: "_aLet2;", + result: '"let3"', + }, + { + line: 16, + column: 13, + expression: "_aConst2;", + result: '"const3"', + }, + ] + ); +} + +function testImportedBindings(dbg) { + return breakpointPreviews( + dbg, + "webpack3-babel6", + "esmodules-cjs", + { line: 20, column: 2 }, + [ + { + line: 20, + column: 16, + expression: "_mod2.default;", + result: '"a-default"', + }, + { + line: 21, + column: 16, + expression: "_mod4.original;", + result: '"an-original"', + }, + { + line: 22, + column: 16, + expression: "_mod3.aNamed;", + result: '"a-named"', + }, + { + line: 23, + column: 16, + expression: "_mod3.aNamed;", + result: '"a-named"', + }, + { + line: 24, + column: 16, + expression: "aNamespace", + fields: [ + ["aNamed", '"a-named"'], + ["default", '"a-default"'], + ], + }, + { + line: 29, + column: 20, + expression: "_mod7.default;", + result: '"a-default2"', + }, + { + line: 30, + column: 20, + expression: "_mod9.original;", + result: '"an-original2"', + }, + { + line: 31, + column: 20, + expression: "_mod8.aNamed2;", + result: '"a-named2"', + }, + { + line: 32, + column: 20, + expression: "_mod8.aNamed2;", + result: '"a-named2"', + }, + ] + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-scopes.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-scopes.js new file mode 100644 index 0000000000..d3029a683e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-scopes.js @@ -0,0 +1,1646 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// This test can be really slow on debug platforms and should be split. +requestLongerTimeout(30); + +// Tests loading sourcemapped sources for Babel's compile output. + +/* eslint-disable no-inline-comments */ + +const ACTIVE_TARGETS = new Set([ + // "webpack3", + "webpack3-babel6", + // "webpack3-babel7", + // "webpack4", + // "webpack4-babel6", + // "webpack4-babel7", + "rollup", + // "rollup-babel6", + // "rollup-babel7", + "parcel", +]); + +const ACTIVE_FIXTURES = [ + testBabelBindingsWithFlow, + testBabelFlowtypeBindings, + testEvalMaps, + testForOf, + testShadowedVars, + testLineStartBindingsES6, + testThisArgumentsBindings, + testClasses, + testForLoops, + testFunctions, + testSwitches, + testTryCatches, + testLexAndNonlex, + testTypescriptClasses, + testTypeModule, + testTypeScriptCJS, + testOutOfOrderDeclarationsCJS, + testModulesCJS, + testWebpackLineMappings, + testWebpackFunctions, + testESModules, + testESModulesCJS, + testESModulesES6, +]; + +async function breakpointScopes( + dbg, + target, + fixture, + { line, column }, + scopes +) { + if (!ACTIVE_TARGETS.has(target)) { + return; + } + + const extension = fixture == "typescript-classes" ? "ts" : "js"; + const url = `${target}://./${fixture}/input.${extension}`; + const fnName = pairToFnName(target, fixture); + + await invokeWithBreakpoint(dbg, fnName, url, { line, column }, async () => { + await assertScopes(dbg, scopes); + }); + + ok(true, `Ran tests for ${fixture} at line ${line} column ${column}`); +} + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemapped.html"); + dbg.actions.toggleMapScopes(); + + for (const fixture of ACTIVE_FIXTURES) { + await fixture(dbg); + } +}); + +function targetToFlags(target) { + const isRollup = target.startsWith("rollup"); + const isWebpack = target.startsWith("webpack"); + const isParcel = target.startsWith("parcel"); + const isWebpack4 = target.startsWith("webpack4"); + + // Rollup removes lots of things as dead code, so they are marked as optimized out. + const rollupOptimized = isRollup ? "(optimized away)" : null; + const webpackImportGetter = isWebpack ? "Getter" : null; + const webpack4ImportGetter = isWebpack4 ? "Getter" : null; + const maybeLineStart = col => col; + const defaultExport = isWebpack4 + ? name => `${name}()` + : name => [name, "(optimized away)"]; + + return { + isRollup, + isWebpack, + isParcel, + rollupOptimized, + webpackImportGetter, + webpack4ImportGetter, + maybeLineStart, + defaultExport, + }; +} +function pairToFnName(target, fixture) { + return `${target}-${fixture}`.replace(/-([a-z])/g, (s, c) => c.toUpperCase()); +} + +function runtimeFunctionName(target, fixture) { + // Webpack 4 appears to output it's bundles in such a way that Spidermonkey + if (target === "webpack4") { + return "js"; + } + + return pairToFnName(target, fixture); +} + +function webpackModule(target, fixture, optimizedOut) { + return [ + runtimeFunctionName(target, fixture), + ["__webpack_exports__", optimizedOut ? "(optimized away)" : "{\u2026}"], + optimizedOut + ? ["__webpack_require__", "(optimized away)"] + : "__webpack_require__()", + ["arguments", optimizedOut ? "(unavailable)" : "Arguments"], + ]; +} + +async function testBabelBindingsWithFlow(dbg) { + // Flow is not available on the non-babel builds. + for (const target of [ + "parcel", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { webpackImportGetter } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "babel-bindings-with-flow", + { line: 9, column: 2 }, + [ + "root", + ["value", '"a-named"'], + "Module", + ["aNamed", webpackImportGetter || '"a-named"'], + "root()", + ] + ); + } +} + +async function testBabelFlowtypeBindings(dbg) { + // Flow is not available on the non-babel builds. + for (const target of [ + "parcel", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { webpackImportGetter } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "babel-flowtype-bindings", + { line: 9, column: 2 }, + [ + "Module", + ["aConst", '"a-const"'], + ["Four", webpackImportGetter || '"one"'], + "root()", + ] + ); + } +} + +async function testEvalMaps(dbg) { + // At times, this test has been a bit flakey due to the inlined source map + // never loading. I'm not sure what causes that. If we observe flakiness in CI, + // we should consider disabling this test for now. + + for (const target of ["webpack3", "webpack4"]) { + const { defaultExport } = targetToFlags(target); + + await breakpointScopes(dbg, target, "eval-maps", { line: 14, column: 4 }, [ + "Block", + ["", "Window"], + ["three", "5"], + ["two", "4"], + "Block", + ["three", "3"], + ["two", "2"], + "Block", + ["arguments", "Arguments"], + ["one", "1"], + ...webpackModule(target, "eval-maps", true /* optimized out */), + ["module", "(optimized away)"], + defaultExport("root"), + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { defaultExport, rollupOptimized, maybeLineStart } = + targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "eval-maps", + { line: 14, column: maybeLineStart(4) }, + [ + "Block", + ["three", "5"], + ["two", "4"], + "Function Body", + ["three", rollupOptimized || "3"], + ["two", rollupOptimized || "2"], + "root", + ["one", "1"], + "Module", + defaultExport("root"), + ] + ); + } +} + +async function testForOf(dbg) { + for (const target of ["webpack3", "webpack4"]) { + const { defaultExport } = targetToFlags(target); + + await breakpointScopes(dbg, target, "for-of", { line: 5, column: 0 }, [ + "Block", + ["", "Window"], + ["x", "1"], + "Block", + ["arguments", "Arguments"], + "class doThing", + "Block", + "mod", + ...webpackModule(target, "for-of", true /* optimizedOut */), + defaultExport("forOf"), + "module", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { defaultExport, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "for-of", + { line: 5, column: maybeLineStart(4) }, + [ + "For", + ["x", "1"], + "forOf", + "doThing(arg)", + "Module", + defaultExport("forOf"), + "mod", + ] + ); + } +} + +async function testShadowedVars(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes( + dbg, + target, + "shadowed-vars", + { line: 18, column: 0 }, + [ + "Block", + ["", "Window"], + ["aConst", '"const3"'], + ["aLet", '"let3"'], + + "Block", + ["aConst", '"const2"'], + ["aLet", '"let2"'], + "class Outer", + + "Block", + ["aConst", '"const1"'], + ["aLet", '"let1"'], + "class Outer", + + "Block", + ["arguments", "Arguments"], + ["aVar", '"var3"'], + + ...webpackModule(target, "shadowed-vars", true /* optimizedOut */), + ["module", "(optimized away)"], + ] + ); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { isParcel, rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "shadowed-vars", + { line: 18, column: maybeLineStart(6) }, + [ + "Block", + ["aConst", rollupOptimized || '"const3"'], + ["aLet", rollupOptimized || '"let3"'], + "Block", + ["aConst", rollupOptimized || '"const2"'], + ["aLet", rollupOptimized || '"let2"'], + // eslint-disable-next-line no-nested-ternary + isParcel + ? "Outer()" + : rollupOptimized + ? ["Outer", rollupOptimized] + : "Outer:_Outer()", + "Function Body", + ["aConst", rollupOptimized || '"const1"'], + ["aLet", rollupOptimized || '"let1"'], + // eslint-disable-next-line no-nested-ternary + rollupOptimized + ? ["Outer", rollupOptimized] + : isParcel + ? "class Outer" + : "Outer()", + "default", + ["aVar", rollupOptimized || '"var3"'], + ] + ); + } +} + +async function testLineStartBindingsES6(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes( + dbg, + target, + "line-start-bindings-es6", + { line: 19, column: 0 }, + [ + "Block", + ["", "{\u2026}"], + ["one", "1"], + ["two", "2"], + "Block", + ["arguments", "Arguments"], + + "Block", + ["aFunc", "(optimized away)"], + ["arguments", "(unavailable)"], + + ...webpackModule( + target, + "line-start-bindings-es6", + true /* optimizedOut */ + ), + ["module", "(optimized away)"], + "root()", + ] + ); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "line-start-bindings-es6", + { line: 19, column: maybeLineStart(4) }, + [ + "Function Body", + ["", "{\u2026}"], + ["one", rollupOptimized || "1"], + ["two", rollupOptimized || "2"], + "root", + ["aFunc", "(optimized away)"], + "Module", + "root()", + ] + ); + } +} + +async function testThisArgumentsBindings(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes( + dbg, + target, + "this-arguments-bindings", + { line: 4, column: 0 }, + [ + "Block", + ["", '"this-value"'], + ["arrow", "(uninitialized)"], + "fn", + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + "root", + ["arguments", "Arguments"], + "fn()", + ...webpackModule( + target, + "this-arguments-bindings", + true /* optimizedOut */ + ), + ["module", "(optimized away)"], + "root()", + ] + ); + + await breakpointScopes( + dbg, + target, + "this-arguments-bindings", + { line: 8, column: 0 }, + [ + "Block", + ["", '"this-value"'], + ["argArrow", '"arrow-arg"'], + ["arguments", "Arguments"], + "Block", + ["arrow", "(optimized away)"], + "fn", + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + "root", + ["arguments", "Arguments"], + "fn()", + ...webpackModule( + target, + "this-arguments-bindings", + true /* optimizedOut */ + ), + ["module", "(optimized away)"], + "root()", + ] + ); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { isParcel, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "this-arguments-bindings", + { line: 4, column: maybeLineStart(4) }, + [ + "Function Body", + ["", '"this-value"'], + [ + "arrow", + target === "rollup" || isParcel ? "(uninitialized)" : "undefined", + ], + "fn", + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + "root", + "fn(arg)", + "Module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + target, + "this-arguments-bindings", + { line: 8, column: maybeLineStart(6) }, + [ + "arrow", + ["", '"this-value"'], + ["argArrow", '"arrow-arg"'], + "Function Body", + target === "rollup" || isParcel + ? ["arrow", "(optimized away)"] + : "arrow(argArrow)", + "fn", + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + "root", + "fn(arg)", + "Module", + "root()", + ] + ); + } +} + +async function testClasses(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "classes", { line: 6, column: 0 }, [ + "Block", + ["", "{}"], + ["arguments", "Arguments"], + "Block", + ["Thing", "(optimized away)"], + "Block", + "Another()", + ["one", "1"], + "Thing()", + "Block", + ["arguments", "(unavailable)"], + ...webpackModule(target, "classes", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + + await breakpointScopes(dbg, target, "classes", { line: 16, column: 0 }, [ + "Block", + ["", "{}"], + ["three", "3"], + ["two", "2"], + "Block", + ["arguments", "Arguments"], + "Block", + "Another()", + "Block", + "Another()", + ["one", "1"], + "Thing()", + "Block", + ["arguments", "(unavailable)"], + ...webpackModule(target, "classes", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { isParcel, rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "classes", + { line: 6, column: maybeLineStart(6) }, + [ + "Class", + target === "rollup" || isParcel + ? ["Thing", "(optimized away)"] + : "Thing()", + "Function Body", + target === "webpack3-babel6" ? "Another()" : "class Another", + "one", + target === "rollup" || isParcel + ? ["Thing", "(optimized away)"] + : "Thing()", + "Module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + target, + "classes", + { line: 16, column: maybeLineStart(6) }, + [ + "Function Body", + ["three", rollupOptimized || "3"], + ["two", rollupOptimized || "2"], + "Class", + target === "webpack3-babel6" ? "Another()" : "class Another", + "Function Body", + target === "webpack3-babel6" ? "Another()" : "class Another", + ["one", "1"], + target === "webpack3-babel6" ? "Thing()" : "class Thing", + "Module", + "root()", + ] + ); + } +} + +async function testForLoops(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "for-loops", { line: 5, column: 0 }, [ + "Block", + ["", "Window"], + ["i", "1"], + "Block", + ["i", "0"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "for-loops", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + await breakpointScopes(dbg, target, "for-loops", { line: 9, column: 0 }, [ + "Block", + ["", "Window"], + ["i", '"2"'], + "Block", + ["i", "0"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "for-loops", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + await breakpointScopes(dbg, target, "for-loops", { line: 13, column: 0 }, [ + "Block", + ["", "Window"], + ["i", "3"], + "Block", + ["i", "0"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "for-loops", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "for-loops", + { line: 5, column: maybeLineStart(4) }, + [ + "For", + ["i", "1"], + "Function Body", + ["i", rollupOptimized || "0"], + "Module", + "root()", + ] + ); + await breakpointScopes( + dbg, + target, + "for-loops", + { line: 9, column: maybeLineStart(4) }, + [ + "For", + ["i", '"2"'], + "Function Body", + ["i", rollupOptimized || "0"], + "Module", + "root()", + ] + ); + await breakpointScopes( + dbg, + target, + "for-loops", + { line: 13, column: maybeLineStart(4) }, + [ + "For", + ["i", target === "rollup" ? "3" : rollupOptimized || "3"], + "Function Body", + ["i", rollupOptimized || "0"], + "Module", + "root()", + ] + ); + } +} + +async function testFunctions(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "functions", { line: 6, column: 0 }, [ + "Block", + ["", "(optimized away)"], + ["arguments", "Arguments"], + ["p3", "undefined"], + "Block", + "arrow()", + "inner", + ["arguments", "Arguments"], + ["p2", "undefined"], + "Block", + "inner(p2)", + "Block", + ["inner", "(optimized away)"], + "decl", + ["arguments", "Arguments"], + ["p1", "undefined"], + "root", + ["arguments", "Arguments"], + "decl()", + ...webpackModule(target, "functions", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { isParcel, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "functions", + { line: 6, column: maybeLineStart(8) }, + [ + "arrow", + ["p3", "undefined"], + "Function Body", + "arrow(p3)", + "inner", + ["p2", "undefined"], + "Function Expression", + "inner(p2)", + "Function Body", + target === "rollup" || isParcel + ? ["inner", "(optimized away)"] + : "inner(p2)", + "decl", + ["p1", "undefined"], + "root", + "decl(p1)", + "Module", + "root()", + ] + ); + } +} + +async function testSwitches(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "switches", { line: 7, column: 0 }, [ + "Block", + ["", "Window"], + ["val", "2"], + "Block", + ["val", "1"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "switches", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + + await breakpointScopes(dbg, target, "switches", { line: 10, column: 0 }, [ + "Block", + ["", "Window"], + ["val", "3"], + "Block", + ["val", "2"], + "Block", + ["val", "1"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "switches", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "switches", + { line: 7, column: maybeLineStart(6) }, + [ + "Switch", + ["val", rollupOptimized || "2"], + "Function Body", + ["val", rollupOptimized || "1"], + "Module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + target, + "switches", + { line: 10, column: maybeLineStart(6) }, + [ + "Block", + ["val", rollupOptimized || "3"], + "Switch", + ["val", rollupOptimized || "2"], + "Function Body", + ["val", rollupOptimized || "1"], + "Module", + "root()", + ] + ); + } +} + +async function testTryCatches(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "try-catches", { line: 8, column: 0 }, [ + "Block", + ["", "Window"], + ["two", "2"], + "Block", + ["err", '"AnError"'], + "Block", + ["one", "1"], + "Block", + ["arguments", "Arguments"], + ...webpackModule(target, "try-catches", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { rollupOptimized, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "try-catches", + { line: 8, column: maybeLineStart(4) }, + [ + "Block", + ["two", rollupOptimized || "2"], + "Catch", + ["err", '"AnError"'], + "Function Body", + ["one", rollupOptimized || "1"], + "Module", + "root()", + ] + ); + } +} + +async function testLexAndNonlex(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes( + dbg, + target, + "lex-and-nonlex", + { line: 3, column: 0 }, + [ + "Block", + ["", "undefined"], + ["arguments", "Arguments"], + "Block", + "class Thing", + "Block", + ["arguments", "(unavailable)"], + ["someHelper", "(optimized away)"], + ...webpackModule(target, "lex-and-nonlex", true /* optimizedOut */), + ["module", "(optimized away)"], + "root()", + ] + ); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { isParcel, maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "lex-and-nonlex", + { line: 3, column: maybeLineStart(4) }, + [ + "Function Body", + target === "rollup" || target === "parcel" ? "class Thing" : "Thing()", + "root", + target === "rollup" || isParcel + ? ["someHelper", "(optimized away)"] + : "someHelper()", + "Module", + "root()", + ] + ); + } +} + +async function testTypescriptClasses(dbg) { + // Typescript is not available on the Babel builds. + for (const target of ["parcel", "webpack3", "webpack4", "rollup"]) { + const { isRollup, isParcel, rollupOptimized } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "typescript-classes", + { line: 50, column: 2 }, + [ + "Module", + "AnotherThing()", + "AppComponent()", + "decoratorFactory(opts)", + rollupOptimized ? ["def", rollupOptimized] : "def()", + rollupOptimized + ? ["ExportedOther", rollupOptimized] + : "ExportedOther()", + rollupOptimized + ? ["ExpressionClass", rollupOptimized] + : "ExpressionClass:Foo()", + "fn(arg)", + // Rollup optimizes out the 'ns' reference here, but when it does, it leave a mapping + // pointed at a location that is super weird, so it ends up being unmapped instead + // be "(optimized out)". + // Parcel converts the "ns;" mapping into a single full-line mapping, for some reason. + // That may have to do with https://github.com/parcel-bundler/parcel/pull/1755#discussion_r205584159 + // though it's not 100% clear. + ["ns", isRollup || isParcel ? "(unmapped)" : "{\u2026}"], + "SubDecl()", + "SubVar:SubExpr()", + ] + ); + } +} + +async function testTypeModule(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "type-module", { line: 7, column: 0 }, [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + "Block", + ["alsoModuleScoped", "2"], + ...webpackModule(target, "type-module", true /* optimizedOut */), + ["module", "(optimized away)"], + ["moduleScoped", "1"], + "thirdModuleScoped()", + ]); + } + + for (const target of [ + "parcel", + "rollup", + "rollup-babel6", + "rollup-babel7", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { maybeLineStart } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "type-module", + { line: 7, column: maybeLineStart(2) }, + [ + "Module", + ["alsoModuleScoped", "2"], + ["moduleScoped", "1"], + "thirdModuleScoped()", + ] + ); + } +} + +async function testTypeScriptCJS(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes( + dbg, + target, + "type-script-cjs", + { line: 7, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + "Block", + "alsoModuleScopes", + + runtimeFunctionName(target, "type-script-cjs"), + ["arguments", "(unavailable)"], + ["exports", "(optimized away)"], + ["module", "(optimized away)"], + "moduleScoped", + "nonModules", + "thirdModuleScoped", + ] + ); + } + + // CJS does not work on Rollup. + for (const target of [ + "parcel", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + await breakpointScopes( + dbg, + target, + "type-script-cjs", + { line: 7, column: 2 }, + [ + "Module", + "alsoModuleScopes", + "moduleScoped", + "nonModules", + "thirdModuleScoped", + ] + ); + } +} + +async function testOutOfOrderDeclarationsCJS(dbg) { + // CJS does not work on Rollup. + for (const target of [ + "parcel", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + await breakpointScopes( + dbg, + target, + "out-of-order-declarations-cjs", + { line: 8, column: 4 }, + [ + "callback", + "fn(inner)", + ["val", "undefined"], + "root", + ["callback", "(optimized away)"], + ["fn", "(optimized away)"], + ["val", "(optimized away)"], + "Module", + + // This value is currently optimized away, which isn't 100% accurate. + // Because import declarations is the last thing in the file, our current + // logic doesn't cover _both_ 'var' statements that it generates, + // making us use the first, optimized-out binding. Given that imports + // are almost never the last thing in a file though, this is probably not + // a huge deal for now. + [ + "aDefault", + target.match(/webpack(3|4)-babel7/) + ? '"a-default"' + : "(optimized away)", + ], + ["root", "(optimized away)"], + ["val", "(optimized away)"], + ] + ); + } +} + +async function testModulesCJS(dbg) { + for (const target of ["webpack3", "webpack4"]) { + await breakpointScopes(dbg, target, "modules-cjs", { line: 7, column: 0 }, [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + "Block", + ["alsoModuleScoped", "2"], + runtimeFunctionName(target, "modules-cjs"), + ["arguments", "(unavailable)"], + ["exports", "(optimized away)"], + ["module", "(optimized away)"], + ["moduleScoped", "1"], + "thirdModuleScoped()", + ]); + } + + // CJS does not work on Rollup. + for (const target of [ + "parcel", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + await breakpointScopes(dbg, target, "modules-cjs", { line: 7, column: 2 }, [ + "Module", + ["alsoModuleScoped", "2"], + ["moduleScoped", "1"], + "thirdModuleScoped()", + ]); + } +} + +async function testWebpackLineMappings(dbg) { + await breakpointScopes( + dbg, + "webpack3", + "webpack-line-mappings", + { line: 11, column: 0 }, + [ + "Block", + ["", '"this-value"'], + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + ["inner", "undefined"], + "Block", + ["someName", "(optimized away)"], + "Block", + ["two", "2"], + "Block", + ["one", "1"], + "root", + ["arguments", "Arguments"], + "fn:someName()", + runtimeFunctionName("webpack3", "webpack-line-mappings"), + ["__webpack_exports__", "(optimized away)"], + ["__WEBPACK_IMPORTED_MODULE_0__src_mod1__", "{\u2026}"], + ["__webpack_require__", "(optimized away)"], + ["arguments", "(unavailable)"], + ["module", "(optimized away)"], + "root()", + ] + ); + + await breakpointScopes( + dbg, + "webpack4", + "webpack-line-mappings", + { line: 11, column: 0 }, + [ + "Block", + ["", '"this-value"'], + ["arg", '"arg-value"'], + ["arguments", "Arguments"], + ["inner", "undefined"], + "Block", + ["someName", "(optimized away)"], + "Block", + ["two", "2"], + "Block", + ["one", "1"], + "root", + ["arguments", "Arguments"], + "fn:someName()", + runtimeFunctionName("webpack4", "webpack-line-mappings"), + ["__webpack_exports__", "(optimized away)"], + ["__webpack_require__", "(optimized away)"], + ["_src_mod1__WEBPACK_IMPORTED_MODULE_0__", "{\u2026}"], + ["arguments", "(unavailable)"], + ["module", "(optimized away)"], + "root()", + ] + ); +} + +async function testWebpackFunctions(dbg) { + for (const target of ["webpack3", "webpack4"]) { + const { defaultExport } = targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "webpack-functions", + { line: 4, column: 0 }, + [ + "Block", + ["", "{\u2026}"], + ["arguments", "Arguments"], + ["x", "4"], + runtimeFunctionName(target, "webpack-functions"), + ["__webpack_exports__", "(optimized away)"], + ["__webpack_require__", "(optimized away)"], + ["arguments", "(unavailable)"], + ["module", "{\u2026}"], + defaultExport("root"), + ] + ); + } +} + +async function testESModules(dbg) { + await breakpointScopes( + dbg, + "webpack3", + "esmodules", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack3", "esmodules"), + "__webpack_exports__", + "__WEBPACK_IMPORTED_MODULE_0__src_mod1__", + "__WEBPACK_IMPORTED_MODULE_1__src_mod2__", + "__WEBPACK_IMPORTED_MODULE_10__src_optimized_out__", + "__WEBPACK_IMPORTED_MODULE_2__src_mod3__", + "__WEBPACK_IMPORTED_MODULE_3__src_mod4__", + "__WEBPACK_IMPORTED_MODULE_4__src_mod5__", + "__WEBPACK_IMPORTED_MODULE_5__src_mod6__", + "__WEBPACK_IMPORTED_MODULE_6__src_mod7__", + "__WEBPACK_IMPORTED_MODULE_7__src_mod9__", + "__WEBPACK_IMPORTED_MODULE_8__src_mod10__", + "__WEBPACK_IMPORTED_MODULE_9__src_mod11__", + "__webpack_require__", + "arguments", + "example", + "module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + "webpack4", + "esmodules", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack4", "esmodules"), + "__webpack_exports__", + "__webpack_require__", + "_src_mod1__WEBPACK_IMPORTED_MODULE_0__", + "_src_mod10__WEBPACK_IMPORTED_MODULE_8__", + "_src_mod11__WEBPACK_IMPORTED_MODULE_9__", + "_src_mod2__WEBPACK_IMPORTED_MODULE_1__", + "_src_mod3__WEBPACK_IMPORTED_MODULE_2__", + "_src_mod4__WEBPACK_IMPORTED_MODULE_3__", + "_src_mod5__WEBPACK_IMPORTED_MODULE_4__", + "_src_mod6__WEBPACK_IMPORTED_MODULE_5__", + "_src_mod7__WEBPACK_IMPORTED_MODULE_6__", + "_src_mod9__WEBPACK_IMPORTED_MODULE_7__", + "_src_optimized_out__WEBPACK_IMPORTED_MODULE_10__", + "arguments", + "example()", + "module", + "root()", + ] + ); + + for (const target of [ + "parcel", + "rollup", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { defaultExport, webpackImportGetter, maybeLineStart } = + targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "esmodules", + { line: 20, column: maybeLineStart(2) }, + [ + "Module", + ["aDefault", '"a-default"'], + ["aDefault2", '"a-default2"'], + ["aDefault3", '"a-default3"'], + ["anAliased", webpackImportGetter || '"an-original"'], + ["anAliased2", webpackImportGetter || '"an-original2"'], + ["anAliased3", webpackImportGetter || '"an-original3"'], + ["aNamed", webpackImportGetter || '"a-named"'], + ["aNamed2", webpackImportGetter || '"a-named2"'], + ["aNamed3", webpackImportGetter || '"a-named3"'], + ["aNamespace", "{\u2026}"], + ["anotherNamed", webpackImportGetter || '"a-named"'], + ["anotherNamed2", webpackImportGetter || '"a-named2"'], + ["anotherNamed3", webpackImportGetter || '"a-named3"'], + defaultExport("example"), + ["optimizedOut", "(optimized away)"], + "root()", + ] + ); + } + + for (const target of ["rollup-babel6", "rollup-babel7"]) { + // This test currently bails out because Babel does not map function calls + // fully and includes the () of the call in the range of the identifier. + // this means that Rollup, has to map locations for calls to imports, + // it can fail. This will be addressed in Babel eventually. + await breakpointScopes(dbg, target, "esmodules", { line: 20, column: 2 }, [ + "root", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName(target, "esmodules"), + ["aDefault", '"a-default"'], + ["aDefault2", '"a-default2"'], + ["aDefault3", '"a-default3"'], + ["aNamed", '"a-named"'], + ["aNamed$1", "(optimized away)"], + ["aNamed2", '"a-named2"'], + ["aNamed3", '"a-named3"'], + ["aNamespace", "{\u2026}"], + ["arguments", "(unavailable)"], + ["mod4", "(optimized away)"], + ["original", '"an-original"'], + ["original$1", '"an-original2"'], + ["original$2", '"an-original3"'], + "root()", + ]); + } +} + +async function testESModulesCJS(dbg) { + await breakpointScopes( + dbg, + "webpack3", + "esmodules-cjs", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack3", "esmodules-cjs"), + "__webpack_exports__", + "__WEBPACK_IMPORTED_MODULE_0__src_mod1__", + "__WEBPACK_IMPORTED_MODULE_1__src_mod2__", + "__WEBPACK_IMPORTED_MODULE_10__src_optimized_out__", + "__WEBPACK_IMPORTED_MODULE_2__src_mod3__", + "__WEBPACK_IMPORTED_MODULE_3__src_mod4__", + "__WEBPACK_IMPORTED_MODULE_4__src_mod5__", + "__WEBPACK_IMPORTED_MODULE_5__src_mod6__", + "__WEBPACK_IMPORTED_MODULE_6__src_mod7__", + "__WEBPACK_IMPORTED_MODULE_7__src_mod9__", + "__WEBPACK_IMPORTED_MODULE_8__src_mod10__", + "__WEBPACK_IMPORTED_MODULE_9__src_mod11__", + "__webpack_require__", + "arguments", + "example", + "module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + "webpack4", + "esmodules-cjs", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack4", "esmodules-cjs"), + "__webpack_exports__", + "__webpack_require__", + "_src_mod1__WEBPACK_IMPORTED_MODULE_0__", + "_src_mod10__WEBPACK_IMPORTED_MODULE_8__", + "_src_mod11__WEBPACK_IMPORTED_MODULE_9__", + "_src_mod2__WEBPACK_IMPORTED_MODULE_1__", + "_src_mod3__WEBPACK_IMPORTED_MODULE_2__", + "_src_mod4__WEBPACK_IMPORTED_MODULE_3__", + "_src_mod5__WEBPACK_IMPORTED_MODULE_4__", + "_src_mod6__WEBPACK_IMPORTED_MODULE_5__", + "_src_mod7__WEBPACK_IMPORTED_MODULE_6__", + "_src_mod9__WEBPACK_IMPORTED_MODULE_7__", + "_src_optimized_out__WEBPACK_IMPORTED_MODULE_10__", + "arguments", + "example()", + "module", + "root()", + ] + ); + + // CJS does not work on Rollup. + for (const target of [ + "parcel", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + await breakpointScopes( + dbg, + target, + "esmodules-cjs", + { line: 20, column: 2 }, + [ + "Module", + ["aDefault", '"a-default"'], + ["aDefault2", '"a-default2"'], + ["aDefault3", '"a-default3"'], + ["anAliased", '"an-original"'], + ["anAliased2", '"an-original2"'], + ["anAliased3", '"an-original3"'], + ["aNamed", '"a-named"'], + ["aNamed2", '"a-named2"'], + ["aNamed3", '"a-named3"'], + ["aNamespace", "{\u2026}"], + ["anotherNamed", '"a-named"'], + ["anotherNamed2", '"a-named2"'], + ["anotherNamed3", '"a-named3"'], + ["example", "(optimized away)"], + ["optimizedOut", "(optimized away)"], + "root()", + ] + ); + } +} + +async function testESModulesES6(dbg) { + await breakpointScopes( + dbg, + "webpack3", + "esmodules-es6", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack3", "esmodules-es6"), + "__webpack_exports__", + "__WEBPACK_IMPORTED_MODULE_0__src_mod1__", + "__WEBPACK_IMPORTED_MODULE_1__src_mod2__", + "__WEBPACK_IMPORTED_MODULE_10__src_optimized_out__", + "__WEBPACK_IMPORTED_MODULE_2__src_mod3__", + "__WEBPACK_IMPORTED_MODULE_3__src_mod4__", + "__WEBPACK_IMPORTED_MODULE_4__src_mod5__", + "__WEBPACK_IMPORTED_MODULE_5__src_mod6__", + "__WEBPACK_IMPORTED_MODULE_6__src_mod7__", + "__WEBPACK_IMPORTED_MODULE_7__src_mod9__", + "__WEBPACK_IMPORTED_MODULE_8__src_mod10__", + "__WEBPACK_IMPORTED_MODULE_9__src_mod11__", + "__webpack_require__", + "arguments", + "example", + "module", + "root()", + ] + ); + + await breakpointScopes( + dbg, + "webpack4", + "esmodules-es6", + { line: 20, column: 0 }, + [ + "Block", + ["", "Window"], + ["arguments", "Arguments"], + runtimeFunctionName("webpack4", "esmodules-es6"), + "__webpack_exports__", + "__webpack_require__", + "_src_mod1__WEBPACK_IMPORTED_MODULE_0__", + "_src_mod10__WEBPACK_IMPORTED_MODULE_8__", + "_src_mod11__WEBPACK_IMPORTED_MODULE_9__", + "_src_mod2__WEBPACK_IMPORTED_MODULE_1__", + "_src_mod3__WEBPACK_IMPORTED_MODULE_2__", + "_src_mod4__WEBPACK_IMPORTED_MODULE_3__", + "_src_mod5__WEBPACK_IMPORTED_MODULE_4__", + "_src_mod6__WEBPACK_IMPORTED_MODULE_5__", + "_src_mod7__WEBPACK_IMPORTED_MODULE_6__", + "_src_mod9__WEBPACK_IMPORTED_MODULE_7__", + "_src_optimized_out__WEBPACK_IMPORTED_MODULE_10__", + "arguments", + "example()", + "module", + "root()", + ] + ); + + for (const target of [ + "parcel", + "rollup", + "webpack3-babel6", + "webpack3-babel7", + "webpack4-babel6", + "webpack4-babel7", + ]) { + const { defaultExport, webpack4ImportGetter, maybeLineStart } = + targetToFlags(target); + + await breakpointScopes( + dbg, + target, + "esmodules-es6", + { line: 20, column: maybeLineStart(2) }, + [ + "Module", + ["aDefault", '"a-default"'], + ["aDefault2", '"a-default2"'], + ["aDefault3", '"a-default3"'], + ["anAliased", webpack4ImportGetter || '"an-original"'], + ["anAliased2", webpack4ImportGetter || '"an-original2"'], + ["anAliased3", webpack4ImportGetter || '"an-original3"'], + ["aNamed", webpack4ImportGetter || '"a-named"'], + ["aNamed2", webpack4ImportGetter || '"a-named2"'], + ["aNamed3", webpack4ImportGetter || '"a-named3"'], + ["aNamespace", "{\u2026}"], + ["anotherNamed", webpack4ImportGetter || '"a-named"'], + ["anotherNamed2", webpack4ImportGetter || '"a-named2"'], + ["anotherNamed3", webpack4ImportGetter || '"a-named3"'], + defaultExport("example"), + ["optimizedOut", "(optimized away)"], + "root()", + ] + ); + } + + for (const target of ["rollup-babel6", "rollup-babel7"]) { + // This test currently bails out because Babel does not map function calls + // fully and includes the () of the call in the range of the identifier. + // this means that Rollup, has to map locations for calls to imports, + // it can fail. This will be addressed in Babel eventually. + await breakpointScopes( + dbg, + target, + "esmodules-es6", + { line: 20, column: 2 }, + [ + "root", + ["", "Window"], + ["arguments", "Arguments"], + + "Block", + ["aNamed", '"a-named"'], + ["aNamed$1", "undefined"], + ["aNamed2", '"a-named2"'], + ["aNamed3", '"a-named3"'], + ["original", '"an-original"'], + ["original$1", '"an-original2"'], + ["original$2", '"an-original3"'], + + runtimeFunctionName(target, "esmodules-es6"), + ["aDefault", '"a-default"'], + ["aDefault2", '"a-default2"'], + ["aDefault3", '"a-default3"'], + + ["aNamespace", "{\u2026}"], + ["arguments", "(unavailable)"], + ["mod4", "(optimized away)"], + "root()", + ] + ); + } +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-stepping.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-stepping.js new file mode 100644 index 0000000000..99d0dde458 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-stepping.js @@ -0,0 +1,158 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests for stepping through Babel's compile output. +requestLongerTimeout(4); + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemapped.html"); + + await testStepOverForOf(dbg); + await testStepOverForOfArray(dbg); + await testStepOveForOfClosure(dbg); + await testStepOverForOfArrayClosure(dbg); + await testStepOverFunctionParams(dbg); + await testStepOverRegeneratorAwait(dbg); +}); + +async function breakpointSteps(dbg, target, fixture, { line, column }, steps) { + const filename = `${target}://./${fixture}/input.`; + const fnName = `${target}-${fixture}`.replace(/-([a-z])/g, (s, c) => + c.toUpperCase() + ); + + await invokeWithBreakpoint( + dbg, + fnName, + filename, + { line, column }, + async source => { + await runSteps(dbg, source, steps); + } + ); + + ok(true, `Ran tests for ${fixture} at line ${line} column ${column}`); +} + +async function runSteps(dbg, source, steps) { + for (const [i, [type, position]] of steps.entries()) { + info(`Step ${i}`); + switch (type) { + case "stepOver": + await stepOver(dbg); + break; + case "stepIn": + await stepIn(dbg); + break; + default: + throw new Error("Unknown stepping type"); + } + + assertPausedAtSourceAndLine(dbg, source.id, position.line, position.column); + } +} + +function testStepOverForOf(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-for-of", + { line: 4, column: 2 }, + [ + ["stepOver", { line: 6, column: 20 }], + ["stepOver", { line: 6, column: 2 }], + ["stepOver", { line: 7, column: 4 }], + ["stepOver", { line: 6, column: 2 }], + ["stepOver", { line: 7, column: 4 }], + ["stepOver", { line: 6, column: 2 }], + ["stepOver", { line: 10, column: 2 }], + ] + ); +} + +// This codifies the current behavior, but stepping twice over the for +// header isn't ideal. +function testStepOverForOfArray(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-for-of-array", + { line: 3, column: 2 }, + [ + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 5, column: 13 }], + ["stepOver", { line: 6, column: 4 }], + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 5, column: 13 }], + ["stepOver", { line: 6, column: 4 }], + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 9, column: 2 }], + ] + ); +} + +// The closure means it isn't actually possible to step into the for body, +// and Babel doesn't map the _loop() call, so we step past it automatically. +function testStepOveForOfClosure(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-for-of-closure", + { line: 6, column: 2 }, + [ + ["stepOver", { line: 8, column: 20 }], + ["stepOver", { line: 8, column: 2 }], + ["stepOver", { line: 12, column: 2 }], + ] + ); +} + +// Same as the previous, not possible to step into the body. The less +// complicated array logic makes it possible to step into the header at least, +// but this does end up double-visiting the for head. +function testStepOverForOfArrayClosure(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-for-of-array-closure", + { line: 3, column: 2 }, + [ + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 5, column: 13 }], + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 5, column: 13 }], + ["stepOver", { line: 5, column: 2 }], + ["stepOver", { line: 9, column: 2 }], + ] + ); +} + +function testStepOverFunctionParams(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-function-params", + { line: 6, column: 2 }, + [ + ["stepOver", { line: 7, column: 2 }], + ["stepIn", { line: 2, column: 2 }], + ] + ); +} + +function testStepOverRegeneratorAwait(dbg) { + return breakpointSteps( + dbg, + "webpack3-babel6", + "step-over-regenerator-await", + { line: 2, column: 2 }, + [ + // Won't work until a fix to regenerator lands and we rebuild. + // https://github.com/facebook/regenerator/issues/342 + // ["stepOver", { line: 4, column: 2 }], + ] + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-toggle.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-toggle.js new file mode 100644 index 0000000000..270375a87c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemapped-toggle.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests for preview through Babel's compile output. +requestLongerTimeout(5); + +// Test pausing with mapScopes enabled and disabled +add_task(async function () { + const dbg = await initDebugger("doc-sourcemapped.html"); + dbg.actions.toggleMapScopes(); + + info("1. Pause on line 20"); + const url = "webpack3-babel6://./esmodules-cjs/input.js"; + await waitForSources(dbg, url); + const source = findSource(dbg, url); + await selectSource(dbg, source); + await addBreakpoint(dbg, source, 20, 2); + invokeInTab("webpack3Babel6EsmodulesCjs"); + await waitForPaused(dbg); + + info("2. Hover on a token with mapScopes enabled"); + await previewToken(dbg, 20, 16, '"a-default"'); + ok(getOriginalScope(dbg) != null, "Scopes are mapped"); + + info("3. Hover on a token with mapScopes disabled"); + clickElement(dbg, "mapScopesCheckbox"); + await previewToken(dbg, 21, 16, "undefined"); + + info("4. StepOver with mapScopes disabled"); + await stepOver(dbg); + await previewToken(dbg, 20, 16, "undefined"); + ok(getOriginalScope(dbg) == null, "Scopes are not mapped"); +}); + +function getOriginalScope(dbg) { + return dbg.selectors.getSelectedOriginalScope( + dbg.selectors.getCurrentThread() + ); +} + +async function previewToken(dbg, line, column, value) { + const previewEl = await tryHovering(dbg, line, column, "previewPopup"); + is(previewEl.innerText, value); + dbg.actions.clearPreview(getContext(dbg)); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-bogus.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-bogus.js new file mode 100644 index 0000000000..b51056bba7 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-bogus.js @@ -0,0 +1,63 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that errors while loading sourcemap does not break debugging. + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + + // - non-existant-map.js has a reference to source map file which doesn't exists. + // There is no particular warning and no original file is displayed, only the generated file. + // - map-with-failed-original-request.js has a reference to a valid source map file, + // but the map doesn't inline source content and refers to a URL which fails loading. + // (this file is based on dom-mutation.js and related map) + const dbg = await initDebugger( + "doc-sourcemap-bogus.html", + "non-existant-map.js", + "map-with-failed-original-request.js", + "map-with-failed-original-request.original.js" + ); + // Make sure there is only the expected sources and we miss some original sources. + is(dbg.selectors.getSourceCount(), 3, "Only 3 source exists"); + + await selectSource(dbg, "non-existant-map.js"); + + // We should still be able to set breakpoints and pause in the + // generated source. + await addBreakpoint(dbg, "non-existant-map.js", 4); + invokeInTab("runCode"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "non-existant-map.js").id, + 4 + ); + await resume(dbg); + + await selectSource(dbg, "map-with-failed-original-request.js"); + await addBreakpoint(dbg, "map-with-failed-original-request.js", 7); + invokeInTab("changeStyleAttribute"); + await waitForPaused(dbg); + + // As the original file can't be loaded, the generated source is automatically selected + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "map-with-failed-original-request.js").id, + 7 + ); + + // The original file is visible in the source tree and can be selected, + // but its content can't be displayed + await selectSource(dbg, "map-with-failed-original-request.original.js"); + is( + getCM(dbg).getValue(), + `Error while fetching an original source: request failed with status 404\nSource URL: ${EXAMPLE_URL}map-with-failed-original-request.original.js` + ); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-breakpoints.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-breakpoints.js new file mode 100644 index 0000000000..b1ae737f35 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-breakpoints.js @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests setting breakpoints in an original file and +// removing it in the generated file. + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger("doc-sourcemaps.html", "entry.js"); + + ok(true, "Original sources exist"); + + await selectSource(dbg, "entry.js"); + + await clickGutter(dbg, 9); + await waitForBreakpointCount(dbg, 1); + await assertBreakpoint(dbg, 9); + assertBreakpointSnippet(dbg, 3, "output(times2(3));"); + + await selectSource(dbg, "bundle.js"); + await assertBreakpoint(dbg, 55); + assertBreakpointSnippet(dbg, 3, "output(times2(3));"); + + await clickGutter(dbg, 55); + await waitForBreakpointCount(dbg, 0); + await assertNoBreakpoint(dbg, 55); + + await selectSource(dbg, "entry.js"); + await assertNoBreakpoint(dbg, 9); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-disabled.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-disabled.js new file mode 100644 index 0000000000..93440dc9e1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-disabled.js @@ -0,0 +1,23 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests loading and pretty printing bundles with sourcemaps disabled + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + await pushPref("devtools.source-map.client-service.enabled", false); + const dbg = await initDebugger("doc-sourcemaps.html"); + + await waitForSources(dbg, "bundle.js"); + const bundleSrc = findSource(dbg, "bundle.js"); + + info("Pretty print the bundle"); + await selectSource(dbg, bundleSrc); + clickElement(dbg, "prettyPrintButton"); + await waitForSelectedSource(dbg, "bundle.js:formatted"); + ok(true, "everything finished"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-ignorelist.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-ignorelist.js new file mode 100644 index 0000000000..9278ccf08e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-ignorelist.js @@ -0,0 +1,75 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that sources on the sourcemaps ignore list are ignored on debugger load +// when the 'Ignore Known Third-party Scripts' setting is enabled. + +"use strict"; + +add_task(async function () { + const sources = [ + "bundle.js", + "original-1.js", + "original-2.js", + "original-3.js", + "original-4.js", + "original-5.js", + ]; + const dbg = await initDebugger("doc-sourcemaps-ignorelist.html", ...sources); + + info("Click the settings menu to ignore the third party scripts"); + await toggleDebbuggerSettingsMenuItem(dbg, { + className: ".debugger-settings-menu-item-enable-sourcemap-ignore-list", + isChecked: false, + }); + await waitForDispatch(dbg.store, "ENABLE_SOURCEMAP_IGNORELIST"); + + info( + "Reload to hit breakpoints in the original-2.js and original-3.js files" + ); + const onReloaded = reload(dbg, ...sources); + await waitForPaused(dbg); + + info("Assert paused in original-2.js as original-1.js is ignored"); + const original2Source = findSource(dbg, "original-2.js"); + assertPausedAtSourceAndLine(dbg, original2Source.id, 2); + + await resume(dbg); + await waitForPaused(dbg); + + info("Assert paused in original-4.js as original-3.js is ignored"); + const original4Source = findSource(dbg, "original-4.js"); + assertPausedAtSourceAndLine(dbg, original4Source.id, 2); + + await resume(dbg); + await onReloaded; + + info("Click the settings menu to stop ignoring the third party scripts"); + await toggleDebbuggerSettingsMenuItem(dbg, { + className: ".debugger-settings-menu-item-enable-sourcemap-ignore-list", + isChecked: true, + }); + await waitForDispatch(dbg.store, "ENABLE_SOURCEMAP_IGNORELIST"); + + info("Reload to hit breakpoints in all the original-[x].js files"); + const onReloaded2 = reload(dbg, "original-1.js"); + await waitForPaused(dbg); + + info("Assert paused in original-1.js as it is no longer ignored"); + const original1Source = findSource(dbg, "original-1.js"); + assertPausedAtSourceAndLine(dbg, original1Source.id, 2); + + const originalSources = ["original-2.js", "original-3.js", "original-4.js"]; + for (const fileName of originalSources) { + await resume(dbg); + await waitForPaused(dbg); + + const originalSource = findSource(dbg, fileName); + assertPausedAtSourceAndLine(dbg, originalSource.id, 2); + } + await resume(dbg); + + await onReloaded2; + await dbg.toolbox.closeToolbox(); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-indexed.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-indexed.js new file mode 100644 index 0000000000..1fad8696c1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-indexed.js @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +"use strict"; + +requestLongerTimeout(2); + +// This source map does not have source contents, so it's fetched separately +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger( + "doc-sourcemaps-indexed.html", + "main.js", + "main.min.js" + ); + const { + selectors: { getBreakpoint, getBreakpointCount }, + } = dbg; + + ok(true, "Original sources exist"); + const mainSrc = findSource(dbg, "main.js"); + + await selectSource(dbg, mainSrc); + + // Test that breakpoint is not off by a line. + await addBreakpoint(dbg, mainSrc, 4, 2); + is(getBreakpointCount(), 1, "One breakpoint exists"); + ok( + getBreakpoint(createLocation({ source: mainSrc, line: 4, column: 2 })), + "Breakpoint has correct line" + ); + + await assertBreakpoint(dbg, 4); + invokeInTab("logMessage"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, mainSrc.id, 4, 2); + + // Tests the existence of the sourcemap link in the original source. + ok(findElement(dbg, "sourceMapLink"), "Sourcemap link in original source"); + await selectSource(dbg, "main.min.js"); + + ok( + !findElement(dbg, "sourceMapLink"), + "No Sourcemap link exists in generated source" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-redirect.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-redirect.js new file mode 100644 index 0000000000..0efa6b25f1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-redirect.js @@ -0,0 +1,54 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test the redirects on the sourceMappingURL are blocked and not followed. + +"use strict"; + +const httpServer = createTestHTTPServer(); +const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}`; + +httpServer.registerContentType("html", "text/html"); +httpServer.registerContentType("js", "application/javascript"); + +httpServer.registerPathHandler("/index.html", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write(` + + + + + + `); +}); + +httpServer.registerPathHandler("/redirect", (request, response) => { + response.setStatusLine(request.httpVersion, 301, "Moved Permanently"); + response.setHeader("Location", `${BASE_URL}/evil`); +}); + +httpServer.registerPathHandler("/evil", (request, response) => { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.write( + `{"version":3,"sources":["evil.original.js"],"names":[], "mappings": ""}` + ); +}); + +add_task(async function () { + const dbg = await initDebuggerWithAbsoluteURL(`${BASE_URL}/index.html`); + + await getDebuggerSplitConsole(dbg); + await hasConsoleMessage(dbg, "Source map error"); + const { value } = await findConsoleMessage(dbg, "Source map error"); + + is( + value, + `Source map error: Error: NetworkError when attempting to fetch resource.\nResource URL: ${BASE_URL}/index.html\nSource Map URL: ${BASE_URL}/redirect[Learn More]`, + "A source map error message is logged indicating the redirect failed" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading-quickly.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading-quickly.js new file mode 100644 index 0000000000..ed2a3ceeac --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading-quickly.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +/* + * Test reloading an original file while the sourcemap is loading. + * The test passes when the selected source is visible after two reloads. + */ + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-sourcemaps.html"); + + await waitForSources(dbg, "entry.js"); + await selectSource(dbg, "entry.js"); + + await reload(dbg); + await waitForSources(dbg, "bundle.js"); + + await reload(dbg); + await waitForLoadedSource(dbg, "entry.js"); + + ok( + getCM(dbg).getValue().includes("window.keepMeAlive"), + "Original source text loaded correctly" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading.js new file mode 100644 index 0000000000..2931087d1d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps-reloading.js @@ -0,0 +1,62 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger("doc-sourcemaps.html"); + const { + selectors: { getBreakpoint, getBreakpointCount }, + } = dbg; + + await waitForSources(dbg, "entry.js", "output.js", "times2.js", "opts.js"); + ok(true, "Original sources exist"); + const entrySrc = findSource(dbg, "entry.js"); + + await selectSource(dbg, entrySrc); + ok( + getCM(dbg).getValue().includes("window.keepMeAlive"), + "Original source text loaded correctly" + ); + + await addBreakpoint(dbg, entrySrc, 5); + await addBreakpoint(dbg, entrySrc, 15, 0); + await disableBreakpoint(dbg, entrySrc, 15, 0); + + // Test reloading the debugger + const onReloaded = reload(dbg, "opts.js"); + await waitForDispatch(dbg.store, "LOAD_ORIGINAL_SOURCE_TEXT"); + + await waitForPaused(dbg); + await waitForDispatch(dbg.store, "ADD_INLINE_PREVIEW"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "entry.js").id, 5); + + await waitForBreakpointCount(dbg, 2); + is(getBreakpointCount(), 2, "Two breakpoints exist"); + + const bp = getBreakpoint( + createLocation({ + source: entrySrc, + line: 15, + column: 0, + }) + ); + ok(bp, "Breakpoint is on the correct line"); + ok(bp.disabled, "Breakpoint is disabled"); + await assertBreakpoint(dbg, 15); + + await resume(dbg); + info("Wait for reload to complete after resume"); + await onReloaded; +}); + +async function waitForBreakpointCount(dbg, count) { + return waitForState( + dbg, + state => dbg.selectors.getBreakpointCount() === count + ); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps.js new file mode 100644 index 0000000000..610cfd88f3 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps.js @@ -0,0 +1,124 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +"use strict"; + +requestLongerTimeout(2); + +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger( + "doc-sourcemaps.html", + "entry.js", + "output.js", + "times2.js", + "opts.js" + ); + const { + selectors: { getBreakpointCount }, + } = dbg; + + // Check that the original sources appear in the source tree + info("Before opening the page directory, no source are displayed"); + await waitForSourcesInSourceTree(dbg, [], { noExpand: true }); + await clickElement(dbg, "sourceDirectoryLabel", 4); + info( + "After opening the page directory, only all original sources (entry, output, time2, opts). (bundle is still hidden)" + ); + await waitForSourcesInSourceTree( + dbg, + ["entry.js", "output.js", "times2.js", "opts.js"], + { noExpand: true } + ); + info("Expand the page folder and assert that the bundle appears"); + await clickElement(dbg, "sourceDirectoryLabel", 3); + await clickElement(dbg, "sourceDirectoryLabel", 4); + await waitForSourcesInSourceTree( + dbg, + ["entry.js", "output.js", "times2.js", "opts.js", "bundle.js"], + { noExpand: true } + ); + + const bundleSrc = findSource(dbg, "bundle.js"); + await selectSource(dbg, bundleSrc); + + await clickGutter(dbg, 70); + await waitForBreakpointCount(dbg, 1); + await assertBreakpoint(dbg, 70); + + await clickGutter(dbg, 70); + await waitForBreakpointCount(dbg, 0); + + const entrySrc = findSource(dbg, "entry.js"); + + await selectSource(dbg, entrySrc); + ok( + getCM(dbg).getValue().includes("window.keepMeAlive"), + "Original source text loaded correctly" + ); + + // Bug 1824375 - pending location shouldn't be location and include only url, line and column attributes + let pendingSelectedLocation = Services.prefs.getStringPref( + "devtools.debugger.pending-selected-location" + ); + is( + pendingSelectedLocation, + JSON.stringify({ url: entrySrc.url, line: 0, column: undefined }), + "Pending selected location is the expected one" + ); + + // Test breaking on a breakpoint + await addBreakpoint(dbg, "entry.js", 15); + is(getBreakpointCount(), 1, "One breakpoint exists"); + assertBreakpointExists(dbg, entrySrc, 15); + + invokeInTab("keepMeAlive"); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, entrySrc.id, 15); + + await stepIn(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 2); + + await stepOver(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "times2.js").id, 3); + + await stepOut(dbg); + assertPausedAtSourceAndLine(dbg, entrySrc.id, 16); + + pendingSelectedLocation = Services.prefs.getStringPref( + "devtools.debugger.pending-selected-location" + ); + is( + pendingSelectedLocation, + JSON.stringify({ url: entrySrc.url, line: 16, column: 0 }), + "Pending selected location is the expected one" + ); + + info("Click on jump to generated source link from editor's footer"); + findElement(dbg, "sourceMapLink").click(); + + await waitForSelectedSource(dbg, bundleSrc); + assertPausedAtSourceAndLine(dbg, bundleSrc.id, 62); +}); + +function assertBreakpointExists(dbg, source, line) { + const { + selectors: { getBreakpoint }, + } = dbg; + + ok( + getBreakpoint(createLocation({ source, line })), + "Breakpoint has correct line" + ); +} + +async function waitForBreakpointCount(dbg, count) { + const { + selectors: { getBreakpointCount }, + } = dbg; + await waitForState(dbg, state => getBreakpointCount() == count); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps2.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps2.js new file mode 100644 index 0000000000..e1e05ba11a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps2.js @@ -0,0 +1,51 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests loading sourcemapped sources, setting breakpoints, and +// stepping in them. + +"use strict"; + +requestLongerTimeout(2); + +// This source map does not have source contents, so it's fetched separately +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger( + "doc-sourcemaps2.html", + "main.js", + "main.min.js" + ); + const { + selectors: { getBreakpoint, getBreakpointCount }, + } = dbg; + + ok(true, "Original sources exist"); + const mainSrc = findSource(dbg, "main.js"); + + await selectSource(dbg, mainSrc); + + // Test that breakpoint is not off by a line. + await addBreakpoint(dbg, mainSrc, 4, 2); + is(getBreakpointCount(), 1, "One breakpoint exists"); + ok( + getBreakpoint(createLocation({ source: mainSrc, line: 4, column: 2 })), + "Breakpoint has correct line" + ); + + await assertBreakpoint(dbg, 4); + invokeInTab("logMessage"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, mainSrc.id, 4); + + // Tests the existence of the sourcemap link in the original source. + ok(findElement(dbg, "sourceMapLink"), "Sourcemap link in original source"); + await selectSource(dbg, "main.min.js"); + + ok( + !findElement(dbg, "sourceMapLink"), + "No Sourcemap link exists in generated source" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps3.js b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps3.js new file mode 100644 index 0000000000..1ab8ea849c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sourcemaps3.js @@ -0,0 +1,65 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests loading sourcemapped sources, setting breakpoints, and +// inspecting restored scopes. +requestLongerTimeout(2); + +// This source map does not have source contents, so it's fetched separately +add_task(async function () { + // NOTE: the CORS call makes the test run times inconsistent + const dbg = await initDebugger( + "doc-sourcemaps3.html", + "bundle.js", + "sorted.js", + "test.js" + ); + dbg.actions.toggleMapScopes(); + + ok(true, "Original sources exist"); + const sortedSrc = findSource(dbg, "sorted.js"); + + await selectSource(dbg, sortedSrc); + + // Test that breakpoint is not off by a line. + await addBreakpoint(dbg, sortedSrc, 9, 4); + is(dbg.selectors.getBreakpointCount(), 1, "One breakpoint exists"); + ok( + dbg.selectors.getBreakpoint( + createLocation({ source: sortedSrc, line: 9, column: 4 }) + ), + "Breakpoint has correct line" + ); + + invokeInTab("test"); + + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, sortedSrc.id, 9, 4); + + is(getScopeLabel(dbg, 1), "Block"); + is(getScopeLabel(dbg, 2), "na"); + is(getScopeLabel(dbg, 3), "nb"); + + is(getScopeLabel(dbg, 4), "Function Body"); + + await toggleScopeNode(dbg, 4); + + is(getScopeLabel(dbg, 5), "ma"); + is(getScopeLabel(dbg, 6), "mb"); + + await toggleScopeNode(dbg, 7); + + is(getScopeLabel(dbg, 8), "a"); + is(getScopeLabel(dbg, 9), "b"); + + is(getScopeLabel(dbg, 10), "Module"); + + await toggleScopeNode(dbg, 10); + + is(getScopeLabel(dbg, 11), "binaryLookup:o(n, e, r)"); + is(getScopeLabel(dbg, 12), "comparer:t(n, e)"); + is(getScopeLabel(dbg, 13), "fancySort"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-sources-project-search.js b/devtools/client/debugger/test/mochitest/browser_dbg-sources-project-search.js new file mode 100644 index 0000000000..c5733d5a97 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-sources-project-search.js @@ -0,0 +1,134 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Testing project search for various types of sources scenarios + +"use strict"; + +requestLongerTimeout(3); + +// Tests for searching in dynamic (without urls) sources +add_task(async function testSearchDynamicScripts() { + const dbg = await initDebugger("doc-minified.html"); + + const executeComplete = dbg.commands.scriptCommand.execute( + `const foo = 5; debugger; console.log(foo)` + ); + await waitForPaused(dbg); + + await openProjectSearch(dbg); + const fileResults = await doProjectSearch(dbg, "foo"); + ok( + /source\d+/g.test(fileResults[0].innerText), + "The search result was found in the eval script." + ); + + await resume(dbg); + await executeComplete; +}); + +// Tests that minified sources are ignored when the prettyfied versions +// exist. +add_task(async function testIgnoreMinifiedSourceForPrettySource() { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + + await openProjectSearch(dbg); + let fileResults = await doProjectSearch(dbg, "stuff"); + + is(fileResults.length, 1, "Only the result was found"); + ok( + fileResults[0].innerText.includes("pretty.js\n(1 match)"), + "The search result was found in the minified (pretty.js) source" + ); + + await selectSource(dbg, "pretty.js"); + await waitForSelectedSource(dbg, "pretty.js"); + + info("Pretty print the source"); + await prettyPrint(dbg); + + fileResults = await doProjectSearch(dbg, "stuff"); + + is( + fileResults.length, + 2, + "Two results were found form both the pretty and minified sources" + ); + ok( + fileResults[0].innerText.includes("pretty.js:formatted\n(1 match)"), + "The first search result was found in the prettyified (pretty.js:formatted) source" + ); + + ok( + fileResults[1].innerText.includes("pretty.js\n(1 match)"), + "The second search result was found in the minified (pretty.js) source" + ); +}); + +// Test the prioritization of files. Original files should be prioritized over +// generated files and third-party files should be deprioritized and load after the others. +add_task(async function testFilesPrioritization() { + const dbg = await initDebugger("doc-react.html", "App.js"); + + await openProjectSearch(dbg); + const fileResults = await doProjectSearch(dbg, "componentDidMount"); + + is(getExpandedResultsCount(dbg), 13); + + ok( + fileResults[0].innerText.includes( + "browser/devtools/client/debugger/test/mochitest/examples/react/build/App.js" + ), + "The first item should be the original (prettified) file" + ); + + ok( + findAllElements(dbg, "projectSearchExpandedResults")[0].innerText.endsWith( + "componentDidMount() {" + ), + "The first result match in the original file is correct" + ); + + const firstNodeModulesResultFound = [...fileResults].findIndex(el => + el.innerText.includes("node_modules") + ); + is( + firstNodeModulesResultFound, + 2, + "The node_modules (third-party) file is the last result in the list" + ); +}); + +add_task(async function testBlackBoxedSources() { + const dbg = await initDebugger("doc-pretty.html", "pretty.js"); + await selectSource(dbg, "pretty.js"); + + info("Blackbox pretty.js"); + await toggleBlackbox(dbg); + + await openProjectSearch(dbg); + let fileResults = await doProjectSearch(dbg, "stuff"); + + is(fileResults.length, 0, "No results were found as pretty.js is blackboxed"); + + info("Unblackbox pretty.js"); + await toggleBlackbox(dbg); + + await openProjectSearch(dbg); + fileResults = await doProjectSearch(dbg, "stuff"); + + is( + fileResults.length, + 1, + "One result was found as pretty.js is no longer blackboxed" + ); +}); + +async function toggleBlackbox(dbg) { + await clickElement(dbg, "blackbox"); + await Promise.any([ + waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"), + waitForDispatch(dbg.store, "UNBLACKBOX_WHOLE_SOURCES"), + ]); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js b/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js new file mode 100644 index 0000000000..0dc81605c9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-state-based-panels.js @@ -0,0 +1,164 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// Tests that breakpoint panels open when their relevant breakpoint is hit +add_task(async function testBreakpointsPaneOpenOnPause() { + const dbg = await initDebugger("doc-sources.html", "simple1.js"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + info("Confirm the breakpoints pane is closed"); + is(getPaneElements(dbg).length, 1); + + await selectSource(dbg, "simple1.js"); + await addBreakpoint(dbg, "simple1.js", 4); + + info("Trigger the breakpoint ane ensure we're paused"); + invokeInTab("main"); + await waitForPaused(dbg, "simple1.js"); + + info("Confirm the breakpoints pane is open"); + is(getPaneElements(dbg).length, 2); + + await resume(dbg); + + info("Confirm the breakpoints pane is closed again"); + is(getPaneElements(dbg).length, 1); +}); + +// Tests that the breakpoint pane remains closed on stepping +add_task(async function testBreakpointsPanePersistOnStepping() { + const dbg = await initDebugger("doc-scripts.html", "simple3.js"); + + await selectSource(dbg, "simple3.js"); + await addBreakpoint(dbg, "simple3.js", 9); + await waitForBreakpoint(dbg, "simple3.js", 9); + + invokeInTab("nestedA"); + await waitForPaused(dbg, "simple3.js"); + + is(getPaneElements(dbg).length, 2, "Breakpoints pane is open"); + + info("Close breakpoints pane"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed"); + + info("Step into nestedB"); + + await stepIn(dbg); + + ok(isFrameSelected(dbg, 1, "nestedB"), "nestedB frame is selected"); + + is(getPaneElements(dbg).length, 1, "Breakpoints pane is still closed"); +}); + +// Tests that the breakpoint pane remains closed on call-stack frame selection +add_task(async function testBreakpointsPanePersistOnFrameSelection() { + const dbg = await initDebugger("doc-scripts.html", "simple3.js"); + + info("Close breakpoints pane"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed"); + + await selectSource(dbg, "simple3.js"); + await addBreakpoint(dbg, "simple3.js", 13); + await waitForBreakpoint(dbg, "simple3.js", 13); + + invokeInTab("nestedA"); + await waitForPaused(dbg, "simple3.js"); + + is(getPaneElements(dbg).length, 2, "Breakpoints pane is open"); + + info("Close breakpoints pane"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed"); + + is(getFrameList(dbg).length, 2, "Call stack has two frames"); + + info("Click on second call stack frame"); + + await clickElement(dbg, "frame", 2); + + ok(isFrameSelected(dbg, 2, "nestedA"), "Second frame is selected"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is still closed"); +}); + +// Tests that the breakpoint pane persists when toggled during pause +add_task(async function testBreakpointsPanePersistOnPauseToggle() { + const dbg = await initDebugger("doc-scripts.html", "simple3.js"); + + await selectSource(dbg, "simple3.js"); + await addBreakpoint(dbg, "simple3.js", 9); + await waitForBreakpoint(dbg, "simple3.js", 9); + + info("Close breakpoint pane"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed"); + + info("Trigger breakpoint"); + + invokeInTab("nestedA"); + await waitForPaused(dbg, "simple3.js"); + + is(getPaneElements(dbg).length, 2, "Breakpoints pane is open"); + + info("Close breakpoint pane and reopen it"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoints pane is closed"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 2, "Breakpoints pane is open"); + + await resume(dbg); + + is(getPaneElements(dbg).length, 2, "Breakpoints pane is still open"); +}); + +// Tests that the breakpoint pane remains closed when event breakpoints log is toggled +add_task(async function testBreakpointsPanePersistOnPauseToggle() { + const dbg = await initDebugger("doc-scripts.html", "simple3.js"); + + await selectSource(dbg, "simple3.js"); + await addBreakpoint(dbg, "simple3.js", 9); + await waitForBreakpoint(dbg, "simple3.js", 9); + + info("Trigger breakpoint"); + + invokeInTab("nestedA"); + await waitForPaused(dbg, "simple3.js"); + + info("Close breakpoint pane"); + + clickElementWithSelector(dbg, ".breakpoints-pane h2"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is closed"); + + info("Check event listener breakpoints log box"); + + await clickElement(dbg, "logEventsCheckbox"); + + is(getPaneElements(dbg).length, 1, "Breakpoint pane is still closed"); +}); + +function getPaneElements(dbg) { + return findElementWithSelector(dbg, ".breakpoints-pane").childNodes; +} + +function getFrameList(dbg) { + return dbg.win.document.querySelectorAll(".call-stack-pane .frame"); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js new file mode 100644 index 0000000000..51127b5a83 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-navigate.js @@ -0,0 +1,34 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that Step In is cancelled when navigating to another page + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "simple3.js", "long.js"); + + // With the debugger stopped at a breakpoint, blackbox the current source and step in + await selectSource(dbg, "simple3.js"); + await addBreakpoint(dbg, "simple3.js", 5); + invokeInTab("simple"); + await waitForPaused(dbg, "simple3"); + + await clickElement(dbg, "blackbox"); + await waitForDispatch(dbg.store, "BLACKBOX_WHOLE_SOURCES"); + await dbg.actions.stepIn(getThreadContext(dbg)); + + // We should stop at this breakpoint, rather than the first executed script + await selectSource(dbg, "long.js"); + await addBreakpoint(dbg, "long.js", 1); + + // Navigation should clear the stepping state + const reloaded = reload(dbg); + await waitForPaused(dbg); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "long.js").id, 1); + + await resume(dbg); + await reloaded; + await waitForSource(dbg, "simple3.js"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-step-in-uninitialized.js b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-uninitialized.js new file mode 100644 index 0000000000..41065295d9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-step-in-uninitialized.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// When stepping into a function, 'let' variables should show as uninitialized +// instead of undefined. + +"use strict"; + +add_task(async function test() { + const dbg = await initDebugger("doc-step-in-uninitialized.html"); + invokeInTab("main"); + await waitForPaused(dbg, "doc-step-in-uninitialized.html"); + + await stepOver(dbg); + await stepIn(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-step-in-uninitialized.html").id, + 8 + ); + + // We step past the 'let x' at the start of the function because it is not + // a breakpoint position. + ok(findNodeValue(dbg, "x") == "undefined", "x undefined"); + ok(findNodeValue(dbg, "y") == "(uninitialized)", "y uninitialized"); + + await stepOver(dbg); + + assertPausedAtSourceAndLine( + dbg, + findSource(dbg, "doc-step-in-uninitialized.html").id, + 9 + ); + + ok(findNodeValue(dbg, "y") == "3", "y initialized"); +}); + +function findNodeValue(dbg, text) { + for (let index = 0; ; index++) { + const elem = findElement(dbg, "scopeNode", index); + if (elem?.innerText == text) { + return findElement(dbg, "scopeValue", index).innerText; + } + } +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-stepping.js b/devtools/client/debugger/test/mochitest/browser_dbg-stepping.js new file mode 100644 index 0000000000..2821075e73 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-stepping.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +"use strict"; + +// This test can be really slow on debug platforms +requestLongerTimeout(5); + +add_task(async function test() { + const dbg = await initDebugger( + "big-sourcemap.html", + "bundle.js", + "step-in-test.js" + ); + invokeInTab("hitDebugStatement"); + // Bug 1829860 - The sourcemap for this file is broken and we couldn't resolve the paused location + // to the related original file. The debugger fallbacks to the generated source, + // but that highlights a bug in the example page. + await waitForPaused(dbg, "bundle.js"); + assertPausedAtSourceAndLine(dbg, findSource(dbg, "bundle.js").id, 52411); + + await stepIn(dbg); + + const whyPaused = await waitFor( + () => dbg.win.document.querySelector(".why-paused")?.innerText + ); + is(whyPaused, `Paused while stepping`); + + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + await stepIn(dbg); + + // Note that we are asserting against an original source here, + // See earlier comment about paused in bundle.js + assertPausedAtSourceAndLine(dbg, findSource(dbg, "step-in-test.js").id, 7679); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-tabs-keyboard.js b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-keyboard.js new file mode 100644 index 0000000000..23c8960d34 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-keyboard.js @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests removing tabs with keyboard shortcuts + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + await selectSource(dbg, "simple1.js"); + await selectSource(dbg, "simple2.js"); + is(countTabs(dbg), 2, "Two tabs are open"); + + pressKey(dbg, "close"); + waitForDispatch(dbg.store, "CLOSE_TAB"); + is(countTabs(dbg), 1, "One tab is open"); + + await waitForSelectedSource(dbg, "simple1.js"); + + pressKey(dbg, "close"); + waitForDispatch(dbg.store, "CLOSE_TAB"); + is(countTabs(dbg), 0, "No tabs open"); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-tabs-pretty-print.js b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-pretty-print.js new file mode 100644 index 0000000000..f8bcdd0381 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-pretty-print.js @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests re-opening pretty printed tabs on load + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-minified.html", "math.min.js"); + + await selectSource(dbg, "math.min.js"); + clickElement(dbg, "prettyPrintButton"); + await waitForSource(dbg, "math.min.js:formatted"); + + await waitFor(() => findElement(dbg, "sourceTabs").children.length == 2); + const [prettyTab, originalTab] = findElement(dbg, "sourceTabs").children; + ok( + prettyTab.querySelector(".source-icon.img.prettyPrint"), + "Pretty printed tab has the pretty-print icon" + ); + ok( + !originalTab.querySelector(".source-icon.img.prettyPrint"), + "original tab does not have the pretty-print icon" + ); + + // Test reloading the debugger + await waitForSelectedSource(dbg, "math.min.js:formatted"); + await reload(dbg); + + await waitForSelectedSource(dbg, "math.min.js:formatted"); + ok(true, "Pretty printed source is selected on reload"); + + await selectSource(dbg, "math.min.js:formatted"); + const source = findSource(dbg, "math.min.js:formatted"); + dbg.actions.showSource(getContext(dbg), source.id); + const focusedTreeElement = findElementWithSelector( + dbg, + ".sources-list .focused .label" + ); + is( + focusedTreeElement.textContent.trim(), + "math.min.js", + "Pretty printed source is selected in tree" + ); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls-selected.js b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls-selected.js new file mode 100644 index 0000000000..fbfef690df --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls-selected.js @@ -0,0 +1,28 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that URL-less sources have tabs and selecting that location does not +// create a new tab for the same URL-less source + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + // Create a URL-less source + invokeInTab("doEval"); + await waitForPaused(dbg); + + // Click a frame which shouldn't open a new source tab + await clickElement(dbg, "frame", 2); + + // Click the frame to select the same location and ensure there's only 1 tab + is(countTabs(dbg), 1); + + await resume(dbg); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls.js b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls.js new file mode 100644 index 0000000000..f6e223a657 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-tabs-without-urls.js @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that URL-less sources have tabs added to the UI, are named correctly +// and do not persist upon reload + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + await selectSource(dbg, "simple1.js"); + is(countTabs(dbg), 1, "Only the `simple.js` source tab exists"); + + invokeInTab("doEval"); + await waitForPaused(dbg); + + is(countTabs(dbg), 2, "The new eval tab is now added"); + + info("Assert that the eval source the tab source name correctly"); + ok( + /source\d+/g.test(getTabContent(dbg, 0)), + "The tab name pattern is correct" + ); + + await resume(dbg); + + // Test reloading the debugger + await reload(dbg, "simple1.js", "simple2.js"); + is(countTabs(dbg), 1, "The eval source tab is no longer available"); +}); + +/* + * Get the tab content for the specific tab + * + * @param {Number} index - index of the tab to get the source content + */ +function getTabContent(dbg, index) { + const tabs = findElement(dbg, "sourceTabs").children; + return tabs[index]?.innerText || ""; +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-tabs.js b/devtools/client/debugger/test/mochitest/browser_dbg-tabs.js new file mode 100644 index 0000000000..08485beecc --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-tabs.js @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests adding and removing tabs + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + await selectSource(dbg, "simple1.js"); + await selectSource(dbg, "simple2.js"); + is(countTabs(dbg), 2); + + info("Test reloading the debugger"); + await reload(dbg, "simple1.js", "simple2.js"); + await waitForSelectedSource(dbg, "simple2.js"); + is(countTabs(dbg), 2); + + info("Test reloading the debuggee a second time"); + await reload(dbg, "simple1.js", "simple2.js"); + await waitForSelectedSource(dbg, "simple2.js"); + is(countTabs(dbg), 2); +}); + +add_task(async function () { + const dbg = await initDebugger( + "doc-scripts.html", + "simple1.js", + "simple2.js" + ); + + await selectSource(dbg, "simple1.js"); + await selectSource(dbg, "simple2.js"); + await closeTab(dbg, "simple1.js"); + await closeTab(dbg, "simple2.js"); + + info("Test reloading the debugger"); + await reload(dbg, "simple1.js", "simple2.js"); + is(countTabs(dbg), 0); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-toggling-tools.js b/devtools/client/debugger/test/mochitest/browser_dbg-toggling-tools.js new file mode 100644 index 0000000000..7e6025869c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-toggling-tools.js @@ -0,0 +1,19 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Tests that you can switch tools, without losing your editor position + +"use strict"; + +add_task(async function () { + const dbg = await initDebugger("doc-scripts.html", "long.js"); + + await selectSource(dbg, "long.js"); + getCM(dbg).scrollTo(0, 284); + + pressKey(dbg, "inspector"); + pressKey(dbg, "debugger"); + + is(getCM(dbg).getScrollInfo().top, 284); +}); diff --git a/devtools/client/debugger/test/mochitest/browser_dbg-ua-widgets.js b/devtools/client/debugger/test/mochitest/browser_dbg-ua-widgets.js new file mode 100644 index 0000000000..e563d52824 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg-ua-widgets.js @@ -0,0 +1,47 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at . */ + +// Test that you can debug User Agent widgets (like video controls) +// only when enabling "devtools.inspector.showAllAnonymousContent" pref. + +"use strict"; + +const TEST_URL = "data:text/html,