diff --git a/test262/config.py b/test262/config.py index e04e869ae8a80d06a7ceda97b1a3b8b89988e744..d4903397a72a9f1cd813ee4f6b3e22ba10eb9f1e 100755 --- a/test262/config.py +++ b/test262/config.py @@ -55,6 +55,7 @@ DEFAULT_TIMEOUT = 60000 ES5_LIST_FILE = os.path.join("test262", "es5_tests.txt") ES2015_LIST_FILE = os.path.join("test262", "es2015_tests.txt") CI_LIST_FILE = os.path.join("test262", "CI_tests.txt") +MODULE_FILES_LIST = os.path.join("test262", "module_tests.txt") TEST262_GIT_HASH = "9ca13b12728b7e0089c7eb03fa2bd17f8abe297f" HARNESS_GIT_HASH = "9c499f028eb24e67781435c0bb442e00343eb39d" @@ -81,27 +82,3 @@ ARK_ARCH_LIST = [ ] DEFAULT_ARK_ARCH = ARK_ARCH_LIST[0] - -MODULE_FILES_LIST = [ - "early-dup-export-decl.js", - "early-dup-export-dflt-id.js", - "early-dup-export-dflt.js", - "early-dup-export-id-as.js", - "early-dup-export-id.js", - "early-dup-lables.js", - "early-dup-lex.js", - "early-export-global.js", - "early-lex-and-var.js", - "early-new-target.js", - "early-strict-mode.js", - "early-super.js", - "early-undef-break.js", - "early-undef-continue.js", - "parse-err-export-dflt-const.js", - "parse-err-export-dflt-let.js", - "parse-err-export-dflt-var.js", - "parse-err-return.js", - "parse-err-yield.js", - "dup-bound-names.js", - "await-module.js" -] diff --git a/test262/es2015_tests.txt b/test262/es2015_tests.txt index 92acde0ddc1283cd60ae04c96534fa89c89b5191..b23ac30a0da61b95dcae42d7b50f059c8a17a753 100755 --- a/test262/es2015_tests.txt +++ b/test262/es2015_tests.txt @@ -5227,4 +5227,414 @@ intl402/Date/prototype/toLocaleString/builtin.js intl402/Date/prototype/toLocaleString/length.js intl402/Date/prototype/toLocaleString/default-options-object-prototype.js intl402/language-tags-valid.js -intl402/language-tags-canonicalized.js \ No newline at end of file +intl402/language-tags-canonicalized.js +language/module-code/comment-multi-line-html-close.js +language/module-code/comment-single-line-html-close.js +language/module-code/comment-single-line-html-open.js +language/module-code/early-dup-export-as-star-as.js +language/module-code/early-dup-export-decl.js +language/module-code/early-dup-export-dflt-id.js +language/module-code/early-dup-export-dflt.js +language/module-code/early-dup-export-id-as.js +language/module-code/early-dup-export-id.js +language/module-code/early-dup-language/module-code/export-star-as-dflt.js +language/module-code/early-dup-lables.js +language/module-code/early-dup-lex.js +language/module-code/early-export-global.js +language/module-code/early-export-ill-formed-string.js +language/module-code/early-export-unresolvable.js +language/module-code/early-import-arguments.js +language/module-code/early-import-as-arguments.js +language/module-code/early-import-as-eval.js +language/module-code/early-import-eval.js +language/module-code/early-lex-and-var.js +language/module-code/early-new-target.js +language/module-code/early-strict-mode.js +language/module-code/early-super.js +language/module-code/early-undef-break.js +language/module-code/early-undef-continue.js +language/module-code/eval-export-cls-semi.js +language/module-code/eval-export-dflt-cls-anon.js +language/module-code/eval-export-dflt-cls-anon-semi.js +language/module-code/eval-export-dflt-cls-named.js +language/module-code/eval-export-dflt-cls-named-semi.js +language/module-code/eval-export-dflt-cls-name-meth.js +language/module-code/eval-export-dflt-expr-cls-anon.js +language/module-code/eval-export-dflt-expr-cls-named.js +language/module-code/eval-export-dflt-expr-cls-name-meth.js +language/module-code/eval-export-dflt-expr-err-eval.js +language/module-code/eval-export-dflt-expr-err-get-value.js +language/module-code/eval-export-dflt-expr-fn-anon.js +language/module-code/eval-export-dflt-expr-fn-named.js +language/module-code/eval-export-dflt-expr-gen-anon.js +language/module-code/eval-export-dflt-expr-gen-named.js +language/module-code/eval-export-dflt-expr-in.js +language/module-code/eval-export-dflt-fun-anon-semi.js +language/module-code/eval-export-dflt-fun-named-semi.js +language/module-code/eval-export-dflt-gen-anon-semi.js +language/module-code/eval-export-dflt-gen-named-semi.js +language/module-code/eval-export-fun-semi.js +language/module-code/eval-export-gen-semi.js +language/module-code/eval-gtbndng-indirect-trlng-comma_FIXTURE.js +language/module-code/eval-gtbndng-indirect-trlng-comma.js +language/module-code/eval-gtbndng-indirect-update-as_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update-as.js +language/module-code/eval-gtbndng-indirect-update-dflt_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update-dflt.js +language/module-code/eval-gtbndng-indirect-update_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update.js +language/module-code/eval-gtbndng-local-bndng-cls.js +language/module-code/eval-gtbndng-local-bndng-const.js +language/module-code/eval-gtbndng-local-bndng-let.js +language/module-code/eval-gtbndng-local-bndng-var.js +language/module-code/eval-rqstd-abrupt-err-type_FIXTURE.js +language/module-code/eval-rqstd-abrupt-err-uri_FIXTURE.js +language/module-code/eval-rqstd-abrupt.js +language/module-code/eval-rqstd-once_FIXTURE.js +language/module-code/eval-rqstd-once.js +language/module-code/eval-rqstd-order-1_FIXTURE.js +language/module-code/eval-rqstd-order-2_FIXTURE.js +language/module-code/eval-rqstd-order-3_FIXTURE.js +language/module-code/eval-rqstd-order-4_FIXTURE.js +language/module-code/eval-rqstd-order-5_FIXTURE.js +language/module-code/eval-rqstd-order-6_FIXTURE.js +language/module-code/eval-rqstd-order-7_FIXTURE.js +language/module-code/eval-rqstd-order-8_FIXTURE.js +language/module-code/eval-rqstd-order-9_FIXTURE.js +language/module-code/eval-rqstd-order.js +language/module-code/eval-self-abrupt.js +language/module-code/eval-self-once.js +language/module-code/eval-this.js +language/module-code/export-default-asyncfunction-declaration-binding-exists.js +language/module-code/export-default-asyncfunction-declaration-binding.js +language/module-code/export-default-asyncgenerator-declaration-binding-exists.js +language/module-code/export-default-asyncgenerator-declaration-binding.js +language/module-code/export-default-function-declaration-binding-exists.js +language/module-code/export-default-function-declaration-binding.js +language/module-code/export-default-generator-declaration-binding-exists.js +language/module-code/export-default-generator-declaration-binding.js +language/module-code/export-expname-binding-string.js +language/module-code/export-expname_FIXTURE.js +language/module-code/export-expname-from-as-unpaired-surrogate.js +language/module-code/export-expname-from-binding-string.js +language/module-code/export-expname-from-star.js +language/module-code/export-expname-from-star-string.js +language/module-code/export-expname-from-star-unpaired-surrogate.js +language/module-code/export-expname-from-string-binding.js +language/module-code/export-expname-from-string.js +language/module-code/export-expname-from-string-string.js +language/module-code/export-expname-from-unpaired-surrogate.js +language/module-code/export-expname-import-string-binding.js +language/module-code/export-expname-import-unpaired-surrogate.js +language/module-code/export-expname-string-binding.js +language/module-code/export-expname-unpaired-surrogate.js +language/module-code/export-star-as-dflt_FIXTURE.js +language/module-code/export-star-as-dflt.js +language/module-code/instn-iee-bndng-cls_FIXTURE.js +language/module-code/instn-iee-bndng-cls.js +language/module-code/instn-iee-bndng-const_FIXTURE.js +language/module-code/instn-iee-bndng-const.js +language/module-code/instn-iee-bndng-fun_FIXTURE.js +language/module-code/instn-iee-bndng-fun.js +language/module-code/instn-iee-bndng-gen_FIXTURE.js +language/module-code/instn-iee-bndng-gen.js +language/module-code/instn-iee-bndng-let_FIXTURE.js +language/module-code/instn-iee-bndng-let.js +language/module-code/instn-iee-bndng-var_FIXTURE.js +language/module-code/instn-iee-bndng-var.js +language/module-code/instn-iee-err-ambiguous-1_FIXTURE.js +language/module-code/instn-iee-err-ambiguous-2_FIXTURE.js +language/module-code/instn-iee-err-ambiguous-as.js +language/module-code/instn-iee-err-ambiguous_FIXTURE.js +language/module-code/instn-iee-err-ambiguous.js +language/module-code/instn-iee-err-circular-as.js +language/module-code/instn-iee-err-circular_FIXTURE.js +language/module-code/instn-iee-err-circular.js +language/module-code/instn-iee-err-dflt-thru-star-as.js +language/module-code/instn-iee-err-dflt-thru-star-dflt_FIXTURE.js +language/module-code/instn-iee-err-dflt-thru-star-int_FIXTURE.js +language/module-code/instn-iee-err-dflt-thru-star.js +language/module-code/instn-iee-err-not-found-as.js +language/module-code/instn-iee-err-not-found-empty_FIXTURE.js +language/module-code/instn-iee-err-not-found.js +language/module-code/instn-iee-iee-cycle-2_FIXTURE.js +language/module-code/instn-iee-iee-cycle.js +language/module-code/instn-iee-star-cycle-2_FIXTURE.js +language/module-code/instn-iee-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-iee-star-cycle.js +language/module-code/instn-iee-trlng-comma_FIXTURE.js +language/module-code/instn-iee-trlng-comma.js +language/module-code/instn-local-bndng-cls.js +language/module-code/instn-local-bndng-const.js +language/module-code/instn-local-bndng-export-cls.js +language/module-code/instn-local-bndng-export-const.js +language/module-code/instn-local-bndng-export-fun.js +language/module-code/instn-local-bndng-export-gen.js +language/module-code/instn-local-bndng-export-let.js +language/module-code/instn-local-bndng-export-var.js +language/module-code/instn-local-bndng-for-dup.js +language/module-code/instn-local-bndng-for.js +language/module-code/instn-local-bndng-fun.js +language/module-code/instn-local-bndng-gen.js +language/module-code/instn-local-bndng-let.js +language/module-code/instn-local-bndng-var-dup.js +language/module-code/instn-local-bndng-var.js +language/module-code/instn-named-bndng-cls.js +language/module-code/instn-named-bndng-const.js +language/module-code/instn-named-bndng-dflt-cls.js +language/module-code/instn-named-bndng-dflt-expr.js +language/module-code/instn-named-bndng-dflt-fun-anon.js +language/module-code/instn-named-bndng-dflt-fun-named.js +language/module-code/instn-named-bndng-dflt-gen-anon.js +language/module-code/instn-named-bndng-dflt-gen-named.js +language/module-code/instn-named-bndng-dflt-named.js +language/module-code/instn-named-bndng-dflt-star.js +language/module-code/instn-named-bndng-fun.js +language/module-code/instn-named-bndng-gen.js +language/module-code/instn-named-bndng-let.js +language/module-code/instn-named-bndng-trlng-comma.js +language/module-code/instn-named-bndng-var.js +language/module-code/instn-named-err-ambiguous-1_FIXTURE.js +language/module-code/instn-named-err-ambiguous-2_FIXTURE.js +language/module-code/instn-named-err-ambiguous-as.js +language/module-code/instn-named-err-ambiguous_FIXTURE.js +language/module-code/instn-named-err-ambiguous.js +language/module-code/instn-named-err-dflt-thru-star-as.js +language/module-code/instn-named-err-dflt-thru-star-dflt_FIXTURE.js +language/module-code/instn-named-err-dflt-thru-star-dflt.js +language/module-code/instn-named-err-dflt-thru-star-int_FIXTURE.js +language/module-code/instn-named-err-not-found-as.js +language/module-code/instn-named-err-not-found-dflt.js +language/module-code/instn-named-err-not-found-empty_FIXTURE.js +language/module-code/instn-named-err-not-found.js +language/module-code/instn-named-id-name.js +language/module-code/instn-named-iee-cycle-2_FIXTURE.js +language/module-code/instn-named-iee-cycle.js +language/module-code/instn-named-star-cycle-2_FIXTURE.js +language/module-code/instn-named-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-named-star-cycle.js +language/module-code/instn-once.js +language/module-code/instn-resolve-empty-export_FIXTURE.js +language/module-code/instn-resolve-empty-export.js +language/module-code/instn-resolve-empty-import_FIXTURE.js +language/module-code/instn-resolve-empty-import.js +language/module-code/instn-resolve-err-syntax-1_FIXTURE.js +language/module-code/instn-resolve-err-syntax-1.js +language/module-code/instn-resolve-err-syntax-2_FIXTURE.js +language/module-code/instn-resolve-err-syntax-2.js +language/module-code/instn-resolve-order-depth-child_FIXTURE.js +language/module-code/instn-resolve-order-depth.js +language/module-code/instn-resolve-order-depth-reference_FIXTURE.js +language/module-code/instn-resolve-order-depth-syntax_FIXTURE.js +language/module-code/instn-resolve-order-src.js +language/module-code/instn-resolve-order-src-reference_FIXTURE.js +language/module-code/instn-resolve-order-src-syntax_FIXTURE.js +language/module-code/instn-resolve-order-src-valid_FIXTURE.js +language/module-code/instn-same-global.js +language/module-code/instn-same-global-set_FIXTURE.js +language/module-code/instn-star-ambiguous-1_FIXTURE.js +language/module-code/instn-star-ambiguous-2_FIXTURE.js +language/module-code/instn-star-ambiguous_FIXTURE.js +language/module-code/instn-star-ambiguous.js +language/module-code/instn-star-as-props-dflt-skip.js +language/module-code/instn-star-binding.js +language/module-code/instn-star-equality.js +language/module-code/instn-star-equality-other_FIXTURE.js +language/module-code/instn-star-err-not-found-empty_FIXTURE.js +language/module-code/instn-star-err-not-found-faulty_FIXTURE.js +language/module-code/instn-star-err-not-found.js +language/module-code/instn-star-id-name.js +language/module-code/instn-star-iee-cycle-2_FIXTURE.js +language/module-code/instn-star-iee-cycle.js +language/module-code/instn-star-props-circular-a_FIXTURE.js +language/module-code/instn-star-props-circular-b_FIXTURE.js +language/module-code/instn-star-props-circular.js +language/module-code/instn-star-props-dflt-keep-indirect-def_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-indirect.js +language/module-code/instn-star-props-dflt-keep-indirect-reexport_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-local.js +language/module-code/instn-star-props-dflt-keep-local-named_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-local-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip.js +language/module-code/instn-star-props-dflt-skip-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-named-end_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-prod-end_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-prod_FIXTURE.js +language/module-code/instn-star-props-nrml-1_FIXTURE.js +language/module-code/instn-star-props-nrml-indirect_FIXTURE.js +language/module-code/instn-star-props-nrml.js +language/module-code/instn-star-props-nrml-star_FIXTURE.js +language/module-code/instn-star-star-cycle-2_FIXTURE.js +language/module-code/instn-star-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-star-star-cycle.js +language/module-code/instn-uniq-env-rec.js +language/module-code/instn-uniq-env-rec-other_FIXTURE.js +language/module-code/invalid-private-names-call-expression-bad-reference.js +language/module-code/invalid-private-names-call-expression-this.js +language/module-code/invalid-private-names-member-expression-bad-reference.js +language/module-code/invalid-private-names-member-expression-this.js +language/module-code/parse-err-decl-pos-export-arrow-function.js +language/module-code/parse-err-decl-pos-export-block-stmt.js +language/module-code/parse-err-decl-pos-export-block-stmt-list.js +language/module-code/parse-err-decl-pos-export-class-decl-meth.js +language/module-code/parse-err-decl-pos-export-class-decl-method-gen.js +language/module-code/parse-err-decl-pos-export-class-decl-method-gen-static.js +language/module-code/parse-err-decl-pos-export-class-decl-meth-static.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-gen.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-gen-static.js +language/module-code/parse-err-decl-pos-export-class-expr-meth.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-static.js +language/module-code/parse-err-decl-pos-export-do-while.js +language/module-code/parse-err-decl-pos-export-for-const.js +language/module-code/parse-err-decl-pos-export-for-in-const.js +language/module-code/parse-err-decl-pos-export-for-in-let.js +language/module-code/parse-err-decl-pos-export-for-in-lhs.js +language/module-code/parse-err-decl-pos-export-for-in-var.js +language/module-code/parse-err-decl-pos-export-for-let.js +language/module-code/parse-err-decl-pos-export-for-lhs.js +language/module-code/parse-err-decl-pos-export-for-of-const.js +language/module-code/parse-err-decl-pos-export-for-of-let.js +language/module-code/parse-err-decl-pos-export-for-of-lhs.js +language/module-code/parse-err-decl-pos-export-for-of-var.js +language/module-code/parse-err-decl-pos-export-for-var.js +language/module-code/parse-err-decl-pos-export-function-decl.js +language/module-code/parse-err-decl-pos-export-function-expr.js +language/module-code/parse-err-decl-pos-export-generator-decl.js +language/module-code/parse-err-decl-pos-export-generator-expr.js +language/module-code/parse-err-decl-pos-export-if-else.js +language/module-code/parse-err-decl-pos-export-if-if.js +language/module-code/parse-err-decl-pos-export-labeled.js +language/module-code/parse-err-decl-pos-export-object-gen-method.js +language/module-code/parse-err-decl-pos-export-object-getter.js +language/module-code/parse-err-decl-pos-export-object-method.js +language/module-code/parse-err-decl-pos-export-object-setter.js +language/module-code/parse-err-decl-pos-export-switch-case-dflt.js +language/module-code/parse-err-decl-pos-export-switch-case.js +language/module-code/parse-err-decl-pos-export-switch-dftl.js +language/module-code/parse-err-decl-pos-export-try-catch-finally.js +language/module-code/parse-err-decl-pos-export-try-catch.js +language/module-code/parse-err-decl-pos-export-try-finally.js +language/module-code/parse-err-decl-pos-export-try-try.js +language/module-code/parse-err-decl-pos-export-while.js +language/module-code/parse-err-decl-pos-import-arrow-function.js +language/module-code/parse-err-decl-pos-import-block-stmt.js +language/module-code/parse-err-decl-pos-import-block-stmt-list.js +language/module-code/parse-err-decl-pos-import-class-decl-meth.js +language/module-code/parse-err-decl-pos-import-class-decl-method-gen.js +language/module-code/parse-err-decl-pos-import-class-decl-method-gen-static.js +language/module-code/parse-err-decl-pos-import-class-decl-meth-static.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-gen.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-gen-static.js +language/module-code/parse-err-decl-pos-import-class-expr-meth.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-static.js +language/module-code/parse-err-decl-pos-import-do-while.js +language/module-code/parse-err-decl-pos-import-for-const.js +language/module-code/parse-err-decl-pos-import-for-in-const.js +language/module-code/parse-err-decl-pos-import-for-in-let.js +language/module-code/parse-err-decl-pos-import-for-in-lhs.js +language/module-code/parse-err-decl-pos-import-for-in-var.js +language/module-code/parse-err-decl-pos-import-for-let.js +language/module-code/parse-err-decl-pos-import-for-lhs.js +language/module-code/parse-err-decl-pos-import-for-of-const.js +language/module-code/parse-err-decl-pos-import-for-of-let.js +language/module-code/parse-err-decl-pos-import-for-of-lhs.js +language/module-code/parse-err-decl-pos-import-for-of-var.js +language/module-code/parse-err-decl-pos-import-for-var.js +language/module-code/parse-err-decl-pos-import-function-decl.js +language/module-code/parse-err-decl-pos-import-function-expr.js +language/module-code/parse-err-decl-pos-import-generator-decl.js +language/module-code/parse-err-decl-pos-import-generator-expr.js +language/module-code/parse-err-decl-pos-import-if-else.js +language/module-code/parse-err-decl-pos-import-if-if.js +language/module-code/parse-err-decl-pos-import-labeled.js +language/module-code/parse-err-decl-pos-import-object-gen-method.js +language/module-code/parse-err-decl-pos-import-object-getter.js +language/module-code/parse-err-decl-pos-import-object-method.js +language/module-code/parse-err-decl-pos-import-object-setter.js +language/module-code/parse-err-decl-pos-import-switch-case-dflt.js +language/module-code/parse-err-decl-pos-import-switch-case.js +language/module-code/parse-err-decl-pos-import-switch-dftl.js +language/module-code/parse-err-decl-pos-import-try-catch-finally.js +language/module-code/parse-err-decl-pos-import-try-catch.js +language/module-code/parse-err-decl-pos-import-try-finally.js +language/module-code/parse-err-decl-pos-import-try-try.js +language/module-code/parse-err-decl-pos-import-while.js +language/module-code/parse-err-export-dflt-const.js +language/module-code/parse-err-export-dflt-expr.js +language/module-code/parse-err-export-dflt-let.js +language/module-code/parse-err-export-dflt-var.js +language/module-code/parse-err-hoist-lex-fun.js +language/module-code/parse-err-hoist-lex-gen.js +language/module-code/parse-err-invoke-anon-fun-decl.js +language/module-code/parse-err-invoke-anon-gen-decl.js +language/module-code/parse-err-return.js +language/module-code/parse-err-semi-dflt-expr.js +language/module-code/parse-err-semi-export-star.js +language/module-code/parse-err-semi-named-export-from.js +language/module-code/parse-err-semi-named-export.js +language/module-code/parse-err-semi-name-space-export.js +language/module-code/parse-err-syntax-1.js +language/module-code/parse-err-syntax-2.js +language/module-code/parse-err-yield.js +language/module-code/parse-export-empty.js +language/module-code/private-identifiers-not-empty.js +language/module-code/privatename-not-valid-earlyerr-module-1.js +language/module-code/privatename-not-valid-earlyerr-module-2.js +language/module-code/privatename-not-valid-earlyerr-module-3.js +language/module-code/privatename-not-valid-earlyerr-module-4.js +language/module-code/privatename-not-valid-earlyerr-module-5.js +language/module-code/privatename-not-valid-earlyerr-module-6.js +language/module-code/privatename-not-valid-earlyerr-module-7.js +language/module-code/privatename-not-valid-earlyerr-module-8.js +language/module-code/privatename-valid-no-earlyerr.js +language/module-code/verify-dfs-a_FIXTURE.js +language/module-code/verify-dfs-b_FIXTURE.js +language/module-code/verify-dfs.js +language/module-code/namespace/Symbol.iterator.js +language/module-code/namespace/Symbol.toStringTag.js +language/module-code/namespace/internals/define-own-property.js +language/module-code/namespace/internals/delete-exported-init.js +language/module-code/namespace/internals/delete-exported-uninit.js +language/module-code/namespace/internals/delete-non-exported.js +language/module-code/namespace/internals/enumerate-binding-uninit.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-named-end_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-named_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-prod-end_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-prod_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-1_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-2_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-3_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml.js +language/module-code/namespace/internals/get-own-property-str-found-init.js +language/module-code/namespace/internals/get-own-property-str-found-uninit.js +language/module-code/namespace/internals/get-own-property-str-not-found.js +language/module-code/namespace/internals/get-own-property-sym.js +language/module-code/namespace/internals/get-prototype-of.js +language/module-code/namespace/internals/get-str-found-init.js +language/module-code/namespace/internals/get-str-found-uninit.js +language/module-code/namespace/internals/get-str-initialize.js +language/module-code/namespace/internals/get-str-not-found.js +language/module-code/namespace/internals/get-str-update.js +language/module-code/namespace/internals/get-sym-found.js +language/module-code/namespace/internals/get-sym-not-found.js +language/module-code/namespace/internals/has-property-str-found-init.js +language/module-code/namespace/internals/has-property-str-found-uninit.js +language/module-code/namespace/internals/has-property-str-not-found.js +language/module-code/namespace/internals/has-property-sym-found.js +language/module-code/namespace/internals/has-property-sym-not-found.js +language/module-code/namespace/internals/is-extensible.js +language/module-code/namespace/internals/object-hasOwnProperty-binding-uninit.js +language/module-code/namespace/internals/object-keys-binding-uninit.js +language/module-code/namespace/internals/object-propertyIsEnumerable-binding-uninit.js +language/module-code/namespace/internals/own-property-keys-binding-types_FIXTURE.js +language/module-code/namespace/internals/own-property-keys-binding-types.js +language/module-code/namespace/internals/own-property-keys-sort.js +language/module-code/namespace/internals/prevent-extensions.js +language/module-code/namespace/internals/set.js +language/module-code/namespace/internals/set-prototype-of.js +language/module-code/namespace/internals/set-prototype-of-null.js diff --git a/test262/module_tests.txt b/test262/module_tests.txt new file mode 100644 index 0000000000000000000000000000000000000000..fc9cd67a5140f6450281e53d6af1bbc745fe5700 --- /dev/null +++ b/test262/module_tests.txt @@ -0,0 +1,431 @@ +early-dup-export-decl.js +early-dup-export-dflt-id.js +early-dup-export-dflt.js +early-dup-export-id-as.js +early-dup-export-id.js +early-dup-lables.js +early-dup-lex.js +early-export-global.js +early-lex-and-var.js +early-new-target.js +early-strict-mode.js +early-super.js +early-undef-break.js +early-undef-continue.js +parse-err-export-dflt-const.js +parse-err-export-dflt-let.js +parse-err-export-dflt-var.js +parse-err-return.js +parse-err-yield.js +dup-bound-names.js +await-module.js +comment-multi-line-html-close.js +comment-single-line-html-close.js +comment-single-line-html-open.js +early-dup-export-as-star-as.js +early-dup-export-decl.js +early-dup-export-dflt-id.js +early-dup-export-dflt.js +early-dup-export-id-as.js +early-dup-export-id.js +export-star-as-dflt.js +early-dup-lables.js +early-dup-lex.js +early-export-global.js +early-export-ill-formed-string.js +early-export-unresolvable.js +early-import-arguments.js +early-import-as-arguments.js +early-import-as-eval.js +early-import-eval.js +early-lex-and-var.js +early-new-target.js +early-strict-mode.js +early-super.js +early-undef-break.js +early-undef-continue.js +eval-export-cls-semi.js +eval-export-dflt-cls-anon.js +eval-export-dflt-cls-anon-semi.js +eval-export-dflt-cls-named.js +eval-export-dflt-cls-named-semi.js +eval-export-dflt-cls-name-meth.js +eval-export-dflt-expr-cls-anon.js +eval-export-dflt-expr-cls-named.js +eval-export-dflt-expr-cls-name-meth.js +eval-export-dflt-expr-err-eval.js +eval-export-dflt-expr-err-get-value.js +eval-export-dflt-expr-fn-anon.js +eval-export-dflt-expr-fn-named.js +eval-export-dflt-expr-gen-anon.js +eval-export-dflt-expr-gen-named.js +eval-export-dflt-expr-in.js +eval-export-dflt-fun-anon-semi.js +eval-export-dflt-fun-named-semi.js +eval-export-dflt-gen-anon-semi.js +eval-export-dflt-gen-named-semi.js +eval-export-fun-semi.js +eval-export-gen-semi.js +eval-gtbndng-indirect-trlng-comma_FIXTURE.js +eval-gtbndng-indirect-trlng-comma.js +eval-gtbndng-indirect-update-as_FIXTURE.js +eval-gtbndng-indirect-update-as.js +eval-gtbndng-indirect-update-dflt_FIXTURE.js +eval-gtbndng-indirect-update-dflt.js +eval-gtbndng-indirect-update_FIXTURE.js +eval-gtbndng-indirect-update.js +eval-gtbndng-local-bndng-cls.js +eval-gtbndng-local-bndng-const.js +eval-gtbndng-local-bndng-let.js +eval-gtbndng-local-bndng-var.js +eval-rqstd-abrupt-err-type_FIXTURE.js +eval-rqstd-abrupt-err-uri_FIXTURE.js +eval-rqstd-abrupt.js +eval-rqstd-once_FIXTURE.js +eval-rqstd-once.js +eval-rqstd-order-1_FIXTURE.js +eval-rqstd-order-2_FIXTURE.js +eval-rqstd-order-3_FIXTURE.js +eval-rqstd-order-4_FIXTURE.js +eval-rqstd-order-5_FIXTURE.js +eval-rqstd-order-6_FIXTURE.js +eval-rqstd-order-7_FIXTURE.js +eval-rqstd-order-8_FIXTURE.js +eval-rqstd-order-9_FIXTURE.js +eval-rqstd-order.js +eval-self-abrupt.js +eval-self-once.js +eval-this.js +export-default-asyncfunction-declaration-binding-exists.js +export-default-asyncfunction-declaration-binding.js +export-default-asyncgenerator-declaration-binding-exists.js +export-default-asyncgenerator-declaration-binding.js +export-default-function-declaration-binding-exists.js +export-default-function-declaration-binding.js +export-default-generator-declaration-binding-exists.js +export-default-generator-declaration-binding.js +export-expname-binding-string.js +export-expname_FIXTURE.js +export-expname-from-as-unpaired-surrogate.js +export-expname-from-binding-string.js +export-expname-from-star.js +export-expname-from-star-string.js +export-expname-from-star-unpaired-surrogate.js +export-expname-from-string-binding.js +export-expname-from-string.js +export-expname-from-string-string.js +export-expname-from-unpaired-surrogate.js +export-expname-import-string-binding.js +export-expname-import-unpaired-surrogate.js +export-expname-string-binding.js +export-expname-unpaired-surrogate.js +export-star-as-dflt_FIXTURE.js +export-star-as-dflt.js +instn-iee-bndng-cls_FIXTURE.js +instn-iee-bndng-cls.js +instn-iee-bndng-const_FIXTURE.js +instn-iee-bndng-const.js +instn-iee-bndng-fun_FIXTURE.js +instn-iee-bndng-fun.js +instn-iee-bndng-gen_FIXTURE.js +instn-iee-bndng-gen.js +instn-iee-bndng-let_FIXTURE.js +instn-iee-bndng-let.js +instn-iee-bndng-var_FIXTURE.js +instn-iee-bndng-var.js +instn-iee-err-ambiguous-1_FIXTURE.js +instn-iee-err-ambiguous-2_FIXTURE.js +instn-iee-err-ambiguous-as.js +instn-iee-err-ambiguous_FIXTURE.js +instn-iee-err-ambiguous.js +instn-iee-err-circular-as.js +instn-iee-err-circular_FIXTURE.js +instn-iee-err-circular.js +instn-iee-err-dflt-thru-star-as.js +instn-iee-err-dflt-thru-star-dflt_FIXTURE.js +instn-iee-err-dflt-thru-star-int_FIXTURE.js +instn-iee-err-dflt-thru-star.js +instn-iee-err-not-found-as.js +instn-iee-err-not-found-empty_FIXTURE.js +instn-iee-err-not-found.js +instn-iee-iee-cycle-2_FIXTURE.js +instn-iee-iee-cycle.js +instn-iee-star-cycle-2_FIXTURE.js +instn-iee-star-cycle-indirect-x_FIXTURE.js +instn-iee-star-cycle.js +instn-iee-trlng-comma_FIXTURE.js +instn-iee-trlng-comma.js +instn-local-bndng-cls.js +instn-local-bndng-const.js +instn-local-bndng-export-cls.js +instn-local-bndng-export-const.js +instn-local-bndng-export-fun.js +instn-local-bndng-export-gen.js +instn-local-bndng-export-let.js +instn-local-bndng-export-var.js +instn-local-bndng-for-dup.js +instn-local-bndng-for.js +instn-local-bndng-fun.js +instn-local-bndng-gen.js +instn-local-bndng-let.js +instn-local-bndng-var-dup.js +instn-local-bndng-var.js +instn-named-bndng-cls.js +instn-named-bndng-const.js +instn-named-bndng-dflt-cls.js +instn-named-bndng-dflt-expr.js +instn-named-bndng-dflt-fun-anon.js +instn-named-bndng-dflt-fun-named.js +instn-named-bndng-dflt-gen-anon.js +instn-named-bndng-dflt-gen-named.js +instn-named-bndng-dflt-named.js +instn-named-bndng-dflt-star.js +instn-named-bndng-fun.js +instn-named-bndng-gen.js +instn-named-bndng-let.js +instn-named-bndng-trlng-comma.js +instn-named-bndng-var.js +instn-named-err-ambiguous-1_FIXTURE.js +instn-named-err-ambiguous-2_FIXTURE.js +instn-named-err-ambiguous-as.js +instn-named-err-ambiguous_FIXTURE.js +instn-named-err-ambiguous.js +instn-named-err-dflt-thru-star-as.js +instn-named-err-dflt-thru-star-dflt_FIXTURE.js +instn-named-err-dflt-thru-star-dflt.js +instn-named-err-dflt-thru-star-int_FIXTURE.js +instn-named-err-not-found-as.js +instn-named-err-not-found-dflt.js +instn-named-err-not-found-empty_FIXTURE.js +instn-named-err-not-found.js +instn-named-id-name.js +instn-named-iee-cycle-2_FIXTURE.js +instn-named-iee-cycle.js +instn-named-star-cycle-2_FIXTURE.js +instn-named-star-cycle-indirect-x_FIXTURE.js +instn-named-star-cycle.js +instn-once.js +instn-resolve-empty-export_FIXTURE.js +instn-resolve-empty-export.js +instn-resolve-empty-import_FIXTURE.js +instn-resolve-empty-import.js +instn-resolve-err-syntax-1_FIXTURE.js +instn-resolve-err-syntax-1.js +instn-resolve-err-syntax-2_FIXTURE.js +instn-resolve-err-syntax-2.js +instn-resolve-order-depth-child_FIXTURE.js +instn-resolve-order-depth.js +instn-resolve-order-depth-reference_FIXTURE.js +instn-resolve-order-depth-syntax_FIXTURE.js +instn-resolve-order-src.js +instn-resolve-order-src-reference_FIXTURE.js +instn-resolve-order-src-syntax_FIXTURE.js +instn-resolve-order-src-valid_FIXTURE.js +instn-same-global.js +instn-same-global-set_FIXTURE.js +instn-star-ambiguous-1_FIXTURE.js +instn-star-ambiguous-2_FIXTURE.js +instn-star-ambiguous_FIXTURE.js +instn-star-ambiguous.js +instn-star-as-props-dflt-skip.js +instn-star-binding.js +instn-star-equality.js +instn-star-equality-other_FIXTURE.js +instn-star-err-not-found-empty_FIXTURE.js +instn-star-err-not-found-faulty_FIXTURE.js +instn-star-err-not-found.js +instn-star-id-name.js +instn-star-iee-cycle-2_FIXTURE.js +instn-star-iee-cycle.js +instn-star-props-circular-a_FIXTURE.js +instn-star-props-circular-b_FIXTURE.js +instn-star-props-circular.js +instn-star-props-dflt-keep-indirect-def_FIXTURE.js +instn-star-props-dflt-keep-indirect.js +instn-star-props-dflt-keep-indirect-reexport_FIXTURE.js +instn-star-props-dflt-keep-local.js +instn-star-props-dflt-keep-local-named_FIXTURE.js +instn-star-props-dflt-keep-local-prod_FIXTURE.js +instn-star-props-dflt-skip.js +instn-star-props-dflt-skip-named_FIXTURE.js +instn-star-props-dflt-skip-prod_FIXTURE.js +instn-star-props-dflt-skip-star-as-named-end_FIXTURE.js +instn-star-props-dflt-skip-star-as-named_FIXTURE.js +instn-star-props-dflt-skip-star-as-prod-end_FIXTURE.js +instn-star-props-dflt-skip-star-as-prod_FIXTURE.js +instn-star-props-dflt-skip-star-named_FIXTURE.js +instn-star-props-dflt-skip-star-prod_FIXTURE.js +instn-star-props-nrml-1_FIXTURE.js +instn-star-props-nrml-indirect_FIXTURE.js +instn-star-props-nrml.js +instn-star-props-nrml-star_FIXTURE.js +instn-star-star-cycle-2_FIXTURE.js +instn-star-star-cycle-indirect-x_FIXTURE.js +instn-star-star-cycle.js +instn-uniq-env-rec.js +instn-uniq-env-rec-other_FIXTURE.js +invalid-private-names-call-expression-bad-reference.js +invalid-private-names-call-expression-this.js +invalid-private-names-member-expression-bad-reference.js +invalid-private-names-member-expression-this.js +parse-err-decl-pos-export-arrow-function.js +parse-err-decl-pos-export-block-stmt.js +parse-err-decl-pos-export-block-stmt-list.js +parse-err-decl-pos-export-class-decl-meth.js +parse-err-decl-pos-export-class-decl-method-gen.js +parse-err-decl-pos-export-class-decl-method-gen-static.js +parse-err-decl-pos-export-class-decl-meth-static.js +parse-err-decl-pos-export-class-expr-meth-gen.js +parse-err-decl-pos-export-class-expr-meth-gen-static.js +parse-err-decl-pos-export-class-expr-meth.js +parse-err-decl-pos-export-class-expr-meth-static.js +parse-err-decl-pos-export-do-while.js +parse-err-decl-pos-export-for-const.js +parse-err-decl-pos-export-for-in-const.js +parse-err-decl-pos-export-for-in-let.js +parse-err-decl-pos-export-for-in-lhs.js +parse-err-decl-pos-export-for-in-var.js +parse-err-decl-pos-export-for-let.js +parse-err-decl-pos-export-for-lhs.js +parse-err-decl-pos-export-for-of-const.js +parse-err-decl-pos-export-for-of-let.js +parse-err-decl-pos-export-for-of-lhs.js +parse-err-decl-pos-export-for-of-var.js +parse-err-decl-pos-export-for-var.js +parse-err-decl-pos-export-function-decl.js +parse-err-decl-pos-export-function-expr.js +parse-err-decl-pos-export-generator-decl.js +parse-err-decl-pos-export-generator-expr.js +parse-err-decl-pos-export-if-else.js +parse-err-decl-pos-export-if-if.js +parse-err-decl-pos-export-labeled.js +parse-err-decl-pos-export-object-gen-method.js +parse-err-decl-pos-export-object-getter.js +parse-err-decl-pos-export-object-method.js +parse-err-decl-pos-export-object-setter.js +parse-err-decl-pos-export-switch-case-dflt.js +parse-err-decl-pos-export-switch-case.js +parse-err-decl-pos-export-switch-dftl.js +parse-err-decl-pos-export-try-catch-finally.js +parse-err-decl-pos-export-try-catch.js +parse-err-decl-pos-export-try-finally.js +parse-err-decl-pos-export-try-try.js +parse-err-decl-pos-export-while.js +parse-err-decl-pos-import-arrow-function.js +parse-err-decl-pos-import-block-stmt.js +parse-err-decl-pos-import-block-stmt-list.js +parse-err-decl-pos-import-class-decl-meth.js +parse-err-decl-pos-import-class-decl-method-gen.js +parse-err-decl-pos-import-class-decl-method-gen-static.js +parse-err-decl-pos-import-class-decl-meth-static.js +parse-err-decl-pos-import-class-expr-meth-gen.js +parse-err-decl-pos-import-class-expr-meth-gen-static.js +parse-err-decl-pos-import-class-expr-meth.js +parse-err-decl-pos-import-class-expr-meth-static.js +parse-err-decl-pos-import-do-while.js +parse-err-decl-pos-import-for-const.js +parse-err-decl-pos-import-for-in-const.js +parse-err-decl-pos-import-for-in-let.js +parse-err-decl-pos-import-for-in-lhs.js +parse-err-decl-pos-import-for-in-var.js +parse-err-decl-pos-import-for-let.js +parse-err-decl-pos-import-for-lhs.js +parse-err-decl-pos-import-for-of-const.js +parse-err-decl-pos-import-for-of-let.js +parse-err-decl-pos-import-for-of-lhs.js +parse-err-decl-pos-import-for-of-var.js +parse-err-decl-pos-import-for-var.js +parse-err-decl-pos-import-function-decl.js +parse-err-decl-pos-import-function-expr.js +parse-err-decl-pos-import-generator-decl.js +parse-err-decl-pos-import-generator-expr.js +parse-err-decl-pos-import-if-else.js +parse-err-decl-pos-import-if-if.js +parse-err-decl-pos-import-labeled.js +parse-err-decl-pos-import-object-gen-method.js +parse-err-decl-pos-import-object-getter.js +parse-err-decl-pos-import-object-method.js +parse-err-decl-pos-import-object-setter.js +parse-err-decl-pos-import-switch-case-dflt.js +parse-err-decl-pos-import-switch-case.js +parse-err-decl-pos-import-switch-dftl.js +parse-err-decl-pos-import-try-catch-finally.js +parse-err-decl-pos-import-try-catch.js +parse-err-decl-pos-import-try-finally.js +parse-err-decl-pos-import-try-try.js +parse-err-decl-pos-import-while.js +parse-err-export-dflt-const.js +parse-err-export-dflt-expr.js +parse-err-export-dflt-let.js +parse-err-export-dflt-var.js +parse-err-hoist-lex-fun.js +parse-err-hoist-lex-gen.js +parse-err-invoke-anon-fun-decl.js +parse-err-invoke-anon-gen-decl.js +parse-err-return.js +parse-err-semi-dflt-expr.js +parse-err-semi-export-star.js +parse-err-semi-named-export-from.js +parse-err-semi-named-export.js +parse-err-semi-name-space-export.js +parse-err-syntax-1.js +parse-err-syntax-2.js +parse-err-yield.js +parse-export-empty.js +private-identifiers-not-empty.js +privatename-not-valid-earlyerr-module-1.js +privatename-not-valid-earlyerr-module-2.js +privatename-not-valid-earlyerr-module-3.js +privatename-not-valid-earlyerr-module-4.js +privatename-not-valid-earlyerr-module-5.js +privatename-not-valid-earlyerr-module-6.js +privatename-not-valid-earlyerr-module-7.js +privatename-not-valid-earlyerr-module-8.js +privatename-valid-no-earlyerr.js +verify-dfs-a_FIXTURE.js +verify-dfs-b_FIXTURE.js +verify-dfs.js +Symbol.iterator.js +Symbol.toStringTag.js +define-own-property.js +delete-exported-init.js +delete-exported-uninit.js +delete-non-exported.js +enumerate-binding-uninit.js +get-nested-namespace-dflt-skip.js +get-nested-namespace-dflt-skip-named-end_FIXTURE.js +get-nested-namespace-dflt-skip-named_FIXTURE.js +get-nested-namespace-dflt-skip-prod-end_FIXTURE.js +get-nested-namespace-dflt-skip-prod_FIXTURE.js +get-nested-namespace-props-nrml-1_FIXTURE.js +get-nested-namespace-props-nrml-2_FIXTURE.js +get-nested-namespace-props-nrml-3_FIXTURE.js +get-nested-namespace-props-nrml.js +get-own-property-str-found-init.js +get-own-property-str-found-uninit.js +get-own-property-str-not-found.js +get-own-property-sym.js +get-prototype-of.js +get-str-found-init.js +get-str-found-uninit.js +get-str-initialize.js +get-str-not-found.js +get-str-update.js +get-sym-found.js +get-sym-not-found.js +has-property-str-found-init.js +has-property-str-found-uninit.js +has-property-str-not-found.js +has-property-sym-found.js +has-property-sym-not-found.js +is-extensible.js +object-hasOwnProperty-binding-uninit.js +object-keys-binding-uninit.js +object-propertyIsEnumerable-binding-uninit.js +own-property-keys-binding-types_FIXTURE.js +own-property-keys-binding-types.js +own-property-keys-sort.js +prevent-extensions.js +set.js +set-prototype-of.js +set-prototype-of-null.js \ No newline at end of file diff --git a/test262/run_sunspider.py b/test262/run_sunspider.py index 3186621dc8e11a9a112fc031b19375eb17bc5ba1..1e8c42ad2432a8912e47f50f392805d8118de817 100755 --- a/test262/run_sunspider.py +++ b/test262/run_sunspider.py @@ -50,6 +50,9 @@ def parse_args(): required=False, nargs='?', choices=ARK_FRONTEND_LIST, type=str, help="Choose one of them") + parser.add_argument('--module-list', + required=True, + help="module file list") parser.add_argument('--ark-arch', default=DEFAULT_ARK_ARCH, required=False, @@ -135,6 +138,7 @@ class ArkProgram(): self.ark_frontend_tool = ARK_FRONTEND_TOOL self.libs_dir = LIBS_DIR self.ark_frontend = ARK_FRONTEND + self.module_list = [] self.js_file = "" self.arch = ARK_ARCH self.arch_root = "" @@ -152,6 +156,8 @@ class ArkProgram(): if self.args.ark_frontend: self.ark_frontend = self.args.ark_frontend + self.module_list = self.args.module_list.splitlines() + self.js_file = self.args.js_file self.arch = self.args.ark_arch @@ -175,7 +181,7 @@ class ArkProgram(): cmd_args = [frontend_tool, '-c', '-e', 'js', '-o', out_file, '-i', js_file] - if file_name in MODULE_FILES_LIST: + if file_name in self.module_list: cmd_args.insert(mod_opt_index, "-m") retcode = exec_command(cmd_args) diff --git a/test262/run_test262.py b/test262/run_test262.py index baa936b005de6c65aa4250df18e7460f5c527140..1ab65ab0918bc9fea6acb124a0e45590c651cadd 100755 --- a/test262/run_test262.py +++ b/test262/run_test262.py @@ -395,6 +395,9 @@ def get_host_args(args, host_type): libs_dir = DEFAULT_LIBS_DIR ark_frontend = DEFAULT_ARK_FRONTEND ark_arch = DEFAULT_ARK_ARCH + module_list = '' + with open(MODULE_FILES_LIST) as fopen: + module_list = fopen.read() if args.hostArgs: host_args = args.hostArgs @@ -417,6 +420,7 @@ def get_host_args(args, host_type): host_args += f"--ark-frontend-tool={ark_frontend_tool} " host_args += f"--libs-dir={libs_dir} " host_args += f"--ark-frontend={ark_frontend} " + host_args += f"--module-list={module_list}" if args.ark_arch != ark_arch: host_args += f"--ark-arch={args.ark_arch} " diff --git a/test262/skip_tests.json b/test262/skip_tests.json index c99bd2a5a19ee921ab000c78609e59ef170c825e..f5c6b7d2c24398a6cb50a8d49977960dc90c4de5 100755 --- a/test262/skip_tests.json +++ b/test262/skip_tests.json @@ -421,6 +421,7 @@ "language/literals/regexp/S7.8.5_A2.1_T2.js", "language/literals/regexp/S7.8.5_A2.4_T2.js", "language/literals/string/legacy-non-octal-escape-sequence-strict.js", + "language/module-code/export-default-asyncgenerator-declaration-binding.js", "language/statements/break/S12.8_A7.js", "language/statements/const/cptn-value.js", "language/statements/continue/S12.7_A7.js", @@ -970,6 +971,7 @@ "language/expressions/unary-minus/S11.4.7_A3_T5.js", "language/expressions/unary-plus/S11.4.6_A3_T5.js", "language/expressions/unsigned-right-shift/S11.7.3_A3_T1.5.js", + "language/module-code/eval-gtbndng-indirect-update-dflt.js", "language/statements/switch/S12.11_A1_T4.js", "language/statements/switch/S12.11_A1_T4.js", "built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js", @@ -1265,7 +1267,7 @@ ] }, { - "reason": "Not support TypedArrayConstructors ecma2021 features", + "reason": "Not support TypedArrayConstructors ecma2020 features", "files": [ "built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js", "built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js", @@ -1323,5 +1325,63 @@ "intl402/Intl/getCanonicalLocales/canonicalized-tags.js", "intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js" ] + }, + { + "reason": "Not support with Class's Privatename(#)", + "files": [ + "language/module-code/invalid-private-names-member-expression-bad-reference.js", + "language/module-code/invalid-private-names-member-expression-this.js", + "language/module-code/invalid-private-names-call-expression-bad-reference.js", + "language/module-code/invalid-private-names-call-expression-this.js", + "language/module-code/privatename-valid-no-earlyerr.js", + "language/module-code/privatename-not-valid-earlyerr-module-1.js", + "language/module-code/privatename-not-valid-earlyerr-module-2.js", + "language/module-code/privatename-not-valid-earlyerr-module-3.js", + "language/module-code/privatename-not-valid-earlyerr-module-4.js", + "language/module-code/privatename-not-valid-earlyerr-module-5.js", + "language/module-code/privatename-not-valid-earlyerr-module-6.js", + "language/module-code/privatename-not-valid-earlyerr-module-7.js", + "language/module-code/privatename-not-valid-earlyerr-module-8.js", + "language/module-code/private-identifiers-not-empty.js" + ] + }, + { + "reason": "Special unicode character that tsc can not recognize", + "files" : [ + "language/module-code/export-expname-binding-string.js", + "language/module-code/export-expname-from-binding-string.js", + "language/module-code/export-expname-from-star-string.js", + "language/module-code/export-expname-from-string-binding.js", + "language/module-code/export-expname-from-star.js", + "language/module-code/export-expname-from-string-string.js", + "language/module-code/export-expname-from-string.js", + "language/module-code/export-expname-import-string-binding.js" + ] + }, + { + "reason": "Not support Dynamic Import", + "files": [ + "language/module-code/verify-dfs.js" + ] + }, + { + "reason": "Unused node will be eliminated when tsc emiting in [after], So module won't get correct entries", + "files": [ + "language/module-code/instn-named-err-ambiguous.js", + "language/module-code/instn-named-err-ambiguous-as.js", + "language/module-code/instn-named-err-not-found.js", + "language/module-code/instn-named-err-not-found-as.js", + "language/module-code/instn-named-err-not-found-dflt.js", + "language/module-code/instn-named-err-dflt-thru-star-as.js", + "language/module-code/instn-named-err-dflt-thru-star-dflt.js", + "language/module-code/eval-rqstd-order.js" + ] + }, + { + "reason": "Not support further ecma-2015's feature in module code", + "files": [ + "language/module-code/namespace/internals/define-own-property.js", + "language/module-code/early-dup-export-as-star-as.js" + ] } ] diff --git a/ts2panda/scripts/diagnosticMessages.json b/ts2panda/scripts/diagnosticMessages.json index b4142d717dcbc994e804387a8ca6c6a0b4e5a635..6fa9df1efc8ae1b8350344eb258931d7cdca81a0 100755 --- a/ts2panda/scripts/diagnosticMessages.json +++ b/ts2panda/scripts/diagnosticMessages.json @@ -143,6 +143,10 @@ "category": "Error", "code": 1119 }, + "An export assignment cannot have modifiers.": { + "category": "Error", + "code": 1120 + }, "Octal literals are not allowed in strict mode.": { "category": "Error", "code": 1121 @@ -159,6 +163,10 @@ "category": "Error", "code": 1142 }, + "Cannot use imports, exports, or module augmentations when '--module' is 'none'.": { + "category": "Error", + "code": 1148 + }, "The 'const' declarations can only be declared inside a block.": { "category": "Error", "code": 1156 @@ -227,6 +235,14 @@ "category": "Error", "code": 1190 }, + "An import declaration cannot have modifiers.": { + "category": "Error", + "code": 1191 + }, + "An export declaration cannot have modifiers.": { + "category": "Error", + "code": 1193 + }, "Line terminator not permitted before arrow.": { "category": "Error", "code": 1200 @@ -243,6 +259,10 @@ "category": "Error", "code": 1210 }, + "A class or function declaration without the 'default' modifier must have a name.": { + "category": "Error", + "code": 1211 + }, "Identifier expected. '{0}' is a reserved word in strict mode.": { "category": "Error", "code": 1212 @@ -255,6 +275,10 @@ "category": "Error", "code": 1214 }, + "An export assignment must be at the top level of a file or module declaration.": { + "category": "Error", + "code": 1231 + }, "An import declaration can only be used in a namespace or module.": { "category": "Error", "code": 1232 @@ -339,6 +363,18 @@ "category": "Error", "code": 2300 }, + "Module '{0}' has no exported member '{1}'.": { + "category": "Error", + "code": 2305 + }, + "Module '{0}' has already exported a member named '{1}'.": { + "category": "Error", + "code": 2308 + }, + "An export assignment cannot be used in a module with other exported elements.": { + "category": "Error", + "code": 2309 + }, "The 'super' can only be referenced in a derived class.": { "category": "Error", "code": 2335 @@ -395,6 +431,10 @@ "category": "Error", "code": 2404 }, + "Import declaration conflicts with local declaration of '{0}'.": { + "category": "Error", + "code": 2440 + }, "The 'super' cannot be referenced in a computed property name.": { "category": "Error", "code": 2466 @@ -423,6 +463,10 @@ "category": "Error", "code": 2501 }, + "A module cannot have multiple default exports.": { + "category": "Error", + "code": 2528 + }, "The 'super' can only be referenced in members of derived classes or object literal expressions.": { "category": "Error", "code": 2660 @@ -512,8 +556,12 @@ "category": "Error", "code": 19009 }, - "Invalid regular expression flag '{0}'":{ + "Invalid regular expression flag '{0}'": { "category": "Error", "code": 19010 + }, + "Unexpected eval or arguments in strict mode": { + "category": "Error", + "code": 20000 } } \ No newline at end of file diff --git a/ts2panda/src/addVariable2Scope.ts b/ts2panda/src/addVariable2Scope.ts index 8d65f686c1b414aea8763f32e298db82c7ca911c..b966e6ccf7d2d08066b97c7c527608a35a20bf28 100644 --- a/ts2panda/src/addVariable2Scope.ts +++ b/ts2panda/src/addVariable2Scope.ts @@ -105,9 +105,9 @@ export function addVariableToScope(recorder: Recorder, enableTypeRecord: boolean hoistDecls.forEach(hoistDecl => { let v: Variable | undefined; if (hoistDecl instanceof VarDecl) { - v = scope.add(hoistDecl.name, VarDeclarationKind.VAR); + v = scope.add(hoistDecl, VarDeclarationKind.VAR); } else if (hoistDecl instanceof FuncDecl) { - v = scope.add(hoistDecl.name, VarDeclarationKind.FUNCTION); + v = scope.add(hoistDecl, VarDeclarationKind.FUNCTION); } else { throw new Error("Wrong type of declaration to be hoisted") } @@ -131,20 +131,20 @@ export function addVariableToScope(recorder: Recorder, enableTypeRecord: boolean } let v: Variable | undefined; if (decl instanceof LetDecl) { - v = scope.add(decl.name, VarDeclarationKind.LET, InitStatus.UNINITIALIZED); + v = scope.add(decl, VarDeclarationKind.LET, InitStatus.UNINITIALIZED); } else if (decl instanceof ConstDecl) { - v = scope.add(decl.name, VarDeclarationKind.CONST, InitStatus.UNINITIALIZED); + v = scope.add(decl, VarDeclarationKind.CONST, InitStatus.UNINITIALIZED); } else if (decl instanceof FuncDecl) { - v = scope.add(decl.name, VarDeclarationKind.FUNCTION); + v = scope.add(decl, VarDeclarationKind.FUNCTION); } else if (decl instanceof CatchParameter) { - v = scope.add(decl.name, VarDeclarationKind.LET); + v = scope.add(decl, VarDeclarationKind.LET); } else if (decl instanceof ClassDecl) { let classNode = decl.node; if (ts.isClassDeclaration(classNode)) { - v = scope.add(decl.name, VarDeclarationKind.CLASS, InitStatus.UNINITIALIZED); + v = scope.add(decl, VarDeclarationKind.CLASS, InitStatus.UNINITIALIZED); } else { let classScope = recorder.getScopeOfNode(classNode); - v = classScope.add(decl.name, VarDeclarationKind.CLASS, InitStatus.UNINITIALIZED); + v = classScope.add(decl, VarDeclarationKind.CLASS, InitStatus.UNINITIALIZED); } } else { /** diff --git a/ts2panda/src/base/bcGenUtil.ts b/ts2panda/src/base/bcGenUtil.ts index 3a841712106c3699266fe940552ce99ec81140c6..e27965fe8acdb05b24dffc9d276bfe00c31ce614 100644 --- a/ts2panda/src/base/bcGenUtil.ts +++ b/ts2panda/src/base/bcGenUtil.ts @@ -22,7 +22,6 @@ import { EcmaCallithisrangedyn, EcmaCloseiterator, EcmaCopydataproperties, - EcmaCopymodule, EcmaCreatearraywithbuffer, EcmaCreateemptyarray, EcmaCreateemptyobject, @@ -43,14 +42,14 @@ import { EcmaGetiteratornext, EcmaGetnextpropname, EcmaGetpropiterator, - EcmaImportmodule, + EcmaGetmodulenamespace, EcmaIsfalse, EcmaIstrue, EcmaLdglobalvar, EcmaLdhomeobject, EcmaLdlexenvdyn, EcmaLdlexvardyn, - EcmaLdmodvarbyname, + EcmaLdmodulevar, EcmaLdobjbyindex, EcmaLdobjbyname, EcmaLdobjbyvalue, @@ -370,20 +369,16 @@ export function ldSuperByValue(obj: VReg, prop: VReg): IRNode { return new EcmaLdsuperbyvalue(obj, prop); } -export function importModule(name: string) { - return new EcmaImportmodule(name); -} - -export function loadModuleVarByName(name: string, module: VReg) { - return new EcmaLdmodvarbyname(name, module); +export function loadModuleVariable(name: string, isLocal: number) { + return new EcmaLdmodulevar(name, new Imm(isLocal)); } export function storeModuleVariable(name: string) { return new EcmaStmodulevar(name); } -export function copyModuleIntoCurrentModule(mod: VReg) { - return new EcmaCopymodule(mod); +export function getModuleNamespace(localName: string) { + return new EcmaGetmodulenamespace(localName); } export function loadHomeObject() { diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index f13a1906b5d0661648a207229f6ed00289dee091..775d2df1437e0c2044697020041023450c8cfa23 100644 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -15,7 +15,6 @@ import * as path from "path"; import { extractCtorOfClass } from "../statement/classStatement"; -import { LocalVariable, Variable } from "../variable"; import * as ts from "typescript"; import { EcmaCallirangedyn, @@ -26,7 +25,6 @@ import { } from "../irnodes"; import * as jshelpers from "../jshelpers"; import { LOGD } from "../log"; -import { ModuleScope, Scope } from "../scope"; import { isFunctionLikeDeclaration } from "../syntaxCheckHelper"; export function containSpreadElement(args?: ts.NodeArray): boolean { @@ -69,16 +67,6 @@ export function hasDefaultKeywordModifier(node: ts.Node): boolean { return hasDefault; } -export function setVariableExported(varName: string, scope: Scope) { - if (!(scope instanceof ModuleScope)) { - throw new Error("variable can't be exported out of module scope"); - } - - let variable: { scope: Scope | undefined, level: number, v: Variable | undefined } = scope.find(varName); - (variable.v!).setExport(); - (variable.v!).setExportedName(varName); -} - export function execute(cmd: string, args: Array) { var spawn = require('child_process').spawn; @@ -304,4 +292,4 @@ export function setPos(node: ts.Node) { setPos(childNode); }); return node; -} \ No newline at end of file +} diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 39698348e9d70871b279c7fda20f703d789b2f20..c0aed04f32f2fb175c20995388fdc6cd066c60b9 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -27,10 +27,8 @@ import { AssignmentOperator } from "typescript"; import * as astutils from "./astutils"; import { LReference } from "./base/lreference"; import { - hasDefaultKeywordModifier, hasExportKeywordModifier, isBindingPattern, - setVariableExported } from "./base/util"; import { CacheList, getVregisterCache } from "./base/vregisterCache"; import { CmdOptions } from "./cmdOptions"; @@ -114,6 +112,7 @@ import { isAssignmentOperator } from "./syntaxCheckHelper"; import { GlobalVariable, LocalVariable, + ModuleVariable, VarDeclarationKind, Variable } from "./variable"; @@ -216,7 +215,7 @@ export class Compiler { }) this.pandaGen.setLocals(tempLocals); - this.pandaGen.setParametersCount(this.pandaGen.getParametersCount()-count); + this.pandaGen.setParametersCount(this.pandaGen.getParametersCount() - count); if (scope.getArgumentsOrRestargs()) { callType += CallMap.get("argumentsOrRestargs") ?? 0; @@ -527,18 +526,12 @@ export class Compiler { private compileVariableStatement(stmt: ts.VariableStatement) { let declList = stmt.declarationList; - let isExported: boolean = hasExportKeywordModifier(stmt); declList.declarations.forEach((decl) => { - this.compileVariableDeclaration(decl, isExported) + this.compileVariableDeclaration(decl) }); } - compileVariableDeclaration(decl: ts.VariableDeclaration, isExported: boolean = false) { - if (isExported) { - let name = jshelpers.getTextOfIdentifierOrLiteral(decl.name); - setVariableExported(name, this.getCurrentScope()); - } - + compileVariableDeclaration(decl: ts.VariableDeclaration) { let lref = LReference.generateLReference(this, decl.name, true); if (decl.initializer) { this.compileExpression(decl.initializer); @@ -552,7 +545,6 @@ export class Compiler { && decl.parent.kind != ts.SyntaxKind.CatchClause) { this.pandaGen.loadAccumulator(decl, getVregisterCache(this.pandaGen, CacheList.undefined)); } - } lref.setValue(); } @@ -707,26 +699,16 @@ export class Compiler { private compileFunctionDeclaration(decl: ts.FunctionDeclaration) { if (!decl.name) { - let hasExport: boolean = hasExportKeywordModifier(decl); - let hasDefault: boolean = hasDefaultKeywordModifier(decl); - if (hasExport && hasDefault) { - if (this.scope instanceof ModuleScope) { - let internalName = this.compilerDriver.getFuncInternalName(decl, this.recorder); - let env = this.getCurrentEnv(); - this.pandaGen.defineFunction(NodeKind.FirstNodeOfFunction, decl, internalName, env); - this.pandaGen.storeModuleVar(decl, "default"); - } else { - throw new Error("SyntaxError: export function declaration cannot in other scope except ModuleScope"); - } - } else { - throw new Error("Function declaration without name is unimplemented"); + if (hasExportKeywordModifier(decl) && this.scope instanceof ModuleScope) { + return; } + throw new Error("Function declaration without name is unimplemented"); } } private compileExportAssignment(stmt: ts.ExportAssignment) { this.compileExpression(stmt.expression); - this.pandaGen.storeModuleVar(stmt, "default"); + this.pandaGen.storeModuleVariable(stmt, "*default*"); } compileCondition(expr: ts.Expression, ifFalseLabel: Label) { @@ -1493,13 +1475,43 @@ export class Compiler { } else { this.pandaGen.storeGlobalVar(node, variable.v.getName()); } + } else if (variable.v instanceof ModuleVariable) { + // import module variable is const, throw `const assignment error` + if (!isDeclaration && variable.v.isConst()) { + let nameReg = this.pandaGen.getTemp(); + this.pandaGen.loadAccumulatorString(node, variable.v.getName()); + this.pandaGen.storeAccumulator(node, nameReg); + this.pandaGen.throwConstAssignment(node, nameReg); + this.pandaGen.freeTemps(nameReg); + return; + } + + if (isDeclaration) { + variable.v.initialize(); + } + + if ((variable.v.isLet() || variable.v.isClass()) && !variable.v.isInitialized()) { + let valueReg = this.pandaGen.getTemp(); + let holeReg = this.pandaGen.getTemp(); + let nameReg = this.pandaGen.getTemp(); + this.pandaGen.storeAccumulator(node, valueReg); + this.pandaGen.loadModuleVariable(node, variable.v.getName(), true); + this.pandaGen.storeAccumulator(node, holeReg); + this.pandaGen.loadAccumulatorString(node, variable.v.getName()); + this.pandaGen.storeAccumulator(node, nameReg); + this.pandaGen.throwUndefinedIfHole(node, holeReg, nameReg); + this.pandaGen.loadAccumulator(node, valueReg); + this.pandaGen.freeTemps(valueReg, holeReg, nameReg); + } + + this.pandaGen.storeModuleVariable(node, variable.v.getName()); } else { throw new Error("invalid lhsRef to store"); } } loadTarget(node: ts.Node, variable: { scope: Scope | undefined, level: number, v: Variable | undefined }) { - if (variable.v instanceof LocalVariable) { + if (variable.v instanceof LocalVariable) { if (variable.v.isLetOrConst() || variable.v.isClass()) { if (variable.scope instanceof GlobalScope) { this.pandaGen.tryLoadGlobalByName(node, variable.v.getName()); @@ -1536,6 +1548,19 @@ export class Compiler { } else { this.pandaGen.loadGlobalVar(node, variable.v.getName()); } + } else if (variable.v instanceof ModuleVariable) { + let isLocal: boolean = variable.v.isExportVar() ? true : false; + this.pandaGen.loadModuleVariable(node, variable.v.getName(), isLocal); + if ((variable.v.isLetOrConst() || variable.v.isClass()) && !variable.v.isInitialized()) { + let valueReg = this.pandaGen.getTemp(); + let nameReg = this.pandaGen.getTemp(); + this.pandaGen.storeAccumulator(node, valueReg); + this.pandaGen.loadAccumulatorString(node, variable.v.getName()); + this.pandaGen.storeAccumulator(node, nameReg); + this.pandaGen.throwUndefinedIfHole(node, valueReg, nameReg); + this.pandaGen.loadAccumulator(node, valueReg); + this.pandaGen.freeTemps(valueReg, nameReg); + } } else { // Handle the variables from lexical scope throw new Error("Only local and global variables are implemented"); diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 99d7568ac9b03301e99104e62e26370ce2cacfea..fc4f34063f119295d36cc1805dc2b375ccb042c3 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -17,7 +17,7 @@ import { writeFileSync } from "fs"; import * as ts from "typescript"; import { addVariableToScope } from "./addVariable2Scope"; import { AssemblyDumper } from "./assemblyDumper"; -import { initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe } from "./base/util"; +import { hasDefaultKeywordModifier, hasExportKeywordModifier, initiateTs2abc, listenChildExit, listenErrorEvent, terminateWritePipe } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { Compiler @@ -26,7 +26,7 @@ import { CompilerStatistics } from "./compilerStatistics"; import { DebugInfo } from "./debuginfo"; import { hoisting } from "./hoisting"; import { LOGD } from "./log"; -import { setExportBinding, setImport } from "./modules"; +import { setModuleNamespaceImports } from "./ecmaModule"; import { PandaGen } from "./pandagen"; import { Pass } from "./pass"; import { CacheExpander } from "./pass/cacheExpander"; @@ -40,10 +40,11 @@ import { VariableScope } from "./scope"; import { getClassNameForConstructor } from "./statement/classStatement"; -import { checkDuplicateDeclaration, checkExportEntries } from "./syntaxChecker"; +import { checkDuplicateDeclaration } from "./syntaxChecker"; import { Ts2Panda } from "./ts2panda"; import { TypeRecorder } from "./typeRecorder"; import { LiteralBuffer } from "./base/literal"; +import { findOuterNodeOfParenthesis } from "./expression/parenthesizedExpression"; export class PendingCompilationUnit { constructor( @@ -149,7 +150,6 @@ export class CompilerDriver { compileForSyntaxCheck(node: ts.SourceFile): void { let recorder = this.compilePrologue(node, false); checkDuplicateDeclaration(recorder); - checkExportEntries(recorder); } compile(node: ts.SourceFile): void { @@ -184,6 +184,7 @@ export class CompilerDriver { Ts2Panda.dumpStringsArray(ts2abcProc); Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpModuleRecords(ts2abcProc); terminateWritePipe(ts2abcProc); if (CmdOptions.isEnableDebugLog()) { @@ -219,13 +220,9 @@ export class CompilerDriver { let compiler = new Compiler(node, pandaGen, this, recorder); - if (CmdOptions.isModules() && ts.isSourceFile(node) && scope instanceof ModuleScope) { - setImport(recorder.getImportStmts(), scope, pandaGen); - setExportBinding(recorder.getExportStmts(), scope, pandaGen); - } - // because of para vreg, don't change hosting's position hoisting(node, pandaGen, recorder, compiler); + setModuleNamespaceImports(compiler, scope, pandaGen); compiler.compile(); this.passes.forEach((pass) => pass.run(pandaGen)); @@ -265,12 +262,8 @@ export class CompilerDriver { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); let compiler = new Compiler(node, pandaGen, this, recorder); - if (CmdOptions.isModules() && ts.isSourceFile(node) && scope instanceof ModuleScope) { - setImport(recorder.getImportStmts(), scope, pandaGen); - setExportBinding(recorder.getExportStmts(), scope, pandaGen); - } - hoisting(node, pandaGen, recorder, compiler); + setModuleNamespaceImports(compiler, scope, pandaGen); compiler.compile(); this.passes.forEach((pass) => pass.run(pandaGen)); @@ -301,8 +294,11 @@ export class CompilerDriver { } let recorder = new Recorder(node, topLevelScope, this, enableTypeRecord, CompilerDriver.isTsFile); recorder.record(); - + if (topLevelScope instanceof ModuleScope) { + topLevelScope.module().setModuleEnvironment(topLevelScope); + } addVariableToScope(recorder, enableTypeRecord); + let postOrderVariableScopes = this.postOrderAnalysis(topLevelScope); for (let variableScope of postOrderVariableScopes) { @@ -353,6 +349,10 @@ export class CompilerDriver { let funcNode = node; name = (recorder.getScopeOfNode(funcNode)).getFuncName(); if (name == '') { + if ((ts.isFunctionDeclaration(node) && hasExportKeywordModifier(node) && hasDefaultKeywordModifier(node)) + || ts.isExportAssignment(findOuterNodeOfParenthesis(node))) { + return 'default'; + } return `#${this.getFuncId(funcNode)}#`; } diff --git a/ts2panda/src/ecmaModule.ts b/ts2panda/src/ecmaModule.ts new file mode 100644 index 0000000000000000000000000000000000000000..dae40da02d08e5c7445fd0d62535eb3ccb343034 --- /dev/null +++ b/ts2panda/src/ecmaModule.ts @@ -0,0 +1,225 @@ +import * as ts from "typescript"; +import { PandaGen } from "./pandagen"; +import { DiagnosticCode, DiagnosticError } from "./diagnostic"; +import { ModuleScope, Scope } from "./scope"; +import { getSourceFileOfNode } from "./jshelpers"; +import { LReference } from "./base/lreference"; +import { Compiler } from "./compiler"; + +class Entry { + node: ts.Node; + exportName: string | undefined; + localName: string | undefined; + importName: string | undefined; + moduleRequest: number = -1; + + constructor(node: ts.Node, exportName: string | undefined, localName: string | undefined, importName: string | undefined, moduleRequest?: number) { + this.node = node; + this.exportName = exportName; + this.localName = localName; + this.importName = importName; + if (moduleRequest !== undefined) { + this.moduleRequest = moduleRequest; + } + } +} + +export class SourceTextModuleRecord { + private moduleName: string; + private moduleRequests: Array = []; + private moduleRequestIdxMap: Map = new Map(); + + private regularImportEntries: Map = new Map(); + private namespaceImportEntries: Array = []; + + private localExportEntries: Map> = new Map>(); + private starExportEntries: Array = []; + private indirectExportEntries: Array = []; + + constructor(moduleName: string) { + this.moduleName = moduleName; + } + + addModuleRequest(moduleRequest: string): number { + if (this.moduleRequestIdxMap.has(moduleRequest)) { + return this.moduleRequestIdxMap.get(moduleRequest)!; + } + let index = this.moduleRequests.length; + this.moduleRequests.push(moduleRequest); + this.moduleRequestIdxMap.set(moduleRequest, index); + return index; + } + + // import x from 'test.js'; + // import {x} from 'test.js'; + // import {x as y} from 'test.js'; + // import defaultExport from 'test.js' + addImportEntry(node: ts.Node, importName: string, localName: string, moduleRequest: string) { + let importEntry: Entry = new Entry(node, undefined, localName, importName, this.addModuleRequest(moduleRequest)); + // We don't care if there's already an entry for this local name, as in that + // case we will report an error when declaring the variable. + this.regularImportEntries.set(localName, importEntry); + } + + // import 'test.js' + // import {} from 'test.js' + // export {} from 'test.js' + addEmptyImportEntry(moduleRequest: string) { + this.addModuleRequest(moduleRequest); + } + + // import * as x from 'test.js'; + addStarImportEntry(node: ts.Node, localName: string, moduleRequest: string) { + let starImportEntry: Entry = new Entry(node, undefined, localName, undefined, this.addModuleRequest(moduleRequest)); + this.namespaceImportEntries.push(starImportEntry); + } + + // export {x}; + // export {x as y}; + // export VariableStatement + // export Declaration + // export default ... + addLocalExportEntry(node: ts.Node, exportName: string, localName: string) { + let localExportEntry: Entry = new Entry(node, exportName, localName, undefined); + if (this.localExportEntries.has(localName)) { + this.localExportEntries.get(localName)!.push(localExportEntry); + } else { + this.localExportEntries.set(localName, [localExportEntry]); + } + } + + // export {x} from 'test.js'; + // export {x as y} from 'test.js'; + // import { x } from 'test.js'; export { x } + addIndirectExportEntry(node: ts.Node, importName: string, exportName: string, moduleRequest: string) { + let indirectExportEntry: Entry = new Entry(node, exportName, undefined, importName, this.addModuleRequest(moduleRequest)); + this.indirectExportEntries.push(indirectExportEntry); + } + + // export * from 'test.js'; + addStarExportEntry(node: ts.Node, moduleRequest: string) { + let starExportEntry: Entry = new Entry(node, undefined, undefined, undefined, this.addModuleRequest(moduleRequest)); + this.starExportEntries.push(starExportEntry); + } + + getModuleName() { + return this.moduleName; + } + + getModuleRequests() { + return this.moduleRequests; + } + + getRegularImportEntries() { + return this.regularImportEntries; + } + + getNamespaceImportEntries() { + return this.namespaceImportEntries; + } + + getLocalExportEntries() { + return this.localExportEntries; + } + + getStarExportEntries() { + return this.starExportEntries; + } + + getIndirectExportEntries() { + return this.indirectExportEntries; + } + + makeIndirectExportsExplicit() { + // @ts-ignore + this.localExportEntries.forEach((entries: Array, localName: string) => { + for (let idx = 0; idx < entries.length;) { + let importEntry: Entry | undefined = this.regularImportEntries.get(entries[idx].localName!); + // get an indirect export entry + if (importEntry) { + entries[idx].importName = importEntry.importName; + entries[idx].moduleRequest = importEntry.moduleRequest; + entries[idx].localName = undefined; + + this.indirectExportEntries.push(entries[idx]); + entries.splice(idx, 1); + } else { + idx += 1; + } + } + }); + } + + nextDuplicateExportEntry(candidate: Entry, exportNameEntry: Map, currentCandidate: Entry | undefined) { + if (!exportNameEntry.has(candidate.exportName!)) { + exportNameEntry.set(candidate.exportName!, candidate); + return currentCandidate; + } + + if (currentCandidate === undefined) { + currentCandidate = candidate; + } + + return candidate.node.pos > currentCandidate.node.pos ? candidate : currentCandidate; + } + + searchDuplicateExport(): Entry | undefined { + let duplicateEntry: Entry | undefined; + let exportNameEntry: Map = new Map(); + + // @ts-ignore + this.localExportEntries.forEach((entries: Array, localName: string) => { + entries.forEach((e: Entry) => { + duplicateEntry = this.nextDuplicateExportEntry(e, exportNameEntry, duplicateEntry); + }); + }); + + this.indirectExportEntries.forEach((e: Entry) => { + duplicateEntry = this.nextDuplicateExportEntry(e, exportNameEntry, duplicateEntry); + }); + + return duplicateEntry; + } + + validateModuleRecordEntries(moduleScope: ModuleScope) { + // check module is well-formed and report errors if not + { + let dupExportEntry: Entry | undefined = this.searchDuplicateExport(); + if (dupExportEntry !== undefined) { + throw new DiagnosticError(dupExportEntry.node, DiagnosticCode.Module_0_has_already_exported_a_member_named_1, getSourceFileOfNode(dupExportEntry.node), [getSourceFileOfNode(dupExportEntry.node).fileName, dupExportEntry.exportName]); + } + } + + this.localExportEntries.forEach((entry: Array, localName: string) => { + if (!moduleScope.hasDecl(localName) && localName != '*default*') { + throw new DiagnosticError(entry[0].node, DiagnosticCode.Module_0_has_no_exported_member_1, getSourceFileOfNode(entry[0].node), [getSourceFileOfNode(entry[0].node).fileName, localName]); + } + }); + + this.makeIndirectExportsExplicit(); + } + + setExportedDecls(moduleScope: ModuleScope) { + // @ts-ignore + this.localExportEntries.forEach((entry: Array, localName: string) => { + moduleScope.setExportDecl(localName); + }) + } + + setModuleEnvironment(moduleScope: ModuleScope) { + this.validateModuleRecordEntries(moduleScope); + this.setExportedDecls(moduleScope); + } +} + +export function setModuleNamespaceImports(compiler: Compiler, moduleScope: Scope, pandagen: PandaGen) { + if (!(moduleScope instanceof ModuleScope)) { + return; + } + + moduleScope.module().getNamespaceImportEntries().forEach(entry => { + let namespace_lref = LReference.generateLReference(compiler, (entry.node).name, true); + pandagen.getModuleNamespace(entry.node, entry.localName!); + namespace_lref.setValue(); + }); +} \ No newline at end of file diff --git a/ts2panda/src/hoisting.ts b/ts2panda/src/hoisting.ts index c18cab39dc057896cf695d6ed7f4b1d3f92c6c6d..2ff281e88df7387a6ae55e7a98bf235d823ed7e6 100644 --- a/ts2panda/src/hoisting.ts +++ b/ts2panda/src/hoisting.ts @@ -14,7 +14,6 @@ */ import * as ts from "typescript"; -import { hasExportKeywordModifier, hasDefaultKeywordModifier } from "./base/util"; import { CacheList, getVregisterCache } from "./base/vregisterCache"; import { Compiler } from "./compiler"; import { CompilerDriver } from "./compilerDriver"; @@ -27,14 +26,14 @@ import { GlobalScope, LocalScope, ModuleScope, + ModuleVarKind, Scope, VarDecl, VariableScope } from "./scope"; -import { LocalVariable } from "./variable"; export function hoisting(rootNode: ts.SourceFile | ts.FunctionLikeDeclaration, pandaGen: PandaGen, - recorder: Recorder, compiler: Compiler) { + recorder: Recorder, compiler: Compiler) { let variableScope = recorder.getScopeOfNode(rootNode); let hoistDecls = recorder.getHoistDeclsOfScope(variableScope); @@ -59,7 +58,11 @@ export function hoistVar(decl: VarDecl, scope: Scope, pandaGen: PandaGen) { } else if (scope instanceof FunctionScope || scope instanceof ModuleScope) { let v = scope.findLocal(name)!; pandaGen.loadAccumulator(NodeKind.FirstNodeOfFunction, getVregisterCache(pandaGen, CacheList.undefined)); - pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + if (decl.isModule !== ModuleVarKind.NOT) { + pandaGen.storeModuleVariable(NodeKind.FirstNodeOfFunction, name); + } else { + pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + } } else { throw new Error("Wrong scope to hoist"); } @@ -74,19 +77,13 @@ export function hoistFunction(decl: FuncDecl, scope: Scope, pandaGen: PandaGen, pandaGen.defineFunction(NodeKind.FirstNodeOfFunction, decl.node, internalName, env); pandaGen.storeGlobalVar(NodeKind.FirstNodeOfFunction, funcName); } else if ((scope instanceof FunctionScope) || (scope instanceof LocalScope) || (scope instanceof ModuleScope)) { - let hasExport: boolean = hasExportKeywordModifier(decl.node); - let hasDefault: boolean = hasDefaultKeywordModifier(decl.node); let v = scope.findLocal(funcName)!; - if (hasExport && scope instanceof ModuleScope) { - (v).setExport(); - if (hasDefault) { - (v).setExportedName("default"); - } else { - (v).setExportedName(v.getName()); - } - } pandaGen.defineFunction(NodeKind.FirstNodeOfFunction, decl.node, internalName, env); - pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + if (decl.isModule !== ModuleVarKind.NOT) { + pandaGen.storeModuleVariable(NodeKind.FirstNodeOfFunction, funcName); + } else { + pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + } } else { throw new Error("Wrong scope to hoist"); } diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index af110c62a6819a1c124dec164273a2ea0073a9e7..0342f1b209652bcb479226de6035d6e1ab5dfd99 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -165,7 +165,8 @@ namespace Compiler { module: ts.ModuleKind.ES2015, strictNullChecks: true, skipLibCheck: true, - alwaysStrict: true + alwaysStrict: true, + importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve }; } } diff --git a/ts2panda/src/lexenv.ts b/ts2panda/src/lexenv.ts index e45d72cf0f300f255bd30151c4e87b4cf5e9b18a..bcc822013dc3b519af8219dafa335560f415172a 100644 --- a/ts2panda/src/lexenv.ts +++ b/ts2panda/src/lexenv.ts @@ -20,7 +20,6 @@ import { loadLexicalVar, storeAccumulator, storeLexicalVar, - storeModuleVariable, throwConstAssignment, throwUndefinedIfHole } from "./base/bcGenUtil"; @@ -108,7 +107,7 @@ export class VariableAccessLoad extends VariableAccessBase { insns.push(loadLexicalVar(this.level, slot)); // check TDZ - if (v.isLetOrConst()) { + if (v.isLetOrConst() || v.isClass()) { let tempReg = pandaGen.getTemp(); insns.push(storeAccumulator(tempReg)); @@ -166,10 +165,6 @@ export class VariableAcessStore extends VariableAccessBase { } insns.push(storeAccumulator(bindVreg)); - if (v.isExportVar()) { - insns.push(storeModuleVariable(v.getExportedName())); - } - return insns; } @@ -202,9 +197,7 @@ export class VariableAcessStore extends VariableAccessBase { insns.push(storeLexicalVar(this.level, slot, valueReg)); insns.push(loadAccumulator(valueReg)); - if (v.isExportVar()) { - insns.push(storeModuleVariable(v.getExportedName())); - } + pandaGen.freeTemps(valueReg); return insns; diff --git a/ts2panda/src/modules.ts b/ts2panda/src/modules.ts index 90113f6969b5757f7c59fd36a3e4555d88a18883..ddb83fa5f66b384e1b908eabbc7591be3c84a84d 100644 --- a/ts2panda/src/modules.ts +++ b/ts2panda/src/modules.ts @@ -13,12 +13,10 @@ * limitations under the License. */ +// [delete it when type system adapts for ESM] import * as ts from "typescript"; -import { PandaGen } from "./pandagen"; import * as jshelpers from "./jshelpers"; -import { LocalVariable } from "./variable"; import { DiagnosticCode, DiagnosticError } from "./diagnostic"; -import { ModuleScope } from "./scope"; export class ModuleStmt { private node: ts.Node @@ -76,63 +74,3 @@ export class ModuleStmt { return this.isCopy; } } - -export function setImport(importStmts: Array, moduleScope: ModuleScope, pandagen: PandaGen) { - importStmts.forEach((importStmt) => { - pandagen.importModule(importStmt.getNode(), importStmt.getModuleRequest()); - // import * as xxx from "a.js" - if (importStmt.getNameSpace()) { - let v = moduleScope.findLocal(importStmt.getNameSpace())!; - pandagen.storeAccToLexEnv(importStmt.getNode(), moduleScope, 0, v, true); - (v).initialize(); - } - - // import { ... } from "a.js" - // import defaultExport, * as a from "a.js" - let moduleReg = pandagen.allocLocalVreg(); - pandagen.storeAccumulator(importStmt.getNode(), moduleReg); - - let bindingNameMap = importStmt.getBindingNameMap(); - bindingNameMap.forEach((value: string, key: string) => { - let v = moduleScope.findLocal(key)!; - pandagen.loadModuleVariable(importStmt.getNode(), moduleReg, value); - pandagen.storeAccToLexEnv(importStmt.getNode(), moduleScope, 0, v, true); - (v).initialize(); - }); - }) -} - -export function setExportBinding(exportStmts: Array, moduleScope: ModuleScope, pandagen: PandaGen) { - exportStmts.forEach((exportStmt) => { - if (exportStmt.getModuleRequest()) { - pandagen.importModule(exportStmt.getNode(), exportStmt.getModuleRequest()); - let moduleReg = pandagen.allocLocalVreg(); - pandagen.storeAccumulator(exportStmt.getNode(), moduleReg); - - if (!exportStmt.getCopyFlag()) { - if (exportStmt.getNameSpace()) { - pandagen.storeModuleVar(exportStmt.getNode(), exportStmt.getNameSpace()); - } - - let bindingNameMap = exportStmt.getBindingNameMap(); - bindingNameMap.forEach((value: string, key: string) => { - pandagen.loadModuleVariable(exportStmt.getNode(), moduleReg, value); - pandagen.storeModuleVar(exportStmt.getNode(), key); - }); - } else { - pandagen.copyModule(exportStmt.getNode(), moduleReg); - } - } else { - let bindingNameMap = exportStmt.getBindingNameMap(); - bindingNameMap.forEach((value: string, key: string) => { - let v = moduleScope.findLocal(value); - if (typeof v == 'undefined') { - throw new DiagnosticError(exportStmt.getNode(), DiagnosticCode.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, jshelpers.getSourceFileOfNode(exportStmt.getNode()), [value]); - } - - (v).setExport(); - (v).setExportedName(key); - }); - } - }) -} \ No newline at end of file diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 8a098828cbc7f53e39789dcbfbcbb099bdfd3d3b..e32108b8940791bf159a70ec33b5ec4d0f8ec1b8 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -30,7 +30,6 @@ import { call, closeIterator, copyDataProperties, - copyModuleIntoCurrentModule, creatDebugger, createArrayWithBuffer, createEmptyArray, @@ -51,7 +50,7 @@ import { getIteratorNext, getNextPropName, getPropIterator, - importModule, + getModuleNamespace, isFalse, isTrue, jumpTarget, @@ -64,7 +63,7 @@ import { loadGlobalVar, loadHomeObject, loadLexicalVar, - loadModuleVarByName, + loadModuleVariable, loadObjByIndex, loadObjByName, loadObjByValue, @@ -92,6 +91,7 @@ import { stSuperByValue, superCall, superCallSpread, + throwConstAssignment, throwDeleteSuperProperty, throwException, throwIfNotObject, @@ -877,6 +877,10 @@ export class PandaGen { this.add(node, throwDeleteSuperProperty()); } + throwConstAssignment(node: ts.Node, nameReg: VReg) { + this.add(node, throwConstAssignment(nameReg)); + } + return(node: ts.Node | NodeKind) { this.add(node, new ReturnDyn()); } @@ -1083,20 +1087,16 @@ export class PandaGen { ) } - importModule(node: ts.Node, moduleName: string) { - this.add(node, importModule(moduleName)); - } - - loadModuleVariable(node: ts.Node, module: VReg, varName: string) { - this.add(node, loadModuleVarByName(varName, module)); + loadModuleVariable(node: ts.Node, moduleVarName: string, isLocal: boolean) { + this.add(node, loadModuleVariable(moduleVarName, isLocal ? 1 : 0)); } - storeModuleVar(node: ts.Node, moduleVarName: string) { + storeModuleVariable(node: ts.Node | NodeKind, moduleVarName: string) { this.add(node, storeModuleVariable(moduleVarName)); } - copyModule(node: ts.Node, module: VReg) { - this.add(node, copyModuleIntoCurrentModule(module)); + getModuleNamespace(node: ts.Node, localName: string) { + this.add(node, getModuleNamespace(localName)); } defineClassWithBuffer(node: ts.Node, name: string, idx: number, parameterLength: number, base: VReg) { diff --git a/ts2panda/src/pandasm.ts b/ts2panda/src/pandasm.ts index 3b1ecdfa8d60bce4139fcda2002afe7a06eaffad..9b368824b98dd6fd63bed8ce7a67e4d21a620a79 100644 --- a/ts2panda/src/pandasm.ts +++ b/ts2panda/src/pandasm.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; import { LiteralBuffer } from "./base/literal"; +import { DebugPosInfo, VariableDebugInfo } from "./debuginfo"; export class Metadata { public attribute: string; @@ -213,6 +213,60 @@ export class DeclaredSymbol2Type { } } +export class RegularImportEntry { + public localName: string; + public importName: string; + public moduleRequest: number; + + constructor(localName: string, importName: string, moduleRequest: number) { + this.localName = localName; + this.importName = importName; + this.moduleRequest = moduleRequest; + } +} + +export class NamespaceImportEntry { + public localName: string; + public moduleRequest: number; + + constructor(localName: string, moduleRequest: number) { + this.localName = localName; + this.moduleRequest = moduleRequest; + } +} + +export class LocalExportEntry { + public localName: string; + public exportName: string; + + constructor(localName: string, exportName: string) { + this.localName = localName; + this.exportName = exportName; + } +} + +export class IndirectExportEntry { + public exportName: string; + public importName: string; + public moduleRequest: number; + + constructor(exportName: string, importName: string, moduleRequest: number) { + this.exportName = exportName; + this.importName = importName; + this.moduleRequest = moduleRequest; + } +} + +export class ModuleRecord { + public moduleName: string = ""; + public moduleRequests: Array = []; + public regularImportEntries: Array = []; + public namespaceImportEntries: Array = []; + public localExportEntries: Array = []; + public indirectExportEntries: Array = []; + public starExportEntries: Array = []; +} + export interface Emmiter { generate_program: (filename: string, program: Program) => string; } diff --git a/ts2panda/src/recorder.ts b/ts2panda/src/recorder.ts index 61f5689708d8b3af9391ed165d823cddaa506cd7..6ca5732434a3ec7f37e10e472567b329e8ea1349 100644 --- a/ts2panda/src/recorder.ts +++ b/ts2panda/src/recorder.ts @@ -15,14 +15,18 @@ import * as ts from "typescript"; import * as astutils from "./astutils"; -import { isAnonymousFunctionDefinition } from "./base/util"; +import { + hasDefaultKeywordModifier, + hasExportKeywordModifier, + isAnonymousFunctionDefinition +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { CompilerDriver } from "./compilerDriver"; import { DiagnosticCode, DiagnosticError } from "./diagnostic"; import { findOuterNodeOfParenthesis } from "./expression/parenthesizedExpression"; import * as jshelpers from "./jshelpers"; import { LOGD } from "./log"; -import { ModuleStmt } from "./modules"; +import { ModuleStmt } from "./modules"; // [delete it when type system adapts for ESM] import { CatchParameter, ClassDecl, @@ -36,6 +40,7 @@ import { LocalScope, LoopScope, ModuleScope, + ModuleVarKind, Scope, VarDecl, VariableScope @@ -51,6 +56,7 @@ import { TypeChecker } from "./typeChecker"; import { VarDeclarationKind } from "./variable"; import { TypeRecorder } from "./typeRecorder"; import { PandaGen } from "./pandagen"; +import path from "path"; export class Recorder { node: ts.Node; @@ -62,10 +68,10 @@ export class Recorder { private parametersMap: Map = new Map(); private funcNameMap: Map; private class2Ctor: Map = new Map(); + private isTsFile: boolean; + // [delete it when type system adapts for ESM] private importStmts: Array = []; private exportStmts: Array = []; - private defaultUsed: boolean = false; - private isTsFile: boolean; constructor(node: ts.Node, scope: Scope, compilerDriver: CompilerDriver, recordType: boolean, isTsFile: boolean) { this.node = node; @@ -116,7 +122,7 @@ export class Recorder { private recordInfo(node: ts.Node, scope: Scope) { node.forEachChild(childNode => { if (!this.recordType) { - checkSyntaxError(childNode); + checkSyntaxError(childNode, scope); } switch (childNode.kind) { case ts.SyntaxKind.FunctionExpression: @@ -132,7 +138,17 @@ export class Recorder { } case ts.SyntaxKind.FunctionDeclaration: { let functionScope = this.buildVariableScope(scope, childNode); - this.recordFuncDecl(childNode, scope); + let isExport: boolean = false; + if (hasExportKeywordModifier(childNode)) { + if (!CmdOptions.isModules()) { + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); + } + this.recordEcmaExportInfo(childNode, scope); + isExport = true; + } + // recordFuncDecl must behind recordEcmaExportInfo() cause function without name + // should be SyntaxChecked in recordEcmaExportInfo + this.recordFuncDecl(childNode, scope, isExport); if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode); } @@ -161,9 +177,23 @@ export class Recorder { this.recordInfo(childNode, loopScope); break; } - case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassDeclaration: { + let isExport: boolean = false; + if (hasExportKeywordModifier(childNode)) { + if (!CmdOptions.isModules()) { + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); + } + this.recordEcmaExportInfo(childNode, scope); + isExport = true; + } + this.recordClassInfo(childNode, scope, isExport); + if (this.recordType) { + TypeChecker.getInstance().formatNodeType(childNode); + } + break; + } case ts.SyntaxKind.ClassExpression: { - this.recordClassInfo(childNode, scope); + this.recordClassInfo(childNode, scope, false); if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode); } @@ -181,12 +211,11 @@ export class Recorder { } case ts.SyntaxKind.ImportDeclaration: { if (!CmdOptions.isModules()) { - throw new DiagnosticError(childNode, DiagnosticCode.An_import_declaration_can_only_be_used_in_a_namespace_or_module, jshelpers.getSourceFileOfNode(childNode)); - } - if (!(scope instanceof ModuleScope)) { - throw new Error("SyntaxError: import statement cannot in other scope except ModuleScope"); + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); } - let importStmt = this.recordImportInfo(childNode, scope); + this.recordEcmaImportInfo(childNode, scope); + + let importStmt = this.recordImportInfo(childNode); // [delete it when type system adapts for ESM] if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode, importStmt); } @@ -194,22 +223,22 @@ export class Recorder { } case ts.SyntaxKind.ExportDeclaration: { if (!CmdOptions.isModules()) { - throw new DiagnosticError(childNode, DiagnosticCode.An_export_declaration_can_only_be_used_in_a_module, jshelpers.getSourceFileOfNode(childNode)); + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); } - if (!(scope instanceof ModuleScope)) { - throw new Error("SyntaxError: export statement cannot in other scope except ModuleScope"); - } - let exportStmt = this.recordExportInfo(childNode); + this.recordEcmaExportInfo(childNode, scope); + + let exportStmt = this.recordExportInfo(childNode); // [delete it when type system adapts for ESM] if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode, exportStmt); } break; } case ts.SyntaxKind.ExportAssignment: { - if (this.defaultUsed) { - throw new DiagnosticError(childNode, DiagnosticCode.Duplicate_identifier_0, jshelpers.getSourceFileOfNode(childNode), ["default"]); + if (!CmdOptions.isModules()) { + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); } - this.defaultUsed = true; + this.recordEcmaExportInfo(childNode, scope); + this.recordInfo(childNode, scope); if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode); @@ -217,6 +246,12 @@ export class Recorder { break; } case ts.SyntaxKind.VariableStatement: { + if (hasExportKeywordModifier(childNode)) { + if (!CmdOptions.isModules()) { + throw new DiagnosticError(childNode, DiagnosticCode.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none, jshelpers.getSourceFileOfNode(childNode)); + } + this.recordEcmaExportInfo(childNode, scope); + } if (this.recordType) { TypeChecker.getInstance().formatNodeType(childNode); } @@ -229,7 +264,7 @@ export class Recorder { }); } - private recordClassInfo(childNode: ts.ClassLikeDeclaration, scope: Scope) { + private recordClassInfo(childNode: ts.ClassLikeDeclaration, scope: Scope, isExport: boolean) { let localScope = new LocalScope(scope); this.setScopeMap(childNode, localScope); let ctor = extractCtorOfClass(childNode); @@ -240,8 +275,9 @@ export class Recorder { } if (childNode.name) { let name = jshelpers.getTextOfIdentifierOrLiteral(childNode.name); - let calssDecl = new ClassDecl(name, childNode); - scope.setDecls(calssDecl); + let moduleKind = isExport ? ModuleVarKind.EXPORTED : ModuleVarKind.NOT; + let classDecl = new ClassDecl(name, childNode, moduleKind); + scope.setDecls(classDecl); } this.recordInfo(childNode, localScope); } @@ -261,9 +297,13 @@ export class Recorder { if (parent) { let declKind = astutils.getVarDeclarationKind(parent); + let isExportDecl: boolean = false; + if ((parent).parent.parent.kind == ts.SyntaxKind.VariableStatement) { + isExportDecl = hasExportKeywordModifier((parent).parent.parent); + } // collect declaration information to corresponding scope - let decl = this.addVariableDeclToScope(scope, id, parent, name, declKind); + let decl = this.addVariableDeclToScope(scope, id, parent, name, declKind, isExportDecl); if (declKind == VarDeclarationKind.VAR) { let variableScopeParent = scope.getNearestVariableScope(); this.collectHoistDecls(id, variableScopeParent, decl); @@ -303,8 +343,10 @@ export class Recorder { } } - private addVariableDeclToScope(scope: Scope, node: ts.Node, parent: ts.Node, name: string, declKind: VarDeclarationKind): Decl { - let decl = new VarDecl(name, node); + private addVariableDeclToScope(scope: Scope, node: ts.Node, parent: ts.Node, name: string, declKind: VarDeclarationKind, isExportDecl: boolean): Decl { + let moduleKind = isExportDecl ? ModuleVarKind.EXPORTED : ModuleVarKind.NOT; + let decl = new VarDecl(name, node, moduleKind); + switch (declKind) { case VarDeclarationKind.VAR: break; @@ -312,11 +354,11 @@ export class Recorder { if (parent.parent.kind == ts.SyntaxKind.CatchClause) { decl = new CatchParameter(name, node); } else { - decl = new LetDecl(name, node); + decl = new LetDecl(name, node, moduleKind); } break; case VarDeclarationKind.CONST: - decl = new ConstDecl(name, node); + decl = new ConstDecl(name, node, moduleKind); break; default: throw new Error("Wrong type of declaration"); @@ -342,7 +384,8 @@ export class Recorder { } } - private recordImportInfo(node: ts.ImportDeclaration, scope: ModuleScope): ModuleStmt { + // [delete it when type system adapts for ESM] + private recordImportInfo(node: ts.ImportDeclaration): ModuleStmt { if (!ts.isStringLiteral(node.moduleSpecifier)) { throw new Error("moduleSpecifier must be a stringLiteral"); } @@ -359,7 +402,6 @@ export class Recorder { // import defaultExport from "a.js" if (importClause.name) { let name = jshelpers.getTextOfIdentifierOrLiteral(importClause.name); - scope.setDecls(new ConstDecl(name, importClause.name)); importStmt.addLocalName(name, "default"); importStmt.addNodeMap(importClause.name, importClause.name); } @@ -372,7 +414,6 @@ export class Recorder { // import * as a from "a.js" if (ts.isNamespaceImport(namedBindings)) { let nameSpace = jshelpers.getTextOfIdentifierOrLiteral((namedBindings).name); - scope.setDecls(new ConstDecl(nameSpace, namedBindings)); importStmt.setNameSpace(nameSpace); } @@ -381,7 +422,6 @@ export class Recorder { namedBindings.elements.forEach((element) => { let name: string = jshelpers.getTextOfIdentifierOrLiteral(element.name); let exoticName: string = element.propertyName ? jshelpers.getTextOfIdentifierOrLiteral(element.propertyName) : name; - scope.setDecls(new ConstDecl(name, element)); importStmt.addLocalName(name, exoticName); importStmt.addNodeMap(element.name, element.propertyName ? element.propertyName : element.name); }); @@ -393,6 +433,7 @@ export class Recorder { return importStmt; } + // [delete it when type system adapts for ESM] private recordExportInfo(node: ts.ExportDeclaration): ModuleStmt { let origNode = ts.getOriginalNode(node); let exportStmt: ModuleStmt; @@ -415,13 +456,6 @@ export class Recorder { if (ts.isNamedExports(namedBindings)) { namedBindings.elements.forEach((element) => { let name: string = jshelpers.getTextOfIdentifierOrLiteral(element.name); - if (name == 'default') { - if (this.defaultUsed) { - throw new DiagnosticError(origNode, DiagnosticCode.Duplicate_identifier_0, jshelpers.getSourceFileOfNode(origNode), [name]); - } else { - this.defaultUsed = true; - } - } let exoticName: string = element.propertyName ? jshelpers.getTextOfIdentifierOrLiteral(element.propertyName) : name; exportStmt.addLocalName(name, exoticName); exportStmt.addNodeMap(element.name, element.propertyName ? element.propertyName : element.name); @@ -432,16 +466,166 @@ export class Recorder { return exportStmt; } - private recordFuncDecl(node: ts.FunctionDeclaration, scope: Scope) { + private getNormalizeModuleSpecifier(moduleSpecifier: ts.Expression): string { + if (!ts.isStringLiteral(moduleSpecifier)) { + throw new Error("moduleSpecifier must be a stringLiteral"); + } + return path.normalize(jshelpers.getTextOfIdentifierOrLiteral(moduleSpecifier)); + } + + private recordEcmaNamedBindings(namedBindings: ts.NamedImportBindings, scope: ModuleScope, moduleRequest: string) { + // import * as a from "a.js" + if (ts.isNamespaceImport(namedBindings)) { + let nameSpace = jshelpers.getTextOfIdentifierOrLiteral((namedBindings).name); + scope.setDecls(new ConstDecl(nameSpace, namedBindings, ModuleVarKind.NOT)); + scope.module().addStarImportEntry(namedBindings, nameSpace, moduleRequest); + } else if (ts.isNamedImports(namedBindings)) { + if (namedBindings.elements.length == 0) { + // import {} from "a.js" + scope.module().addEmptyImportEntry(moduleRequest); + } + // import { ... } from "a.js" + namedBindings.elements.forEach((element: any) => { + let localName: string = jshelpers.getTextOfIdentifierOrLiteral(element.name); + let importName: string = element.propertyName ? jshelpers.getTextOfIdentifierOrLiteral(element.propertyName) : localName; + scope.setDecls(new ConstDecl(localName, element, ModuleVarKind.IMPORTED)); + scope.module().addImportEntry(element, importName, localName, moduleRequest); + }); + } else { + throw new Error("Unreachable kind for namedBindings"); + } + } + + private recordEcmaImportClause(importClause: ts.ImportClause, scope: ModuleScope, moduleRequest: string) { + // import defaultExport from "a.js" + if (importClause.name) { + let localName = jshelpers.getTextOfIdentifierOrLiteral(importClause.name); + scope.setDecls(new ConstDecl(localName, importClause.name, ModuleVarKind.IMPORTED)); + scope.module().addImportEntry(importClause, "default", localName, moduleRequest); + } + if (importClause.namedBindings) { + let namedBindings = importClause.namedBindings; + this.recordEcmaNamedBindings(namedBindings, scope, moduleRequest); + } + } + + private recordEcmaImportInfo(node: ts.ImportDeclaration, scope: Scope) { + if (!(scope instanceof ModuleScope)) { + return; + } + + let moduleRequest: string = this.getNormalizeModuleSpecifier(node.moduleSpecifier); + + if (node.importClause) { + let importClause: ts.ImportClause = node.importClause; + this.recordEcmaImportClause(importClause, scope, moduleRequest); + } else { + // import "a.js" + scope.module().addEmptyImportEntry(moduleRequest); + } + } + + private recordEcmaExportDecl(node: ts.ExportDeclaration, scope: ModuleScope) { + if (node.moduleSpecifier) { + let moduleRequest: string = this.getNormalizeModuleSpecifier(node.moduleSpecifier); + + if (node.exportClause) { + let namedBindings: ts.NamedExportBindings = node.exportClause; + if (ts.isNamespaceExport(namedBindings)) { + // export * as m from "mod"; + // `export namespace` is not the ECMA2018's feature + } else if (ts.isNamedExports(namedBindings)) { + if (namedBindings.elements.length == 0) { + // export {} from "mod"; + scope.module().addEmptyImportEntry(moduleRequest); + } + // export {x} from "mod"; + // export {v as x} from "mod"; + namedBindings.elements.forEach((element: any) => { + let exportName: string = jshelpers.getTextOfIdentifierOrLiteral(element.name); + let importName: string = element.propertyName ? jshelpers.getTextOfIdentifierOrLiteral(element.propertyName) : exportName; + scope.module().addIndirectExportEntry(element, importName, exportName, moduleRequest); + }); + } + } else { + // export * from "mod"; + scope.module().addStarExportEntry(node, moduleRequest); + } + } else if (node.exportClause && ts.isNamedExports(node.exportClause)) { + // export {x}; + // export {v as x}; + node.exportClause.elements.forEach((element: any) => { + let exportName: string = jshelpers.getTextOfIdentifierOrLiteral(element.name); + let localName: string = element.propertyName ? jshelpers.getTextOfIdentifierOrLiteral(element.propertyName) : exportName; + scope.module().addLocalExportEntry(element, exportName, localName); + }); + } else { + throw new Error("Unreachable node kind for Export Declaration"); + } + } + + private recordEcmaExportInfo(node: ts.ExportDeclaration | ts.ExportAssignment | ts.VariableStatement | ts.FunctionDeclaration | ts.ClassDeclaration, scope: Scope) { + if (!(scope instanceof ModuleScope)) { + return; + } + + switch (node.kind) { + case ts.SyntaxKind.ExportDeclaration: { + this.recordEcmaExportDecl(node, scope); + break; + } + case ts.SyntaxKind.ExportAssignment: { + // export default 42; + // export default v; + // "*default*" is used within this specification as a synthetic name for anonymous default export values. + scope.module().addLocalExportEntry(node, "default", "*default*"); + break; + } + case ts.SyntaxKind.VariableStatement: { + // export var a,b; + node.declarationList.declarations.forEach(decl => { + let name = jshelpers.getTextOfIdentifierOrLiteral(decl.name); + scope.module().addLocalExportEntry(decl, name, name); + }); + break; + } + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.ClassDeclaration: { + if (hasDefaultKeywordModifier(node)) { + // HoistableDeclaration : FunctionDecl/GeneratorDecl/AsyncFunctionDecl/AsyncGeneratorDecl + // export default function f(){} + // export default function(){} + // export default class{} + let localName = node.name ? jshelpers.getTextOfIdentifierOrLiteral(node.name) : "*default*"; + scope.module().addLocalExportEntry(node, "default", localName); + } else { + // export function f(){} + // export class c{} + if (!node.name) { + throw new DiagnosticError(node, DiagnosticCode.A_class_or_function_declaration_without_the_default_modifier_must_have_a_name, jshelpers.getSourceFileOfNode(node)); + } + let name = jshelpers.getTextOfIdentifierOrLiteral(node.name!); + scope.module().addLocalExportEntry(node, name, name); + } + break; + } + default: + throw new Error("Unreachable syntax kind for static exporting"); + } + } + + private recordFuncDecl(node: ts.FunctionDeclaration, scope: Scope, isExport: boolean) { this.recordFuncInfo(node); let funcId = (node).name; - if (!funcId) { - // function declaration without name doesn't need to record hoisting. + if (!funcId && !isExport) { + // unexported function declaration without name doesn't need to record hoisting. return; } - let funcName = jshelpers.getTextOfIdentifierOrLiteral(funcId); - let funcDecl = new FuncDecl(funcName, node); + // if function without name must has modifiers of 'export' & 'default' + let funcName = funcId ? jshelpers.getTextOfIdentifierOrLiteral(funcId) : '*default*'; + let moduleKind = isExport ? ModuleVarKind.EXPORTED : ModuleVarKind.NOT; + let funcDecl = new FuncDecl(funcName, node, moduleKind); scope.setDecls(funcDecl); let hoistScope = scope; if (scope instanceof GlobalScope || scope instanceof ModuleScope) { @@ -603,14 +787,6 @@ export class Recorder { return this.scopeMap.get(node); } - getImportStmts() { - return this.importStmts; - } - - getExportStmts() { - return this.exportStmts; - } - setHoistMap(scope: VariableScope, decl: Decl) { if (!this.hoistMap.has(scope)) { this.hoistMap.set(scope, [decl]); @@ -648,4 +824,4 @@ export class Recorder { getFuncNameMap() { return this.funcNameMap; } -} \ No newline at end of file +} diff --git a/ts2panda/src/scope.ts b/ts2panda/src/scope.ts index 52cf3bbcdeb515cda66c02f7a9ee582524e12338..92f7f8dac2a3dc98d1fca16947db9e8590a051e0 100644 --- a/ts2panda/src/scope.ts +++ b/ts2panda/src/scope.ts @@ -14,10 +14,12 @@ */ import * as ts from "typescript"; +import { SourceTextModuleRecord } from "./ecmaModule"; import { LOGD, LOGE } from "./log"; import { GlobalVariable, LocalVariable, + ModuleVariable, VarDeclarationKind, Variable } from "./variable"; @@ -26,61 +28,66 @@ export enum InitStatus { INITIALIZED, UNINITIALIZED } +export enum ModuleVarKind { + IMPORTED, EXPORTED, NOT +} + export abstract class Decl { name: string; node: ts.Node; - constructor(name: string, node: ts.Node) { + isModule: ModuleVarKind; + + constructor(name: string, node: ts.Node, isModule: ModuleVarKind) { this.name = name; this.node = node; + this.isModule = isModule; } } export class VarDecl extends Decl { - constructor(varName: string, node: ts.Node) { - super(varName, node); + constructor(varName: string, node: ts.Node, isModule: ModuleVarKind) { + super(varName, node, isModule); } } export class LetDecl extends Decl { - constructor(letName: string, node: ts.Node) { - super(letName, node); + constructor(letName: string, node: ts.Node, isModule: ModuleVarKind) { + super(letName, node, isModule); } } export class ConstDecl extends Decl { - constructor(constName: string, node: ts.Node) { - super(constName, node); + constructor(constName: string, node: ts.Node, isModule: ModuleVarKind) { + super(constName, node, isModule); } } export class FuncDecl extends Decl { - constructor(funcName: string, node: ts.Node) { - super(funcName, node); + constructor(funcName: string, node: ts.Node, isModule: ModuleVarKind) { + super(funcName, node, isModule); } } export class ClassDecl extends Decl { - constructor(className: string, node: ts.Node) { - super(className, node); + constructor(className: string, node: ts.Node, isModule: ModuleVarKind) { + super(className, node, isModule); } } export class CatchParameter extends Decl { - constructor(CpName: string, node: ts.Node) { - super(CpName, node); + constructor(CpName: string, node: ts.Node, isModule: ModuleVarKind = ModuleVarKind.NOT) { + super(CpName, node, isModule); } } export class FunctionParameter extends Decl { - constructor(FpName: string, node: ts.Node) { - super(FpName, node); + constructor(FpName: string, node: ts.Node, isModule: ModuleVarKind = ModuleVarKind.NOT) { + super(FpName, node, isModule); } } export abstract class Scope { protected debugTag = "scope"; - protected globals: Variable[] = []; - protected locals: Variable[] = []; protected name2variable: Map = new Map(); protected decls: Decl[] = []; protected parent: Scope | undefined = undefined; @@ -92,7 +99,7 @@ export abstract class Scope { constructor() { } - abstract add(name: string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined; + abstract add(decl: Decl | string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined; getName2variable(): Map { return this.name2variable; @@ -388,15 +395,14 @@ export class GlobalScope extends VariableScope { this.node = node ? node : undefined; } - add(name: string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + add(decl: Decl | string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + let name = decl instanceof Decl ? decl.name : decl; LOGD(this.debugTag, "globalscope.add (" + name + "), kind:" + declKind); let v: Variable | undefined; if (declKind == VarDeclarationKind.NONE || declKind == VarDeclarationKind.VAR || declKind == VarDeclarationKind.FUNCTION) { v = new GlobalVariable(declKind, name); - this.globals.push(v); } else { v = new LocalVariable(declKind, name, status); - this.locals.push(v); } this.name2variable.set(name, v); return v; @@ -404,24 +410,45 @@ export class GlobalScope extends VariableScope { } export class ModuleScope extends VariableScope { - constructor(node?: ts.SourceFile | ts.ModuleBlock) { + private moduleRecord: SourceTextModuleRecord; + + constructor(node: ts.SourceFile) { super(); - this.node = node ? node : undefined; + this.node = node; + this.moduleRecord = new SourceTextModuleRecord(node.fileName); + } + + setExportDecl(exportedLocalName: string) { + let decl = this.getDecl(exportedLocalName); + if (decl) { + decl.isModule = ModuleVarKind.EXPORTED; + } + } + + module() { + return this.moduleRecord; } - add(name: string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + add(decl: Decl | string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + let [name, isModule] = decl instanceof Decl ? [decl.name, decl.isModule] : [decl, ModuleVarKind.NOT]; LOGD(this.debugTag, "modulescope.add (" + name + "), kind:" + declKind); let v: Variable | undefined; - if (declKind == VarDeclarationKind.NONE) { - v = new GlobalVariable(declKind, name); - this.globals.push(v); - } else if (declKind == VarDeclarationKind.VAR || declKind == VarDeclarationKind.FUNCTION) { - v = new LocalVariable(declKind, name); - this.locals.push(v); + + if (isModule !== ModuleVarKind.NOT) { + v = new ModuleVariable(declKind, name, InitStatus.UNINITIALIZED); + if (isModule == ModuleVarKind.EXPORTED) { + (v).setExport(); + } } else { - v = new LocalVariable(declKind, name, status); - this.locals.push(v); + if (declKind === VarDeclarationKind.NONE) { + v = new GlobalVariable(declKind, name); + } else if (declKind == VarDeclarationKind.VAR || declKind == VarDeclarationKind.FUNCTION) { + v = new LocalVariable(declKind, name); + } else { + v = new LocalVariable(declKind, name, status); + } } + this.name2variable.set(name, v); return v; } @@ -456,7 +483,8 @@ export class FunctionScope extends VariableScope { return this.parent; } - add(name: string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + add(decl: Decl | string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + let name = decl instanceof Decl ? decl.name : decl; let v: Variable | undefined; LOGD(this.debugTag, "functionscope.add (" + name + "), kind:" + declKind); @@ -464,7 +492,7 @@ export class FunctionScope extends VariableScope { // the variable declared without anything should be global // See EcmaStandard: 13.3.2 Variable Statement let globalScope = this.getRootScope(); - if (globalScope instanceof GlobalScope || globalScope instanceof ModuleScope) { + if (globalScope instanceof GlobalScope) { v = globalScope.add(name, declKind); } else { v = undefined; @@ -472,11 +500,9 @@ export class FunctionScope extends VariableScope { } } else if (declKind == VarDeclarationKind.VAR || declKind == VarDeclarationKind.FUNCTION) { v = new LocalVariable(declKind, name); - this.locals.push(v); this.name2variable.set(name, v); } else { v = new LocalVariable(declKind, name, status); - this.locals.push(v); this.name2variable.set(name, v); } return v; @@ -495,14 +521,15 @@ export class LocalScope extends Scope { } - add(name: string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + add(decl: Decl | string, declKind: VarDeclarationKind, status?: InitStatus): Variable | undefined { + let name = decl instanceof Decl ? decl.name : decl; let v: Variable | undefined; LOGD(this.debugTag, "localscope.add (" + name + "), kind:" + declKind); if (declKind == VarDeclarationKind.NONE) { let root = this.getRootScope(); - if (root instanceof GlobalScope || root instanceof ModuleScope) { + if (root instanceof GlobalScope) { return root.add(name, declKind, status); } else { LOGE(undefined, "Error: the root of this scope is not global scope, it is wrong"); @@ -518,7 +545,6 @@ export class LocalScope extends Scope { v = functionScope!.add(name, declKind); } else { v = new LocalVariable(declKind, name, status); - this.locals.push(v); this.name2variable.set(name, v); } diff --git a/ts2panda/src/statement/classStatement.ts b/ts2panda/src/statement/classStatement.ts index 880f4a5f6439912b09efb1f636363e4f9ed8bc00..6e977d831a4b9ff49ee7903d21cd773c6a88a704 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -23,7 +23,13 @@ import { propertyKeyAsString, PropertyKind } from "../base/properties"; -import { getParameterLength4Ctor, getParamLengthOfFunc, isUndefinedIdentifier } from "../base/util"; +import { + getParameterLength4Ctor, + getParamLengthOfFunc, + hasDefaultKeywordModifier, + hasExportKeywordModifier, + isUndefinedIdentifier +} from "../base/util"; import { CacheList, getVregisterCache } from "../base/vregisterCache"; import { Compiler } from "../compiler"; import { createArrayFromElements } from "../expression/arrayLiteralExpression"; @@ -42,7 +48,7 @@ import { Scope, VariableScope } from "../scope"; -import { LocalVariable, Variable } from "../variable"; +import { LocalVariable, ModuleVariable, Variable } from "../variable"; export function compileClassDeclaration(compiler: Compiler, stmt: ts.ClassLikeDeclaration) { compiler.pushScope(stmt); @@ -112,15 +118,30 @@ export function compileClassDeclaration(compiler: Compiler, stmt: ts.ClassLikeDe compileUnCompiledProperty(compiler, properties, classReg); pandaGen.loadAccumulator(stmt, classReg); - if (stmt.name) { - let className = jshelpers.getTextOfIdentifierOrLiteral(stmt.name); - let classScope = compiler.getRecorder().getScopeOfNode(stmt); - if (!ts.isClassExpression(stmt) && classScope.getParent() instanceof GlobalScope) { - pandaGen.stClassToGlobalRecord(stmt, className); - } else { + let classScope = compiler.getRecorder().getScopeOfNode(stmt); + if (hasExportKeywordModifier(stmt)) { + if (stmt.name) { + let className = jshelpers.getTextOfIdentifierOrLiteral(stmt.name); let classInfo = classScope.find(className); - (classInfo.v).initialize(); - pandaGen.storeAccToLexEnv(stmt, classInfo.scope!, classInfo.level, classInfo.v!, true); + (classInfo.v).initialize(); + pandaGen.storeModuleVariable(stmt, className); + } else if (hasDefaultKeywordModifier(stmt)) { + pandaGen.storeModuleVariable(stmt, "*default*"); + } else { + // throw SyntaxError in Recorder + } + } else { + if (stmt.name) { + let className = jshelpers.getTextOfIdentifierOrLiteral(stmt.name); + if (!ts.isClassExpression(stmt) && classScope.getParent() instanceof GlobalScope) { + pandaGen.stClassToGlobalRecord(stmt, className); + } else { + let classInfo = classScope.find(className); + (classInfo.v).initialize(); + pandaGen.storeAccToLexEnv(stmt, classInfo.scope!, classInfo.level, classInfo.v!, true); + } + } else { + // throw SyntaxError in SyntaxChecker } } @@ -497,6 +518,10 @@ export function getClassNameForConstructor(classNode: ts.ClassLikeDeclaration) { if (!isAnonymousClass(classNode)) { className = jshelpers.getTextOfIdentifierOrLiteral(classNode.name!); } else { + if (ts.isClassDeclaration(classNode) && hasExportKeywordModifier(classNode) && hasDefaultKeywordModifier(classNode)) { + return 'default'; + } + let outerNode = findOuterNodeOfParenthesis(classNode); if (ts.isVariableDeclaration(outerNode)) { @@ -514,6 +539,8 @@ export function getClassNameForConstructor(classNode: ts.ClassLikeDeclaration) { if (ts.isIdentifier(propName) || ts.isStringLiteral(propName) || ts.isNumericLiteral(propName)) { className = jshelpers.getTextOfIdentifierOrLiteral(propName); } + } else if (ts.isExportAssignment(outerNode)) { + className = 'default'; } } diff --git a/ts2panda/src/syntaxChecker.ts b/ts2panda/src/syntaxChecker.ts index b8eadcc202713f4e7dfc49d35e3b25debb177da4..e7311cf8eee7c15d3db1a73ea71be67f2e1402ef 100644 --- a/ts2panda/src/syntaxChecker.ts +++ b/ts2panda/src/syntaxChecker.ts @@ -144,6 +144,7 @@ function hasDuplicateEntryInScope(decl1: Decl, decl2: Decl, scope: Scope) { return decl1.name == decl2.name; } // Var and FunctionDeclaration with same names, FunctionDeclaration and FunctionDeclaration with same names are illegal in strict mode + // and Module /** * eg1. * if (true) { @@ -156,15 +157,16 @@ function hasDuplicateEntryInScope(decl1: Decl, decl2: Decl, scope: Scope) { * function a() {}; * function a() {}; * } + * eg3. [module] + * var a; + * function a(){}; */ - if (scope instanceof LocalScope) { - if (isStrictMode(decl1.node)) { - if (decl1 instanceof FuncDecl || decl2 instanceof FuncDecl) { - if (isFunctionLikeDeclaration(decl1.node.parent.parent) || isFunctionLikeDeclaration(decl2.node.parent.parent)) { - return false; - } - return decl1.name == decl2.name; + if (scope instanceof LocalScope && isStrictMode(decl1.node) || scope instanceof ModuleScope) { + if (decl1 instanceof FuncDecl || decl2 instanceof FuncDecl) { + if (isFunctionLikeDeclaration(decl1.node.parent.parent) || isFunctionLikeDeclaration(decl2.node.parent.parent)) { + return false; } + return decl1.name == decl2.name; } } @@ -266,10 +268,10 @@ function throwDupIdError(decl: Decl) { } //**********************************Part 2: Implementing syntax check except declaration******************************************// -export function checkSyntaxError(node: ts.Node) { +export function checkSyntaxError(node: ts.Node, scope:Scope) { checkSyntaxErrorForSloppyAndStrictMode(node); if (isStrictMode(node) || CmdOptions.isModules()) { - checkSyntaxErrorForStrictMode(node); + checkSyntaxErrorForStrictMode(node, scope); } } @@ -1422,19 +1424,3 @@ function checkBindingPattern(node: ts.BindingPattern) { } } } - -export function checkExportEntries(recorder: Recorder) { - let exportStmts = recorder.getExportStmts(); - let exportNames: Set = new Set(); - exportStmts.forEach(exportStmt => { - let bindingNameMap = exportStmt.getBindingNameMap(); - // @ts-ignore - bindingNameMap.forEach((value: string, key: string) => { - if (!exportNames.has(key)) { - exportNames.add(key); - } else { - throw new DiagnosticError(exportStmt.getNode(), DiagnosticCode.Duplicate_identifier_0, jshelpers.getSourceFileOfNode(exportStmt.getNode()), [key]); - } - }) - }) -} \ No newline at end of file diff --git a/ts2panda/src/syntaxCheckerForStrcitMode.ts b/ts2panda/src/syntaxCheckerForStrcitMode.ts index c251b517f4c49e031ab02b406377163cefdaa98c..2b35fc1d154d65457477f4be45338b4d42c662a5 100644 --- a/ts2panda/src/syntaxCheckerForStrcitMode.ts +++ b/ts2panda/src/syntaxCheckerForStrcitMode.ts @@ -14,10 +14,12 @@ */ import * as ts from "typescript"; +import { hasDefaultKeywordModifier, hasExportKeywordModifier } from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { DiagnosticCode, DiagnosticError } from "./diagnostic"; import { findInnerExprOfParenthesis } from "./expression/parenthesizedExpression"; import * as jshelpers from "./jshelpers"; +import { ModuleScope, Scope } from "./scope"; import { checkStrictModeStatementList } from "./strictMode"; import { isAssignmentOperator, @@ -171,7 +173,6 @@ function checkNoSubstitutionTemplateLiteral(expr: ts.NoSubstitutionTemplateLiter } function checkFunctionDeclaration(node: ts.FunctionDeclaration) { - checkEvalOrArgumentsOrOriginalKeyword(node, node.name); checkParameters(node); if (!isInBlockScope(node.parent!)) { @@ -179,7 +180,57 @@ function checkFunctionDeclaration(node: ts.FunctionDeclaration) { } } -export function checkSyntaxErrorForStrictMode(node: ts.Node) { +function checkClassDeclaration(node: ts.ClassDeclaration) { + if (!hasExportKeywordModifier(node) && !node.name) { + if (!node.name && !hasDefaultKeywordModifier(node)) { + throw new DiagnosticError(node, DiagnosticCode.Identifier_expected); + } + } +} + +function checkImportDeclaration(node: ts.ImportDeclaration, scope: Scope) { + if (!(scope instanceof ModuleScope)) { + throw new DiagnosticError(node, DiagnosticCode.An_import_declaration_can_only_be_used_in_a_namespace_or_module); + } + + if (node.modifiers) { + throw new DiagnosticError(node, DiagnosticCode.An_import_declaration_cannot_have_modifiers); + } + + if (node.importClause && node.importClause.namedBindings) { + let namedBindings = node.importClause.namedBindings; + if (ts.isNamedImports(namedBindings)) { + namedBindings.elements.forEach((element: any) => { + if (jshelpers.getTextOfIdentifierOrLiteral(element.name) == 'arguments' + || jshelpers.getTextOfIdentifierOrLiteral(element.name) == 'eval') { + throw new DiagnosticError(node, DiagnosticCode.Unexpected_eval_or_arguments_in_strict_mode); + } + }); + } + } +} + +function checkExportAssignment(node: ts.ExportAssignment, scope: Scope) { + if (!(scope instanceof ModuleScope)) { + throw new DiagnosticError(node, DiagnosticCode.An_export_assignment_must_be_at_the_top_level_of_a_file_or_module_declaration); + } + + if (node.modifiers) { + throw new DiagnosticError(node, DiagnosticCode.An_export_assignment_cannot_have_modifiers); + } +} + +function checkExportDeclaration(node: ts.ExportDeclaration, scope: Scope) { + if (!(scope instanceof ModuleScope)) { + throw new DiagnosticError(node, DiagnosticCode.An_export_declaration_can_only_be_used_in_a_module); + } + + if (node.modifiers) { + throw new DiagnosticError(node, DiagnosticCode.An_export_declaration_cannot_have_modifiers); + } +} + +export function checkSyntaxErrorForStrictMode(node: ts.Node, scope: Scope) { switch (node.kind) { case ts.SyntaxKind.NumericLiteral: checkNumericLiteral(node); @@ -199,6 +250,9 @@ export function checkSyntaxErrorForStrictMode(node: ts.Node) { case ts.SyntaxKind.ArrowFunction: checkParameters(node); break; + case ts.SyntaxKind.ClassDeclaration: + checkClassDeclaration(node); + break; case ts.SyntaxKind.VariableDeclaration: let varNode = node; checkEvalOrArgumentsOrOriginalKeyword(varNode, varNode.name); @@ -229,7 +283,16 @@ export function checkSyntaxErrorForStrictMode(node: ts.Node) { case ts.SyntaxKind.LastLiteralToken: checkNoSubstitutionTemplateLiteral(node); break; + case ts.SyntaxKind.ImportDeclaration: + checkImportDeclaration(node, scope); + break; + case ts.SyntaxKind.ExportAssignment: + checkExportAssignment(node, scope); + break; + case ts.SyntaxKind.ExportDeclaration: + checkExportDeclaration(node, scope); + break; default: break; } -} \ No newline at end of file +} diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index dd1555e4fd94d6d7e9df8e068f977bf54fd2930d..660637b88cc479cb8015db8d0cd6d94776892c8b 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -14,6 +14,7 @@ */ import { CmdOptions } from "./cmdOptions"; +import { SourceTextModuleRecord } from "./ecmaModule"; import { Imm, IRNode, @@ -30,6 +31,11 @@ import { ExportedSymbol2Type, Function, Ins, + IndirectExportEntry, + LocalExportEntry, + ModuleRecord, + NamespaceImportEntry, + RegularImportEntry, Signature } from "./pandasm"; import { generateCatchTables } from "./statement/tryStatement"; @@ -40,6 +46,7 @@ import { } from "./base/util"; import { LiteralBuffer } from "./base/literal"; import { CompilerDriver } from "./compilerDriver"; +import { ModuleScope } from "./scope"; const dollarSign: RegExp = /\$/g; @@ -48,13 +55,14 @@ const JsonType = { "record": 1, "string": 2, "literal_arr": 3, - "options": 4, - "type_arr": 5 + "module": 4, + "options": 5 }; export class Ts2Panda { static strings: Set = new Set(); static labelPrefix = "L_"; static jsonString: string = ""; + static moduleRecordlist: Array = []; constructor() { } @@ -234,6 +242,12 @@ export class Ts2Panda { } } + if (pg.getScope() instanceof ModuleScope) { + Ts2Panda.moduleRecordlist.push( + makeModuleRecord((pg.getScope()).module()) + ); + } + let variables, sourceCode; if (CmdOptions.isDebugMode()) { variables = pg.getVariableDebugInfoArray(); @@ -292,8 +306,55 @@ export class Ts2Panda { ts2abc.stdio[3].write(jsonFuncUnicode + '\n'); } + static dumpModuleRecords(ts2abc: any): void { + Ts2Panda.moduleRecordlist.forEach(function(module){ + let moduleObject = { + "t": JsonType.module, + "mod": module + }; + let jsonModuleUnicode = escapeUnicode(JSON.stringify(moduleObject, null, 2)); + jsonModuleUnicode = "$" + jsonModuleUnicode.replace(dollarSign, '#$') + "$"; + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonModuleUnicode; + } + ts2abc.stdio[3].write(jsonModuleUnicode + '\n'); + }); + } + static clearDumpData() { Ts2Panda.strings.clear(); Ts2Panda.jsonString = ""; + Ts2Panda.moduleRecordlist = []; } } + +function makeModuleRecord(sourceTextModule: SourceTextModuleRecord): ModuleRecord { + let moduleRecord = new ModuleRecord(); + moduleRecord.moduleName = sourceTextModule.getModuleName(); + + moduleRecord.moduleRequests = [...sourceTextModule.getModuleRequests()]; + + sourceTextModule.getRegularImportEntries().forEach(e => { + moduleRecord.regularImportEntries.push(new RegularImportEntry(e.localName!, e.importName!, e.moduleRequest!)); + }); + + sourceTextModule.getNamespaceImportEntries().forEach(e => { + moduleRecord.namespaceImportEntries.push(new NamespaceImportEntry(e.localName!, e.moduleRequest!)); + }); + + sourceTextModule.getLocalExportEntries().forEach(entries => { + entries.forEach(e => { + moduleRecord.localExportEntries.push(new LocalExportEntry(e.localName!, e.exportName!)); + }); + }); + + sourceTextModule.getIndirectExportEntries().forEach(e => { + moduleRecord.indirectExportEntries.push(new IndirectExportEntry(e.exportName!, e.importName!, e.moduleRequest!)); + }); + + sourceTextModule.getStarExportEntries().forEach(e => { + moduleRecord.starExportEntries.push(e.moduleRequest!); + }); + + return moduleRecord; +} diff --git a/ts2panda/src/variable.ts b/ts2panda/src/variable.ts index d06957d00bca95c7999b6d241f209db060f1d46f..37c79530900c9e7d2a9072e09268995ee8e9ebe1 100644 --- a/ts2panda/src/variable.ts +++ b/ts2panda/src/variable.ts @@ -26,7 +26,6 @@ export enum VarDeclarationKind { CONST, VAR, FUNCTION, - MODULE, CLASS } @@ -113,8 +112,6 @@ export abstract class Variable { export class LocalVariable extends Variable { status: InitStatus | null; - isExport: boolean = false; - exportedName: string = ""; constructor(declKind: VarDeclarationKind, name: string, status?: InitStatus) { super(declKind, name); @@ -131,24 +128,35 @@ export class LocalVariable extends Variable { } return true; } +} - setExport() { - this.isExport = true; - } +export class ModuleVariable extends Variable { + private isExport: boolean = false; + private status: InitStatus | null; - isExportVar() { - return this.isExport; + + constructor(declKind: VarDeclarationKind, name: string, status?: InitStatus) { + super(declKind, name); + this.status = status ? status : null; } - setExportedName(name: string) { - this.exportedName = name; + initialize() { + this.status = InitStatus.INITIALIZED; } - getExportedName() { - if (!this.exportedName) { - throw new Error("Exported Variable " + this.getName() + " doesn't have exported name"); + isInitialized() { + if (this.status != null) { + return this.status == InitStatus.INITIALIZED; } - return this.exportedName; + return true; + } + + setExport() { + this.isExport = true; + } + + isExportVar() { + return this.isExport; } } @@ -156,4 +164,4 @@ export class GlobalVariable extends Variable { constructor(declKind: VarDeclarationKind, name: string) { super(declKind, name); } -} \ No newline at end of file +} diff --git a/ts2panda/templates/diagnostic.ts.erb b/ts2panda/templates/diagnostic.ts.erb index b489f8f98ddc0efd7de83a4f2c21ff74777f9e38..1de13a95244cf349f2f2b32c6273cd68615ed509 100755 --- a/ts2panda/templates/diagnostic.ts.erb +++ b/ts2panda/templates/diagnostic.ts.erb @@ -46,26 +46,26 @@ export function createDiagnosticOnFirstToken(file:ts.SourceFile, node: ts.Node , return diagnostic; } -export function createFileDiagnostic(file:ts.SourceFile, node: ts.Node, message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) { - - let diagnostic; - let span = jshelpers.getErrorSpanForNode(file, node); - switch (node.kind) { - case ts.SyntaxKind.Identifier: - diagnostic = jshelpers.createFileDiagnostic(file,span.start,span.length,message,ts.idText(node)); - break; - case ts.SyntaxKind.PrivateIdentifier: - diagnostic = jshelpers.createFileDiagnostic(file,span.start,span.length,message,ts.idText(node)); - break; - case ts.SyntaxKind.ReturnStatement: - diagnostic = createDiagnosticOnFirstToken(file,node,message,...args); - break; - default: - diagnostic = jshelpers.createFileDiagnostic(file,span.start,span.length,message,...args); - break; - } +export function createFileDiagnostic(node: ts.Node, message: ts.DiagnosticMessage, ...args: (string | number | undefined)[]) { + let diagnostic; + let soureceFile: ts.SourceFile = jshelpers.getSourceFileOfNode(node); + let span = jshelpers.getErrorSpanForNode(soureceFile, node); + switch (node.kind) { + case ts.SyntaxKind.Identifier: + diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(node)); + break; + case ts.SyntaxKind.PrivateIdentifier: + diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(node)); + break; + case ts.SyntaxKind.ReturnStatement: + diagnostic = createDiagnosticOnFirstToken(soureceFile, node, message, ...args); + break; + default: + diagnostic = jshelpers.createDiagnosticForNode(node, message, ...args); + break; + } - return diagnostic; + return diagnostic; } export function createDiagnostic(file:ts.SourceFile | undefined, location: ts.Node | undefined, message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) { @@ -76,7 +76,7 @@ export function createDiagnostic(file:ts.SourceFile | undefined, location: ts.No } if (file) { - diagnostic = createFileDiagnostic(file, location, message, ...args); + diagnostic = createFileDiagnostic(location, message, ...args); } else { diagnostic = jshelpers.createDiagnosticForNode(location, message, ...args) } diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index 04e3df954c1468be7c55e751a32108e316d2e5e4..40713d4541614fb732da8b5185c683f7a1d367e4 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -40,10 +40,7 @@ namespace { bool g_debugLogEnabled = false; int g_optLevel = 0; std::string g_optLogLevel = "error"; - bool g_moduleModeEnabled = false; - const int BASE = 16; - - int g_literalArrayCount = 0; + uint32_t g_literalArrayCount = 0; constexpr std::size_t BOUND_LEFT = 0; constexpr std::size_t BOUND_RIGHT = 0; @@ -177,6 +174,7 @@ static std::string ParseUnicodeEscapeString(const std::string &data) { const int unicodeEscapeSymbolLen = 2; const int unicodeCharacterLen = 4; + const int base = 16; std::string::size_type startIdx = 0; std::string newData = ""; std::string::size_type len = data.length(); @@ -195,7 +193,7 @@ static std::string ParseUnicodeEscapeString(const std::string &data) std::string tmpStr = data.substr(startIdx, index - startIdx); newData += ConvertUtf8ToMUtf8(tmpStr); std::string uStr = data.substr(index + unicodeEscapeSymbolLen, unicodeCharacterLen); - uint16_t u16Data = static_cast(std::stoi(uStr.c_str(), NULL, BASE)); + uint16_t u16Data = static_cast(std::stoi(uStr.c_str(), NULL, base)); newData += ConvertUtf16ToMUtf8(&u16Data, 1); startIdx = index + unicodeEscapeSymbolLen + unicodeCharacterLen; } @@ -796,20 +794,26 @@ static void GenerateESTypeAnnotationRecord(panda::pandasm::Program &prog) prog.record_table.emplace(tsTypeAnnotationRecord.name, std::move(tsTypeAnnotationRecord)); } -static void GenrateESModuleModeRecord(panda::pandasm::Program &prog, bool moduleMode) +static void GenerateESModuleRecord(panda::pandasm::Program &prog) { - auto ecmaModuleModeRecord = panda::pandasm::Record("_ESModuleMode", LANG_EXT); - ecmaModuleModeRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); - - auto modeField = panda::pandasm::Field(LANG_EXT); - modeField.name = "isModule"; - modeField.type = panda::pandasm::Type("u8", 0); - modeField.metadata->SetValue(panda::pandasm::ScalarValue::Create( - static_cast(moduleMode))); + auto ecmaModuleRecord = panda::pandasm::Record("_ESModuleRecord", LANG_EXT); + ecmaModuleRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); + prog.record_table.emplace(ecmaModuleRecord.name, std::move(ecmaModuleRecord)); +} - ecmaModuleModeRecord.field_list.emplace_back(std::move(modeField)); +static void AddModuleRecord(panda::pandasm::Program &prog, std::string &moduleName, uint32_t moduleIdx) +{ + auto iter = prog.record_table.find("_ESModuleRecord"); + if (iter != prog.record_table.end()) { + auto &rec = iter->second; + auto moduleIdxField = panda::pandasm::Field(LANG_EXT); + moduleIdxField.name = moduleName; + moduleIdxField.type = panda::pandasm::Type("u32", 0); + moduleIdxField.metadata->SetValue(panda::pandasm::ScalarValue::Create( + static_cast(moduleIdx))); - prog.record_table.emplace(ecmaModuleModeRecord.name, std::move(ecmaModuleModeRecord)); + rec.field_list.emplace_back(std::move(moduleIdxField)); + } } int ParseJson(const std::string &data, Json::Value &rootValue) @@ -837,10 +841,10 @@ static void ParseModuleMode(const Json::Value &rootValue, panda::pandasm::Progra { Logd("----------------parse module_mode-----------------"); if (rootValue.isMember("module_mode") && rootValue["module_mode"].isBool()) { - g_moduleModeEnabled = rootValue["module_mode"].asBool(); + if (rootValue["module_mode"].asBool()) { + GenerateESModuleRecord(prog); + } } - - GenrateESModuleModeRecord(prog, g_moduleModeEnabled); } void ParseLogEnable(const Json::Value &rootValue) @@ -932,6 +936,130 @@ static void ParseSingleLiteralBuf(const Json::Value &rootValue, panda::pandasm:: prog.literalarray_table.emplace(std::to_string(g_literalArrayCount++), std::move(literalarrayInstance)); } +static void ParseModuleRequests(const Json::Value &moduleRequests, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal moduleSize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast(moduleRequests.size())}; + moduleLiteralArray.emplace_back(moduleSize); + for (Json::ArrayIndex i = 0; i < moduleRequests.size(); ++i) { + panda::pandasm::LiteralArray::Literal moduleRequest = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(moduleRequests[i].asString())}; + moduleLiteralArray.emplace_back(moduleRequest); + } +} + +static void ParseRegularImportEntries(const Json::Value ®ularImportEntries, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal entrySize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast(regularImportEntries.size())}; + moduleLiteralArray.emplace_back(entrySize); + for (Json::ArrayIndex i = 0; i < regularImportEntries.size(); ++i) { + auto entry = regularImportEntries[i]; + panda::pandasm::LiteralArray::Literal localName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["localName"].asString())}; + moduleLiteralArray.emplace_back(localName); + panda::pandasm::LiteralArray::Literal importName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["importName"].asString())}; + moduleLiteralArray.emplace_back(importName); + panda::pandasm::LiteralArray::Literal moduleRequest = { + .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE, + .value_ = static_cast(entry["moduleRequest"].asUInt())}; + moduleLiteralArray.emplace_back(moduleRequest); + } +} + +static void ParseNamespaceImportEntries(const Json::Value &namespaceImportEntries, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal entrySize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, + .value_ = static_cast(namespaceImportEntries.size())}; + moduleLiteralArray.emplace_back(entrySize); + for (Json::ArrayIndex i = 0; i < namespaceImportEntries.size(); ++i) { + auto entry = namespaceImportEntries[i]; + panda::pandasm::LiteralArray::Literal localName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["localName"].asString())}; + moduleLiteralArray.emplace_back(localName); + panda::pandasm::LiteralArray::Literal moduleRequest = { + .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE, + .value_ = static_cast(entry["moduleRequest"].asUInt())}; + moduleLiteralArray.emplace_back(moduleRequest); + } +} + +static void ParseLocalExportEntries(const Json::Value &localExportEntries, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal entrySize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast(localExportEntries.size())}; + moduleLiteralArray.emplace_back(entrySize); + for (Json::ArrayIndex i = 0; i < localExportEntries.size(); ++i) { + auto entry = localExportEntries[i]; + panda::pandasm::LiteralArray::Literal localName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["localName"].asString())}; + moduleLiteralArray.emplace_back(localName); + panda::pandasm::LiteralArray::Literal exportName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["exportName"].asString())}; + moduleLiteralArray.emplace_back(exportName); + } +} + +static void ParseIndirectExportEntries(const Json::Value &indirectExportEntries, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal entrySize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast(indirectExportEntries.size())}; + moduleLiteralArray.emplace_back(entrySize); + for (Json::ArrayIndex i = 0; i < indirectExportEntries.size(); ++i) { + auto entry = indirectExportEntries[i]; + panda::pandasm::LiteralArray::Literal exportName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["exportName"].asString())}; + moduleLiteralArray.emplace_back(exportName); + panda::pandasm::LiteralArray::Literal importName = { + .tag_ = panda::panda_file::LiteralTag::STRING, .value_ = ParseString(entry["importName"].asString())}; + moduleLiteralArray.emplace_back(importName); + panda::pandasm::LiteralArray::Literal moduleRequest = { + .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE, + .value_ = static_cast(entry["moduleRequest"].asUInt())}; + moduleLiteralArray.emplace_back(moduleRequest); + } +} + +static void ParseStarExportEntries(const Json::Value &starExportEntries, + std::vector &moduleLiteralArray) +{ + panda::pandasm::LiteralArray::Literal entrySize = { + .tag_ = panda::panda_file::LiteralTag::INTEGER, .value_ = static_cast(starExportEntries.size())}; + moduleLiteralArray.emplace_back(entrySize); + for (Json::ArrayIndex i = 0; i < starExportEntries.size(); ++i) { + panda::pandasm::LiteralArray::Literal moduleRequest = { + .tag_ = panda::panda_file::LiteralTag::METHODAFFILIATE, + .value_ = static_cast(starExportEntries[i].asUInt())}; + moduleLiteralArray.emplace_back(moduleRequest); + } +} + +static void ParseSingleModule(const Json::Value &rootValue, panda::pandasm::Program &prog) +{ + std::vector moduleLiteralArray; + + auto moduleRecord = rootValue["mod"]; + ParseModuleRequests(moduleRecord["moduleRequests"], moduleLiteralArray); + ParseRegularImportEntries(moduleRecord["regularImportEntries"], moduleLiteralArray); + ParseNamespaceImportEntries(moduleRecord["namespaceImportEntries"], moduleLiteralArray); + ParseLocalExportEntries(moduleRecord["localExportEntries"], moduleLiteralArray); + ParseIndirectExportEntries(moduleRecord["indirectExportEntries"], moduleLiteralArray); + ParseStarExportEntries(moduleRecord["starExportEntries"], moduleLiteralArray); + + auto moduleName = ParseString(moduleRecord["moduleName"].asString()); + AddModuleRecord(prog, moduleName, g_literalArrayCount); + + auto moduleLiteralarrayInstance = panda::pandasm::LiteralArray(moduleLiteralArray); + prog.literalarray_table.emplace(std::to_string(g_literalArrayCount++), std::move(moduleLiteralarrayInstance)); +} + static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Program &prog) { Json::Value rootValue; @@ -968,6 +1096,12 @@ static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Progr } break; } + case static_cast(JsonType::MODULE): { + if (rootValue.isMember("mod") && rootValue["mod"].isObject()) { + ParseSingleModule(rootValue, prog); + } + break; + } case static_cast(JsonType::OPTIONS): { ParseOptions(rootValue, prog); break; diff --git a/ts2panda/ts2abc/ts2abc.h b/ts2panda/ts2abc/ts2abc.h index 691e87a0de11bf81af137d734610d46d65c92005..4da99b73a8cac58eb4ab50baeb42eb325056cffe 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -33,6 +33,7 @@ enum class JsonType { RECORD, STRING, LITERALBUFFER, + MODULE, OPTIONS };