From f0bcae0a81f09d351f8c13176fbd3dddef240603 Mon Sep 17 00:00:00 2001 From: hufeng Date: Tue, 21 Dec 2021 20:57:23 +0800 Subject: [PATCH] EcmaScript Standard Module Implementation Signed-off-by: hufeng Change-Id: I72a6707f023f1ab300acdecfde5ec968e786d6ab --- test262/config.py | 412 ++++++++++++++++++++- test262/es2015_tests.txt | 412 ++++++++++++++++++++- test262/skip_tests.json | 62 +++- ts2panda/scripts/diagnosticMessages.json | 50 ++- ts2panda/src/addVariable2Scope.ts | 18 +- ts2panda/src/base/bcGenUtil.ts | 23 +- ts2panda/src/base/util.ts | 14 +- ts2panda/src/compiler.ts | 80 ++-- ts2panda/src/compilerDriver.ts | 29 +- ts2panda/src/ecmaModule.ts | 222 +++++++++++ ts2panda/src/hoisting.ts | 27 +- ts2panda/src/index.ts | 3 +- ts2panda/src/lexenv.ts | 14 +- ts2panda/src/modules.ts | 64 +--- ts2panda/src/pandagen.ts | 24 +- ts2panda/src/pandasm.ts | 56 ++- ts2panda/src/recorder.ts | 284 +++++++++++--- ts2panda/src/scope.ts | 106 ++++-- ts2panda/src/statement/classStatement.ts | 48 ++- ts2panda/src/syntaxChecker.ts | 35 +- ts2panda/src/syntaxCheckerForStrcitMode.ts | 67 +++- ts2panda/src/ts2panda.ts | 65 +++- ts2panda/src/variable.ts | 38 +- ts2panda/templates/diagnostic.ts.erb | 40 +- ts2panda/ts2abc/ts2abc.cpp | 169 ++++++++- ts2panda/ts2abc/ts2abc.h | 1 + 26 files changed, 1992 insertions(+), 371 deletions(-) create mode 100644 ts2panda/src/ecmaModule.ts diff --git a/test262/config.py b/test262/config.py index 34670ad68a..4cad0ff059 100755 --- a/test262/config.py +++ b/test262/config.py @@ -108,5 +108,415 @@ MODULE_FILES_LIST = [ "parse-err-return.js", "parse-err-yield.js", "dup-bound-names.js", - "await-module.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" ] diff --git a/test262/es2015_tests.txt b/test262/es2015_tests.txt index 92acde0ddc..b23ac30a0d 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/skip_tests.json b/test262/skip_tests.json index c99bd2a5a1..f5c6b7d2c2 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 b4142d717d..6fa9df1efc 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 a441654999..dce373adaa 100644 --- a/ts2panda/src/addVariable2Scope.ts +++ b/ts2panda/src/addVariable2Scope.ts @@ -35,8 +35,6 @@ import { Variable } from "./variable"; import { TypeRecorder } from "./typeRecorder"; -import { CmdOptions } from "./cmdOptions"; -import { PrimitiveType } from "./base/typeSystem"; function setVariableOrParameterType(node: ts.Node, v: Variable | undefined) { if (v) { @@ -107,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") } @@ -132,20 +130,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 4f19537799..d3faa8aa29 100755 --- 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, @@ -367,20 +366,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(ResultType.Int, 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() { @@ -419,14 +414,14 @@ export function createRegExpWithLiteral(pattern: string, flags: number) { return new EcmaCreateregexpwithliteral(pattern, new Imm(ResultType.Int, flags)); } -export function stLetToGlobalRecord (name: string) { +export function stLetToGlobalRecord(name: string) { return new EcmaStlettoglobalrecord(name); } -export function stConstToGlobalRecord (name: string) { +export function stConstToGlobalRecord(name: string) { return new EcmaStconsttoglobalrecord(name); } -export function stClassToGlobalRecord (name: string) { +export function stClassToGlobalRecord(name: string) { return new EcmaStclasstoglobalrecord(name); } \ No newline at end of file diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index e0f66130a0..dce483e0d4 100755 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -15,7 +15,6 @@ import path = require("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; @@ -295,4 +283,4 @@ export function getRangeStartVregPos(ins: IRNode): number { return -1; } return ins instanceof EcmaCreateobjectwithexcludedkeys ? 2 : 1; -} \ No newline at end of file +} diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index b323fc7b57..949635865f 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 { CompilerDriver } from "./compilerDriver"; @@ -84,7 +82,6 @@ import { import { checkValidUseSuperBeforeSuper, compileClassDeclaration, - compileConstructor, compileDefaultConstructor, compileDefaultInitClassMembers, compileReturnThis4Ctor, @@ -114,6 +111,7 @@ import { isAssignmentOperator } from "./syntaxCheckHelper"; import { GlobalVariable, LocalVariable, + ModuleVariable, VarDeclarationKind, Variable } from "./variable"; @@ -211,7 +209,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; @@ -515,18 +513,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); @@ -540,7 +532,6 @@ export class Compiler { && decl.parent.kind != ts.SyntaxKind.CatchClause) { this.pandaGen.loadAccumulator(decl, getVregisterCache(this.pandaGen, CacheList.undefined)); } - } lref.setValue(); } @@ -695,26 +686,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) { @@ -1481,13 +1462,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()); @@ -1524,6 +1535,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 e4dd5dc0c6..f53f175eb8 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 @@ -27,7 +27,7 @@ import { DebugInfo } from "./debuginfo"; import { hoisting } from "./hoisting"; import { IntrinsicExpander } from "./intrinsicExpander"; 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"; @@ -41,10 +41,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( @@ -148,7 +149,6 @@ export class CompilerDriver { compileForSyntaxCheck(node: ts.SourceFile): void { let recorder = this.compilePrologue(node, false); checkDuplicateDeclaration(recorder); - checkExportEntries(recorder); } compile(node: ts.SourceFile): void { @@ -182,6 +182,7 @@ export class CompilerDriver { Ts2Panda.dumpStringsArray(ts2abcProc); Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpModuleRecords(ts2abcProc); terminateWritePipe(ts2abcProc); if (CmdOptions.isEnableDebugLog()) { @@ -217,13 +218,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)); @@ -263,11 +260,6 @@ 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); compiler.compile(); @@ -300,8 +292,11 @@ export class CompilerDriver { } let recorder = new Recorder(node, topLevelScope, this, enableTypeRecord, isTsFile); recorder.record(); - + if (topLevelScope instanceof ModuleScope) { + topLevelScope.module().setModuleEnvironment(topLevelScope); + } addVariableToScope(recorder, enableTypeRecord); + let postOrderVariableScopes = this.postOrderAnalysis(topLevelScope); for (let variableScope of postOrderVariableScopes) { @@ -352,6 +347,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 0000000000..13509b6589 --- /dev/null +++ b/ts2panda/src/ecmaModule.ts @@ -0,0 +1,222 @@ +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() { + 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(); + + 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) { + 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 c18cab39dc..2ff281e88d 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 19cc5075fa..114781683e 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -157,7 +157,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 d4c1cc7776..7069bb0432 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"; @@ -109,7 +108,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)); @@ -161,13 +160,8 @@ export class VariableAcessStore extends VariableAccessBase { // check const assignment checkConstAssignment(pandaGen, v, insns, this.node); } - insns.push(storeAccumulator(bindVreg)); - if (v.isExportVar()) { - insns.push(storeModuleVariable(v.getExportedName())); - } - return insns; } @@ -200,9 +194,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; @@ -246,4 +238,4 @@ function checkConstAssignment(pg: PandaGen, v: Variable, expansion: IRNode[], no } pg.freeTemps(nameReg); -} \ No newline at end of file +} diff --git a/ts2panda/src/modules.ts b/ts2panda/src/modules.ts index 8e1ea468a7..b8110b4fec 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 jshelpers from "./jshelpers"; -import { LocalVariable } from "./variable"; import { DiagnosticCode, DiagnosticError } from "./diagnostic"; -import { ModuleScope } from "./scope"; export class ModuleStmt { private node: ts.Node @@ -75,64 +73,4 @@ export class ModuleStmt { getCopyFlag() { 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 d7b0bfceb7..6d88711db1 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, @@ -65,7 +64,7 @@ import { loadHomeObject, loadLexicalEnv, loadLexicalVar, - loadModuleVarByName, + loadModuleVariable, loadObjByIndex, loadObjByName, loadObjByValue, @@ -93,6 +92,7 @@ import { stSuperByValue, superCall, superCallSpread, + throwConstAssignment, throwDeleteSuperProperty, throwException, throwIfNotObject, @@ -874,6 +874,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()); } @@ -1080,20 +1084,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 565615a2f5..4db6705149 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; @@ -208,6 +208,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 670bd357f2..495c746cfd 100644 --- a/ts2panda/src/recorder.ts +++ b/ts2panda/src/recorder.ts @@ -15,14 +15,18 @@ import 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); } @@ -262,9 +298,13 @@ export class Recorder { if (parent) { // console.log(id.getText()); 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); @@ -304,8 +344,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; @@ -313,11 +355,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"); @@ -343,7 +385,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"); } @@ -360,7 +403,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); } @@ -373,7 +415,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); } @@ -382,7 +423,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); }); @@ -394,6 +434,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; @@ -416,13 +457,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); @@ -433,16 +467,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) { @@ -600,14 +784,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]); @@ -645,4 +821,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 79a59c0486..f4c796d55a 100644 --- a/ts2panda/src/scope.ts +++ b/ts2panda/src/scope.ts @@ -14,11 +14,13 @@ */ import * as ts from "typescript"; +import { SourceTextModuleRecord } from "./ecmaModule"; import { DebugInsPlaceHolder } from "./irnodes"; import { LOGD, LOGE } from "./log"; import { GlobalVariable, LocalVariable, + ModuleVariable, VarDeclarationKind, Variable } from "./variable"; @@ -27,61 +29,68 @@ 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 globals: Variable[] = []; + // protected locals: Variable[] = []; protected name2variable: Map = new Map(); protected decls: Decl[] = []; protected parent: Scope | undefined = undefined; @@ -90,7 +99,7 @@ export abstract class Scope { protected endIns: DebugInsPlaceHolder = new DebugInsPlaceHolder(); 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; @@ -352,15 +361,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; @@ -368,24 +376,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; } @@ -438,7 +467,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); @@ -446,7 +476,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; @@ -454,11 +484,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; @@ -477,14 +505,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"); @@ -500,7 +529,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 982d1ab35d..ddfd066bf5 100644 --- a/ts2panda/src/statement/classStatement.ts +++ b/ts2panda/src/statement/classStatement.ts @@ -13,7 +13,6 @@ * limitations under the License. */ -import { Ts2Panda } from "src/ts2panda"; import * as ts from "typescript"; import { Literal, LiteralBuffer, LiteralTag } from "../base/literal"; import { LReference } from "../base/lreference"; @@ -24,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"; @@ -43,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); @@ -113,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 } } @@ -499,6 +519,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)) { @@ -516,6 +540,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 185e3a2df3..0ffeffdf3a 100644 --- a/ts2panda/src/syntaxChecker.ts +++ b/ts2panda/src/syntaxChecker.ts @@ -143,6 +143,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) { @@ -155,15 +156,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; } } @@ -263,10 +265,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); } } @@ -1417,19 +1419,4 @@ 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(); - 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 42b09db21e..ea59eefab3 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 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,6 +283,15 @@ 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; } diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 6e0d6e7cd9..1db6500cb6 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -15,6 +15,7 @@ import { CmdOptions } from "./cmdOptions"; import { DebugPosInfo } from "./debuginfo"; +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 { TypeOfVreg } from "./pandasm"; import { LiteralBuffer } from "./base/literal"; +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 = "LABEL_"; 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(); @@ -284,8 +298,55 @@ export class Ts2Panda { ts2abc.stdio[3].write(jsonFuncUnicode + '\n'); } + static dumpModuleRecords(ts2abc: any): void { + Ts2Panda.moduleRecordlist.forEach(function(module){ + let moduleObject = { + "type": JsonType.module, + "module_rec": module + }; + let jsonModuleUnicode = escapeUnicode(JSON.stringify(moduleObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonModuleUnicode; + } + jsonModuleUnicode = "$" + jsonModuleUnicode.replace(dollarSign, '#$') + "$"; + 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 5563f6dfea..c721055112 100644 --- a/ts2panda/src/variable.ts +++ b/ts2panda/src/variable.ts @@ -26,7 +26,6 @@ export enum VarDeclarationKind { CONST, VAR, FUNCTION, - MODULE, CLASS } @@ -112,8 +111,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); @@ -130,24 +127,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; } } @@ -155,4 +163,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 795fda099a..9b414d761e 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 b9918d6e0a..6f79e10932 100644 --- a/ts2panda/ts2abc/ts2abc.cpp +++ b/ts2panda/ts2abc/ts2abc.cpp @@ -40,13 +40,12 @@ namespace { bool g_debugLogEnabled = false; int g_optLevel = 0; std::string g_optLogLevel = "error"; - bool g_moduleModeEnabled = false; const int LOG_BUFFER_SIZE = 1024; const int BASE = 16; const int UNICODE_ESCAPE_SYMBOL_LEN = 2; const int UNICODE_CHARACTER_LEN = 4; - int g_literalArrayCount = 0; + uint32_t g_literalArrayCount = 0; constexpr std::size_t BOUND_LEFT = 0; constexpr std::size_t BOUND_RIGHT = 0; @@ -819,20 +818,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))); - - ecmaModuleModeRecord.field_list.emplace_back(std::move(modeField)); + auto ecmaModuleRecord = panda::pandasm::Record("_ESModuleRecord", LANG_EXT); + ecmaModuleRecord.metadata->SetAccessFlags(panda::ACC_PUBLIC); + prog.record_table.emplace(ecmaModuleRecord.name, std::move(ecmaModuleRecord)); +} - prog.record_table.emplace(ecmaModuleModeRecord.name, std::move(ecmaModuleModeRecord)); +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))); + + rec.field_list.emplace_back(std::move(moduleIdxField)); + } } int ParseJson(const std::string &data, Json::Value &rootValue) @@ -860,10 +865,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) @@ -952,6 +957,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["module_rec"]; + 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; @@ -988,6 +1117,12 @@ static int ParseSmallPieceJson(const std::string &subJson, panda::pandasm::Progr } break; } + case static_cast(JsonType::MODULE): { + if (rootValue.isMember("module_rec") && rootValue["module_rec"].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 691e87a0de..4da99b73a8 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -33,6 +33,7 @@ enum class JsonType { RECORD, STRING, LITERALBUFFER, + MODULE, OPTIONS }; -- Gitee