mdbe 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +53 -0
- data/app.rb +182 -0
- data/bin/mdbe +5 -0
- data/config.ru +2 -0
- data/environment.rb +8 -0
- data/lib/mdbe.rb +39 -0
- data/lib/mdbe/action_controller_debug_patch.rb +12 -0
- data/lib/mdbe/code_evaluation.rb +46 -0
- data/lib/mdbe/database_views.rb +24 -0
- data/lib/mdbe/database_views/abstract_dictionary.rb +69 -0
- data/lib/mdbe/database_views/abstract_exception.rb +25 -0
- data/lib/mdbe/database_views/array.rb +28 -0
- data/lib/mdbe/database_views/boolean.rb +12 -0
- data/lib/mdbe/database_views/class.rb +46 -0
- data/lib/mdbe/database_views/exception.rb +3 -0
- data/lib/mdbe/database_views/execblock.rb +5 -0
- data/lib/mdbe/database_views/fixnum.rb +5 -0
- data/lib/mdbe/database_views/float.rb +5 -0
- data/lib/mdbe/database_views/globals.rb +2 -0
- data/lib/mdbe/database_views/gsnmethod.rb +29 -0
- data/lib/mdbe/database_views/hash.rb +5 -0
- data/lib/mdbe/database_views/maglev_record.rb +42 -0
- data/lib/mdbe/database_views/module.rb +103 -0
- data/lib/mdbe/database_views/nilclass.rb +5 -0
- data/lib/mdbe/database_views/object.rb +80 -0
- data/lib/mdbe/database_views/proc.rb +3 -0
- data/lib/mdbe/database_views/repository.rb +3 -0
- data/lib/mdbe/database_views/ruby_workspace.rb +5 -0
- data/lib/mdbe/database_views/smalltalk_classes.rb +34 -0
- data/lib/mdbe/database_views/smalltalk_classes.st +60 -0
- data/lib/mdbe/database_views/string.rb +31 -0
- data/lib/mdbe/database_views/symbol.rb +32 -0
- data/lib/mdbe/database_views/system.rb +61 -0
- data/lib/mdbe/database_views/thread.rb +101 -0
- data/lib/mdbe/debug_server.rb +22 -0
- data/lib/mdbe/halt.rb +42 -0
- data/lib/mdbe/ruby_workspace.rb +29 -0
- data/lib/mdbe/version.rb +3 -0
- data/lib/tasks/maglev-database-explorer_tasks.rake +4 -0
- data/public/LICENSE +35 -0
- data/public/amber/CHANGELOG +65 -0
- data/public/amber/LICENSE +22 -0
- data/public/amber/Makefile +53 -0
- data/public/amber/README.md +30 -0
- data/public/amber/bin/amber +3 -0
- data/public/amber/bin/amberc +352 -0
- data/public/amber/bin/nodecompile.js +33 -0
- data/public/amber/bin/server +3 -0
- data/public/amber/bin/server.bat +3 -0
- data/public/amber/css/amber-normalize.css +468 -0
- data/public/amber/css/amber-normalize.less +501 -0
- data/public/amber/css/amber.css +539 -0
- data/public/amber/css/documentation.css +84 -0
- data/public/amber/css/profstef.css +75 -0
- data/public/amber/css/style.css +313 -0
- data/public/amber/documentation.html +37 -0
- data/public/amber/examples/Makefile +23 -0
- data/public/amber/examples/README +4 -0
- data/public/amber/examples/android/helloamber/AndroidManifest.xml +19 -0
- data/public/amber/examples/android/helloamber/HelloAmber.st +13 -0
- data/public/amber/examples/android/helloamber/Makefile +56 -0
- data/public/amber/examples/android/helloamber/README.md +80 -0
- data/public/amber/examples/android/helloamber/ant.properties +17 -0
- data/public/amber/examples/android/helloamber/assets/index.html +15 -0
- data/public/amber/examples/android/helloamber/assets/jquery-1.7.2.min.js +4 -0
- data/public/amber/examples/android/helloamber/build.xml +83 -0
- data/public/amber/examples/android/helloamber/local.properties +10 -0
- data/public/amber/examples/android/helloamber/proguard-project.txt +20 -0
- data/public/amber/examples/android/helloamber/project.properties +14 -0
- data/public/amber/examples/android/helloamber/res/layout/main.xml +6 -0
- data/public/amber/examples/android/helloamber/res/values/strings.xml +4 -0
- data/public/amber/examples/android/helloamber/src/org/amberlang/android/helloamber/HelloAmber.java +59 -0
- data/public/amber/examples/myproject/index.html +16 -0
- data/public/amber/examples/nodejs/README +9 -0
- data/public/amber/examples/nodejs/benchfib/Benchfib.st +124 -0
- data/public/amber/examples/nodejs/benchfib/Makefile +8 -0
- data/public/amber/examples/nodejs/benchfib/benchfib +1 -0
- data/public/amber/examples/nodejs/hello/Hello.st +9 -0
- data/public/amber/examples/nodejs/hello/Makefile +8 -0
- data/public/amber/examples/nodejs/hello/README +13 -0
- data/public/amber/examples/nodejs/hello/hello +1 -0
- data/public/amber/examples/nodejs/meta/Makefile +8 -0
- data/public/amber/examples/nodejs/meta/MyScript.st +27 -0
- data/public/amber/examples/nodejs/meta/meta +1 -0
- data/public/amber/examples/nodejs/pystone/Makefile +8 -0
- data/public/amber/examples/nodejs/pystone/Pystone.st +306 -0
- data/public/amber/examples/nodejs/pystone/pystone +1 -0
- data/public/amber/examples/nodejs/trivialserver/Makefile +8 -0
- data/public/amber/examples/nodejs/trivialserver/TrivialServer.st +51 -0
- data/public/amber/examples/nodejs/trivialserver/trivial +1 -0
- data/public/amber/examples/presentation/esug2011/images/asterix.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/background_box.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/background_header.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/balloon.jpg +0 -0
- data/public/amber/examples/presentation/esug2011/images/balloon_header.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/devices.jpg +0 -0
- data/public/amber/examples/presentation/esug2011/images/enyo.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/ide_star_wars.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/nodejs.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/terminal.png +0 -0
- data/public/amber/examples/presentation/esug2011/images/webos.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/amber.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/ambrhino.jpg +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/nodejs.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/pharo.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/php.gif +0 -0
- data/public/amber/examples/presentation/fosdem2012/images/rails.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/arrow-next.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/arrow-prev.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/closedhand.cur +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/openhand.cur +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow-top-back.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow-top-forward.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/images/shadow.png +0 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.css +100 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.js +1232 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.booklet.1.2.0.min.js +13 -0
- data/public/amber/examples/presentation/fosdem2012/lib/booklet/jquery.easing.1.3.js +38 -0
- data/public/amber/examples/presentation/index.html +17 -0
- data/public/amber/examples/presentation/js/Presentation.deploy.js +1922 -0
- data/public/amber/examples/presentation/js/Presentation.js +2712 -0
- data/public/amber/examples/presentation/st/Presentation.st +1996 -0
- data/public/amber/examples/trysmalltalk/index.html +18 -0
- data/public/amber/examples/trysmalltalk/js/TrySmalltalk.deploy.js +837 -0
- data/public/amber/examples/trysmalltalk/js/TrySmalltalk.js +1206 -0
- data/public/amber/examples/trysmalltalk/st/TrySmalltalk.st +964 -0
- data/public/amber/examples/twitterwall/css/twitterwall.css +19 -0
- data/public/amber/examples/twitterwall/index.html +35 -0
- data/public/amber/examples/twitterwall/js/TwitterWall.deploy.js +116 -0
- data/public/amber/examples/twitterwall/js/TwitterWall.js +146 -0
- data/public/amber/examples/twitterwall/st/TwitterWall.st +91 -0
- data/public/amber/examples/webos/README +11 -0
- data/public/amber/examples/webos/eris/DuckQwaq.wav +0 -0
- data/public/amber/examples/webos/eris/EnyoAmber.st +36 -0
- data/public/amber/examples/webos/eris/Eris.css +0 -0
- data/public/amber/examples/webos/eris/Eris.st +86 -0
- data/public/amber/examples/webos/eris/Makefile +37 -0
- data/public/amber/examples/webos/eris/README +3 -0
- data/public/amber/examples/webos/eris/appinfo.json +10 -0
- data/public/amber/examples/webos/eris/index.html +12 -0
- data/public/amber/examples/webos/helloamber/EnyoAmber.st +36 -0
- data/public/amber/examples/webos/helloamber/HelloAmber.st +86 -0
- data/public/amber/examples/webos/helloamber/Makefile +38 -0
- data/public/amber/examples/webos/helloamber/README +5 -0
- data/public/amber/examples/webos/helloamber/appinfo.json +10 -0
- data/public/amber/examples/webos/helloamber/index.html +12 -0
- data/public/amber/favicon.ico +0 -0
- data/public/amber/images/amber.png +0 -0
- data/public/amber/images/amber.svg +706 -0
- data/public/amber/images/amber_small.png +0 -0
- data/public/amber/images/off.amber.png +0 -0
- data/public/amber/images/off.png +0 -0
- data/public/amber/images/offHover.amber.png +0 -0
- data/public/amber/images/offHover.png +0 -0
- data/public/amber/images/presentation.png +0 -0
- data/public/amber/images/profstef.png +0 -0
- data/public/amber/images/sprite.amber.png +0 -0
- data/public/amber/images/sprite.png +0 -0
- data/public/amber/images/tinylogo.amber.png +0 -0
- data/public/amber/images/tinylogo.png +0 -0
- data/public/amber/images/twitterwall.png +0 -0
- data/public/amber/index.html +55 -0
- data/public/amber/js/Additional-Examples.deploy.js +15 -0
- data/public/amber/js/Additional-Examples.js +21 -0
- data/public/amber/js/Benchfib.deploy.js +132 -0
- data/public/amber/js/Benchfib.js +167 -0
- data/public/amber/js/Canvas.deploy.js +2446 -0
- data/public/amber/js/Canvas.js +3547 -0
- data/public/amber/js/Compiler-Tests.deploy.js +97 -0
- data/public/amber/js/Compiler-Tests.js +137 -0
- data/public/amber/js/Compiler.deploy.js +1877 -0
- data/public/amber/js/Compiler.js +2622 -0
- data/public/amber/js/Documentation.deploy.js +961 -0
- data/public/amber/js/Documentation.js +1376 -0
- data/public/amber/js/Examples.deploy.js +53 -0
- data/public/amber/js/Examples.js +73 -0
- data/public/amber/js/IDE.deploy.js +3557 -0
- data/public/amber/js/IDE.js +5002 -0
- data/public/amber/js/Kernel-Announcements.deploy.js +107 -0
- data/public/amber/js/Kernel-Announcements.js +152 -0
- data/public/amber/js/Kernel-Classes.deploy.js +774 -0
- data/public/amber/js/Kernel-Classes.js +1095 -0
- data/public/amber/js/Kernel-Collections.deploy.js +3121 -0
- data/public/amber/js/Kernel-Collections.js +4427 -0
- data/public/amber/js/Kernel-Exceptions.deploy.js +244 -0
- data/public/amber/js/Kernel-Exceptions.js +349 -0
- data/public/amber/js/Kernel-Methods.deploy.js +573 -0
- data/public/amber/js/Kernel-Methods.js +807 -0
- data/public/amber/js/Kernel-Objects.deploy.js +2877 -0
- data/public/amber/js/Kernel-Objects.js +4107 -0
- data/public/amber/js/Kernel-Tests.deploy.js +1513 -0
- data/public/amber/js/Kernel-Tests.js +2053 -0
- data/public/amber/js/Kernel-Transcript.deploy.js +142 -0
- data/public/amber/js/Kernel-Transcript.js +202 -0
- data/public/amber/js/Maglev-Core.deploy.js +2996 -0
- data/public/amber/js/Maglev-Core.js +4246 -0
- data/public/amber/js/Maglev-Database-Explorer.deploy.js +4476 -0
- data/public/amber/js/Maglev-Database-Explorer.js +6232 -0
- data/public/amber/js/Maglev-Vendor.deploy.js +350 -0
- data/public/amber/js/Maglev-Vendor.js +465 -0
- data/public/amber/js/README.md +5 -0
- data/public/amber/js/SUnit.deploy.js +351 -0
- data/public/amber/js/SUnit.js +501 -0
- data/public/amber/js/amber.js +273 -0
- data/public/amber/js/boot.js +602 -0
- data/public/amber/js/compat.js +22 -0
- data/public/amber/js/init.js +9 -0
- data/public/amber/js/lib/CodeMirror/LICENSE +19 -0
- data/public/amber/js/lib/CodeMirror/active-line.js +39 -0
- data/public/amber/js/lib/CodeMirror/amber.css +21 -0
- data/public/amber/js/lib/CodeMirror/codemirror.css +67 -0
- data/public/amber/js/lib/CodeMirror/codemirror.js +2144 -0
- data/public/amber/js/lib/CodeMirror/smalltalk.js +134 -0
- data/public/amber/js/lib/jQuery/jquery-1.4.4.min.js +167 -0
- data/public/amber/js/lib/jQuery/jquery-1.6.4.min.js +4 -0
- data/public/amber/js/lib/jQuery/jquery-ui-1.8.16.custom.min.js +791 -0
- data/public/amber/js/lib/jQuery/jquery.textarea.js +267 -0
- data/public/amber/js/lib/peg-0.6.2.min.js +2 -0
- data/public/amber/js/lib/showdown.js +419 -0
- data/public/amber/js/parser.js +4222 -0
- data/public/amber/js/parser.pegjs +223 -0
- data/public/amber/learn.html +40 -0
- data/public/amber/repl/Makefile +8 -0
- data/public/amber/repl/REPL.js +124 -0
- data/public/amber/repl/REPL.st +56 -0
- data/public/amber/repl/amber.js +18085 -0
- data/public/amber/server/FileServer.st +576 -0
- data/public/amber/server/Makefile +8 -0
- data/public/amber/server/server.js +13049 -0
- data/public/amber/st/Benchfib.js +297 -0
- data/public/amber/st/Benchfib.st +124 -0
- data/public/amber/st/Canvas.st +968 -0
- data/public/amber/st/Compiler-Tests.st +471 -0
- data/public/amber/st/Compiler.st +1445 -0
- data/public/amber/st/Documentation.st +758 -0
- data/public/amber/st/Examples.js +100 -0
- data/public/amber/st/Examples.st +38 -0
- data/public/amber/st/IDE.st +2404 -0
- data/public/amber/st/Kernel-Announcements.st +61 -0
- data/public/amber/st/Kernel-Classes.st +462 -0
- data/public/amber/st/Kernel-Collections.st +1611 -0
- data/public/amber/st/Kernel-Exceptions.st +124 -0
- data/public/amber/st/Kernel-Methods.st +291 -0
- data/public/amber/st/Kernel-Objects.st +1587 -0
- data/public/amber/st/Kernel-Tests.st +953 -0
- data/public/amber/st/Kernel-Transcript.st +70 -0
- data/public/amber/st/Maglev-Core.st +1694 -0
- data/public/amber/st/Maglev-Database-Explorer.st +3148 -0
- data/public/amber/st/Maglev-Vendor.st +151 -0
- data/public/amber/st/Makefile +104 -0
- data/public/amber/st/README.md +4 -0
- data/public/amber/st/SUnit.st +172 -0
- data/public/css/bootstrap-combined.no-icons.min.css +731 -0
- data/public/css/bootstrap.css +6811 -0
- data/public/css/images/animated-overlay.gif +0 -0
- data/public/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/public/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/public/css/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/public/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/public/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/public/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/public/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/public/css/images/ui-icons_222222_256x240.png +0 -0
- data/public/css/images/ui-icons_228ef1_256x240.png +0 -0
- data/public/css/images/ui-icons_ef8c08_256x240.png +0 -0
- data/public/css/images/ui-icons_ffd27a_256x240.png +0 -0
- data/public/css/images/ui-icons_ffffff_256x240.png +0 -0
- data/public/css/jquery-ui.min.css +5 -0
- data/public/css/smalltalk_code.css +42 -0
- data/public/css/style.css +210 -0
- data/public/images/bg_tile.png +0 -0
- data/public/images/maglev-logo.gif +0 -0
- data/public/images/mchammer.gif +0 -0
- data/public/images/rails_tiny.png +0 -0
- data/public/images/ruby.png +0 -0
- data/public/images/ruby_smalltalk_bridge.png +0 -0
- data/public/images/smalltalk.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/index.html +118 -0
- data/public/libs/bootstrap.min.js +7 -0
- data/public/libs/codemirror/CONTRIBUTING.md +72 -0
- data/public/libs/codemirror/LICENSE +23 -0
- data/public/libs/codemirror/README.md +11 -0
- data/public/libs/codemirror/addon/dialog/dialog.css +32 -0
- data/public/libs/codemirror/addon/dialog/dialog.js +80 -0
- data/public/libs/codemirror/addon/display/placeholder.js +54 -0
- data/public/libs/codemirror/addon/edit/closebrackets.js +54 -0
- data/public/libs/codemirror/addon/edit/closetag.js +86 -0
- data/public/libs/codemirror/addon/edit/continuecomment.js +44 -0
- data/public/libs/codemirror/addon/edit/continuelist.js +25 -0
- data/public/libs/codemirror/addon/edit/matchbrackets.js +82 -0
- data/public/libs/codemirror/addon/fold/brace-fold.js +31 -0
- data/public/libs/codemirror/addon/fold/foldcode.js +32 -0
- data/public/libs/codemirror/addon/fold/indent-fold.js +11 -0
- data/public/libs/codemirror/addon/fold/xml-fold.js +64 -0
- data/public/libs/codemirror/addon/hint/html-hint.js +582 -0
- data/public/libs/codemirror/addon/hint/javascript-hint.js +142 -0
- data/public/libs/codemirror/addon/hint/pig-hint.js +117 -0
- data/public/libs/codemirror/addon/hint/python-hint.js +93 -0
- data/public/libs/codemirror/addon/hint/show-hint.css +38 -0
- data/public/libs/codemirror/addon/hint/show-hint.js +180 -0
- data/public/libs/codemirror/addon/hint/xml-hint.js +118 -0
- data/public/libs/codemirror/addon/lint/javascript-lint.js +127 -0
- data/public/libs/codemirror/addon/lint/json-lint.js +14 -0
- data/public/libs/codemirror/addon/lint/lint.css +96 -0
- data/public/libs/codemirror/addon/lint/lint.js +197 -0
- data/public/libs/codemirror/addon/mode/loadmode.js +51 -0
- data/public/libs/codemirror/addon/mode/multiplex.js +95 -0
- data/public/libs/codemirror/addon/mode/overlay.js +59 -0
- data/public/libs/codemirror/addon/runmode/colorize.js +29 -0
- data/public/libs/codemirror/addon/runmode/runmode-standalone.js +130 -0
- data/public/libs/codemirror/addon/runmode/runmode.js +52 -0
- data/public/libs/codemirror/addon/runmode/runmode.node.js +89 -0
- data/public/libs/codemirror/addon/search/match-highlighter.js +60 -0
- data/public/libs/codemirror/addon/search/search.js +131 -0
- data/public/libs/codemirror/addon/search/searchcursor.js +133 -0
- data/public/libs/codemirror/addon/selection/active-line.js +39 -0
- data/public/libs/codemirror/addon/selection/mark-selection.js +34 -0
- data/public/libs/codemirror/bin/compress +91 -0
- data/public/libs/codemirror/bin/lint +11 -0
- data/public/libs/codemirror/demo/activeline.html +70 -0
- data/public/libs/codemirror/demo/bidi.html +61 -0
- data/public/libs/codemirror/demo/btree.html +87 -0
- data/public/libs/codemirror/demo/buffers.html +98 -0
- data/public/libs/codemirror/demo/changemode.html +50 -0
- data/public/libs/codemirror/demo/closebrackets.html +63 -0
- data/public/libs/codemirror/demo/closetag.html +37 -0
- data/public/libs/codemirror/demo/complete.html +70 -0
- data/public/libs/codemirror/demo/emacs.html +60 -0
- data/public/libs/codemirror/demo/folding.html +69 -0
- data/public/libs/codemirror/demo/fullscreen.html +147 -0
- data/public/libs/codemirror/demo/html5complete.html +92 -0
- data/public/libs/codemirror/demo/indentwrap.html +49 -0
- data/public/libs/codemirror/demo/lint.html +90 -0
- data/public/libs/codemirror/demo/loadmode.html +40 -0
- data/public/libs/codemirror/demo/marker.html +59 -0
- data/public/libs/codemirror/demo/markselection.html +36 -0
- data/public/libs/codemirror/demo/matchhighlighter.html +38 -0
- data/public/libs/codemirror/demo/multiplex.html +60 -0
- data/public/libs/codemirror/demo/mustache.html +59 -0
- data/public/libs/codemirror/demo/placeholder.html +36 -0
- data/public/libs/codemirror/demo/preview.html +76 -0
- data/public/libs/codemirror/demo/resize.html +49 -0
- data/public/libs/codemirror/demo/runmode.html +50 -0
- data/public/libs/codemirror/demo/search.html +85 -0
- data/public/libs/codemirror/demo/spanaffectswrapping_shim.html +73 -0
- data/public/libs/codemirror/demo/theme.html +89 -0
- data/public/libs/codemirror/demo/variableheight.html +52 -0
- data/public/libs/codemirror/demo/vim.html +65 -0
- data/public/libs/codemirror/demo/visibletabs.html +53 -0
- data/public/libs/codemirror/demo/widget.html +74 -0
- data/public/libs/codemirror/demo/xmlcomplete.html +81 -0
- data/public/libs/codemirror/index.html +487 -0
- data/public/libs/codemirror/keymap/emacs.js +30 -0
- data/public/libs/codemirror/keymap/vim.js +3044 -0
- data/public/libs/codemirror/lib/codemirror.css +253 -0
- data/public/libs/codemirror/lib/codemirror.js +5585 -0
- data/public/libs/codemirror/mode/apl/apl.js +160 -0
- data/public/libs/codemirror/mode/apl/index.html +61 -0
- data/public/libs/codemirror/mode/asterisk/asterisk.js +183 -0
- data/public/libs/codemirror/mode/asterisk/index.html +142 -0
- data/public/libs/codemirror/mode/clike/clike.js +302 -0
- data/public/libs/codemirror/mode/clike/index.html +103 -0
- data/public/libs/codemirror/mode/clike/scala.html +767 -0
- data/public/libs/codemirror/mode/clojure/clojure.js +222 -0
- data/public/libs/codemirror/mode/clojure/index.html +76 -0
- data/public/libs/codemirror/mode/coffeescript/LICENSE +22 -0
- data/public/libs/codemirror/mode/coffeescript/coffeescript.js +346 -0
- data/public/libs/codemirror/mode/coffeescript/index.html +728 -0
- data/public/libs/codemirror/mode/commonlisp/commonlisp.js +101 -0
- data/public/libs/codemirror/mode/commonlisp/index.html +165 -0
- data/public/libs/codemirror/mode/css/css.js +567 -0
- data/public/libs/codemirror/mode/css/index.html +58 -0
- data/public/libs/codemirror/mode/css/scss.html +145 -0
- data/public/libs/codemirror/mode/css/scss_test.js +80 -0
- data/public/libs/codemirror/mode/css/test.js +113 -0
- data/public/libs/codemirror/mode/d/d.js +205 -0
- data/public/libs/codemirror/mode/d/index.html +262 -0
- data/public/libs/codemirror/mode/diff/diff.js +32 -0
- data/public/libs/codemirror/mode/diff/index.html +105 -0
- data/public/libs/codemirror/mode/ecl/ecl.js +192 -0
- data/public/libs/codemirror/mode/ecl/index.html +39 -0
- data/public/libs/codemirror/mode/erlang/erlang.js +463 -0
- data/public/libs/codemirror/mode/erlang/index.html +64 -0
- data/public/libs/codemirror/mode/gas/gas.js +326 -0
- data/public/libs/codemirror/mode/gas/index.html +57 -0
- data/public/libs/codemirror/mode/gfm/gfm.js +96 -0
- data/public/libs/codemirror/mode/gfm/index.html +74 -0
- data/public/libs/codemirror/mode/gfm/test.js +112 -0
- data/public/libs/codemirror/mode/go/go.js +165 -0
- data/public/libs/codemirror/mode/go/index.html +74 -0
- data/public/libs/codemirror/mode/groovy/groovy.js +210 -0
- data/public/libs/codemirror/mode/groovy/index.html +73 -0
- data/public/libs/codemirror/mode/haskell/haskell.js +242 -0
- data/public/libs/codemirror/mode/haskell/index.html +62 -0
- data/public/libs/codemirror/mode/haxe/haxe.js +429 -0
- data/public/libs/codemirror/mode/haxe/index.html +90 -0
- data/public/libs/codemirror/mode/htmlembedded/htmlembedded.js +73 -0
- data/public/libs/codemirror/mode/htmlembedded/index.html +49 -0
- data/public/libs/codemirror/mode/htmlmixed/htmlmixed.js +104 -0
- data/public/libs/codemirror/mode/htmlmixed/index.html +73 -0
- data/public/libs/codemirror/mode/http/http.js +98 -0
- data/public/libs/codemirror/mode/http/index.html +32 -0
- data/public/libs/codemirror/mode/javascript/index.html +92 -0
- data/public/libs/codemirror/mode/javascript/javascript.js +467 -0
- data/public/libs/codemirror/mode/javascript/typescript.html +48 -0
- data/public/libs/codemirror/mode/jinja2/index.html +38 -0
- data/public/libs/codemirror/mode/jinja2/jinja2.js +42 -0
- data/public/libs/codemirror/mode/less/index.html +741 -0
- data/public/libs/codemirror/mode/less/less.js +266 -0
- data/public/libs/codemirror/mode/livescript/LICENSE +23 -0
- data/public/libs/codemirror/mode/livescript/index.html +446 -0
- data/public/libs/codemirror/mode/livescript/livescript.js +267 -0
- data/public/libs/codemirror/mode/livescript/livescript.ls +266 -0
- data/public/libs/codemirror/mode/lua/index.html +74 -0
- data/public/libs/codemirror/mode/lua/lua.js +140 -0
- data/public/libs/codemirror/mode/markdown/index.html +344 -0
- data/public/libs/codemirror/mode/markdown/markdown.js +526 -0
- data/public/libs/codemirror/mode/markdown/test.js +636 -0
- data/public/libs/codemirror/mode/meta.js +75 -0
- data/public/libs/codemirror/mode/mirc/index.html +149 -0
- data/public/libs/codemirror/mode/mirc/mirc.js +177 -0
- data/public/libs/codemirror/mode/ntriples/index.html +33 -0
- data/public/libs/codemirror/mode/ntriples/ntriples.js +170 -0
- data/public/libs/codemirror/mode/ocaml/index.html +131 -0
- data/public/libs/codemirror/mode/ocaml/ocaml.js +113 -0
- data/public/libs/codemirror/mode/pascal/LICENSE +7 -0
- data/public/libs/codemirror/mode/pascal/index.html +48 -0
- data/public/libs/codemirror/mode/pascal/pascal.js +94 -0
- data/public/libs/codemirror/mode/perl/LICENSE +19 -0
- data/public/libs/codemirror/mode/perl/index.html +62 -0
- data/public/libs/codemirror/mode/perl/perl.js +816 -0
- data/public/libs/codemirror/mode/php/index.html +51 -0
- data/public/libs/codemirror/mode/php/php.js +129 -0
- data/public/libs/codemirror/mode/pig/index.html +42 -0
- data/public/libs/codemirror/mode/pig/pig.js +171 -0
- data/public/libs/codemirror/mode/properties/index.html +41 -0
- data/public/libs/codemirror/mode/properties/properties.js +63 -0
- data/public/libs/codemirror/mode/python/LICENSE.txt +21 -0
- data/public/libs/codemirror/mode/python/index.html +135 -0
- data/public/libs/codemirror/mode/python/python.js +340 -0
- data/public/libs/codemirror/mode/q/index.html +131 -0
- data/public/libs/codemirror/mode/q/q.js +124 -0
- data/public/libs/codemirror/mode/r/LICENSE +24 -0
- data/public/libs/codemirror/mode/r/index.html +74 -0
- data/public/libs/codemirror/mode/r/r.js +141 -0
- data/public/libs/codemirror/mode/rpm/changes/changes.js +19 -0
- data/public/libs/codemirror/mode/rpm/changes/index.html +53 -0
- data/public/libs/codemirror/mode/rpm/spec/index.html +99 -0
- data/public/libs/codemirror/mode/rpm/spec/spec.css +5 -0
- data/public/libs/codemirror/mode/rpm/spec/spec.js +66 -0
- data/public/libs/codemirror/mode/rst/LICENSE.txt +21 -0
- data/public/libs/codemirror/mode/rst/index.html +524 -0
- data/public/libs/codemirror/mode/rst/rst.js +550 -0
- data/public/libs/codemirror/mode/ruby/LICENSE +24 -0
- data/public/libs/codemirror/mode/ruby/index.html +173 -0
- data/public/libs/codemirror/mode/ruby/ruby.js +197 -0
- data/public/libs/codemirror/mode/rust/index.html +48 -0
- data/public/libs/codemirror/mode/rust/rust.js +432 -0
- data/public/libs/codemirror/mode/sass/index.html +54 -0
- data/public/libs/codemirror/mode/sass/sass.js +349 -0
- data/public/libs/codemirror/mode/scheme/index.html +65 -0
- data/public/libs/codemirror/mode/scheme/scheme.js +230 -0
- data/public/libs/codemirror/mode/shell/index.html +51 -0
- data/public/libs/codemirror/mode/shell/shell.js +118 -0
- data/public/libs/codemirror/mode/sieve/LICENSE +19 -0
- data/public/libs/codemirror/mode/sieve/index.html +81 -0
- data/public/libs/codemirror/mode/sieve/sieve.js +183 -0
- data/public/libs/codemirror/mode/smalltalk/index.html +57 -0
- data/public/libs/codemirror/mode/smalltalk/smalltalk.js +141 -0
- data/public/libs/codemirror/mode/smarty/index.html +83 -0
- data/public/libs/codemirror/mode/smarty/smarty.js +148 -0
- data/public/libs/codemirror/mode/sparql/index.html +42 -0
- data/public/libs/codemirror/mode/sparql/sparql.js +143 -0
- data/public/libs/codemirror/mode/sql/index.html +68 -0
- data/public/libs/codemirror/mode/sql/sql.js +268 -0
- data/public/libs/codemirror/mode/stex/index.html +98 -0
- data/public/libs/codemirror/mode/stex/stex.js +246 -0
- data/public/libs/codemirror/mode/stex/test.js +117 -0
- data/public/libs/codemirror/mode/tcl/index.html +129 -0
- data/public/libs/codemirror/mode/tcl/tcl.js +131 -0
- data/public/libs/codemirror/mode/tiddlywiki/index.html +142 -0
- data/public/libs/codemirror/mode/tiddlywiki/tiddlywiki.css +14 -0
- data/public/libs/codemirror/mode/tiddlywiki/tiddlywiki.js +353 -0
- data/public/libs/codemirror/mode/tiki/index.html +81 -0
- data/public/libs/codemirror/mode/tiki/tiki.css +26 -0
- data/public/libs/codemirror/mode/tiki/tiki.js +308 -0
- data/public/libs/codemirror/mode/turtle/index.html +39 -0
- data/public/libs/codemirror/mode/turtle/turtle.js +145 -0
- data/public/libs/codemirror/mode/vb/LICENSE.txt +21 -0
- data/public/libs/codemirror/mode/vb/index.html +88 -0
- data/public/libs/codemirror/mode/vb/vb.js +259 -0
- data/public/libs/codemirror/mode/vbscript/index.html +42 -0
- data/public/libs/codemirror/mode/vbscript/vbscript.js +26 -0
- data/public/libs/codemirror/mode/velocity/index.html +103 -0
- data/public/libs/codemirror/mode/velocity/velocity.js +144 -0
- data/public/libs/codemirror/mode/verilog/index.html +121 -0
- data/public/libs/codemirror/mode/verilog/verilog.js +182 -0
- data/public/libs/codemirror/mode/xml/index.html +45 -0
- data/public/libs/codemirror/mode/xml/xml.js +328 -0
- data/public/libs/codemirror/mode/xquery/LICENSE +20 -0
- data/public/libs/codemirror/mode/xquery/index.html +221 -0
- data/public/libs/codemirror/mode/xquery/test.js +64 -0
- data/public/libs/codemirror/mode/xquery/xquery.js +450 -0
- data/public/libs/codemirror/mode/yaml/index.html +68 -0
- data/public/libs/codemirror/mode/yaml/yaml.js +95 -0
- data/public/libs/codemirror/mode/z80/index.html +39 -0
- data/public/libs/codemirror/mode/z80/z80.js +85 -0
- data/public/libs/codemirror/package.json +21 -0
- data/public/libs/codemirror/test/doc_test.js +329 -0
- data/public/libs/codemirror/test/driver.js +138 -0
- data/public/libs/codemirror/test/index.html +182 -0
- data/public/libs/codemirror/test/lint/acorn.js +1593 -0
- data/public/libs/codemirror/test/lint/lint.js +112 -0
- data/public/libs/codemirror/test/lint/parse-js.js +1372 -0
- data/public/libs/codemirror/test/lint/walk.js +216 -0
- data/public/libs/codemirror/test/mode_test.css +10 -0
- data/public/libs/codemirror/test/mode_test.js +192 -0
- data/public/libs/codemirror/test/phantom_driver.js +31 -0
- data/public/libs/codemirror/test/run.js +33 -0
- data/public/libs/codemirror/test/test.js +1400 -0
- data/public/libs/codemirror/test/vim_test.js +1688 -0
- data/public/libs/codemirror/theme/ambiance-mobile.css +5 -0
- data/public/libs/codemirror/theme/ambiance.css +75 -0
- data/public/libs/codemirror/theme/blackboard.css +25 -0
- data/public/libs/codemirror/theme/cobalt.css +18 -0
- data/public/libs/codemirror/theme/eclipse.css +25 -0
- data/public/libs/codemirror/theme/elegant.css +10 -0
- data/public/libs/codemirror/theme/erlang-dark.css +21 -0
- data/public/libs/codemirror/theme/lesser-dark.css +44 -0
- data/public/libs/codemirror/theme/midnight.css +52 -0
- data/public/libs/codemirror/theme/monokai.css +28 -0
- data/public/libs/codemirror/theme/neat.css +9 -0
- data/public/libs/codemirror/theme/night.css +21 -0
- data/public/libs/codemirror/theme/rubyblue.css +21 -0
- data/public/libs/codemirror/theme/solarized.css +207 -0
- data/public/libs/codemirror/theme/twilight.css +26 -0
- data/public/libs/codemirror/theme/vibrant-ink.css +27 -0
- data/public/libs/codemirror/theme/xq-dark.css +46 -0
- data/public/libs/codemirror/theme/xq-light.css +43 -0
- data/public/libs/font-awesome/css/font-awesome-ie7.css +983 -0
- data/public/libs/font-awesome/css/font-awesome-ie7.min.css +24 -0
- data/public/libs/font-awesome/css/font-awesome.css +1268 -0
- data/public/libs/font-awesome/css/font-awesome.min.css +24 -0
- data/public/libs/font-awesome/font/FontAwesome.otf +0 -0
- data/public/libs/font-awesome/font/fontawesome-webfont.eot +0 -0
- data/public/libs/font-awesome/font/fontawesome-webfont.svg +339 -0
- data/public/libs/font-awesome/font/fontawesome-webfont.ttf +0 -0
- data/public/libs/font-awesome/font/fontawesome-webfont.woff +0 -0
- data/public/libs/font-awesome/less/bootstrap.less +78 -0
- data/public/libs/font-awesome/less/core.less +132 -0
- data/public/libs/font-awesome/less/extras.less +79 -0
- data/public/libs/font-awesome/less/font-awesome-ie7.less +413 -0
- data/public/libs/font-awesome/less/font-awesome.less +32 -0
- data/public/libs/font-awesome/less/icons.less +330 -0
- data/public/libs/font-awesome/less/mixins.less +34 -0
- data/public/libs/font-awesome/less/path.less +15 -0
- data/public/libs/font-awesome/less/variables.less +9 -0
- data/public/libs/jquery-1.10.0.min.js +6 -0
- data/public/libs/jquery-ui.min.js +12 -0
- data/public/libs/jquery.jsPlumb-1.4.0-all.js +9571 -0
- data/public/libs/jquery.livequery.js +226 -0
- data/public/libs/jsPlumbInitializer.js +72 -0
- data/public/libs/jstree/README.txt +10 -0
- data/public/libs/jstree/_demo/_dump.sql +20 -0
- data/public/libs/jstree/_demo/_inc/__mysql_errors.log +0 -0
- data/public/libs/jstree/_demo/_inc/class._database.php +146 -0
- data/public/libs/jstree/_demo/_inc/class._database_i.php +152 -0
- data/public/libs/jstree/_demo/_inc/class.tree.php +602 -0
- data/public/libs/jstree/_demo/_install.txt +6 -0
- data/public/libs/jstree/_demo/config.php +14 -0
- data/public/libs/jstree/_demo/file.png +0 -0
- data/public/libs/jstree/_demo/folder.png +0 -0
- data/public/libs/jstree/_demo/index.html +461 -0
- data/public/libs/jstree/_demo/root.png +0 -0
- data/public/libs/jstree/_demo/server.php +69 -0
- data/public/libs/jstree/_docs/!style.css +48 -0
- data/public/libs/jstree/_docs/_drive.png +0 -0
- data/public/libs/jstree/_docs/_html_data.html +2 -0
- data/public/libs/jstree/_docs/_json_data.json +4 -0
- data/public/libs/jstree/_docs/_search_data.json +6 -0
- data/public/libs/jstree/_docs/_search_result.json +1 -0
- data/public/libs/jstree/_docs/_xml_flat.xml +12 -0
- data/public/libs/jstree/_docs/_xml_nest.xml +18 -0
- data/public/libs/jstree/_docs/checkbox.html +171 -0
- data/public/libs/jstree/_docs/contextmenu.html +121 -0
- data/public/libs/jstree/_docs/cookies.html +97 -0
- data/public/libs/jstree/_docs/core.html +689 -0
- data/public/libs/jstree/_docs/crrm.html +316 -0
- data/public/libs/jstree/_docs/dnd.html +199 -0
- data/public/libs/jstree/_docs/hotkeys.html +82 -0
- data/public/libs/jstree/_docs/html_data.html +175 -0
- data/public/libs/jstree/_docs/index.html +86 -0
- data/public/libs/jstree/_docs/json_data.html +249 -0
- data/public/libs/jstree/_docs/languages.html +152 -0
- data/public/libs/jstree/_docs/logo.png +0 -0
- data/public/libs/jstree/_docs/search.html +153 -0
- data/public/libs/jstree/_docs/sort.html +85 -0
- data/public/libs/jstree/_docs/syntax/!script.js +2232 -0
- data/public/libs/jstree/_docs/syntax/!style.css +511 -0
- data/public/libs/jstree/_docs/syntax/clipboard.swf +0 -0
- data/public/libs/jstree/_docs/syntax/help.png +0 -0
- data/public/libs/jstree/_docs/syntax/magnifier.png +0 -0
- data/public/libs/jstree/_docs/syntax/page_white_code.png +0 -0
- data/public/libs/jstree/_docs/syntax/page_white_copy.png +0 -0
- data/public/libs/jstree/_docs/syntax/printer.png +0 -0
- data/public/libs/jstree/_docs/syntax/wrapping.png +0 -0
- data/public/libs/jstree/_docs/themeroller.html +107 -0
- data/public/libs/jstree/_docs/themes.html +127 -0
- data/public/libs/jstree/_docs/types.html +178 -0
- data/public/libs/jstree/_docs/ui.html +197 -0
- data/public/libs/jstree/_docs/unique.html +85 -0
- data/public/libs/jstree/_docs/xml_data.html +218 -0
- data/public/libs/jstree/_lib/jquery.cookie.js +96 -0
- data/public/libs/jstree/_lib/jquery.hotkeys.js +99 -0
- data/public/libs/jstree/_lib/jquery.js +5 -0
- data/public/libs/jstree/jquery.jstree.js +4564 -0
- data/public/libs/jstree/themes/apple/bg.jpg +0 -0
- data/public/libs/jstree/themes/apple/d.png +0 -0
- data/public/libs/jstree/themes/apple/dot_for_ie.gif +0 -0
- data/public/libs/jstree/themes/apple/style.css +61 -0
- data/public/libs/jstree/themes/apple/throbber.gif +0 -0
- data/public/libs/jstree/themes/classic/d.gif +0 -0
- data/public/libs/jstree/themes/classic/d.png +0 -0
- data/public/libs/jstree/themes/classic/dot_for_ie.gif +0 -0
- data/public/libs/jstree/themes/classic/style.css +77 -0
- data/public/libs/jstree/themes/classic/throbber.gif +0 -0
- data/public/libs/jstree/themes/default-rtl/d.gif +0 -0
- data/public/libs/jstree/themes/default-rtl/d.png +0 -0
- data/public/libs/jstree/themes/default-rtl/dots.gif +0 -0
- data/public/libs/jstree/themes/default-rtl/style.css +84 -0
- data/public/libs/jstree/themes/default-rtl/throbber.gif +0 -0
- data/public/libs/jstree/themes/default/d.gif +0 -0
- data/public/libs/jstree/themes/default/d.png +0 -0
- data/public/libs/jstree/themes/default/style.css +74 -0
- data/public/libs/jstree/themes/default/throbber.gif +0 -0
- data/public/themes/geo-bootstrap/README.md +25 -0
- data/public/themes/geo-bootstrap/img/flames.gif +0 -0
- data/public/themes/geo-bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/public/themes/geo-bootstrap/img/glyphicons-halflings.png +0 -0
- data/public/themes/geo-bootstrap/img/microfab.gif +0 -0
- data/public/themes/geo-bootstrap/img/progress.gif +0 -0
- data/public/themes/geo-bootstrap/img/rainbow.gif +0 -0
- data/public/themes/geo-bootstrap/img/stars.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/7upspot.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/americanflag.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/community.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/computer-01.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/computer.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/construction.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/counter.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/counter2.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/divider.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/divider1.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/divider2.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/divider3.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/divider4.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/drudgesiren.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/emailme.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/funky.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/geocities.jpg +0 -0
- data/public/themes/geo-bootstrap/img/test/hacker.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/heart.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/hot.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/ie_logo.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/mailkitten.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/mchammer.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/new.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/new2.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/noframes.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/notepad.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/ns_logo.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/sign-in.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/spinningearth.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/underconstruction.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/wabwalk.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/webtrips.gif +0 -0
- data/public/themes/geo-bootstrap/img/test/yahooweek.gif +0 -0
- data/public/themes/geo-bootstrap/package.json +21 -0
- data/public/themes/geo-bootstrap/swatch/bootstrap-responsive.css +1109 -0
- data/public/themes/geo-bootstrap/swatch/bootstrap-responsive.min.css +9 -0
- data/public/themes/geo-bootstrap/swatch/bootstrap.css +6462 -0
- data/public/themes/geo-bootstrap/swatch/bootstrap.min.css +9 -0
- metadata +791 -0
@@ -0,0 +1,138 @@
|
|
1
|
+
var tests = [], debug = null, debugUsed = new Array(), allNames = [];
|
2
|
+
|
3
|
+
function Failure(why) {this.message = why;}
|
4
|
+
Failure.prototype.toString = function() { return this.message; };
|
5
|
+
|
6
|
+
function indexOf(collection, elt) {
|
7
|
+
if (collection.indexOf) return collection.indexOf(elt);
|
8
|
+
for (var i = 0, e = collection.length; i < e; ++i)
|
9
|
+
if (collection[i] == elt) return i;
|
10
|
+
return -1;
|
11
|
+
}
|
12
|
+
|
13
|
+
function test(name, run, expectedFail) {
|
14
|
+
// Force unique names
|
15
|
+
var originalName = name;
|
16
|
+
var i = 2; // Second function would be NAME_2
|
17
|
+
while (indexOf(allNames, name) !== -1){
|
18
|
+
name = originalName + "_" + i;
|
19
|
+
i++;
|
20
|
+
}
|
21
|
+
allNames.push(name);
|
22
|
+
// Add test
|
23
|
+
tests.push({name: name, func: run, expectedFail: expectedFail});
|
24
|
+
return name;
|
25
|
+
}
|
26
|
+
function testCM(name, run, opts, expectedFail) {
|
27
|
+
return test("core_" + name, function() {
|
28
|
+
var place = document.getElementById("testground"), cm = CodeMirror(place, opts);
|
29
|
+
var successful = false;
|
30
|
+
try {
|
31
|
+
run(cm);
|
32
|
+
successful = true;
|
33
|
+
} finally {
|
34
|
+
if ((debug && !successful) || verbose) {
|
35
|
+
place.style.visibility = "visible";
|
36
|
+
} else {
|
37
|
+
place.removeChild(cm.getWrapperElement());
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}, expectedFail);
|
41
|
+
}
|
42
|
+
|
43
|
+
function runTests(callback) {
|
44
|
+
if (debug) {
|
45
|
+
if (indexOf(debug, "verbose") === 0) {
|
46
|
+
verbose = true;
|
47
|
+
debug.splice(0, 1);
|
48
|
+
}
|
49
|
+
if (debug.length < 1) {
|
50
|
+
debug = null;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
var totalTime = 0;
|
54
|
+
function step(i) {
|
55
|
+
if (i === tests.length){
|
56
|
+
running = false;
|
57
|
+
return callback("done");
|
58
|
+
}
|
59
|
+
var test = tests[i], expFail = test.expectedFail, startTime = +new Date;
|
60
|
+
if (debug !== null) {
|
61
|
+
var debugIndex = indexOf(debug, test.name);
|
62
|
+
if (debugIndex !== -1) {
|
63
|
+
// Remove from array for reporting incorrect tests later
|
64
|
+
debug.splice(debugIndex, 1);
|
65
|
+
} else {
|
66
|
+
var wildcardName = test.name.split("_")[0] + "_*";
|
67
|
+
debugIndex = indexOf(debug, wildcardName);
|
68
|
+
if (debugIndex !== -1) {
|
69
|
+
// Remove from array for reporting incorrect tests later
|
70
|
+
debug.splice(debugIndex, 1);
|
71
|
+
debugUsed.push(wildcardName);
|
72
|
+
} else {
|
73
|
+
debugIndex = indexOf(debugUsed, wildcardName);
|
74
|
+
if (debugIndex == -1) return step(i + 1);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
var threw = false;
|
79
|
+
try {
|
80
|
+
var message = test.func();
|
81
|
+
} catch(e) {
|
82
|
+
threw = true;
|
83
|
+
if (expFail) callback("expected", test.name);
|
84
|
+
else if (e instanceof Failure) callback("fail", test.name, e.message);
|
85
|
+
else {
|
86
|
+
var pos = /\bat .*?([^\/:]+):(\d+):/.exec(e.stack);
|
87
|
+
callback("error", test.name, e.toString() + (pos ? " (" + pos[1] + ":" + pos[2] + ")" : ""));
|
88
|
+
}
|
89
|
+
}
|
90
|
+
if (!threw) {
|
91
|
+
if (expFail) callback("fail", test.name, message || "expected failure, but succeeded");
|
92
|
+
else callback("ok", test.name, message);
|
93
|
+
}
|
94
|
+
if (!quit) { // Run next test
|
95
|
+
var delay = 0;
|
96
|
+
totalTime += (+new Date) - startTime;
|
97
|
+
if (totalTime > 500){
|
98
|
+
totalTime = 0;
|
99
|
+
delay = 50;
|
100
|
+
}
|
101
|
+
setTimeout(function(){step(i + 1);}, delay);
|
102
|
+
} else { // Quit tests
|
103
|
+
running = false;
|
104
|
+
return null;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
step(0);
|
108
|
+
}
|
109
|
+
|
110
|
+
function label(str, msg) {
|
111
|
+
if (msg) return str + " (" + msg + ")";
|
112
|
+
return str;
|
113
|
+
}
|
114
|
+
function eq(a, b, msg) {
|
115
|
+
if (a != b) throw new Failure(label(a + " != " + b, msg));
|
116
|
+
}
|
117
|
+
function eqPos(a, b, msg) {
|
118
|
+
function str(p) { return "{line:" + p.line + ",ch:" + p.ch + "}"; }
|
119
|
+
if (a == b) return;
|
120
|
+
if (a == null) throw new Failure(label("comparing null to " + str(b), msg));
|
121
|
+
if (b == null) throw new Failure(label("comparing " + str(a) + " to null", msg));
|
122
|
+
if (a.line != b.line || a.ch != b.ch) throw new Failure(label(str(a) + " != " + str(b), msg));
|
123
|
+
}
|
124
|
+
function is(a, msg) {
|
125
|
+
if (!a) throw new Failure(label("assertion failed", msg));
|
126
|
+
}
|
127
|
+
|
128
|
+
function countTests() {
|
129
|
+
if (!debug) return tests.length;
|
130
|
+
var sum = 0;
|
131
|
+
for (var i = 0; i < tests.length; ++i) {
|
132
|
+
var name = tests[i].name;
|
133
|
+
if (indexOf(debug, name) != -1 ||
|
134
|
+
indexOf(debug, name.split("_")[0] + "_*") != -1)
|
135
|
+
++sum;
|
136
|
+
}
|
137
|
+
return sum;
|
138
|
+
}
|
@@ -0,0 +1,182 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>CodeMirror: Test Suite</title>
|
6
|
+
<link rel="stylesheet" href="../lib/codemirror.css">
|
7
|
+
<link rel="stylesheet" href="../doc/docs.css">
|
8
|
+
<link rel="stylesheet" href="mode_test.css">
|
9
|
+
<script src="../lib/codemirror.js"></script>
|
10
|
+
<script src="../addon/mode/overlay.js"></script>
|
11
|
+
<script src="../addon/search/searchcursor.js"></script>
|
12
|
+
<script src="../mode/javascript/javascript.js"></script>
|
13
|
+
<script src="../mode/xml/xml.js"></script>
|
14
|
+
<script src="../keymap/vim.js"></script>
|
15
|
+
|
16
|
+
<style type="text/css">
|
17
|
+
.ok {color: #090;}
|
18
|
+
.fail {color: #e00;}
|
19
|
+
.error {color: #c90;}
|
20
|
+
.done {font-weight: bold;}
|
21
|
+
#progress {
|
22
|
+
background: #45d;
|
23
|
+
color: white;
|
24
|
+
text-shadow: 0 0 1px #45d, 0 0 2px #45d, 0 0 3px #45d;
|
25
|
+
font-weight: bold;
|
26
|
+
white-space: pre;
|
27
|
+
}
|
28
|
+
#testground {
|
29
|
+
visibility: hidden;
|
30
|
+
}
|
31
|
+
#testground.offscreen {
|
32
|
+
visibility: visible;
|
33
|
+
position: absolute;
|
34
|
+
left: -10000px;
|
35
|
+
top: -10000px;
|
36
|
+
}
|
37
|
+
.CodeMirror { border: 1px solid black; }
|
38
|
+
</style>
|
39
|
+
</head>
|
40
|
+
<body>
|
41
|
+
<h1>CodeMirror: Test Suite</h1>
|
42
|
+
|
43
|
+
<p>A limited set of programmatic sanity tests for CodeMirror.</p>
|
44
|
+
|
45
|
+
<div style="border: 1px solid black; padding: 1px; max-width: 700px;">
|
46
|
+
<div style="width: 0px;" id=progress><div style="padding: 3px;">Ran <span id="progress_ran">0</span><span id="progress_total"> of 0</span> tests</div></div>
|
47
|
+
</div>
|
48
|
+
<p id=status>Please enable JavaScript...</p>
|
49
|
+
<div id=output></div>
|
50
|
+
|
51
|
+
<div id=testground></div>
|
52
|
+
|
53
|
+
<script src="driver.js"></script>
|
54
|
+
<script src="test.js"></script>
|
55
|
+
<script src="doc_test.js"></script>
|
56
|
+
<script src="mode_test.js"></script>
|
57
|
+
<script src="../mode/css/css.js"></script>
|
58
|
+
<script src="../mode/css/test.js"></script>
|
59
|
+
<script src="../mode/css/scss_test.js"></script>
|
60
|
+
<script src="../mode/markdown/markdown.js"></script>
|
61
|
+
<script src="../mode/markdown/test.js"></script>
|
62
|
+
<script src="../mode/gfm/gfm.js"></script>
|
63
|
+
<script src="../mode/gfm/test.js"></script>
|
64
|
+
<script src="../mode/stex/stex.js"></script>
|
65
|
+
<script src="../mode/stex/test.js"></script>
|
66
|
+
<script src="../mode/xquery/xquery.js"></script>
|
67
|
+
<script src="../mode/xquery/test.js"></script>
|
68
|
+
<script src="vim_test.js"></script>
|
69
|
+
<script>
|
70
|
+
window.onload = runHarness;
|
71
|
+
CodeMirror.on(window, 'hashchange', runHarness);
|
72
|
+
|
73
|
+
function esc(str) {
|
74
|
+
return str.replace(/[<&]/, function(ch) { return ch == "<" ? "<" : "&"; });
|
75
|
+
}
|
76
|
+
|
77
|
+
var output = document.getElementById("output"),
|
78
|
+
progress = document.getElementById("progress"),
|
79
|
+
progressRan = document.getElementById("progress_ran").childNodes[0],
|
80
|
+
progressTotal = document.getElementById("progress_total").childNodes[0];
|
81
|
+
var count = 0,
|
82
|
+
failed = 0,
|
83
|
+
bad = "",
|
84
|
+
running = false, // Flag that states tests are running
|
85
|
+
quit = false, // Flag to quit tests ASAP
|
86
|
+
verbose = false; // Adds message for *every* test to output
|
87
|
+
|
88
|
+
function runHarness(){
|
89
|
+
if (running) {
|
90
|
+
quit = true;
|
91
|
+
setStatus("Restarting tests...", '', true);
|
92
|
+
setTimeout(function(){runHarness();}, 500);
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
if (window.location.hash.substr(1)){
|
96
|
+
debug = window.location.hash.substr(1).split(",");
|
97
|
+
} else {
|
98
|
+
debug = null;
|
99
|
+
}
|
100
|
+
quit = false;
|
101
|
+
running = true;
|
102
|
+
setStatus("Loading tests...");
|
103
|
+
count = 0;
|
104
|
+
failed = 0;
|
105
|
+
bad = "";
|
106
|
+
verbose = false;
|
107
|
+
debugUsed = Array();
|
108
|
+
totalTests = countTests();
|
109
|
+
progressTotal.nodeValue = " of " + totalTests;
|
110
|
+
progressRan.nodeValue = count;
|
111
|
+
output.innerHTML = '';
|
112
|
+
document.getElementById("testground").innerHTML = "<form>" +
|
113
|
+
"<textarea id=\"code\" name=\"code\"></textarea>" +
|
114
|
+
"<input type=submit value=ok name=submit>" +
|
115
|
+
"</form>";
|
116
|
+
runTests(displayTest);
|
117
|
+
}
|
118
|
+
|
119
|
+
function setStatus(message, className, force){
|
120
|
+
if (quit && !force) return;
|
121
|
+
if (!message) throw("must provide message");
|
122
|
+
var status = document.getElementById("status").childNodes[0];
|
123
|
+
status.nodeValue = message;
|
124
|
+
status.parentNode.className = className;
|
125
|
+
}
|
126
|
+
function addOutput(name, className, code){
|
127
|
+
var newOutput = document.createElement("dl");
|
128
|
+
var newTitle = document.createElement("dt");
|
129
|
+
newTitle.className = className;
|
130
|
+
newTitle.appendChild(document.createTextNode(name));
|
131
|
+
newOutput.appendChild(newTitle);
|
132
|
+
var newMessage = document.createElement("dd");
|
133
|
+
newMessage.innerHTML = code;
|
134
|
+
newOutput.appendChild(newTitle);
|
135
|
+
newOutput.appendChild(newMessage);
|
136
|
+
output.appendChild(newOutput);
|
137
|
+
}
|
138
|
+
function displayTest(type, name, customMessage) {
|
139
|
+
var message = "???";
|
140
|
+
if (type != "done") ++count;
|
141
|
+
progress.style.width = (count * (progress.parentNode.clientWidth - 2) / totalTests) + "px";
|
142
|
+
progressRan.nodeValue = count;
|
143
|
+
if (type == "ok") {
|
144
|
+
message = "Test '" + name + "' succeeded";
|
145
|
+
if (!verbose) customMessage = false;
|
146
|
+
} else if (type == "expected") {
|
147
|
+
message = "Test '" + name + "' failed as expected";
|
148
|
+
if (!verbose) customMessage = false;
|
149
|
+
} else if (type == "error" || type == "fail") {
|
150
|
+
++failed;
|
151
|
+
message = "Test '" + name + "' failed";
|
152
|
+
} else if (type == "done") {
|
153
|
+
if (failed) {
|
154
|
+
type += " fail";
|
155
|
+
message = failed + " failure" + (failed > 1 ? "s" : "");
|
156
|
+
} else if (count < totalTests) {
|
157
|
+
failed = totalTests - count;
|
158
|
+
type += " fail";
|
159
|
+
message = failed + " failure" + (failed > 1 ? "s" : "");
|
160
|
+
} else {
|
161
|
+
type += " ok";
|
162
|
+
message = "All passed";
|
163
|
+
}
|
164
|
+
if (debug && debug.length) {
|
165
|
+
var bogusTests = totalTests - count;
|
166
|
+
message += " — " + bogusTests + " nonexistent test" +
|
167
|
+
(bogusTests > 1 ? "s" : "") + " requested by location.hash: " +
|
168
|
+
"`" + debug.join("`, `") + "`";
|
169
|
+
} else {
|
170
|
+
progressTotal.nodeValue = '';
|
171
|
+
}
|
172
|
+
customMessage = true; // Hack to avoid adding to output
|
173
|
+
}
|
174
|
+
if (verbose && !customMessage) customMessage = message;
|
175
|
+
setStatus(message, type);
|
176
|
+
if (customMessage && customMessage.length > 0) {
|
177
|
+
addOutput(name, type, customMessage);
|
178
|
+
}
|
179
|
+
}
|
180
|
+
</script>
|
181
|
+
</body>
|
182
|
+
</html>
|
@@ -0,0 +1,1593 @@
|
|
1
|
+
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
|
2
|
+
//
|
3
|
+
// Acorn was written by Marijn Haverbeke and released under an MIT
|
4
|
+
// license. The Unicode regexps (for identifiers and whitespace) were
|
5
|
+
// taken from [Esprima](http://esprima.org) by Ariya Hidayat.
|
6
|
+
//
|
7
|
+
// Git repositories for Acorn are available at
|
8
|
+
//
|
9
|
+
// http://marijnhaverbeke.nl/git/acorn
|
10
|
+
// https://github.com/marijnh/acorn.git
|
11
|
+
//
|
12
|
+
// Please use the [github bug tracker][ghbt] to report issues.
|
13
|
+
//
|
14
|
+
// [ghbt]: https://github.com/marijnh/acorn/issues
|
15
|
+
|
16
|
+
(function(exports) {
|
17
|
+
"use strict";
|
18
|
+
|
19
|
+
exports.version = "0.0.1";
|
20
|
+
|
21
|
+
// The main exported interface (under `window.acorn` when in the
|
22
|
+
// browser) is a `parse` function that takes a code string and
|
23
|
+
// returns an abstract syntax tree as specified by [Mozilla parser
|
24
|
+
// API][api], with the caveat that the SpiderMonkey-specific syntax
|
25
|
+
// (`let`, `yield`, inline XML, etc) is not recognized.
|
26
|
+
//
|
27
|
+
// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
|
28
|
+
|
29
|
+
var options, input, inputLen, sourceFile;
|
30
|
+
|
31
|
+
exports.parse = function(inpt, opts) {
|
32
|
+
input = String(inpt); inputLen = input.length;
|
33
|
+
options = opts || {};
|
34
|
+
for (var opt in defaultOptions) if (!options.hasOwnProperty(opt))
|
35
|
+
options[opt] = defaultOptions[opt];
|
36
|
+
sourceFile = options.sourceFile || null;
|
37
|
+
return parseTopLevel(options.program);
|
38
|
+
};
|
39
|
+
|
40
|
+
// A second optional argument can be given to further configure
|
41
|
+
// the parser process. These options are recognized:
|
42
|
+
|
43
|
+
var defaultOptions = exports.defaultOptions = {
|
44
|
+
// `ecmaVersion` indicates the ECMAScript version to parse. Must
|
45
|
+
// be either 3 or 5. This
|
46
|
+
// influences support for strict mode, the set of reserved words, and
|
47
|
+
// support for getters and setter.
|
48
|
+
ecmaVersion: 5,
|
49
|
+
// Turn on `strictSemicolons` to prevent the parser from doing
|
50
|
+
// automatic semicolon insertion.
|
51
|
+
strictSemicolons: false,
|
52
|
+
// When `allowTrailingCommas` is false, the parser will not allow
|
53
|
+
// trailing commas in array and object literals.
|
54
|
+
allowTrailingCommas: true,
|
55
|
+
// By default, reserved words are not enforced. Enable
|
56
|
+
// `forbidReserved` to enforce them.
|
57
|
+
forbidReserved: false,
|
58
|
+
// When `trackComments` is turned on, the parser will attach
|
59
|
+
// `commentsBefore` and `commentsAfter` properties to AST nodes
|
60
|
+
// holding arrays of strings. A single comment may appear in both
|
61
|
+
// a `commentsBefore` and `commentsAfter` array (of the nodes
|
62
|
+
// after and before it), but never twice in the before (or after)
|
63
|
+
// array of different nodes.
|
64
|
+
trackComments: false,
|
65
|
+
// When `locations` is on, `loc` properties holding objects with
|
66
|
+
// `start` and `end` properties in `{line, column}` form (with
|
67
|
+
// line being 1-based and column 0-based) will be attached to the
|
68
|
+
// nodes.
|
69
|
+
locations: false,
|
70
|
+
// Nodes have their start and end characters offsets recorded in
|
71
|
+
// `start` and `end` properties (directly on the node, rather than
|
72
|
+
// the `loc` object, which holds line/column data. To also add a
|
73
|
+
// [semi-standardized][range] `range` property holding a `[start,
|
74
|
+
// end]` array with the same numbers, set the `ranges` option to
|
75
|
+
// `true`.
|
76
|
+
//
|
77
|
+
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
|
78
|
+
ranges: false,
|
79
|
+
// It is possible to parse multiple files into a single AST by
|
80
|
+
// passing the tree produced by parsing the first file as
|
81
|
+
// `program` option in subsequent parses. This will add the
|
82
|
+
// toplevel forms of the parsed file to the `Program` (top) node
|
83
|
+
// of an existing parse tree.
|
84
|
+
program: null,
|
85
|
+
// When `location` is on, you can pass this to record the source
|
86
|
+
// file in every node's `loc` object.
|
87
|
+
sourceFile: null
|
88
|
+
};
|
89
|
+
|
90
|
+
// The `getLineInfo` function is mostly useful when the
|
91
|
+
// `locations` option is off (for performance reasons) and you
|
92
|
+
// want to find the line/column position for a given character
|
93
|
+
// offset. `input` should be the code string that the offset refers
|
94
|
+
// into.
|
95
|
+
|
96
|
+
var getLineInfo = exports.getLineInfo = function(input, offset) {
|
97
|
+
for (var line = 1, cur = 0;;) {
|
98
|
+
lineBreak.lastIndex = cur;
|
99
|
+
var match = lineBreak.exec(input);
|
100
|
+
if (match && match.index < offset) {
|
101
|
+
++line;
|
102
|
+
cur = match.index + match[0].length;
|
103
|
+
} else break;
|
104
|
+
}
|
105
|
+
return {line: line, column: offset - cur};
|
106
|
+
};
|
107
|
+
|
108
|
+
// Acorn is organized as a tokenizer and a recursive-descent parser.
|
109
|
+
// Both use (closure-)global variables to keep their state and
|
110
|
+
// communicate. We already saw the `options`, `input`, and
|
111
|
+
// `inputLen` variables above (set in `parse`).
|
112
|
+
|
113
|
+
// The current position of the tokenizer in the input.
|
114
|
+
|
115
|
+
var tokPos;
|
116
|
+
|
117
|
+
// The start and end offsets of the current token.
|
118
|
+
|
119
|
+
var tokStart, tokEnd;
|
120
|
+
|
121
|
+
// When `options.locations` is true, these hold objects
|
122
|
+
// containing the tokens start and end line/column pairs.
|
123
|
+
|
124
|
+
var tokStartLoc, tokEndLoc;
|
125
|
+
|
126
|
+
// The type and value of the current token. Token types are objects,
|
127
|
+
// named by variables against which they can be compared, and
|
128
|
+
// holding properties that describe them (indicating, for example,
|
129
|
+
// the precedence of an infix operator, and the original name of a
|
130
|
+
// keyword token). The kind of value that's held in `tokVal` depends
|
131
|
+
// on the type of the token. For literals, it is the literal value,
|
132
|
+
// for operators, the operator name, and so on.
|
133
|
+
|
134
|
+
var tokType, tokVal;
|
135
|
+
|
136
|
+
// These are used to hold arrays of comments when
|
137
|
+
// `options.trackComments` is true.
|
138
|
+
|
139
|
+
var tokCommentsBefore, tokCommentsAfter;
|
140
|
+
|
141
|
+
// Interal state for the tokenizer. To distinguish between division
|
142
|
+
// operators and regular expressions, it remembers whether the last
|
143
|
+
// token was one that is allowed to be followed by an expression.
|
144
|
+
// (If it is, a slash is probably a regexp, if it isn't it's a
|
145
|
+
// division operator. See the `parseStatement` function for a
|
146
|
+
// caveat.)
|
147
|
+
|
148
|
+
var tokRegexpAllowed, tokComments;
|
149
|
+
|
150
|
+
// When `options.locations` is true, these are used to keep
|
151
|
+
// track of the current line, and know when a new line has been
|
152
|
+
// entered. See the `curLineLoc` function.
|
153
|
+
|
154
|
+
var tokCurLine, tokLineStart, tokLineStartNext;
|
155
|
+
|
156
|
+
// These store the position of the previous token, which is useful
|
157
|
+
// when finishing a node and assigning its `end` position.
|
158
|
+
|
159
|
+
var lastStart, lastEnd, lastEndLoc;
|
160
|
+
|
161
|
+
// This is the parser's state. `inFunction` is used to reject
|
162
|
+
// `return` statements outside of functions, `labels` to verify that
|
163
|
+
// `break` and `continue` have somewhere to jump to, and `strict`
|
164
|
+
// indicates whether strict mode is on.
|
165
|
+
|
166
|
+
var inFunction, labels, strict;
|
167
|
+
|
168
|
+
// This function is used to raise exceptions on parse errors. It
|
169
|
+
// takes either a `{line, column}` object or an offset integer (into
|
170
|
+
// the current `input`) as `pos` argument. It attaches the position
|
171
|
+
// to the end of the error message, and then raises a `SyntaxError`
|
172
|
+
// with that message.
|
173
|
+
|
174
|
+
function raise(pos, message) {
|
175
|
+
if (typeof pos == "number") pos = getLineInfo(input, pos);
|
176
|
+
message += " (" + pos.line + ":" + pos.column + ")";
|
177
|
+
throw new SyntaxError(message);
|
178
|
+
}
|
179
|
+
|
180
|
+
// ## Token types
|
181
|
+
|
182
|
+
// The assignment of fine-grained, information-carrying type objects
|
183
|
+
// allows the tokenizer to store the information it has about a
|
184
|
+
// token in a way that is very cheap for the parser to look up.
|
185
|
+
|
186
|
+
// All token type variables start with an underscore, to make them
|
187
|
+
// easy to recognize.
|
188
|
+
|
189
|
+
// These are the general types. The `type` property is only used to
|
190
|
+
// make them recognizeable when debugging.
|
191
|
+
|
192
|
+
var _num = {type: "num"}, _regexp = {type: "regexp"}, _string = {type: "string"};
|
193
|
+
var _name = {type: "name"}, _eof = {type: "eof"};
|
194
|
+
|
195
|
+
// Keyword tokens. The `keyword` property (also used in keyword-like
|
196
|
+
// operators) indicates that the token originated from an
|
197
|
+
// identifier-like word, which is used when parsing property names.
|
198
|
+
//
|
199
|
+
// The `beforeExpr` property is used to disambiguate between regular
|
200
|
+
// expressions and divisions. It is set on all token types that can
|
201
|
+
// be followed by an expression (thus, a slash after them would be a
|
202
|
+
// regular expression).
|
203
|
+
//
|
204
|
+
// `isLoop` marks a keyword as starting a loop, which is important
|
205
|
+
// to know when parsing a label, in order to allow or disallow
|
206
|
+
// continue jumps to that label.
|
207
|
+
|
208
|
+
var _break = {keyword: "break"}, _case = {keyword: "case", beforeExpr: true}, _catch = {keyword: "catch"};
|
209
|
+
var _continue = {keyword: "continue"}, _debugger = {keyword: "debugger"}, _default = {keyword: "default"};
|
210
|
+
var _do = {keyword: "do", isLoop: true}, _else = {keyword: "else", beforeExpr: true};
|
211
|
+
var _finally = {keyword: "finally"}, _for = {keyword: "for", isLoop: true}, _function = {keyword: "function"};
|
212
|
+
var _if = {keyword: "if"}, _return = {keyword: "return", beforeExpr: true}, _switch = {keyword: "switch"};
|
213
|
+
var _throw = {keyword: "throw", beforeExpr: true}, _try = {keyword: "try"}, _var = {keyword: "var"};
|
214
|
+
var _while = {keyword: "while", isLoop: true}, _with = {keyword: "with"}, _new = {keyword: "new", beforeExpr: true};
|
215
|
+
var _this = {keyword: "this"};
|
216
|
+
|
217
|
+
// The keywords that denote values.
|
218
|
+
|
219
|
+
var _null = {keyword: "null", atomValue: null}, _true = {keyword: "true", atomValue: true};
|
220
|
+
var _false = {keyword: "false", atomValue: false};
|
221
|
+
|
222
|
+
// Some keywords are treated as regular operators. `in` sometimes
|
223
|
+
// (when parsing `for`) needs to be tested against specifically, so
|
224
|
+
// we assign a variable name to it for quick comparing.
|
225
|
+
|
226
|
+
var _in = {keyword: "in", binop: 7, beforeExpr: true};
|
227
|
+
|
228
|
+
// Map keyword names to token types.
|
229
|
+
|
230
|
+
var keywordTypes = {"break": _break, "case": _case, "catch": _catch,
|
231
|
+
"continue": _continue, "debugger": _debugger, "default": _default,
|
232
|
+
"do": _do, "else": _else, "finally": _finally, "for": _for,
|
233
|
+
"function": _function, "if": _if, "return": _return, "switch": _switch,
|
234
|
+
"throw": _throw, "try": _try, "var": _var, "while": _while, "with": _with,
|
235
|
+
"null": _null, "true": _true, "false": _false, "new": _new, "in": _in,
|
236
|
+
"instanceof": {keyword: "instanceof", binop: 7}, "this": _this,
|
237
|
+
"typeof": {keyword: "typeof", prefix: true},
|
238
|
+
"void": {keyword: "void", prefix: true},
|
239
|
+
"delete": {keyword: "delete", prefix: true}};
|
240
|
+
|
241
|
+
// Punctuation token types. Again, the `type` property is purely for debugging.
|
242
|
+
|
243
|
+
var _bracketL = {type: "[", beforeExpr: true}, _bracketR = {type: "]"}, _braceL = {type: "{", beforeExpr: true};
|
244
|
+
var _braceR = {type: "}"}, _parenL = {type: "(", beforeExpr: true}, _parenR = {type: ")"};
|
245
|
+
var _comma = {type: ",", beforeExpr: true}, _semi = {type: ";", beforeExpr: true};
|
246
|
+
var _colon = {type: ":", beforeExpr: true}, _dot = {type: "."}, _question = {type: "?", beforeExpr: true};
|
247
|
+
|
248
|
+
// Operators. These carry several kinds of properties to help the
|
249
|
+
// parser use them properly (the presence of these properties is
|
250
|
+
// what categorizes them as operators).
|
251
|
+
//
|
252
|
+
// `binop`, when present, specifies that this operator is a binary
|
253
|
+
// operator, and will refer to its precedence.
|
254
|
+
//
|
255
|
+
// `prefix` and `postfix` mark the operator as a prefix or postfix
|
256
|
+
// unary operator. `isUpdate` specifies that the node produced by
|
257
|
+
// the operator should be of type UpdateExpression rather than
|
258
|
+
// simply UnaryExpression (`++` and `--`).
|
259
|
+
//
|
260
|
+
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
|
261
|
+
// binary operators with a very low precedence, that should result
|
262
|
+
// in AssignmentExpression nodes.
|
263
|
+
|
264
|
+
var _slash = {binop: 10, beforeExpr: true}, _eq = {isAssign: true, beforeExpr: true};
|
265
|
+
var _assign = {isAssign: true, beforeExpr: true}, _plusmin = {binop: 9, prefix: true, beforeExpr: true};
|
266
|
+
var _incdec = {postfix: true, prefix: true, isUpdate: true}, _prefix = {prefix: true, beforeExpr: true};
|
267
|
+
var _bin1 = {binop: 1, beforeExpr: true}, _bin2 = {binop: 2, beforeExpr: true};
|
268
|
+
var _bin3 = {binop: 3, beforeExpr: true}, _bin4 = {binop: 4, beforeExpr: true};
|
269
|
+
var _bin5 = {binop: 5, beforeExpr: true}, _bin6 = {binop: 6, beforeExpr: true};
|
270
|
+
var _bin7 = {binop: 7, beforeExpr: true}, _bin8 = {binop: 8, beforeExpr: true};
|
271
|
+
var _bin10 = {binop: 10, beforeExpr: true};
|
272
|
+
|
273
|
+
// This is a trick taken from Esprima. It turns out that, on
|
274
|
+
// non-Chrome browsers, to check whether a string is in a set, a
|
275
|
+
// predicate containing a big ugly `switch` statement is faster than
|
276
|
+
// a regular expression, and on Chrome the two are about on par.
|
277
|
+
// This function uses `eval` (non-lexical) to produce such a
|
278
|
+
// predicate from a space-separated string of words.
|
279
|
+
//
|
280
|
+
// It starts by sorting the words by length.
|
281
|
+
|
282
|
+
function makePredicate(words) {
|
283
|
+
words = words.split(" ");
|
284
|
+
var f = "", cats = [];
|
285
|
+
out: for (var i = 0; i < words.length; ++i) {
|
286
|
+
for (var j = 0; j < cats.length; ++j)
|
287
|
+
if (cats[j][0].length == words[i].length) {
|
288
|
+
cats[j].push(words[i]);
|
289
|
+
continue out;
|
290
|
+
}
|
291
|
+
cats.push([words[i]]);
|
292
|
+
}
|
293
|
+
function compareTo(arr) {
|
294
|
+
if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
|
295
|
+
f += "switch(str){";
|
296
|
+
for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
|
297
|
+
f += "return true}return false;";
|
298
|
+
}
|
299
|
+
|
300
|
+
// When there are more than three length categories, an outer
|
301
|
+
// switch first dispatches on the lengths, to save on comparisons.
|
302
|
+
|
303
|
+
if (cats.length > 3) {
|
304
|
+
cats.sort(function(a, b) {return b.length - a.length;});
|
305
|
+
f += "switch(str.length){";
|
306
|
+
for (var i = 0; i < cats.length; ++i) {
|
307
|
+
var cat = cats[i];
|
308
|
+
f += "case " + cat[0].length + ":";
|
309
|
+
compareTo(cat);
|
310
|
+
}
|
311
|
+
f += "}";
|
312
|
+
|
313
|
+
// Otherwise, simply generate a flat `switch` statement.
|
314
|
+
|
315
|
+
} else {
|
316
|
+
compareTo(words);
|
317
|
+
}
|
318
|
+
return new Function("str", f);
|
319
|
+
}
|
320
|
+
|
321
|
+
// The ECMAScript 3 reserved word list.
|
322
|
+
|
323
|
+
var isReservedWord3 = makePredicate("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile");
|
324
|
+
|
325
|
+
// ECMAScript 5 reserved words.
|
326
|
+
|
327
|
+
var isReservedWord5 = makePredicate("class enum extends super const export import");
|
328
|
+
|
329
|
+
// The additional reserved words in strict mode.
|
330
|
+
|
331
|
+
var isStrictReservedWord = makePredicate("implements interface let package private protected public static yield");
|
332
|
+
|
333
|
+
// The forbidden variable names in strict mode.
|
334
|
+
|
335
|
+
var isStrictBadIdWord = makePredicate("eval arguments");
|
336
|
+
|
337
|
+
// And the keywords.
|
338
|
+
|
339
|
+
var isKeyword = makePredicate("break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this");
|
340
|
+
|
341
|
+
// ## Character categories
|
342
|
+
|
343
|
+
// Big ugly regular expressions that match characters in the
|
344
|
+
// whitespace, identifier, and identifier-start categories. These
|
345
|
+
// are only applied when a character is found to actually have a
|
346
|
+
// code point above 128.
|
347
|
+
|
348
|
+
var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/;
|
349
|
+
var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\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\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\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\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-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\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-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\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\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\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\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\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";
|
350
|
+
var nonASCIIidentifierChars = "\u0371-\u0374\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u0620-\u0649\u0672-\u06d3\u06e7-\u06e8\u06fb-\u06fc\u0730-\u074a\u0800-\u0814\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0840-\u0857\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962-\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09d7\u09df-\u09e0\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\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5f-\u0b60\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2-\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d46-\u0d48\u0d57\u0d62-\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e34-\u0e3a\u0e40-\u0e45\u0e50-\u0e59\u0eb4-\u0eb9\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f41-\u0f47\u0f71-\u0f84\u0f86-\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1029\u1040-\u1049\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u170e-\u1710\u1720-\u1730\u1740-\u1750\u1772\u1773\u1780-\u17b2\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1920-\u192b\u1930-\u193b\u1951-\u196d\u19b0-\u19c0\u19c8-\u19c9\u19d0-\u19d9\u1a00-\u1a15\u1a20-\u1a53\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b46-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1bb0-\u1bb9\u1be6-\u1bf3\u1c00-\u1c22\u1c40-\u1c49\u1c5b-\u1c7d\u1cd0-\u1cd2\u1d00-\u1dbe\u1e01-\u1f15\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2d81-\u2d96\u2de0-\u2dff\u3021-\u3028\u3099\u309a\ua640-\ua66d\ua674-\ua67d\ua69f\ua6f0-\ua6f1\ua7f8-\ua800\ua806\ua80b\ua823-\ua827\ua880-\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8f3-\ua8f7\ua900-\ua909\ua926-\ua92d\ua930-\ua945\ua980-\ua983\ua9b3-\ua9c0\uaa00-\uaa27\uaa40-\uaa41\uaa4c-\uaa4d\uaa50-\uaa59\uaa7b\uaae0-\uaae9\uaaf2-\uaaf3\uabc0-\uabe1\uabec\uabed\uabf0-\uabf9\ufb20-\ufb28\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
|
351
|
+
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
|
352
|
+
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
|
353
|
+
|
354
|
+
// Whether a single character denotes a newline.
|
355
|
+
|
356
|
+
var newline = /[\n\r\u2028\u2029]/;
|
357
|
+
|
358
|
+
// Matches a whole line break (where CRLF is considered a single
|
359
|
+
// line break). Used to count lines.
|
360
|
+
|
361
|
+
var lineBreak = /\r\n|[\n\r\u2028\u2029]/g;
|
362
|
+
|
363
|
+
// Test whether a given character code starts an identifier.
|
364
|
+
|
365
|
+
function isIdentifierStart(code) {
|
366
|
+
if (code < 65) return code === 36;
|
367
|
+
if (code < 91) return true;
|
368
|
+
if (code < 97) return code === 95;
|
369
|
+
if (code < 123)return true;
|
370
|
+
return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code));
|
371
|
+
}
|
372
|
+
|
373
|
+
// Test whether a given character is part of an identifier.
|
374
|
+
|
375
|
+
function isIdentifierChar(code) {
|
376
|
+
if (code < 48) return code === 36;
|
377
|
+
if (code < 58) return true;
|
378
|
+
if (code < 65) return false;
|
379
|
+
if (code < 91) return true;
|
380
|
+
if (code < 97) return code === 95;
|
381
|
+
if (code < 123)return true;
|
382
|
+
return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code));
|
383
|
+
}
|
384
|
+
|
385
|
+
// ## Tokenizer
|
386
|
+
|
387
|
+
// These are used when `options.locations` is on, in order to track
|
388
|
+
// the current line number and start of line offset, in order to set
|
389
|
+
// `tokStartLoc` and `tokEndLoc`.
|
390
|
+
|
391
|
+
function nextLineStart() {
|
392
|
+
lineBreak.lastIndex = tokLineStart;
|
393
|
+
var match = lineBreak.exec(input);
|
394
|
+
return match ? match.index + match[0].length : input.length + 1;
|
395
|
+
}
|
396
|
+
|
397
|
+
function curLineLoc() {
|
398
|
+
while (tokLineStartNext <= tokPos) {
|
399
|
+
++tokCurLine;
|
400
|
+
tokLineStart = tokLineStartNext;
|
401
|
+
tokLineStartNext = nextLineStart();
|
402
|
+
}
|
403
|
+
return {line: tokCurLine, column: tokPos - tokLineStart};
|
404
|
+
}
|
405
|
+
|
406
|
+
// Reset the token state. Used at the start of a parse.
|
407
|
+
|
408
|
+
function initTokenState() {
|
409
|
+
tokCurLine = 1;
|
410
|
+
tokPos = tokLineStart = 0;
|
411
|
+
tokLineStartNext = nextLineStart();
|
412
|
+
tokRegexpAllowed = true;
|
413
|
+
tokComments = null;
|
414
|
+
skipSpace();
|
415
|
+
}
|
416
|
+
|
417
|
+
// Called at the end of every token. Sets `tokEnd`, `tokVal`,
|
418
|
+
// `tokCommentsAfter`, and `tokRegexpAllowed`, and skips the space
|
419
|
+
// after the token, so that the next one's `tokStart` will point at
|
420
|
+
// the right position.
|
421
|
+
|
422
|
+
function finishToken(type, val) {
|
423
|
+
tokEnd = tokPos;
|
424
|
+
if (options.locations) tokEndLoc = curLineLoc();
|
425
|
+
tokType = type;
|
426
|
+
skipSpace();
|
427
|
+
tokVal = val;
|
428
|
+
tokCommentsAfter = tokComments;
|
429
|
+
tokRegexpAllowed = type.beforeExpr;
|
430
|
+
}
|
431
|
+
|
432
|
+
function skipBlockComment() {
|
433
|
+
var end = input.indexOf("*/", tokPos += 2);
|
434
|
+
if (end === -1) raise(tokPos - 2, "Unterminated comment");
|
435
|
+
if (options.trackComments)
|
436
|
+
(tokComments || (tokComments = [])).push(input.slice(tokPos, end));
|
437
|
+
tokPos = end + 2;
|
438
|
+
}
|
439
|
+
|
440
|
+
function skipLineComment() {
|
441
|
+
var start = tokPos;
|
442
|
+
var ch = input.charCodeAt(tokPos+=2);
|
443
|
+
while (tokPos < inputLen && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8329) {
|
444
|
+
++tokPos;
|
445
|
+
ch = input.charCodeAt(tokPos);
|
446
|
+
}
|
447
|
+
(tokComments || (tokComments = [])).push(input.slice(start, tokPos));
|
448
|
+
}
|
449
|
+
|
450
|
+
// Called at the start of the parse and after every token. Skips
|
451
|
+
// whitespace and comments, and, if `options.trackComments` is on,
|
452
|
+
// will store all skipped comments in `tokComments`.
|
453
|
+
|
454
|
+
function skipSpace() {
|
455
|
+
tokComments = null;
|
456
|
+
while (tokPos < inputLen) {
|
457
|
+
var ch = input.charCodeAt(tokPos);
|
458
|
+
if (ch === 47) { // '/'
|
459
|
+
var next = input.charCodeAt(tokPos+1);
|
460
|
+
if (next === 42) { // '*'
|
461
|
+
skipBlockComment();
|
462
|
+
} else if (next === 47) { // '/'
|
463
|
+
skipLineComment();
|
464
|
+
} else break;
|
465
|
+
} else if (ch < 14 && ch > 8) {
|
466
|
+
++tokPos;
|
467
|
+
} else if (ch === 32 || ch === 160) { // ' ', '\xa0'
|
468
|
+
++tokPos;
|
469
|
+
} else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
|
470
|
+
++tokPos;
|
471
|
+
} else {
|
472
|
+
break;
|
473
|
+
}
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
// ### Token reading
|
478
|
+
|
479
|
+
// This is the function that is called to fetch the next token. It
|
480
|
+
// is somewhat obscure, because it works in character codes rather
|
481
|
+
// than characters, and because operator parsing has been inlined
|
482
|
+
// into it.
|
483
|
+
//
|
484
|
+
// All in the name of speed.
|
485
|
+
//
|
486
|
+
// The `forceRegexp` parameter is used in the one case where the
|
487
|
+
// `tokRegexpAllowed` trick does not work. See `parseStatement`.
|
488
|
+
|
489
|
+
function readToken(forceRegexp) {
|
490
|
+
tokStart = tokPos;
|
491
|
+
if (options.locations) tokStartLoc = curLineLoc();
|
492
|
+
tokCommentsBefore = tokComments;
|
493
|
+
if (forceRegexp) return readRegexp();
|
494
|
+
if (tokPos >= inputLen) return finishToken(_eof);
|
495
|
+
|
496
|
+
var code = input.charCodeAt(tokPos);
|
497
|
+
// Identifier or keyword. '\uXXXX' sequences are allowed in
|
498
|
+
// identifiers, so '\' also dispatches to that.
|
499
|
+
if (isIdentifierStart(code) || code === 92 /* '\' */) return readWord();
|
500
|
+
var next = input.charCodeAt(tokPos+1);
|
501
|
+
|
502
|
+
switch(code) {
|
503
|
+
// The interpretation of a dot depends on whether it is followed
|
504
|
+
// by a digit.
|
505
|
+
case 46: // '.'
|
506
|
+
if (next >= 48 && next <= 57) return readNumber(String.fromCharCode(code));
|
507
|
+
++tokPos;
|
508
|
+
return finishToken(_dot);
|
509
|
+
|
510
|
+
// Punctuation tokens.
|
511
|
+
case 40: ++tokPos; return finishToken(_parenL);
|
512
|
+
case 41: ++tokPos; return finishToken(_parenR);
|
513
|
+
case 59: ++tokPos; return finishToken(_semi);
|
514
|
+
case 44: ++tokPos; return finishToken(_comma);
|
515
|
+
case 91: ++tokPos; return finishToken(_bracketL);
|
516
|
+
case 93: ++tokPos; return finishToken(_bracketR);
|
517
|
+
case 123: ++tokPos; return finishToken(_braceL);
|
518
|
+
case 125: ++tokPos; return finishToken(_braceR);
|
519
|
+
case 58: ++tokPos; return finishToken(_colon);
|
520
|
+
case 63: ++tokPos; return finishToken(_question);
|
521
|
+
|
522
|
+
// '0x' is a hexadecimal number.
|
523
|
+
case 48: // '0'
|
524
|
+
if (next === 120 || next === 88) return readHexNumber();
|
525
|
+
// Anything else beginning with a digit is an integer, octal
|
526
|
+
// number, or float.
|
527
|
+
case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
|
528
|
+
return readNumber(String.fromCharCode(code));
|
529
|
+
|
530
|
+
// Quotes produce strings.
|
531
|
+
case 34: case 39: // '"', "'"
|
532
|
+
return readString(code);
|
533
|
+
|
534
|
+
// Operators are parsed inline in tiny state machines. '=' (61) is
|
535
|
+
// often referred to. `finishOp` simply skips the amount of
|
536
|
+
// characters it is given as second argument, and returns a token
|
537
|
+
// of the type given by its first argument.
|
538
|
+
|
539
|
+
case 47: // '/'
|
540
|
+
if (tokRegexpAllowed) {++tokPos; return readRegexp();}
|
541
|
+
if (next === 61) return finishOp(_assign, 2);
|
542
|
+
return finishOp(_slash, 1);
|
543
|
+
|
544
|
+
case 37: case 42: // '%*'
|
545
|
+
if (next === 61) return finishOp(_assign, 2);
|
546
|
+
return finishOp(_bin10, 1);
|
547
|
+
|
548
|
+
case 124: case 38: // '|&'
|
549
|
+
if (next === code) return finishOp(code === 124 ? _bin1 : _bin2, 2);
|
550
|
+
if (next === 61) return finishOp(_assign, 2);
|
551
|
+
return finishOp(code === 124 ? _bin3 : _bin5, 1);
|
552
|
+
|
553
|
+
case 94: // '^'
|
554
|
+
if (next === 61) return finishOp(_assign, 2);
|
555
|
+
return finishOp(_bin4, 1);
|
556
|
+
|
557
|
+
case 43: case 45: // '+-'
|
558
|
+
if (next === code) return finishOp(_incdec, 2);
|
559
|
+
if (next === 61) return finishOp(_assign, 2);
|
560
|
+
return finishOp(_plusmin, 1);
|
561
|
+
|
562
|
+
case 60: case 62: // '<>'
|
563
|
+
var size = 1;
|
564
|
+
if (next === code) {
|
565
|
+
size = code === 62 && input.charCodeAt(tokPos+2) === 62 ? 3 : 2;
|
566
|
+
if (input.charCodeAt(tokPos + size) === 61) return finishOp(_assign, size + 1);
|
567
|
+
return finishOp(_bin8, size);
|
568
|
+
}
|
569
|
+
if (next === 61)
|
570
|
+
size = input.charCodeAt(tokPos+2) === 61 ? 3 : 2;
|
571
|
+
return finishOp(_bin7, size);
|
572
|
+
|
573
|
+
case 61: case 33: // '=!'
|
574
|
+
if (next === 61) return finishOp(_bin6, input.charCodeAt(tokPos+2) === 61 ? 3 : 2);
|
575
|
+
return finishOp(code === 61 ? _eq : _prefix, 1);
|
576
|
+
|
577
|
+
case 126: // '~'
|
578
|
+
return finishOp(_prefix, 1);
|
579
|
+
}
|
580
|
+
|
581
|
+
// If we are here, we either found a non-ASCII identifier
|
582
|
+
// character, or something that's entirely disallowed.
|
583
|
+
var ch = String.fromCharCode(code);
|
584
|
+
if (ch === "\\" || nonASCIIidentifierStart.test(ch)) return readWord();
|
585
|
+
raise(tokPos, "Unexpected character '" + ch + "'");
|
586
|
+
}
|
587
|
+
|
588
|
+
function finishOp(type, size) {
|
589
|
+
var str = input.slice(tokPos, tokPos + size);
|
590
|
+
tokPos += size;
|
591
|
+
finishToken(type, str);
|
592
|
+
}
|
593
|
+
|
594
|
+
// Parse a regular expression. Some context-awareness is necessary,
|
595
|
+
// since a '/' inside a '[]' set does not end the expression.
|
596
|
+
|
597
|
+
function readRegexp() {
|
598
|
+
var content = "", escaped, inClass, start = tokPos;
|
599
|
+
for (;;) {
|
600
|
+
if (tokPos >= inputLen) raise(start, "Unterminated regular expression");
|
601
|
+
var ch = input.charAt(tokPos);
|
602
|
+
if (newline.test(ch)) raise(start, "Unterminated regular expression");
|
603
|
+
if (!escaped) {
|
604
|
+
if (ch === "[") inClass = true;
|
605
|
+
else if (ch === "]" && inClass) inClass = false;
|
606
|
+
else if (ch === "/" && !inClass) break;
|
607
|
+
escaped = ch === "\\";
|
608
|
+
} else escaped = false;
|
609
|
+
++tokPos;
|
610
|
+
}
|
611
|
+
var content = input.slice(start, tokPos);
|
612
|
+
++tokPos;
|
613
|
+
// Need to use `readWord1` because '\uXXXX' sequences are allowed
|
614
|
+
// here (don't ask).
|
615
|
+
var mods = readWord1();
|
616
|
+
if (mods && !/^[gmsiy]*$/.test(mods)) raise(start, "Invalid regexp flag");
|
617
|
+
return finishToken(_regexp, new RegExp(content, mods));
|
618
|
+
}
|
619
|
+
|
620
|
+
// Read an integer in the given radix. Return null if zero digits
|
621
|
+
// were read, the integer value otherwise. When `len` is given, this
|
622
|
+
// will return `null` unless the integer has exactly `len` digits.
|
623
|
+
|
624
|
+
function readInt(radix, len) {
|
625
|
+
var start = tokPos, total = 0;
|
626
|
+
for (;;) {
|
627
|
+
var code = input.charCodeAt(tokPos), val;
|
628
|
+
if (code >= 97) val = code - 97 + 10; // a
|
629
|
+
else if (code >= 65) val = code - 65 + 10; // A
|
630
|
+
else if (code >= 48 && code <= 57) val = code - 48; // 0-9
|
631
|
+
else val = Infinity;
|
632
|
+
if (val >= radix) break;
|
633
|
+
++tokPos;
|
634
|
+
total = total * radix + val;
|
635
|
+
}
|
636
|
+
if (tokPos === start || len != null && tokPos - start !== len) return null;
|
637
|
+
|
638
|
+
return total;
|
639
|
+
}
|
640
|
+
|
641
|
+
function readHexNumber() {
|
642
|
+
tokPos += 2; // 0x
|
643
|
+
var val = readInt(16);
|
644
|
+
if (val == null) raise(tokStart + 2, "Expected hexadecimal number");
|
645
|
+
if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
|
646
|
+
return finishToken(_num, val);
|
647
|
+
}
|
648
|
+
|
649
|
+
// Read an integer, octal integer, or floating-point number.
|
650
|
+
|
651
|
+
function readNumber(ch) {
|
652
|
+
var start = tokPos, isFloat = ch === ".";
|
653
|
+
if (!isFloat && readInt(10) == null) raise(start, "Invalid number");
|
654
|
+
if (isFloat || input.charAt(tokPos) === ".") {
|
655
|
+
var next = input.charAt(++tokPos);
|
656
|
+
if (next === "-" || next === "+") ++tokPos;
|
657
|
+
if (readInt(10) === null && ch === ".") raise(start, "Invalid number");
|
658
|
+
isFloat = true;
|
659
|
+
}
|
660
|
+
if (/e/i.test(input.charAt(tokPos))) {
|
661
|
+
var next = input.charAt(++tokPos);
|
662
|
+
if (next === "-" || next === "+") ++tokPos;
|
663
|
+
if (readInt(10) === null) raise(start, "Invalid number")
|
664
|
+
isFloat = true;
|
665
|
+
}
|
666
|
+
if (isIdentifierStart(input.charCodeAt(tokPos))) raise(tokPos, "Identifier directly after number");
|
667
|
+
|
668
|
+
var str = input.slice(start, tokPos), val;
|
669
|
+
if (isFloat) val = parseFloat(str);
|
670
|
+
else if (ch !== "0" || str.length === 1) val = parseInt(str, 10);
|
671
|
+
else if (/[89]/.test(str) || strict) raise(start, "Invalid number");
|
672
|
+
else val = parseInt(str, 8);
|
673
|
+
return finishToken(_num, val);
|
674
|
+
}
|
675
|
+
|
676
|
+
// Read a string value, interpreting backslash-escapes.
|
677
|
+
|
678
|
+
function readString(quote) {
|
679
|
+
tokPos++;
|
680
|
+
var str = [];
|
681
|
+
for (;;) {
|
682
|
+
if (tokPos >= inputLen) raise(tokStart, "Unterminated string constant");
|
683
|
+
var ch = input.charCodeAt(tokPos);
|
684
|
+
if (ch === quote) {
|
685
|
+
++tokPos;
|
686
|
+
return finishToken(_string, String.fromCharCode.apply(null, str));
|
687
|
+
}
|
688
|
+
if (ch === 92) { // '\'
|
689
|
+
ch = input.charCodeAt(++tokPos);
|
690
|
+
var octal = /^[0-7]+/.exec(input.slice(tokPos, tokPos + 3));
|
691
|
+
if (octal) octal = octal[0];
|
692
|
+
while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, octal.length - 1);
|
693
|
+
if (octal === "0") octal = null;
|
694
|
+
++tokPos;
|
695
|
+
if (octal) {
|
696
|
+
if (strict) raise(tokPos - 2, "Octal literal in strict mode");
|
697
|
+
str.push(parseInt(octal, 8));
|
698
|
+
tokPos += octal.length - 1;
|
699
|
+
} else {
|
700
|
+
switch (ch) {
|
701
|
+
case 110: str.push(10); break; // 'n' -> '\n'
|
702
|
+
case 114: str.push(13); break; // 'r' -> '\r'
|
703
|
+
case 120: str.push(readHexChar(2)); break; // 'x'
|
704
|
+
case 117: str.push(readHexChar(4)); break; // 'u'
|
705
|
+
case 85: str.push(readHexChar(8)); break; // 'U'
|
706
|
+
case 116: str.push(9); break; // 't' -> '\t'
|
707
|
+
case 98: str.push(8); break; // 'b' -> '\b'
|
708
|
+
case 118: str.push(11); break; // 'v' -> '\u000b'
|
709
|
+
case 102: str.push(12); break; // 'f' -> '\f'
|
710
|
+
case 48: str.push(0); break; // 0 -> '\0'
|
711
|
+
case 13: if (input.charCodeAt(tokPos) === 10) ++tokPos; // '\r\n'
|
712
|
+
case 10: break; // ' \n'
|
713
|
+
default: str.push(ch); break;
|
714
|
+
}
|
715
|
+
}
|
716
|
+
} else {
|
717
|
+
if (ch === 13 || ch === 10 || ch === 8232 || ch === 8329) raise(tokStart, "Unterminated string constant");
|
718
|
+
if (ch !== 92) str.push(ch); // '\'
|
719
|
+
++tokPos;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
}
|
723
|
+
|
724
|
+
// Used to read character escape sequences ('\x', '\u', '\U').
|
725
|
+
|
726
|
+
function readHexChar(len) {
|
727
|
+
var n = readInt(16, len);
|
728
|
+
if (n === null) raise(tokStart, "Bad character escape sequence");
|
729
|
+
return n;
|
730
|
+
}
|
731
|
+
|
732
|
+
// Used to signal to callers of `readWord1` whether the word
|
733
|
+
// contained any escape sequences. This is needed because words with
|
734
|
+
// escape sequences must not be interpreted as keywords.
|
735
|
+
|
736
|
+
var containsEsc;
|
737
|
+
|
738
|
+
// Read an identifier, and return it as a string. Sets `containsEsc`
|
739
|
+
// to whether the word contained a '\u' escape.
|
740
|
+
//
|
741
|
+
// Only builds up the word character-by-character when it actually
|
742
|
+
// containeds an escape, as a micro-optimization.
|
743
|
+
|
744
|
+
function readWord1() {
|
745
|
+
containsEsc = false;
|
746
|
+
var word, first = true, start = tokPos;
|
747
|
+
for (;;) {
|
748
|
+
var ch = input.charCodeAt(tokPos);
|
749
|
+
if (isIdentifierChar(ch)) {
|
750
|
+
if (containsEsc) word += input.charAt(tokPos);
|
751
|
+
++tokPos;
|
752
|
+
} else if (ch === 92) { // "\"
|
753
|
+
if (!containsEsc) word = input.slice(start, tokPos);
|
754
|
+
containsEsc = true;
|
755
|
+
if (input.charCodeAt(++tokPos) != 117) // "u"
|
756
|
+
raise(tokPos, "Expecting Unicode escape sequence \\uXXXX");
|
757
|
+
++tokPos;
|
758
|
+
var esc = readHexChar(4);
|
759
|
+
var escStr = String.fromCharCode(esc);
|
760
|
+
if (!escStr) raise(tokPos - 1, "Invalid Unicode escape");
|
761
|
+
if (!(first ? isIdentifierStart(esc) : isIdentifierChar(esc)))
|
762
|
+
raise(tokPos - 4, "Invalid Unicode escape");
|
763
|
+
word += escStr;
|
764
|
+
} else {
|
765
|
+
break;
|
766
|
+
}
|
767
|
+
first = false;
|
768
|
+
}
|
769
|
+
return containsEsc ? word : input.slice(start, tokPos);
|
770
|
+
}
|
771
|
+
|
772
|
+
// Read an identifier or keyword token. Will check for reserved
|
773
|
+
// words when necessary.
|
774
|
+
|
775
|
+
function readWord() {
|
776
|
+
var word = readWord1();
|
777
|
+
var type = _name;
|
778
|
+
if (!containsEsc) {
|
779
|
+
if (isKeyword(word)) type = keywordTypes[word];
|
780
|
+
else if (options.forbidReserved &&
|
781
|
+
(options.ecmaVersion === 3 ? isReservedWord3 : isReservedWord5)(word) ||
|
782
|
+
strict && isStrictReservedWord(word))
|
783
|
+
raise(tokStart, "The keyword '" + word + "' is reserved");
|
784
|
+
}
|
785
|
+
return finishToken(type, word);
|
786
|
+
}
|
787
|
+
|
788
|
+
// ## Parser
|
789
|
+
|
790
|
+
// A recursive descent parser operates by defining functions for all
|
791
|
+
// syntactic elements, and recursively calling those, each function
|
792
|
+
// advancing the input stream and returning an AST node. Precedence
|
793
|
+
// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
|
794
|
+
// instead of `(!x)[1]` is handled by the fact that the parser
|
795
|
+
// function that parses unary prefix operators is called first, and
|
796
|
+
// in turn calls the function that parses `[]` subscripts — that
|
797
|
+
// way, it'll receive the node for `x[1]` already parsed, and wraps
|
798
|
+
// *that* in the unary operator node.
|
799
|
+
//
|
800
|
+
// Acorn uses an [operator precedence parser][opp] to handle binary
|
801
|
+
// operator precedence, because it is much more compact than using
|
802
|
+
// the technique outlined above, which uses different, nesting
|
803
|
+
// functions to specify precedence, for all of the ten binary
|
804
|
+
// precedence levels that JavaScript defines.
|
805
|
+
//
|
806
|
+
// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
|
807
|
+
|
808
|
+
// ### Parser utilities
|
809
|
+
|
810
|
+
// Continue to the next token.
|
811
|
+
|
812
|
+
function next() {
|
813
|
+
lastStart = tokStart;
|
814
|
+
lastEnd = tokEnd;
|
815
|
+
lastEndLoc = tokEndLoc;
|
816
|
+
readToken();
|
817
|
+
}
|
818
|
+
|
819
|
+
// Enter strict mode. Re-reads the next token to please pedantic
|
820
|
+
// tests ("use strict"; 010; -- should fail).
|
821
|
+
|
822
|
+
function setStrict(strct) {
|
823
|
+
strict = strct;
|
824
|
+
tokPos = lastEnd;
|
825
|
+
skipSpace();
|
826
|
+
readToken();
|
827
|
+
}
|
828
|
+
|
829
|
+
// Start an AST node, attaching a start offset and optionally a
|
830
|
+
// `commentsBefore` property to it.
|
831
|
+
|
832
|
+
function startNode() {
|
833
|
+
var node = {type: null, start: tokStart, end: null};
|
834
|
+
if (options.trackComments && tokCommentsBefore) {
|
835
|
+
node.commentsBefore = tokCommentsBefore;
|
836
|
+
tokCommentsBefore = null;
|
837
|
+
}
|
838
|
+
if (options.locations)
|
839
|
+
node.loc = {start: tokStartLoc, end: null, source: sourceFile};
|
840
|
+
if (options.ranges)
|
841
|
+
node.range = [tokStart, 0];
|
842
|
+
return node;
|
843
|
+
}
|
844
|
+
|
845
|
+
// Start a node whose start offset/comments information should be
|
846
|
+
// based on the start of another node. For example, a binary
|
847
|
+
// operator node is only started after its left-hand side has
|
848
|
+
// already been parsed.
|
849
|
+
|
850
|
+
function startNodeFrom(other) {
|
851
|
+
var node = {type: null, start: other.start};
|
852
|
+
if (other.commentsBefore) {
|
853
|
+
node.commentsBefore = other.commentsBefore;
|
854
|
+
other.commentsBefore = null;
|
855
|
+
}
|
856
|
+
if (options.locations)
|
857
|
+
node.loc = {start: other.loc.start, end: null, source: other.loc.source};
|
858
|
+
if (options.ranges)
|
859
|
+
node.range = [other.range[0], 0];
|
860
|
+
|
861
|
+
return node;
|
862
|
+
}
|
863
|
+
|
864
|
+
// Finish an AST node, adding `type`, `end`, and `commentsAfter`
|
865
|
+
// properties.
|
866
|
+
//
|
867
|
+
// We keep track of the last node that we finished, in order
|
868
|
+
// 'bubble' `commentsAfter` properties up to the biggest node. I.e.
|
869
|
+
// in '`1 + 1 // foo', the comment should be attached to the binary
|
870
|
+
// operator node, not the second literal node.
|
871
|
+
|
872
|
+
var lastFinishedNode;
|
873
|
+
|
874
|
+
function finishNode(node, type) {
|
875
|
+
node.type = type;
|
876
|
+
node.end = lastEnd;
|
877
|
+
if (options.trackComments) {
|
878
|
+
if (tokCommentsAfter) {
|
879
|
+
node.commentsAfter = tokCommentsAfter;
|
880
|
+
tokCommentsAfter = null;
|
881
|
+
} else if (lastFinishedNode && lastFinishedNode.end === lastEnd) {
|
882
|
+
node.commentsAfter = lastFinishedNode.commentsAfter;
|
883
|
+
lastFinishedNode.commentsAfter = null;
|
884
|
+
}
|
885
|
+
lastFinishedNode = node;
|
886
|
+
}
|
887
|
+
if (options.locations)
|
888
|
+
node.loc.end = lastEndLoc;
|
889
|
+
if (options.ranges)
|
890
|
+
node.range[1] = lastEnd;
|
891
|
+
return node;
|
892
|
+
}
|
893
|
+
|
894
|
+
// Test whether a statement node is the string literal `"use strict"`.
|
895
|
+
|
896
|
+
function isUseStrict(stmt) {
|
897
|
+
return options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" &&
|
898
|
+
stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
|
899
|
+
}
|
900
|
+
|
901
|
+
// Predicate that tests whether the next token is of the given
|
902
|
+
// type, and if yes, consumes it as a side effect.
|
903
|
+
|
904
|
+
function eat(type) {
|
905
|
+
if (tokType === type) {
|
906
|
+
next();
|
907
|
+
return true;
|
908
|
+
}
|
909
|
+
}
|
910
|
+
|
911
|
+
// Test whether a semicolon can be inserted at the current position.
|
912
|
+
|
913
|
+
function canInsertSemicolon() {
|
914
|
+
return !options.strictSemicolons &&
|
915
|
+
(tokType === _eof || tokType === _braceR || newline.test(input.slice(lastEnd, tokStart)));
|
916
|
+
}
|
917
|
+
|
918
|
+
// Consume a semicolon, or, failing that, see if we are allowed to
|
919
|
+
// pretend that there is a semicolon at this position.
|
920
|
+
|
921
|
+
function semicolon() {
|
922
|
+
if (!eat(_semi) && !canInsertSemicolon()) unexpected();
|
923
|
+
}
|
924
|
+
|
925
|
+
// Expect a token of a given type. If found, consume it, otherwise,
|
926
|
+
// raise an unexpected token error.
|
927
|
+
|
928
|
+
function expect(type) {
|
929
|
+
if (tokType === type) next();
|
930
|
+
else unexpected();
|
931
|
+
}
|
932
|
+
|
933
|
+
// Raise an unexpected token error.
|
934
|
+
|
935
|
+
function unexpected() {
|
936
|
+
raise(tokStart, "Unexpected token");
|
937
|
+
}
|
938
|
+
|
939
|
+
// Verify that a node is an lval — something that can be assigned
|
940
|
+
// to.
|
941
|
+
|
942
|
+
function checkLVal(expr) {
|
943
|
+
if (expr.type !== "Identifier" && expr.type !== "MemberExpression")
|
944
|
+
raise(expr.start, "Assigning to rvalue");
|
945
|
+
if (strict && expr.type === "Identifier" && isStrictBadIdWord(expr.name))
|
946
|
+
raise(expr.start, "Assigning to " + expr.name + " in strict mode");
|
947
|
+
}
|
948
|
+
|
949
|
+
// ### Statement parsing
|
950
|
+
|
951
|
+
// Parse a program. Initializes the parser, reads any number of
|
952
|
+
// statements, and wraps them in a Program node. Optionally takes a
|
953
|
+
// `program` argument. If present, the statements will be appended
|
954
|
+
// to its body instead of creating a new node.
|
955
|
+
|
956
|
+
function parseTopLevel(program) {
|
957
|
+
initTokenState();
|
958
|
+
lastStart = lastEnd = tokPos;
|
959
|
+
if (options.locations) lastEndLoc = curLineLoc();
|
960
|
+
inFunction = strict = null;
|
961
|
+
labels = [];
|
962
|
+
readToken();
|
963
|
+
|
964
|
+
var node = program || startNode(), first = true;
|
965
|
+
if (!program) node.body = [];
|
966
|
+
while (tokType !== _eof) {
|
967
|
+
var stmt = parseStatement();
|
968
|
+
node.body.push(stmt);
|
969
|
+
if (first && isUseStrict(stmt)) setStrict(true);
|
970
|
+
first = false;
|
971
|
+
}
|
972
|
+
return finishNode(node, "Program");
|
973
|
+
};
|
974
|
+
|
975
|
+
var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
|
976
|
+
|
977
|
+
// Parse a single statement.
|
978
|
+
//
|
979
|
+
// If expecting a statement and finding a slash operator, parse a
|
980
|
+
// regular expression literal. This is to handle cases like
|
981
|
+
// `if (foo) /blah/.exec(foo);`, where looking at the previous token
|
982
|
+
// does not help.
|
983
|
+
|
984
|
+
function parseStatement() {
|
985
|
+
if (tokType === _slash)
|
986
|
+
readToken(true);
|
987
|
+
|
988
|
+
var starttype = tokType, node = startNode();
|
989
|
+
|
990
|
+
// Most types of statements are recognized by the keyword they
|
991
|
+
// start with. Many are trivial to parse, some require a bit of
|
992
|
+
// complexity.
|
993
|
+
|
994
|
+
switch (starttype) {
|
995
|
+
case _break: case _continue:
|
996
|
+
next();
|
997
|
+
var isBreak = starttype === _break;
|
998
|
+
if (eat(_semi) || canInsertSemicolon()) node.label = null;
|
999
|
+
else if (tokType !== _name) unexpected();
|
1000
|
+
else {
|
1001
|
+
node.label = parseIdent();
|
1002
|
+
semicolon();
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
// Verify that there is an actual destination to break or
|
1006
|
+
// continue to.
|
1007
|
+
for (var i = 0; i < labels.length; ++i) {
|
1008
|
+
var lab = labels[i];
|
1009
|
+
if (node.label == null || lab.name === node.label.name) {
|
1010
|
+
if (lab.kind != null && (isBreak || lab.kind === "loop")) break;
|
1011
|
+
if (node.label && isBreak) break;
|
1012
|
+
}
|
1013
|
+
}
|
1014
|
+
if (i === labels.length) raise(node.start, "Unsyntactic " + starttype.keyword);
|
1015
|
+
return finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement");
|
1016
|
+
|
1017
|
+
case _debugger:
|
1018
|
+
next();
|
1019
|
+
return finishNode(node, "DebuggerStatement");
|
1020
|
+
|
1021
|
+
case _do:
|
1022
|
+
next();
|
1023
|
+
labels.push(loopLabel);
|
1024
|
+
node.body = parseStatement();
|
1025
|
+
labels.pop();
|
1026
|
+
expect(_while);
|
1027
|
+
node.test = parseParenExpression();
|
1028
|
+
semicolon();
|
1029
|
+
return finishNode(node, "DoWhileStatement");
|
1030
|
+
|
1031
|
+
// Disambiguating between a `for` and a `for`/`in` loop is
|
1032
|
+
// non-trivial. Basically, we have to parse the init `var`
|
1033
|
+
// statement or expression, disallowing the `in` operator (see
|
1034
|
+
// the second parameter to `parseExpression`), and then check
|
1035
|
+
// whether the next token is `in`. When there is no init part
|
1036
|
+
// (semicolon immediately after the opening parenthesis), it is
|
1037
|
+
// a regular `for` loop.
|
1038
|
+
|
1039
|
+
case _for:
|
1040
|
+
next();
|
1041
|
+
labels.push(loopLabel);
|
1042
|
+
expect(_parenL);
|
1043
|
+
if (tokType === _semi) return parseFor(node, null);
|
1044
|
+
if (tokType === _var) {
|
1045
|
+
var init = startNode();
|
1046
|
+
next();
|
1047
|
+
parseVar(init, true);
|
1048
|
+
if (init.declarations.length === 1 && eat(_in))
|
1049
|
+
return parseForIn(node, init);
|
1050
|
+
return parseFor(node, init);
|
1051
|
+
}
|
1052
|
+
var init = parseExpression(false, true);
|
1053
|
+
if (eat(_in)) {checkLVal(init); return parseForIn(node, init);}
|
1054
|
+
return parseFor(node, init);
|
1055
|
+
|
1056
|
+
case _function:
|
1057
|
+
next();
|
1058
|
+
return parseFunction(node, true);
|
1059
|
+
|
1060
|
+
case _if:
|
1061
|
+
next();
|
1062
|
+
node.test = parseParenExpression();
|
1063
|
+
node.consequent = parseStatement();
|
1064
|
+
node.alternate = eat(_else) ? parseStatement() : null;
|
1065
|
+
return finishNode(node, "IfStatement");
|
1066
|
+
|
1067
|
+
case _return:
|
1068
|
+
if (!inFunction) raise(tokStart, "'return' outside of function");
|
1069
|
+
next();
|
1070
|
+
|
1071
|
+
// In `return` (and `break`/`continue`), the keywords with
|
1072
|
+
// optional arguments, we eagerly look for a semicolon or the
|
1073
|
+
// possibility to insert one.
|
1074
|
+
|
1075
|
+
if (eat(_semi) || canInsertSemicolon()) node.argument = null;
|
1076
|
+
else { node.argument = parseExpression(); semicolon(); }
|
1077
|
+
return finishNode(node, "ReturnStatement");
|
1078
|
+
|
1079
|
+
case _switch:
|
1080
|
+
next();
|
1081
|
+
node.discriminant = parseParenExpression();
|
1082
|
+
node.cases = [];
|
1083
|
+
expect(_braceL);
|
1084
|
+
labels.push(switchLabel);
|
1085
|
+
|
1086
|
+
// Statements under must be grouped (by label) in SwitchCase
|
1087
|
+
// nodes. `cur` is used to keep the node that we are currently
|
1088
|
+
// adding statements to.
|
1089
|
+
|
1090
|
+
for (var cur, sawDefault; tokType != _braceR;) {
|
1091
|
+
if (tokType === _case || tokType === _default) {
|
1092
|
+
var isCase = tokType === _case;
|
1093
|
+
if (cur) finishNode(cur, "SwitchCase");
|
1094
|
+
node.cases.push(cur = startNode());
|
1095
|
+
cur.consequent = [];
|
1096
|
+
next();
|
1097
|
+
if (isCase) cur.test = parseExpression();
|
1098
|
+
else {
|
1099
|
+
if (sawDefault) raise(lastStart, "Multiple default clauses"); sawDefault = true;
|
1100
|
+
cur.test = null;
|
1101
|
+
}
|
1102
|
+
expect(_colon);
|
1103
|
+
} else {
|
1104
|
+
if (!cur) unexpected();
|
1105
|
+
cur.consequent.push(parseStatement());
|
1106
|
+
}
|
1107
|
+
}
|
1108
|
+
if (cur) finishNode(cur, "SwitchCase");
|
1109
|
+
next(); // Closing brace
|
1110
|
+
labels.pop();
|
1111
|
+
return finishNode(node, "SwitchStatement");
|
1112
|
+
|
1113
|
+
case _throw:
|
1114
|
+
next();
|
1115
|
+
if (newline.test(input.slice(lastEnd, tokStart)))
|
1116
|
+
raise(lastEnd, "Illegal newline after throw");
|
1117
|
+
node.argument = parseExpression();
|
1118
|
+
return finishNode(node, "ThrowStatement");
|
1119
|
+
|
1120
|
+
case _try:
|
1121
|
+
next();
|
1122
|
+
node.block = parseBlock();
|
1123
|
+
node.handlers = [];
|
1124
|
+
while (tokType === _catch) {
|
1125
|
+
var clause = startNode();
|
1126
|
+
next();
|
1127
|
+
expect(_parenL);
|
1128
|
+
clause.param = parseIdent();
|
1129
|
+
if (strict && isStrictBadIdWord(clause.param.name))
|
1130
|
+
raise(clause.param.start, "Binding " + clause.param.name + " in strict mode");
|
1131
|
+
expect(_parenR);
|
1132
|
+
clause.guard = null;
|
1133
|
+
clause.body = parseBlock();
|
1134
|
+
node.handlers.push(finishNode(clause, "CatchClause"));
|
1135
|
+
}
|
1136
|
+
node.finalizer = eat(_finally) ? parseBlock() : null;
|
1137
|
+
if (!node.handlers.length && !node.finalizer)
|
1138
|
+
raise(node.start, "Missing catch or finally clause");
|
1139
|
+
return finishNode(node, "TryStatement");
|
1140
|
+
|
1141
|
+
case _var:
|
1142
|
+
next();
|
1143
|
+
node = parseVar(node);
|
1144
|
+
semicolon();
|
1145
|
+
return node;
|
1146
|
+
|
1147
|
+
case _while:
|
1148
|
+
next();
|
1149
|
+
node.test = parseParenExpression();
|
1150
|
+
labels.push(loopLabel);
|
1151
|
+
node.body = parseStatement();
|
1152
|
+
labels.pop();
|
1153
|
+
return finishNode(node, "WhileStatement");
|
1154
|
+
|
1155
|
+
case _with:
|
1156
|
+
if (strict) raise(tokStart, "'with' in strict mode");
|
1157
|
+
next();
|
1158
|
+
node.object = parseParenExpression();
|
1159
|
+
node.body = parseStatement();
|
1160
|
+
return finishNode(node, "WithStatement");
|
1161
|
+
|
1162
|
+
case _braceL:
|
1163
|
+
return parseBlock();
|
1164
|
+
|
1165
|
+
case _semi:
|
1166
|
+
next();
|
1167
|
+
return finishNode(node, "EmptyStatement");
|
1168
|
+
|
1169
|
+
// If the statement does not start with a statement keyword or a
|
1170
|
+
// brace, it's an ExpressionStatement or LabeledStatement. We
|
1171
|
+
// simply start parsing an expression, and afterwards, if the
|
1172
|
+
// next token is a colon and the expression was a simple
|
1173
|
+
// Identifier node, we switch to interpreting it as a label.
|
1174
|
+
|
1175
|
+
default:
|
1176
|
+
var maybeName = tokVal, expr = parseExpression();
|
1177
|
+
if (starttype === _name && expr.type === "Identifier" && eat(_colon)) {
|
1178
|
+
for (var i = 0; i < labels.length; ++i)
|
1179
|
+
if (labels[i].name === maybeName) raise(expr.start, "Label '" + maybeName + "' is already declared");
|
1180
|
+
var kind = tokType.isLoop ? "loop" : tokType === _switch ? "switch" : null;
|
1181
|
+
labels.push({name: maybeName, kind: kind});
|
1182
|
+
node.body = parseStatement();
|
1183
|
+
node.label = expr;
|
1184
|
+
return finishNode(node, "LabeledStatement");
|
1185
|
+
} else {
|
1186
|
+
node.expression = expr;
|
1187
|
+
semicolon();
|
1188
|
+
return finishNode(node, "ExpressionStatement");
|
1189
|
+
}
|
1190
|
+
}
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
// Used for constructs like `switch` and `if` that insist on
|
1194
|
+
// parentheses around their expression.
|
1195
|
+
|
1196
|
+
function parseParenExpression() {
|
1197
|
+
expect(_parenL);
|
1198
|
+
var val = parseExpression();
|
1199
|
+
expect(_parenR);
|
1200
|
+
return val;
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
// Parse a semicolon-enclosed block of statements, handling `"use
|
1204
|
+
// strict"` declarations when `allowStrict` is true (used for
|
1205
|
+
// function bodies).
|
1206
|
+
|
1207
|
+
function parseBlock(allowStrict) {
|
1208
|
+
var node = startNode(), first = true, strict = false, oldStrict;
|
1209
|
+
node.body = [];
|
1210
|
+
expect(_braceL);
|
1211
|
+
while (!eat(_braceR)) {
|
1212
|
+
var stmt = parseStatement();
|
1213
|
+
node.body.push(stmt);
|
1214
|
+
if (first && isUseStrict(stmt)) {
|
1215
|
+
oldStrict = strict;
|
1216
|
+
setStrict(strict = true);
|
1217
|
+
}
|
1218
|
+
first = false
|
1219
|
+
}
|
1220
|
+
if (strict && !oldStrict) setStrict(false);
|
1221
|
+
return finishNode(node, "BlockStatement");
|
1222
|
+
}
|
1223
|
+
|
1224
|
+
// Parse a regular `for` loop. The disambiguation code in
|
1225
|
+
// `parseStatement` will already have parsed the init statement or
|
1226
|
+
// expression.
|
1227
|
+
|
1228
|
+
function parseFor(node, init) {
|
1229
|
+
node.init = init;
|
1230
|
+
expect(_semi);
|
1231
|
+
node.test = tokType === _semi ? null : parseExpression();
|
1232
|
+
expect(_semi);
|
1233
|
+
node.update = tokType === _parenR ? null : parseExpression();
|
1234
|
+
expect(_parenR);
|
1235
|
+
node.body = parseStatement();
|
1236
|
+
labels.pop();
|
1237
|
+
return finishNode(node, "ForStatement");
|
1238
|
+
}
|
1239
|
+
|
1240
|
+
// Parse a `for`/`in` loop.
|
1241
|
+
|
1242
|
+
function parseForIn(node, init) {
|
1243
|
+
node.left = init;
|
1244
|
+
node.right = parseExpression();
|
1245
|
+
expect(_parenR);
|
1246
|
+
node.body = parseStatement();
|
1247
|
+
labels.pop();
|
1248
|
+
return finishNode(node, "ForInStatement");
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
// Parse a list of variable declarations.
|
1252
|
+
|
1253
|
+
function parseVar(node, noIn) {
|
1254
|
+
node.declarations = [];
|
1255
|
+
node.kind = "var";
|
1256
|
+
for (;;) {
|
1257
|
+
var decl = startNode();
|
1258
|
+
decl.id = parseIdent();
|
1259
|
+
if (strict && isStrictBadIdWord(decl.id.name))
|
1260
|
+
raise(decl.id.start, "Binding " + decl.id.name + " in strict mode");
|
1261
|
+
decl.init = eat(_eq) ? parseExpression(true, noIn) : null;
|
1262
|
+
node.declarations.push(finishNode(decl, "VariableDeclarator"));
|
1263
|
+
if (!eat(_comma)) break;
|
1264
|
+
}
|
1265
|
+
return finishNode(node, "VariableDeclaration");
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
// ### Expression parsing
|
1269
|
+
|
1270
|
+
// These nest, from the most general expression type at the top to
|
1271
|
+
// 'atomic', nondivisible expression types at the bottom. Most of
|
1272
|
+
// the functions will simply let the function(s) below them parse,
|
1273
|
+
// and, *if* the syntactic construct they handle is present, wrap
|
1274
|
+
// the AST node that the inner parser gave them in another node.
|
1275
|
+
|
1276
|
+
// Parse a full expression. The arguments are used to forbid comma
|
1277
|
+
// sequences (in argument lists, array literals, or object literals)
|
1278
|
+
// or the `in` operator (in for loops initalization expressions).
|
1279
|
+
|
1280
|
+
function parseExpression(noComma, noIn) {
|
1281
|
+
var expr = parseMaybeAssign(noIn);
|
1282
|
+
if (!noComma && tokType === _comma) {
|
1283
|
+
var node = startNodeFrom(expr);
|
1284
|
+
node.expressions = [expr];
|
1285
|
+
while (eat(_comma)) node.expressions.push(parseMaybeAssign(noIn));
|
1286
|
+
return finishNode(node, "SequenceExpression");
|
1287
|
+
}
|
1288
|
+
return expr;
|
1289
|
+
}
|
1290
|
+
|
1291
|
+
// Parse an assignment expression. This includes applications of
|
1292
|
+
// operators like `+=`.
|
1293
|
+
|
1294
|
+
function parseMaybeAssign(noIn) {
|
1295
|
+
var left = parseMaybeConditional(noIn);
|
1296
|
+
if (tokType.isAssign) {
|
1297
|
+
var node = startNodeFrom(left);
|
1298
|
+
node.operator = tokVal;
|
1299
|
+
node.left = left;
|
1300
|
+
next();
|
1301
|
+
node.right = parseMaybeAssign(noIn);
|
1302
|
+
checkLVal(left);
|
1303
|
+
return finishNode(node, "AssignmentExpression");
|
1304
|
+
}
|
1305
|
+
return left;
|
1306
|
+
}
|
1307
|
+
|
1308
|
+
// Parse a ternary conditional (`?:`) operator.
|
1309
|
+
|
1310
|
+
function parseMaybeConditional(noIn) {
|
1311
|
+
var expr = parseExprOps(noIn);
|
1312
|
+
if (eat(_question)) {
|
1313
|
+
var node = startNodeFrom(expr);
|
1314
|
+
node.test = expr;
|
1315
|
+
node.consequent = parseExpression(true);
|
1316
|
+
expect(_colon);
|
1317
|
+
node.alternate = parseExpression(true, noIn);
|
1318
|
+
return finishNode(node, "ConditionalExpression");
|
1319
|
+
}
|
1320
|
+
return expr;
|
1321
|
+
}
|
1322
|
+
|
1323
|
+
// Start the precedence parser.
|
1324
|
+
|
1325
|
+
function parseExprOps(noIn) {
|
1326
|
+
return parseExprOp(parseMaybeUnary(noIn), -1, noIn);
|
1327
|
+
}
|
1328
|
+
|
1329
|
+
// Parse binary operators with the operator precedence parsing
|
1330
|
+
// algorithm. `left` is the left-hand side of the operator.
|
1331
|
+
// `minPrec` provides context that allows the function to stop and
|
1332
|
+
// defer further parser to one of its callers when it encounters an
|
1333
|
+
// operator that has a lower precedence than the set it is parsing.
|
1334
|
+
|
1335
|
+
function parseExprOp(left, minPrec, noIn) {
|
1336
|
+
var prec = tokType.binop;
|
1337
|
+
if (prec != null && (!noIn || tokType !== _in)) {
|
1338
|
+
if (prec > minPrec) {
|
1339
|
+
var node = startNodeFrom(left);
|
1340
|
+
node.left = left;
|
1341
|
+
node.operator = tokVal;
|
1342
|
+
next();
|
1343
|
+
node.right = parseExprOp(parseMaybeUnary(noIn), prec, noIn);
|
1344
|
+
var node = finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression");
|
1345
|
+
return parseExprOp(node, minPrec, noIn);
|
1346
|
+
}
|
1347
|
+
}
|
1348
|
+
return left;
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
// Parse unary operators, both prefix and postfix.
|
1352
|
+
|
1353
|
+
function parseMaybeUnary(noIn) {
|
1354
|
+
if (tokType.prefix) {
|
1355
|
+
var node = startNode(), update = tokType.isUpdate;
|
1356
|
+
node.operator = tokVal;
|
1357
|
+
node.prefix = true;
|
1358
|
+
next();
|
1359
|
+
node.argument = parseMaybeUnary(noIn);
|
1360
|
+
if (update) checkLVal(node.argument);
|
1361
|
+
else if (strict && node.operator === "delete" &&
|
1362
|
+
node.argument.type === "Identifier")
|
1363
|
+
raise(node.start, "Deleting local variable in strict mode");
|
1364
|
+
return finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
|
1365
|
+
}
|
1366
|
+
var expr = parseExprSubscripts();
|
1367
|
+
while (tokType.postfix && !canInsertSemicolon()) {
|
1368
|
+
var node = startNodeFrom(expr);
|
1369
|
+
node.operator = tokVal;
|
1370
|
+
node.prefix = false;
|
1371
|
+
node.argument = expr;
|
1372
|
+
checkLVal(expr);
|
1373
|
+
next();
|
1374
|
+
expr = finishNode(node, "UpdateExpression");
|
1375
|
+
}
|
1376
|
+
return expr;
|
1377
|
+
}
|
1378
|
+
|
1379
|
+
// Parse call, dot, and `[]`-subscript expressions.
|
1380
|
+
|
1381
|
+
function parseExprSubscripts() {
|
1382
|
+
return parseSubscripts(parseExprAtom());
|
1383
|
+
}
|
1384
|
+
|
1385
|
+
function parseSubscripts(base, noCalls) {
|
1386
|
+
if (eat(_dot)) {
|
1387
|
+
var node = startNodeFrom(base);
|
1388
|
+
node.object = base;
|
1389
|
+
node.property = parseIdent(true);
|
1390
|
+
node.computed = false;
|
1391
|
+
return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
|
1392
|
+
} else if (eat(_bracketL)) {
|
1393
|
+
var node = startNodeFrom(base);
|
1394
|
+
node.object = base;
|
1395
|
+
node.property = parseExpression();
|
1396
|
+
node.computed = true;
|
1397
|
+
expect(_bracketR);
|
1398
|
+
return parseSubscripts(finishNode(node, "MemberExpression"), noCalls);
|
1399
|
+
} else if (!noCalls && eat(_parenL)) {
|
1400
|
+
var node = startNodeFrom(base);
|
1401
|
+
node.callee = base;
|
1402
|
+
node.arguments = parseExprList(_parenR, false);
|
1403
|
+
return parseSubscripts(finishNode(node, "CallExpression"), noCalls);
|
1404
|
+
} else return base;
|
1405
|
+
}
|
1406
|
+
|
1407
|
+
// Parse an atomic expression — either a single token that is an
|
1408
|
+
// expression, an expression started by a keyword like `function` or
|
1409
|
+
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
|
1410
|
+
// or `{}`.
|
1411
|
+
|
1412
|
+
function parseExprAtom() {
|
1413
|
+
switch (tokType) {
|
1414
|
+
case _this:
|
1415
|
+
var node = startNode();
|
1416
|
+
next();
|
1417
|
+
return finishNode(node, "ThisExpression");
|
1418
|
+
case _name:
|
1419
|
+
return parseIdent();
|
1420
|
+
case _num: case _string: case _regexp:
|
1421
|
+
var node = startNode();
|
1422
|
+
node.value = tokVal;
|
1423
|
+
node.raw = input.slice(tokStart, tokEnd);
|
1424
|
+
next();
|
1425
|
+
return finishNode(node, "Literal");
|
1426
|
+
|
1427
|
+
case _null: case _true: case _false:
|
1428
|
+
var node = startNode();
|
1429
|
+
node.value = tokType.atomValue;
|
1430
|
+
next();
|
1431
|
+
return finishNode(node, "Literal");
|
1432
|
+
|
1433
|
+
case _parenL:
|
1434
|
+
next();
|
1435
|
+
var val = parseExpression();
|
1436
|
+
expect(_parenR);
|
1437
|
+
return val;
|
1438
|
+
|
1439
|
+
case _bracketL:
|
1440
|
+
var node = startNode();
|
1441
|
+
next();
|
1442
|
+
node.elements = parseExprList(_bracketR, true, true);
|
1443
|
+
return finishNode(node, "ArrayExpression");
|
1444
|
+
|
1445
|
+
case _braceL:
|
1446
|
+
return parseObj();
|
1447
|
+
|
1448
|
+
case _function:
|
1449
|
+
var node = startNode();
|
1450
|
+
next();
|
1451
|
+
return parseFunction(node, false);
|
1452
|
+
|
1453
|
+
case _new:
|
1454
|
+
return parseNew();
|
1455
|
+
|
1456
|
+
default:
|
1457
|
+
unexpected();
|
1458
|
+
}
|
1459
|
+
}
|
1460
|
+
|
1461
|
+
// New's precedence is slightly tricky. It must allow its argument
|
1462
|
+
// to be a `[]` or dot subscript expression, but not a call — at
|
1463
|
+
// least, not without wrapping it in parentheses. Thus, it uses the
|
1464
|
+
|
1465
|
+
function parseNew() {
|
1466
|
+
var node = startNode();
|
1467
|
+
next();
|
1468
|
+
node.callee = parseSubscripts(parseExprAtom(false), true);
|
1469
|
+
if (eat(_parenL)) node.arguments = parseExprList(_parenR, false);
|
1470
|
+
else node.arguments = [];
|
1471
|
+
return finishNode(node, "NewExpression");
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
// Parse an object literal.
|
1475
|
+
|
1476
|
+
function parseObj() {
|
1477
|
+
var node = startNode(), first = true, sawGetSet = false;
|
1478
|
+
node.properties = [];
|
1479
|
+
next();
|
1480
|
+
while (!eat(_braceR)) {
|
1481
|
+
if (!first) {
|
1482
|
+
expect(_comma);
|
1483
|
+
if (options.allowTrailingCommas && eat(_braceR)) break;
|
1484
|
+
} else first = false;
|
1485
|
+
|
1486
|
+
var prop = {key: parsePropertyName()}, isGetSet = false, kind;
|
1487
|
+
if (eat(_colon)) {
|
1488
|
+
prop.value = parseExpression(true);
|
1489
|
+
kind = prop.kind = "init";
|
1490
|
+
} else if (options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
|
1491
|
+
(prop.key.name === "get" || prop.key.name === "set")) {
|
1492
|
+
isGetSet = sawGetSet = true;
|
1493
|
+
kind = prop.kind = prop.key.name;
|
1494
|
+
prop.key = parsePropertyName();
|
1495
|
+
if (!tokType === _parenL) unexpected();
|
1496
|
+
prop.value = parseFunction(startNode(), false);
|
1497
|
+
} else unexpected();
|
1498
|
+
|
1499
|
+
// getters and setters are not allowed to clash — either with
|
1500
|
+
// each other or with an init property — and in strict mode,
|
1501
|
+
// init properties are also not allowed to be repeated.
|
1502
|
+
|
1503
|
+
if (prop.key.type === "Identifier" && (strict || sawGetSet)) {
|
1504
|
+
for (var i = 0; i < node.properties.length; ++i) {
|
1505
|
+
var other = node.properties[i];
|
1506
|
+
if (other.key.name === prop.key.name) {
|
1507
|
+
var conflict = kind == other.kind || isGetSet && other.kind === "init" ||
|
1508
|
+
kind === "init" && (other.kind === "get" || other.kind === "set");
|
1509
|
+
if (conflict && !strict && kind === "init" && other.kind === "init") conflict = false;
|
1510
|
+
if (conflict) raise(prop.key.start, "Redefinition of property");
|
1511
|
+
}
|
1512
|
+
}
|
1513
|
+
}
|
1514
|
+
node.properties.push(prop);
|
1515
|
+
}
|
1516
|
+
return finishNode(node, "ObjectExpression");
|
1517
|
+
}
|
1518
|
+
|
1519
|
+
function parsePropertyName() {
|
1520
|
+
if (tokType === _num || tokType === _string) return parseExprAtom();
|
1521
|
+
return parseIdent(true);
|
1522
|
+
}
|
1523
|
+
|
1524
|
+
// Parse a function declaration or literal (depending on the
|
1525
|
+
// `isStatement` parameter).
|
1526
|
+
|
1527
|
+
function parseFunction(node, isStatement) {
|
1528
|
+
if (tokType === _name) node.id = parseIdent();
|
1529
|
+
else if (isStatement) unexpected();
|
1530
|
+
else node.id = null;
|
1531
|
+
node.params = [];
|
1532
|
+
var first = true;
|
1533
|
+
expect(_parenL);
|
1534
|
+
while (!eat(_parenR)) {
|
1535
|
+
if (!first) expect(_comma); else first = false;
|
1536
|
+
node.params.push(parseIdent());
|
1537
|
+
}
|
1538
|
+
|
1539
|
+
// Start a new scope with regard to labels and the `inFunction`
|
1540
|
+
// flag (restore them to their old value afterwards).
|
1541
|
+
var oldInFunc = inFunction, oldLabels = labels;
|
1542
|
+
inFunction = true; labels = [];
|
1543
|
+
node.body = parseBlock(true);
|
1544
|
+
inFunction = oldInFunc; labels = oldLabels;
|
1545
|
+
|
1546
|
+
// If this is a strict mode function, verify that argument names
|
1547
|
+
// are not repeated, and it does not try to bind the words `eval`
|
1548
|
+
// or `arguments`.
|
1549
|
+
if (strict || node.body.body.length && isUseStrict(node.body.body[0])) {
|
1550
|
+
for (var i = node.id ? -1 : 0; i < node.params.length; ++i) {
|
1551
|
+
var id = i < 0 ? node.id : node.params[i];
|
1552
|
+
if (isStrictReservedWord(id.name) || isStrictBadIdWord(id.name))
|
1553
|
+
raise(id.start, "Defining '" + id.name + "' in strict mode");
|
1554
|
+
if (i >= 0) for (var j = 0; j < i; ++j) if (id.name === node.params[j].name)
|
1555
|
+
raise(id.start, "Argument name clash in strict mode");
|
1556
|
+
}
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
return finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
|
1560
|
+
}
|
1561
|
+
|
1562
|
+
// Parses a comma-separated list of expressions, and returns them as
|
1563
|
+
// an array. `close` is the token type that ends the list, and
|
1564
|
+
// `allowEmpty` can be turned on to allow subsequent commas with
|
1565
|
+
// nothing in between them to be parsed as `null` (which is needed
|
1566
|
+
// for array literals).
|
1567
|
+
|
1568
|
+
function parseExprList(close, allowTrailingComma, allowEmpty) {
|
1569
|
+
var elts = [], first = true;
|
1570
|
+
while (!eat(close)) {
|
1571
|
+
if (!first) {
|
1572
|
+
expect(_comma);
|
1573
|
+
if (allowTrailingComma && options.allowTrailingCommas && eat(close)) break;
|
1574
|
+
} else first = false;
|
1575
|
+
|
1576
|
+
if (allowEmpty && tokType === _comma) elts.push(null);
|
1577
|
+
else elts.push(parseExpression(true));
|
1578
|
+
}
|
1579
|
+
return elts;
|
1580
|
+
}
|
1581
|
+
|
1582
|
+
// Parse the next token as an identifier. If `liberal` is true (used
|
1583
|
+
// when parsing properties), it will also convert keywords into
|
1584
|
+
// identifiers.
|
1585
|
+
|
1586
|
+
function parseIdent(liberal) {
|
1587
|
+
var node = startNode();
|
1588
|
+
node.name = tokType === _name ? tokVal : (liberal && !options.forbidReserved && tokType.keyword) || unexpected();
|
1589
|
+
next();
|
1590
|
+
return finishNode(node, "Identifier");
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
})(typeof exports === "undefined" ? (window.acorn = {}) : exports);
|