diff --git a/test262/config.py b/test262/config.py index 34670ad68a2d760e44ddc489b0feabafdde6fb97..4cad0ff059fed0a184bf431e9a419713398c14b7 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 92acde0ddc1283cd60ae04c96534fa89c89b5191..b23ac30a0da61b95dcae42d7b50f059c8a17a753 100755 --- a/test262/es2015_tests.txt +++ b/test262/es2015_tests.txt @@ -5227,4 +5227,414 @@ intl402/Date/prototype/toLocaleString/builtin.js intl402/Date/prototype/toLocaleString/length.js intl402/Date/prototype/toLocaleString/default-options-object-prototype.js intl402/language-tags-valid.js -intl402/language-tags-canonicalized.js \ No newline at end of file +intl402/language-tags-canonicalized.js +language/module-code/comment-multi-line-html-close.js +language/module-code/comment-single-line-html-close.js +language/module-code/comment-single-line-html-open.js +language/module-code/early-dup-export-as-star-as.js +language/module-code/early-dup-export-decl.js +language/module-code/early-dup-export-dflt-id.js +language/module-code/early-dup-export-dflt.js +language/module-code/early-dup-export-id-as.js +language/module-code/early-dup-export-id.js +language/module-code/early-dup-language/module-code/export-star-as-dflt.js +language/module-code/early-dup-lables.js +language/module-code/early-dup-lex.js +language/module-code/early-export-global.js +language/module-code/early-export-ill-formed-string.js +language/module-code/early-export-unresolvable.js +language/module-code/early-import-arguments.js +language/module-code/early-import-as-arguments.js +language/module-code/early-import-as-eval.js +language/module-code/early-import-eval.js +language/module-code/early-lex-and-var.js +language/module-code/early-new-target.js +language/module-code/early-strict-mode.js +language/module-code/early-super.js +language/module-code/early-undef-break.js +language/module-code/early-undef-continue.js +language/module-code/eval-export-cls-semi.js +language/module-code/eval-export-dflt-cls-anon.js +language/module-code/eval-export-dflt-cls-anon-semi.js +language/module-code/eval-export-dflt-cls-named.js +language/module-code/eval-export-dflt-cls-named-semi.js +language/module-code/eval-export-dflt-cls-name-meth.js +language/module-code/eval-export-dflt-expr-cls-anon.js +language/module-code/eval-export-dflt-expr-cls-named.js +language/module-code/eval-export-dflt-expr-cls-name-meth.js +language/module-code/eval-export-dflt-expr-err-eval.js +language/module-code/eval-export-dflt-expr-err-get-value.js +language/module-code/eval-export-dflt-expr-fn-anon.js +language/module-code/eval-export-dflt-expr-fn-named.js +language/module-code/eval-export-dflt-expr-gen-anon.js +language/module-code/eval-export-dflt-expr-gen-named.js +language/module-code/eval-export-dflt-expr-in.js +language/module-code/eval-export-dflt-fun-anon-semi.js +language/module-code/eval-export-dflt-fun-named-semi.js +language/module-code/eval-export-dflt-gen-anon-semi.js +language/module-code/eval-export-dflt-gen-named-semi.js +language/module-code/eval-export-fun-semi.js +language/module-code/eval-export-gen-semi.js +language/module-code/eval-gtbndng-indirect-trlng-comma_FIXTURE.js +language/module-code/eval-gtbndng-indirect-trlng-comma.js +language/module-code/eval-gtbndng-indirect-update-as_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update-as.js +language/module-code/eval-gtbndng-indirect-update-dflt_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update-dflt.js +language/module-code/eval-gtbndng-indirect-update_FIXTURE.js +language/module-code/eval-gtbndng-indirect-update.js +language/module-code/eval-gtbndng-local-bndng-cls.js +language/module-code/eval-gtbndng-local-bndng-const.js +language/module-code/eval-gtbndng-local-bndng-let.js +language/module-code/eval-gtbndng-local-bndng-var.js +language/module-code/eval-rqstd-abrupt-err-type_FIXTURE.js +language/module-code/eval-rqstd-abrupt-err-uri_FIXTURE.js +language/module-code/eval-rqstd-abrupt.js +language/module-code/eval-rqstd-once_FIXTURE.js +language/module-code/eval-rqstd-once.js +language/module-code/eval-rqstd-order-1_FIXTURE.js +language/module-code/eval-rqstd-order-2_FIXTURE.js +language/module-code/eval-rqstd-order-3_FIXTURE.js +language/module-code/eval-rqstd-order-4_FIXTURE.js +language/module-code/eval-rqstd-order-5_FIXTURE.js +language/module-code/eval-rqstd-order-6_FIXTURE.js +language/module-code/eval-rqstd-order-7_FIXTURE.js +language/module-code/eval-rqstd-order-8_FIXTURE.js +language/module-code/eval-rqstd-order-9_FIXTURE.js +language/module-code/eval-rqstd-order.js +language/module-code/eval-self-abrupt.js +language/module-code/eval-self-once.js +language/module-code/eval-this.js +language/module-code/export-default-asyncfunction-declaration-binding-exists.js +language/module-code/export-default-asyncfunction-declaration-binding.js +language/module-code/export-default-asyncgenerator-declaration-binding-exists.js +language/module-code/export-default-asyncgenerator-declaration-binding.js +language/module-code/export-default-function-declaration-binding-exists.js +language/module-code/export-default-function-declaration-binding.js +language/module-code/export-default-generator-declaration-binding-exists.js +language/module-code/export-default-generator-declaration-binding.js +language/module-code/export-expname-binding-string.js +language/module-code/export-expname_FIXTURE.js +language/module-code/export-expname-from-as-unpaired-surrogate.js +language/module-code/export-expname-from-binding-string.js +language/module-code/export-expname-from-star.js +language/module-code/export-expname-from-star-string.js +language/module-code/export-expname-from-star-unpaired-surrogate.js +language/module-code/export-expname-from-string-binding.js +language/module-code/export-expname-from-string.js +language/module-code/export-expname-from-string-string.js +language/module-code/export-expname-from-unpaired-surrogate.js +language/module-code/export-expname-import-string-binding.js +language/module-code/export-expname-import-unpaired-surrogate.js +language/module-code/export-expname-string-binding.js +language/module-code/export-expname-unpaired-surrogate.js +language/module-code/export-star-as-dflt_FIXTURE.js +language/module-code/export-star-as-dflt.js +language/module-code/instn-iee-bndng-cls_FIXTURE.js +language/module-code/instn-iee-bndng-cls.js +language/module-code/instn-iee-bndng-const_FIXTURE.js +language/module-code/instn-iee-bndng-const.js +language/module-code/instn-iee-bndng-fun_FIXTURE.js +language/module-code/instn-iee-bndng-fun.js +language/module-code/instn-iee-bndng-gen_FIXTURE.js +language/module-code/instn-iee-bndng-gen.js +language/module-code/instn-iee-bndng-let_FIXTURE.js +language/module-code/instn-iee-bndng-let.js +language/module-code/instn-iee-bndng-var_FIXTURE.js +language/module-code/instn-iee-bndng-var.js +language/module-code/instn-iee-err-ambiguous-1_FIXTURE.js +language/module-code/instn-iee-err-ambiguous-2_FIXTURE.js +language/module-code/instn-iee-err-ambiguous-as.js +language/module-code/instn-iee-err-ambiguous_FIXTURE.js +language/module-code/instn-iee-err-ambiguous.js +language/module-code/instn-iee-err-circular-as.js +language/module-code/instn-iee-err-circular_FIXTURE.js +language/module-code/instn-iee-err-circular.js +language/module-code/instn-iee-err-dflt-thru-star-as.js +language/module-code/instn-iee-err-dflt-thru-star-dflt_FIXTURE.js +language/module-code/instn-iee-err-dflt-thru-star-int_FIXTURE.js +language/module-code/instn-iee-err-dflt-thru-star.js +language/module-code/instn-iee-err-not-found-as.js +language/module-code/instn-iee-err-not-found-empty_FIXTURE.js +language/module-code/instn-iee-err-not-found.js +language/module-code/instn-iee-iee-cycle-2_FIXTURE.js +language/module-code/instn-iee-iee-cycle.js +language/module-code/instn-iee-star-cycle-2_FIXTURE.js +language/module-code/instn-iee-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-iee-star-cycle.js +language/module-code/instn-iee-trlng-comma_FIXTURE.js +language/module-code/instn-iee-trlng-comma.js +language/module-code/instn-local-bndng-cls.js +language/module-code/instn-local-bndng-const.js +language/module-code/instn-local-bndng-export-cls.js +language/module-code/instn-local-bndng-export-const.js +language/module-code/instn-local-bndng-export-fun.js +language/module-code/instn-local-bndng-export-gen.js +language/module-code/instn-local-bndng-export-let.js +language/module-code/instn-local-bndng-export-var.js +language/module-code/instn-local-bndng-for-dup.js +language/module-code/instn-local-bndng-for.js +language/module-code/instn-local-bndng-fun.js +language/module-code/instn-local-bndng-gen.js +language/module-code/instn-local-bndng-let.js +language/module-code/instn-local-bndng-var-dup.js +language/module-code/instn-local-bndng-var.js +language/module-code/instn-named-bndng-cls.js +language/module-code/instn-named-bndng-const.js +language/module-code/instn-named-bndng-dflt-cls.js +language/module-code/instn-named-bndng-dflt-expr.js +language/module-code/instn-named-bndng-dflt-fun-anon.js +language/module-code/instn-named-bndng-dflt-fun-named.js +language/module-code/instn-named-bndng-dflt-gen-anon.js +language/module-code/instn-named-bndng-dflt-gen-named.js +language/module-code/instn-named-bndng-dflt-named.js +language/module-code/instn-named-bndng-dflt-star.js +language/module-code/instn-named-bndng-fun.js +language/module-code/instn-named-bndng-gen.js +language/module-code/instn-named-bndng-let.js +language/module-code/instn-named-bndng-trlng-comma.js +language/module-code/instn-named-bndng-var.js +language/module-code/instn-named-err-ambiguous-1_FIXTURE.js +language/module-code/instn-named-err-ambiguous-2_FIXTURE.js +language/module-code/instn-named-err-ambiguous-as.js +language/module-code/instn-named-err-ambiguous_FIXTURE.js +language/module-code/instn-named-err-ambiguous.js +language/module-code/instn-named-err-dflt-thru-star-as.js +language/module-code/instn-named-err-dflt-thru-star-dflt_FIXTURE.js +language/module-code/instn-named-err-dflt-thru-star-dflt.js +language/module-code/instn-named-err-dflt-thru-star-int_FIXTURE.js +language/module-code/instn-named-err-not-found-as.js +language/module-code/instn-named-err-not-found-dflt.js +language/module-code/instn-named-err-not-found-empty_FIXTURE.js +language/module-code/instn-named-err-not-found.js +language/module-code/instn-named-id-name.js +language/module-code/instn-named-iee-cycle-2_FIXTURE.js +language/module-code/instn-named-iee-cycle.js +language/module-code/instn-named-star-cycle-2_FIXTURE.js +language/module-code/instn-named-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-named-star-cycle.js +language/module-code/instn-once.js +language/module-code/instn-resolve-empty-export_FIXTURE.js +language/module-code/instn-resolve-empty-export.js +language/module-code/instn-resolve-empty-import_FIXTURE.js +language/module-code/instn-resolve-empty-import.js +language/module-code/instn-resolve-err-syntax-1_FIXTURE.js +language/module-code/instn-resolve-err-syntax-1.js +language/module-code/instn-resolve-err-syntax-2_FIXTURE.js +language/module-code/instn-resolve-err-syntax-2.js +language/module-code/instn-resolve-order-depth-child_FIXTURE.js +language/module-code/instn-resolve-order-depth.js +language/module-code/instn-resolve-order-depth-reference_FIXTURE.js +language/module-code/instn-resolve-order-depth-syntax_FIXTURE.js +language/module-code/instn-resolve-order-src.js +language/module-code/instn-resolve-order-src-reference_FIXTURE.js +language/module-code/instn-resolve-order-src-syntax_FIXTURE.js +language/module-code/instn-resolve-order-src-valid_FIXTURE.js +language/module-code/instn-same-global.js +language/module-code/instn-same-global-set_FIXTURE.js +language/module-code/instn-star-ambiguous-1_FIXTURE.js +language/module-code/instn-star-ambiguous-2_FIXTURE.js +language/module-code/instn-star-ambiguous_FIXTURE.js +language/module-code/instn-star-ambiguous.js +language/module-code/instn-star-as-props-dflt-skip.js +language/module-code/instn-star-binding.js +language/module-code/instn-star-equality.js +language/module-code/instn-star-equality-other_FIXTURE.js +language/module-code/instn-star-err-not-found-empty_FIXTURE.js +language/module-code/instn-star-err-not-found-faulty_FIXTURE.js +language/module-code/instn-star-err-not-found.js +language/module-code/instn-star-id-name.js +language/module-code/instn-star-iee-cycle-2_FIXTURE.js +language/module-code/instn-star-iee-cycle.js +language/module-code/instn-star-props-circular-a_FIXTURE.js +language/module-code/instn-star-props-circular-b_FIXTURE.js +language/module-code/instn-star-props-circular.js +language/module-code/instn-star-props-dflt-keep-indirect-def_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-indirect.js +language/module-code/instn-star-props-dflt-keep-indirect-reexport_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-local.js +language/module-code/instn-star-props-dflt-keep-local-named_FIXTURE.js +language/module-code/instn-star-props-dflt-keep-local-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip.js +language/module-code/instn-star-props-dflt-skip-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-named-end_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-prod-end_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-as-prod_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-named_FIXTURE.js +language/module-code/instn-star-props-dflt-skip-star-prod_FIXTURE.js +language/module-code/instn-star-props-nrml-1_FIXTURE.js +language/module-code/instn-star-props-nrml-indirect_FIXTURE.js +language/module-code/instn-star-props-nrml.js +language/module-code/instn-star-props-nrml-star_FIXTURE.js +language/module-code/instn-star-star-cycle-2_FIXTURE.js +language/module-code/instn-star-star-cycle-indirect-x_FIXTURE.js +language/module-code/instn-star-star-cycle.js +language/module-code/instn-uniq-env-rec.js +language/module-code/instn-uniq-env-rec-other_FIXTURE.js +language/module-code/invalid-private-names-call-expression-bad-reference.js +language/module-code/invalid-private-names-call-expression-this.js +language/module-code/invalid-private-names-member-expression-bad-reference.js +language/module-code/invalid-private-names-member-expression-this.js +language/module-code/parse-err-decl-pos-export-arrow-function.js +language/module-code/parse-err-decl-pos-export-block-stmt.js +language/module-code/parse-err-decl-pos-export-block-stmt-list.js +language/module-code/parse-err-decl-pos-export-class-decl-meth.js +language/module-code/parse-err-decl-pos-export-class-decl-method-gen.js +language/module-code/parse-err-decl-pos-export-class-decl-method-gen-static.js +language/module-code/parse-err-decl-pos-export-class-decl-meth-static.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-gen.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-gen-static.js +language/module-code/parse-err-decl-pos-export-class-expr-meth.js +language/module-code/parse-err-decl-pos-export-class-expr-meth-static.js +language/module-code/parse-err-decl-pos-export-do-while.js +language/module-code/parse-err-decl-pos-export-for-const.js +language/module-code/parse-err-decl-pos-export-for-in-const.js +language/module-code/parse-err-decl-pos-export-for-in-let.js +language/module-code/parse-err-decl-pos-export-for-in-lhs.js +language/module-code/parse-err-decl-pos-export-for-in-var.js +language/module-code/parse-err-decl-pos-export-for-let.js +language/module-code/parse-err-decl-pos-export-for-lhs.js +language/module-code/parse-err-decl-pos-export-for-of-const.js +language/module-code/parse-err-decl-pos-export-for-of-let.js +language/module-code/parse-err-decl-pos-export-for-of-lhs.js +language/module-code/parse-err-decl-pos-export-for-of-var.js +language/module-code/parse-err-decl-pos-export-for-var.js +language/module-code/parse-err-decl-pos-export-function-decl.js +language/module-code/parse-err-decl-pos-export-function-expr.js +language/module-code/parse-err-decl-pos-export-generator-decl.js +language/module-code/parse-err-decl-pos-export-generator-expr.js +language/module-code/parse-err-decl-pos-export-if-else.js +language/module-code/parse-err-decl-pos-export-if-if.js +language/module-code/parse-err-decl-pos-export-labeled.js +language/module-code/parse-err-decl-pos-export-object-gen-method.js +language/module-code/parse-err-decl-pos-export-object-getter.js +language/module-code/parse-err-decl-pos-export-object-method.js +language/module-code/parse-err-decl-pos-export-object-setter.js +language/module-code/parse-err-decl-pos-export-switch-case-dflt.js +language/module-code/parse-err-decl-pos-export-switch-case.js +language/module-code/parse-err-decl-pos-export-switch-dftl.js +language/module-code/parse-err-decl-pos-export-try-catch-finally.js +language/module-code/parse-err-decl-pos-export-try-catch.js +language/module-code/parse-err-decl-pos-export-try-finally.js +language/module-code/parse-err-decl-pos-export-try-try.js +language/module-code/parse-err-decl-pos-export-while.js +language/module-code/parse-err-decl-pos-import-arrow-function.js +language/module-code/parse-err-decl-pos-import-block-stmt.js +language/module-code/parse-err-decl-pos-import-block-stmt-list.js +language/module-code/parse-err-decl-pos-import-class-decl-meth.js +language/module-code/parse-err-decl-pos-import-class-decl-method-gen.js +language/module-code/parse-err-decl-pos-import-class-decl-method-gen-static.js +language/module-code/parse-err-decl-pos-import-class-decl-meth-static.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-gen.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-gen-static.js +language/module-code/parse-err-decl-pos-import-class-expr-meth.js +language/module-code/parse-err-decl-pos-import-class-expr-meth-static.js +language/module-code/parse-err-decl-pos-import-do-while.js +language/module-code/parse-err-decl-pos-import-for-const.js +language/module-code/parse-err-decl-pos-import-for-in-const.js +language/module-code/parse-err-decl-pos-import-for-in-let.js +language/module-code/parse-err-decl-pos-import-for-in-lhs.js +language/module-code/parse-err-decl-pos-import-for-in-var.js +language/module-code/parse-err-decl-pos-import-for-let.js +language/module-code/parse-err-decl-pos-import-for-lhs.js +language/module-code/parse-err-decl-pos-import-for-of-const.js +language/module-code/parse-err-decl-pos-import-for-of-let.js +language/module-code/parse-err-decl-pos-import-for-of-lhs.js +language/module-code/parse-err-decl-pos-import-for-of-var.js +language/module-code/parse-err-decl-pos-import-for-var.js +language/module-code/parse-err-decl-pos-import-function-decl.js +language/module-code/parse-err-decl-pos-import-function-expr.js +language/module-code/parse-err-decl-pos-import-generator-decl.js +language/module-code/parse-err-decl-pos-import-generator-expr.js +language/module-code/parse-err-decl-pos-import-if-else.js +language/module-code/parse-err-decl-pos-import-if-if.js +language/module-code/parse-err-decl-pos-import-labeled.js +language/module-code/parse-err-decl-pos-import-object-gen-method.js +language/module-code/parse-err-decl-pos-import-object-getter.js +language/module-code/parse-err-decl-pos-import-object-method.js +language/module-code/parse-err-decl-pos-import-object-setter.js +language/module-code/parse-err-decl-pos-import-switch-case-dflt.js +language/module-code/parse-err-decl-pos-import-switch-case.js +language/module-code/parse-err-decl-pos-import-switch-dftl.js +language/module-code/parse-err-decl-pos-import-try-catch-finally.js +language/module-code/parse-err-decl-pos-import-try-catch.js +language/module-code/parse-err-decl-pos-import-try-finally.js +language/module-code/parse-err-decl-pos-import-try-try.js +language/module-code/parse-err-decl-pos-import-while.js +language/module-code/parse-err-export-dflt-const.js +language/module-code/parse-err-export-dflt-expr.js +language/module-code/parse-err-export-dflt-let.js +language/module-code/parse-err-export-dflt-var.js +language/module-code/parse-err-hoist-lex-fun.js +language/module-code/parse-err-hoist-lex-gen.js +language/module-code/parse-err-invoke-anon-fun-decl.js +language/module-code/parse-err-invoke-anon-gen-decl.js +language/module-code/parse-err-return.js +language/module-code/parse-err-semi-dflt-expr.js +language/module-code/parse-err-semi-export-star.js +language/module-code/parse-err-semi-named-export-from.js +language/module-code/parse-err-semi-named-export.js +language/module-code/parse-err-semi-name-space-export.js +language/module-code/parse-err-syntax-1.js +language/module-code/parse-err-syntax-2.js +language/module-code/parse-err-yield.js +language/module-code/parse-export-empty.js +language/module-code/private-identifiers-not-empty.js +language/module-code/privatename-not-valid-earlyerr-module-1.js +language/module-code/privatename-not-valid-earlyerr-module-2.js +language/module-code/privatename-not-valid-earlyerr-module-3.js +language/module-code/privatename-not-valid-earlyerr-module-4.js +language/module-code/privatename-not-valid-earlyerr-module-5.js +language/module-code/privatename-not-valid-earlyerr-module-6.js +language/module-code/privatename-not-valid-earlyerr-module-7.js +language/module-code/privatename-not-valid-earlyerr-module-8.js +language/module-code/privatename-valid-no-earlyerr.js +language/module-code/verify-dfs-a_FIXTURE.js +language/module-code/verify-dfs-b_FIXTURE.js +language/module-code/verify-dfs.js +language/module-code/namespace/Symbol.iterator.js +language/module-code/namespace/Symbol.toStringTag.js +language/module-code/namespace/internals/define-own-property.js +language/module-code/namespace/internals/delete-exported-init.js +language/module-code/namespace/internals/delete-exported-uninit.js +language/module-code/namespace/internals/delete-non-exported.js +language/module-code/namespace/internals/enumerate-binding-uninit.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-named-end_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-named_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-prod-end_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-dflt-skip-prod_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-1_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-2_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml-3_FIXTURE.js +language/module-code/namespace/internals/get-nested-namespace-props-nrml.js +language/module-code/namespace/internals/get-own-property-str-found-init.js +language/module-code/namespace/internals/get-own-property-str-found-uninit.js +language/module-code/namespace/internals/get-own-property-str-not-found.js +language/module-code/namespace/internals/get-own-property-sym.js +language/module-code/namespace/internals/get-prototype-of.js +language/module-code/namespace/internals/get-str-found-init.js +language/module-code/namespace/internals/get-str-found-uninit.js +language/module-code/namespace/internals/get-str-initialize.js +language/module-code/namespace/internals/get-str-not-found.js +language/module-code/namespace/internals/get-str-update.js +language/module-code/namespace/internals/get-sym-found.js +language/module-code/namespace/internals/get-sym-not-found.js +language/module-code/namespace/internals/has-property-str-found-init.js +language/module-code/namespace/internals/has-property-str-found-uninit.js +language/module-code/namespace/internals/has-property-str-not-found.js +language/module-code/namespace/internals/has-property-sym-found.js +language/module-code/namespace/internals/has-property-sym-not-found.js +language/module-code/namespace/internals/is-extensible.js +language/module-code/namespace/internals/object-hasOwnProperty-binding-uninit.js +language/module-code/namespace/internals/object-keys-binding-uninit.js +language/module-code/namespace/internals/object-propertyIsEnumerable-binding-uninit.js +language/module-code/namespace/internals/own-property-keys-binding-types_FIXTURE.js +language/module-code/namespace/internals/own-property-keys-binding-types.js +language/module-code/namespace/internals/own-property-keys-sort.js +language/module-code/namespace/internals/prevent-extensions.js +language/module-code/namespace/internals/set.js +language/module-code/namespace/internals/set-prototype-of.js +language/module-code/namespace/internals/set-prototype-of-null.js diff --git a/test262/run_sunspider.py b/test262/run_sunspider.py index af5cdc6f94a512dd4d4e8473ac7f9ee1fe269ad4..87ee8da80710f33ca35a1c05c444c65e8ce11970 100755 --- a/test262/run_sunspider.py +++ b/test262/run_sunspider.py @@ -64,7 +64,7 @@ def parse_args(): ARK_ARGS = "--gc-type=epsilon" -ICU_PATH = f"--icu-data-path={CODE_ROOT}/third_party/icu/ohos_icu4j/data" +ICU_PATH = "--icu-data-path={}/third_party/icu/ohos_icu4j/data".format(CODE_ROOT) ARK_TOOL = DEFAULT_ARK_TOOL ARK_FRONTEND_TOOL = DEFAULT_ARK_FRONTEND_TOOL LIBS_DIR = DEFAULT_LIBS_DIR @@ -85,7 +85,7 @@ def output(retcode, msg): elif msg != '': sys.stderr.write(str(msg)) else: - sys.stderr.write("Unknown Error: " + str(retcode)) + sys.stderr.write("Unknown Error: {}".format(str(retcode))) def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): @@ -109,8 +109,8 @@ def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): if ret_code and ret_code != 1: code = ret_code - msg = f"Command {cmd_string}: \n" - msg += f"error: {str(errs.decode(code_format,'ignore'))}" + msg = "Command {}: \n".format(cmd_string) + msg += "error: {}".format(str(errs.decode(code_format,'ignore'))) else: code = 0 msg = str(msg.decode(code_format, 'ignore')) @@ -120,10 +120,10 @@ def exec_command(cmd_args, timeout=DEFAULT_TIMEOUT): proc.terminate() os.kill(proc.pid, signal.SIGTERM) code = 1 - msg = f"Timeout:'{cmd_string}' timed out after' {str(timeout)} seconds" + msg = "Timeout:'{}' timed out after' {} seconds".format(cmd_string, str(timeout)) except Exception as err: code = 1 - msg = f"{cmd_string}: unknown error: {str(err)}" + msg = "{}: unknown error: {}".format(cmd_string, str(err)) output(code, msg) return code @@ -162,7 +162,7 @@ class ArkProgram(): js_file = self.js_file file_name_pre = os.path.splitext(js_file)[0] file_name = os.path.basename(js_file) - out_file = f"{file_name_pre}.abc" + out_file = "{}.abc".format(file_name_pre) mod_opt_index = 0 cmd_args = [] frontend_tool = self.ark_frontend_tool @@ -192,17 +192,17 @@ class ArkProgram(): qemu_arg2 = self.arch_root cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] elif self.arch == ARK_ARCH_LIST[2]: qemu_tool = "qemu-arm" qemu_arg1 = "-L" qemu_arg2 = self.arch_root cmd_args = [qemu_tool, qemu_arg1, qemu_arg2, self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] elif self.arch == ARK_ARCH_LIST[0]: cmd_args = [self.ark_tool, ARK_ARGS, ICU_PATH, - f'{file_name_pre}.abc'] + "{}.abc".format(file_name_pre)] retcode = exec_command(cmd_args) return retcode diff --git a/test262/run_test262.py b/test262/run_test262.py index 014c45062e97b564af32fd837e5b5a8c17303d27..39de7a8791686aecca75999b68fbda4387d6161c 100755 --- a/test262/run_test262.py +++ b/test262/run_test262.py @@ -138,7 +138,7 @@ def collect_files(path): return if not os.path.isdir(path): - raise ValueError(f'Not found: "{path}"') + raise ValueError("Not found: {}".format(path)) for root, _, file_names in os.walk(path): for file_name in file_names: @@ -151,7 +151,7 @@ def collect_files(path): def mkdstdir(file, src_dir, dist_dir): idx = file.rfind(src_dir) if idx == -1: - raise SystemExit(f'{file} can not found in {src_dir}') + raise SystemExit("{} can not found in {}".format(file, src_dir)) fpath, fname = os.path.split(file[idx:]) fpath = fpath.replace(src_dir, dist_dir) @@ -245,7 +245,7 @@ class TestPrepare(): dstdir = os.path.join(TEST_ES2015_DIR, file) elif self.args.ci_build: dstdir = os.path.join(TEST_CI_DIR, file) - subprocess.getstatusoutput("cp %s %s" % (srcdir, dstdir)) + subprocess.getstatusoutput("cp {} {}".format(srcdir, dstdir)) def collect_tests(self): files = [] @@ -413,15 +413,15 @@ def get_host_args(args, host_type): ark_frontend = args.ark_frontend if host_type == DEFAULT_HOST_TYPE: - host_args = f"-B test262/run_sunspider.py " - host_args += f"--ark-tool={ark_tool} " - host_args += f"--ark-frontend-tool={ark_frontend_tool} " - host_args += f"--libs-dir={libs_dir} " - host_args += f"--ark-frontend={ark_frontend} " + host_args = "-B test262/run_sunspider.py " + host_args += "--ark-tool={} ".format(ark_tool) + host_args += "--ark-frontend-tool={} ".format(ark_frontend_tool) + host_args += "--libs-dir={} ".format(libs_dir) + host_args += "--ark-frontend={} ".format(ark_frontend) if args.ark_arch != ark_arch: - host_args += f"--ark-arch={args.ark_arch} " - host_args += f"--ark-arch-root={args.ark_arch_root} " + host_args += "--ark-arch={} ".format(args.ark_arch) + host_args += "--ark-arch-root={} ".format(args.ark_arch_root) return host_args @@ -434,15 +434,15 @@ def run_test262_test(args): timeout = get_timeout(args, threads) test_cmd = ["node", TEST262_RUNNER_SCRIPT] - test_cmd.append(f"--hostType={host_type}") - test_cmd.append(f"--hostPath={host_path}") + test_cmd.append("--hostType={}".format(host_type)) + test_cmd.append("--hostPath={}".format(host_path)) if host_args != "": - test_cmd.append(f"--hostArgs='{host_args}'") - test_cmd.append(f"--threads={threads}") - test_cmd.append(f"--mode={run_test262_mode(args)}") - test_cmd.append(f"--timeout={timeout}") - test_cmd.append(f"--tempDir={BASE_OUT_DIR}") - test_cmd.append(f"--test262Dir={DATA_DIR}") + test_cmd.append("--hostArgs='{}'".format(host_args)) + test_cmd.append("--threads={}".format(threads)) + test_cmd.append("--mode={}".format(run_test262_mode(args))) + test_cmd.append("--timeout={}".format(timeout)) + test_cmd.append("--tempDir={}".format(BASE_OUT_DIR)) + test_cmd.append("--test262Dir={}".format(DATA_DIR)) if args.babel: test_cmd.append("--preprocessor='test262/babel-preprocessor.js'") @@ -465,7 +465,7 @@ def main(args): if ret: sys.exit(ret) endtime = datetime.datetime.now() - print(f"used time is: {str(endtime - starttime)}") + print("used time is: {}".format(str(endtime - starttime))) if __name__ == "__main__": diff --git a/test262/skip_tests.json b/test262/skip_tests.json index c99bd2a5a19ee921ab000c78609e59ef170c825e..f5c6b7d2c24398a6cb50a8d49977960dc90c4de5 100755 --- a/test262/skip_tests.json +++ b/test262/skip_tests.json @@ -421,6 +421,7 @@ "language/literals/regexp/S7.8.5_A2.1_T2.js", "language/literals/regexp/S7.8.5_A2.4_T2.js", "language/literals/string/legacy-non-octal-escape-sequence-strict.js", + "language/module-code/export-default-asyncgenerator-declaration-binding.js", "language/statements/break/S12.8_A7.js", "language/statements/const/cptn-value.js", "language/statements/continue/S12.7_A7.js", @@ -970,6 +971,7 @@ "language/expressions/unary-minus/S11.4.7_A3_T5.js", "language/expressions/unary-plus/S11.4.6_A3_T5.js", "language/expressions/unsigned-right-shift/S11.7.3_A3_T1.5.js", + "language/module-code/eval-gtbndng-indirect-update-dflt.js", "language/statements/switch/S12.11_A1_T4.js", "language/statements/switch/S12.11_A1_T4.js", "built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js", @@ -1265,7 +1267,7 @@ ] }, { - "reason": "Not support TypedArrayConstructors ecma2021 features", + "reason": "Not support TypedArrayConstructors ecma2020 features", "files": [ "built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js", "built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js", @@ -1323,5 +1325,63 @@ "intl402/Intl/getCanonicalLocales/canonicalized-tags.js", "intl402/Intl/getCanonicalLocales/transformed-ext-invalid.js" ] + }, + { + "reason": "Not support with Class's Privatename(#)", + "files": [ + "language/module-code/invalid-private-names-member-expression-bad-reference.js", + "language/module-code/invalid-private-names-member-expression-this.js", + "language/module-code/invalid-private-names-call-expression-bad-reference.js", + "language/module-code/invalid-private-names-call-expression-this.js", + "language/module-code/privatename-valid-no-earlyerr.js", + "language/module-code/privatename-not-valid-earlyerr-module-1.js", + "language/module-code/privatename-not-valid-earlyerr-module-2.js", + "language/module-code/privatename-not-valid-earlyerr-module-3.js", + "language/module-code/privatename-not-valid-earlyerr-module-4.js", + "language/module-code/privatename-not-valid-earlyerr-module-5.js", + "language/module-code/privatename-not-valid-earlyerr-module-6.js", + "language/module-code/privatename-not-valid-earlyerr-module-7.js", + "language/module-code/privatename-not-valid-earlyerr-module-8.js", + "language/module-code/private-identifiers-not-empty.js" + ] + }, + { + "reason": "Special unicode character that tsc can not recognize", + "files" : [ + "language/module-code/export-expname-binding-string.js", + "language/module-code/export-expname-from-binding-string.js", + "language/module-code/export-expname-from-star-string.js", + "language/module-code/export-expname-from-string-binding.js", + "language/module-code/export-expname-from-star.js", + "language/module-code/export-expname-from-string-string.js", + "language/module-code/export-expname-from-string.js", + "language/module-code/export-expname-import-string-binding.js" + ] + }, + { + "reason": "Not support Dynamic Import", + "files": [ + "language/module-code/verify-dfs.js" + ] + }, + { + "reason": "Unused node will be eliminated when tsc emiting in [after], So module won't get correct entries", + "files": [ + "language/module-code/instn-named-err-ambiguous.js", + "language/module-code/instn-named-err-ambiguous-as.js", + "language/module-code/instn-named-err-not-found.js", + "language/module-code/instn-named-err-not-found-as.js", + "language/module-code/instn-named-err-not-found-dflt.js", + "language/module-code/instn-named-err-dflt-thru-star-as.js", + "language/module-code/instn-named-err-dflt-thru-star-dflt.js", + "language/module-code/eval-rqstd-order.js" + ] + }, + { + "reason": "Not support further ecma-2015's feature in module code", + "files": [ + "language/module-code/namespace/internals/define-own-property.js", + "language/module-code/early-dup-export-as-star-as.js" + ] } ] diff --git a/ts2panda/scripts/diagnosticMessages.json b/ts2panda/scripts/diagnosticMessages.json index b4142d717dcbc994e804387a8ca6c6a0b4e5a635..6fa9df1efc8ae1b8350344eb258931d7cdca81a0 100755 --- a/ts2panda/scripts/diagnosticMessages.json +++ b/ts2panda/scripts/diagnosticMessages.json @@ -143,6 +143,10 @@ "category": "Error", "code": 1119 }, + "An export assignment cannot have modifiers.": { + "category": "Error", + "code": 1120 + }, "Octal literals are not allowed in strict mode.": { "category": "Error", "code": 1121 @@ -159,6 +163,10 @@ "category": "Error", "code": 1142 }, + "Cannot use imports, exports, or module augmentations when '--module' is 'none'.": { + "category": "Error", + "code": 1148 + }, "The 'const' declarations can only be declared inside a block.": { "category": "Error", "code": 1156 @@ -227,6 +235,14 @@ "category": "Error", "code": 1190 }, + "An import declaration cannot have modifiers.": { + "category": "Error", + "code": 1191 + }, + "An export declaration cannot have modifiers.": { + "category": "Error", + "code": 1193 + }, "Line terminator not permitted before arrow.": { "category": "Error", "code": 1200 @@ -243,6 +259,10 @@ "category": "Error", "code": 1210 }, + "A class or function declaration without the 'default' modifier must have a name.": { + "category": "Error", + "code": 1211 + }, "Identifier expected. '{0}' is a reserved word in strict mode.": { "category": "Error", "code": 1212 @@ -255,6 +275,10 @@ "category": "Error", "code": 1214 }, + "An export assignment must be at the top level of a file or module declaration.": { + "category": "Error", + "code": 1231 + }, "An import declaration can only be used in a namespace or module.": { "category": "Error", "code": 1232 @@ -339,6 +363,18 @@ "category": "Error", "code": 2300 }, + "Module '{0}' has no exported member '{1}'.": { + "category": "Error", + "code": 2305 + }, + "Module '{0}' has already exported a member named '{1}'.": { + "category": "Error", + "code": 2308 + }, + "An export assignment cannot be used in a module with other exported elements.": { + "category": "Error", + "code": 2309 + }, "The 'super' can only be referenced in a derived class.": { "category": "Error", "code": 2335 @@ -395,6 +431,10 @@ "category": "Error", "code": 2404 }, + "Import declaration conflicts with local declaration of '{0}'.": { + "category": "Error", + "code": 2440 + }, "The 'super' cannot be referenced in a computed property name.": { "category": "Error", "code": 2466 @@ -423,6 +463,10 @@ "category": "Error", "code": 2501 }, + "A module cannot have multiple default exports.": { + "category": "Error", + "code": 2528 + }, "The 'super' can only be referenced in members of derived classes or object literal expressions.": { "category": "Error", "code": 2660 @@ -512,8 +556,12 @@ "category": "Error", "code": 19009 }, - "Invalid regular expression flag '{0}'":{ + "Invalid regular expression flag '{0}'": { "category": "Error", "code": 19010 + }, + "Unexpected eval or arguments in strict mode": { + "category": "Error", + "code": 20000 } } \ No newline at end of file diff --git a/ts2panda/scripts/gen_diagnostic.sh b/ts2panda/scripts/gen_diagnostic.sh deleted file mode 100755 index 3f5e53eb61b5502aa90f936d87aa897caaa87cd3..0000000000000000000000000000000000000000 --- a/ts2panda/scripts/gen_diagnostic.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -PANDA_ROOT="../submodules/panda" -ISA="scripts/diagnosticMessages.json" -TEMPLATE="templates/diagnostic.ts.erb" -OUTPUT="src/diagnostic.ts" - -ruby scripts/gen_diagnostic.rb --template $TEMPLATE --data $ISA --output $OUTPUT diff --git a/ts2panda/scripts/gen_irnodes.sh b/ts2panda/scripts/gen_irnodes.sh deleted file mode 100755 index e3ba64b5af69f6848d67c52571e5352de851dbb7..0000000000000000000000000000000000000000 --- a/ts2panda/scripts/gen_irnodes.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e - -PANDA_ROOT="../submodules/panda" -ISA="$PANDA_ROOT/isa/isa.yaml" -DEPS="$PANDA_ROOT/isa/isapi.rb,$PANDA_ROOT/libpandafile/pandafile_isapi.rb" -TEMPLATE="templates/irnodes.ts.erb" -OUTPUT="src/irnodes.ts" - -ruby $PANDA_ROOT/isa/gen.rb --template $TEMPLATE --data $ISA --output $OUTPUT --require "$DEPS" - -BUILTIN_DATA="$PANDA_ROOT/isa/builtins.yaml" -BUILTIN_REQS="$PANDA_ROOT/isa/builtinsapi.rb,$PANDA_ROOT/runtime/ecmascript/ecma_builtins.rb" -BUILTIN_TEMPLATE="templates/builtinsMap.ts.erb" -BUILTIN_OUTPUT="src/builtinsMap.ts" - -ruby $PANDA_ROOT/isa/gen.rb --template $BUILTIN_TEMPLATE --data $BUILTIN_DATA --output $BUILTIN_OUTPUT --require "$BUILTIN_REQS" diff --git a/ts2panda/scripts/generate_js_bytecode.py b/ts2panda/scripts/generate_js_bytecode.py index 755b07a6da72a24ae834f1ff62479fa66b760775..62c1c64b7def126a72ffa2a6edfc59c5af93c00a 100755 --- a/ts2panda/scripts/generate_js_bytecode.py +++ b/ts2panda/scripts/generate_js_bytecode.py @@ -19,6 +19,7 @@ Description: Generate javascript byte code """ import os +import string import subprocess import platform import argparse @@ -40,6 +41,12 @@ def parse_args(): help='whether add debuginfo') parser.add_argument("--module", action='store_true', help='whether is module') + parser.add_argument("--dts-type-record", action='store_true', + help='Record type info for .d.ts files. Default: false') + parser.add_argument("--merge-abc-files", action='store_true', + help='Merge multiple abc files into one. Default: false') + parser.add_argument("--other-files", nargs='*', + help='other files') arguments = parser.parse_args() return arguments @@ -53,7 +60,7 @@ def set_env(input_arguments): def run_command(cmd, execution_path): - print(" ".join(cmd) + " | execution_path: " + execution_path) + print("{} | execution_path:{}".format(" ".join(cmd), execution_path)) proc = subprocess.Popen(cmd, cwd=execution_path) proc.wait() @@ -77,13 +84,20 @@ def gen_abc_info(input_arguments): '--expose-gc', os.path.join(name, 'src/index.js'), input_arguments.src_js, - '-o', input_arguments.dst_file, - '-t', '0'] + '-o', + input_arguments.dst_file] if input_arguments.debug: cmd.insert(3, '--debug') if input_arguments.module: cmd.insert(4, '-m') + if input_arguments.dts_type_record: + cmd.append('--dts-type-record') + if input_arguments.merge_abc_files: + cmd.append('--merge-abc-files') + if input_arguments.other_files: + cmd.append(input_arguments.other_files) + run_command(cmd, path) diff --git a/ts2panda/scripts/run.py b/ts2panda/scripts/run.py index 089868e28ebadbc5744a2d904db3804377078657..2cc4c1568f8bfbaa2586db3663d482d134f866c5 100755 --- a/ts2panda/scripts/run.py +++ b/ts2panda/scripts/run.py @@ -51,10 +51,10 @@ def set_env(node_dir): def run_command(cmd, execution_path=os.getcwd()): - print(" ".join(cmd) + " | execution_path: " + execution_path) + print("{} | execution_path:{}".format(" ".join(cmd), execution_path)) proc = subprocess.Popen(cmd, cwd=execution_path) ret = proc.wait() - assert not ret, f'\n{" ".join(cmd)} failed' + assert not ret, "\n{} failed".format(" ".join(cmd)) def node_modules(options): diff --git a/ts2panda/scripts/run_tests.py b/ts2panda/scripts/run_tests.py index 52899474369f1d258ad17092390426c723f93c6a..d712fc0392a36926122a818ec2a2345078796717 100755 --- a/ts2panda/scripts/run_tests.py +++ b/ts2panda/scripts/run_tests.py @@ -35,21 +35,21 @@ DEFAULT_NODE_MODULE = os.path.join( def parse_args(): parser = argparse.ArgumentParser() - parser.add_argument('--src-dir', + parser.add_argument("--src-dir", default=TS2PANDA_DIR, - help='Source directory') - parser.add_argument('--dist-dir', + help="Source directory") + parser.add_argument("--dist-dir", default=DEFAULT_TARGET_DIR, - help='Destination directory') + help="Destination directory") parser.add_argument("--node-modules", default=DEFAULT_NODE_MODULE, - help='path to node-modules exetuable') - parser.add_argument('--platform', + help="path to node-modules exetuable") + parser.add_argument("--platform", default="linux", - help='platform, as: linux, mac, win') - parser.add_argument('--js-file', - metavar='FILE', - help='The name of the test use case file to execute') + help="platform, as: linux, mac, win") + parser.add_argument("--js-file", + metavar="FILE", + help="The name of the test use case file to execute") return parser.parse_args() @@ -85,37 +85,38 @@ class Ts2abcTests(): def copy_node_modules(self): src_dir = self.src_dir dist_dir = self.dist_dir - run_command(['cp', '-f', os.path.join(src_dir, "package.json"), + run_command(["cp", "-f", os.path.join(src_dir, "package.json"), os.path.join(dist_dir, "package.json")]) - run_command(['cp', '-f', os.path.join(src_dir, "package-lock.json"), + run_command(["cp", "-f", os.path.join(src_dir, "package-lock.json"), os.path.join(dist_dir, "package-lock.json")]) if self.node_modules: - run_command(['cp', '-rf', self.node_modules, dist_dir]) + run_command(["cp", "-rf", self.node_modules, dist_dir]) else: - run_command(['npm', 'install'], dist_dir) + run_command(["npm", "install"], dist_dir) def copy_tests(self): - if os.path.exists(f'{self.dist_dir}/tests'): - run_command(['rm', '-rf', f'{self.dist_dir}/tests']) - run_command(['cp', '-rf', f'{self.src_dir}/tests', self.dist_dir]) + if os.path.exists("{}/tests".format(self.dist_dir)): + run_command(["rm", "-rf", "{}/tests".format(self.dist_dir)]) + run_command( + ["cp", "-rf", "{}/tests".format(self.src_dir), self.dist_dir]) def run_build(self): plat_form = self.platform tsc = "node_modules/typescript/bin/tsc" if plat_form == "linux": - cmd = [tsc, '-b', 'src', 'tests'] + cmd = [tsc, "-b", "src", "tests"] ret = run_command(cmd, self.dist_dir) elif plat_form == "win": - cmd = [tsc, '-b', 'src/tsconfig.win.json', - 'tests/tsconfig.win.json'] + cmd = [tsc, "-b", "src/tsconfig.win.json", + "tests/tsconfig.win.json"] ret = run_command(cmd, self.dist_dir) - elif plat_form == 'mac': - cmd = [tsc, '-b', 'src/tsconfig.mac.json', - 'tests/tsconfig.mac.json'] + elif plat_form == "mac": + cmd = [tsc, "-b", "src/tsconfig.mac.json", + "tests/tsconfig.mac.json"] ret = run_command(cmd, self.dist_dir) if ret: - raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + raise RuntimeError("Run [ {} ] failed !".format(" ".join(cmd))) def run_tests(self): os.chdir(self.dist_dir) @@ -129,19 +130,18 @@ class Ts2abcTests(): tests_args = "tests/**/*.test.js" if plat_form == "linux": - cmd = [mocha, f'build/{tests_args}'] - ret = run_command(cmd, self.dist_dir) + cmd = [mocha, "build/{}".format(tests_args)] elif plat_form == "win": - cmd = [mocha, f'build-win/{tests_args}'] - ret = run_command(cmd, self.dist_dir) - elif plat_form == 'mac': - cmd = [mocha, f'build-mac/{tests_args}'] - ret = run_command(cmd, self.dist_dir) + cmd = [mocha, "build-win/{}".format(tests_args)] + elif plat_form == "mac": + cmd = [mocha, "build-mac/{}".format(tests_args)] + cmd.extend(["--exit", "--recursive", "--timeout", "30000000"]) + ret = run_command(cmd, self.dist_dir) if ret: - raise RuntimeError("Run [" + " ".join(cmd) + "] failed !") + raise RuntimeError("Run [ {} ] failed !".format(" ".join(cmd))) else: - print("Run [" + " ".join(cmd) + "] success!") - print("used: %.5f seconds" % (time.time() - start_time)) + print("Run [ {} ] success!".format(" ".join(cmd))) + print("used: {:0,.5f} seconds".format(time.time() - start_time)) def main(): diff --git a/ts2panda/src/addVariable2Scope.ts b/ts2panda/src/addVariable2Scope.ts index a4416549993d1fcc20ce215af9ca64a4e04b4a00..dce373adaaba4f0144f2799b5104fd307e45535d 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 4f195377993e283eddb3c9dc4ad6dcd08b555bf1..d3faa8aa29a2145888f2f2db4d2cc1be79805331 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 e0f66130a02ba1ba5062e2d9730cea09134ec7b9..0bc3c81c3d43313ceabd660fe5873c727e194eb0 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,8 +25,8 @@ import { } from "../irnodes"; import * as jshelpers from "../jshelpers"; import { LOGD } from "../log"; -import { ModuleScope, Scope } from "../scope"; import { isFunctionLikeDeclaration } from "../syntaxCheckHelper"; +import { CmdOptions } from "../cmdOptions"; export function containSpreadElement(args?: ts.NodeArray): boolean { if (!args) { @@ -69,16 +68,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; @@ -196,7 +185,7 @@ export function initiateTs2abc(args: Array) { args.unshift("--compile-by-pipe"); var spawn = require('child_process').spawn; let child = spawn(js2abc, [...args], { - stdio: ['pipe', 'inherit', 'inherit', 'pipe'] + stdio: ['pipe', 'inherit', 'pipe', 'pipe'] }); return child; @@ -206,10 +195,19 @@ export function terminateWritePipe(ts2abc: any) { if (!ts2abc) { LOGD("ts2abc is not a valid object"); } - ts2abc.stdio[3].end(); } +export function initiateTs2abcChildProcess(outputFileName: string): any { + let ts2abcProcess; + if (!CmdOptions.isAssemblyMode()) { + ts2abcProcess = initiateTs2abc([outputFileName]); + listenChildExit(ts2abcProcess); + listenErrorEvent(ts2abcProcess); + } + return ts2abcProcess; +} + export function listenChildExit(child: any) { if (!child) { LOGD("child is not a valid object"); @@ -295,4 +293,25 @@ export function getRangeStartVregPos(ins: IRNode): number { return -1; } return ins instanceof EcmaCreateobjectwithexcludedkeys ? 2 : 1; -} \ No newline at end of file +} + +export function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { + for (let statement of sourceFile.statements) { + if (statement.modifiers) { + for (let modifier of statement.modifiers) { + if (modifier.kind === ts.SyntaxKind.ExportKeyword) { + return false; + } + } + } else if (statement.kind === ts.SyntaxKind.ExportAssignment) { + return false; + } else if (statement.kind === ts.SyntaxKind.ImportKeyword || statement.kind === ts.SyntaxKind.ImportDeclaration) { + return false; + } + } + return true; +} + +export function isSourceFileFromLibrary(program:ts.Program, node: ts.SourceFile) { + return program.isSourceFileFromExternalLibrary(node) || program.isSourceFileDefaultLibrary(node); +} diff --git a/ts2panda/src/cmdOptions.ts b/ts2panda/src/cmdOptions.ts index 884d706ea7ffed403982e683fcd50e820285d88c..6bd289f5e9f7c4b97f9d7ede2d7024ef18310827 100644 --- a/ts2panda/src/cmdOptions.ts +++ b/ts2panda/src/cmdOptions.ts @@ -22,214 +22,281 @@ import path = require("path"); import { execute } from "./base/util"; const ts2pandaOptions = [ - { name: 'variant-bytecode', alias: 'r', type: Boolean, defaultValue: true, description: "emit 2nd bytecode to pandafile." }, - { name: 'modules', alias: 'm', type: Boolean, defaultValue: false, description: "compile as module." }, - { name: 'debug-log', alias: 'l', type: Boolean, defaultValue: false, description: "show info debug log and generate the json file."}, - { name: 'dump-assembly', alias: 'a', type: Boolean, defaultValue: false, description: "dump assembly to file." }, - { name: 'debug', alias: 'd', type: Boolean, defaultValue: false, description: "compile with debug info." }, - { name: 'show-statistics', alias: 's', type: String, lazyMultiple: true, defaultValue: "", description: "show compile statistics(ast, histogram, hoisting, all)." }, - { name: 'output', alias: 'o', type: String, defaultValue: "", description: "set output file." }, - { name: 'timeout', alias: 't', type: Number, defaultValue: 0, description: "js to abc timeout threshold(unit: seconds)." }, - { name: 'opt-log-level', type: String, defaultValue: "error", description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" }, - { - name: 'opt-level', type: Number, defaultValue: 1, description: "Optimization level. Possible values: [0, 1, 2]. Default: 0\n 0: no optimizations\n \ - 1: basic bytecode optimizations, including valueNumber, lowering, constantResolver, regAccAllocator\n \ - 2: other bytecode optimizations, unimplemented yet"}, - { name: 'help', alias: 'h', type: Boolean, description: "Show usage guide." }, - { name: 'bc-version', alias: 'v', type: Boolean, defaultValue: false, description: "Print ark bytecode version" }, - { name: 'bc-min-version', type: Boolean, defaultValue: false, description: "Print ark bytecode minimum supported version" }, - { name: 'included-files', alias: 'i', type: String, lazyMultiple: true, defaultValue: [], description: "The list of dependent files." }, - { name: 'record-type', alias: 'p', type: Boolean, defaultValue: false, description: "Record type info. Default: true" }, - { name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, description: "Record type info for .d.ts files. Default: false" }, - { name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, description: "Print type-related log. Default: false" }, - { name: 'output-type', type: Boolean, defaultValue: false, description: "set output type."} + { + name: 'variant-bytecode', alias: 'r', type: Boolean, defaultValue: true, + description: "emit 2nd bytecode to pandafile." + }, + { + name: 'modules', alias: 'm', type: Boolean, defaultValue: false, + description: "compile as module." + }, + { + name: 'debug-log', alias: 'l', type: Boolean, defaultValue: false, + description: "show info debug log." + }, + { + name: 'dump-assembly', alias: 'a', type: Boolean, defaultValue: false, + description: "dump assembly to file." + }, + { + name: 'debug', alias: 'd', type: Boolean, defaultValue: false, + description: "compile with debug info." + }, + { + name: 'show-statistics', alias: 's', type: String, lazyMultiple: true, defaultValue: "", + description: "show compile statistics(ast, histogram, hoisting, all)." + }, + { + name: 'output', alias: 'o', type: String, defaultValue: "", + description: "set output file." + }, + { + name: 'timeout', alias: 't', type: Number, defaultValue: 0, + description: "js to abc timeout threshold(unit: seconds)." + }, + { + name: 'opt-log-level', type: String, defaultValue: "error", + description: "specifie optimizer log level. Possible values: ['debug', 'info', 'error', 'fatal']" + }, + { + name: 'opt-level', type: Number, defaultValue: 1, + description: `Optimization level. Possible values: [0, 1, 2]. Default: 0\n + 0: no optimizations\n + 1: basic bytecode optimizations, including valueNumber, lowering, constantResolver, regAccAllocator\n + 2: other bytecode optimizations, unimplemented yet` + }, + { + name: 'help', alias: 'h', type: Boolean, + description: "Show usage guide." + }, + { + name: 'bc-version', alias: 'v', type: Boolean, defaultValue: false, + description: "Print ark bytecode version" + }, + { + name: 'bc-min-version', type: Boolean, defaultValue: false, + description: "Print ark bytecode minimum supported version" + }, + { + name: 'record-type', alias: 'p', type: Boolean, defaultValue: false, + description: "Record type info. Default: true" + }, + { + name: 'dts-type-record', alias: 'q', type: Boolean, defaultValue: false, + description: "Record type info for .d.ts files. Default: false" + }, + { + name: 'debug-type', alias: 'g', type: Boolean, defaultValue: false, + description: "Record type info for .d.ts files. Default: false" + }, + { + name: 'output-type', type: Boolean, defaultValue: false, + description: "set output type." + }, + { + name: 'merge-abc-files', alias: 'e', type: Boolean, defaultValue: false, + description: "Merge multiple abc files into one" + }, + { + name: 'modules-dir-map', type: String, defaultValue: "", + description: "The modules path map relation table." + } ] - - export class CmdOptions { - private static parsedResult: ts.ParsedCommandLine; - private static options: commandLineArgs.CommandLineOptions; + private static parsedResult: ts.ParsedCommandLine; + private static options: commandLineArgs.CommandLineOptions; - static isEnableDebugLog(): boolean { - if (!this.options) { - return false; - } - return this.options["debug-log"]; + static isEnableDebugLog(): boolean { + if (!this.options) { + return false; } + return this.options["debug-log"]; + } - static isAssemblyMode(): boolean { - if (!this.options) { - return false; - } - return this.options["dump-assembly"]; + static isAssemblyMode(): boolean { + if (!this.options) { + return false; } + return this.options["dump-assembly"]; + } - static isDebugMode(): boolean { - if (!this.options) { - return false; - } - return this.options["debug"]; + static isDebugMode(): boolean { + if (!this.options) { + return false; } + return this.options["debug"]; + } - static isModules(): boolean { - if (!this.options) { - return false; - } - return this.options["modules"]; + static isModules(): boolean { + if (!this.options) { + return false; } + return this.options["modules"]; + } - static isVariantBytecode(): boolean { - if (!this.options) { - return true; - } - return this.options["variant-bytecode"]; + static isVariantBytecode(): boolean { + if (!this.options) { + return true; } + return this.options["variant-bytecode"]; + } - static getOptLevel(): number { - return this.options["opt-level"]; - } + static getOptLevel(): number { + return this.options["opt-level"]; + } - static getOptLogLevel(): string { - return this.options["opt-log-level"]; - } + static getOptLogLevel(): string { + return this.options["opt-log-level"]; + } - static showASTStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("ast") || this.options["show-statistics"].includes("all"); + static showASTStatistics(): boolean { + if (!this.options) { + return false; } + return this.options["show-statistics"].includes("ast") || this.options["show-statistics"].includes("all"); + } - static showHistogramStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("histogram"); + static showHistogramStatistics(): boolean { + if (!this.options) { + return false; } + return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("histogram"); + } - static showHoistingStatistics(): boolean { - if (!this.options) { - return false; - } - return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("hoisting"); + static showHoistingStatistics(): boolean { + if (!this.options) { + return false; } - - static getInputFileName(): string { - let path = this.parsedResult.fileNames[0]; - let inputFile = path.substring(0, path.lastIndexOf('.')); - return inputFile; + return this.options["show-statistics"].includes("all") || this.options["show-statistics"].includes("hoisting"); + } + + static getInputFileName(): string { + let path = this.parsedResult.fileNames[0]; + let inputFile = path.substring(0, path.lastIndexOf('.')); + return inputFile; + } + + static getOutputFileName(): string { + let outputFile = this.options.output; + if (outputFile == "") { + outputFile = CmdOptions.getInputFileName() + ".abc"; } + return outputFile; + } - static getOutputBinName(): string { - let outputFile = this.options.output; - if (outputFile == "") { - outputFile = CmdOptions.getInputFileName() + ".abc"; - } - return outputFile; + static getTimeOut(): Number { + if (!this.options) { + return 0; } + return this.options["timeout"]; + } - static getTimeOut(): Number { - if (!this.options) { - return 0; - } - return this.options["timeout"]; + static isOutputType(): false { + if (!this.options) { + return false; } - - static isOutputType(): false { - if (!this.options) { - return false; - } - return this.options["output-type"]; + return this.options["output-type"]; + } + + static showHelp(): void { + const usage = commandLineUsage([ + { + header: "Ark JavaScript Compiler", + content: 'node --expose-gc index.js [options] file.js' + }, + { + header: 'Options', + optionList: ts2pandaOptions + }, + { + content: 'Project Ark' + } + ]) + LOGE(usage); + } + + static isBcVersion(): boolean { + if (!this.options) { + return false; } - - static showHelp(): void { - const usage = commandLineUsage([ - { - header: "Ark JavaScript Compiler", - content: 'node --expose-gc index.js [options] file.js' - }, - { - header: 'Options', - optionList: ts2pandaOptions - }, - { - content: 'Project Ark' - } - ]) - LOGE(usage); + return this.options["bc-version"]; + } + + static getVersion(isBcVersion: boolean = true): void { + let js2abc = path.join(path.resolve(__dirname, '../bin'), "js2abc"); + let version_arg = isBcVersion ? "--bc-version" : "--bc-min-version" + execute(`${js2abc}`, [version_arg]); + } + + static isBcMinVersion(): boolean { + if (!this.options) { + return false; } + return this.options["bc-min-version"]; + } - static isBcVersion(): boolean { - if (!this.options) { - return false; - } - return this.options["bc-version"]; + static needRecordType(): boolean { + if (!this.options) { + return false; } - static getVersion(isBcVersion: boolean = true): void { - let js2abc = path.join(path.resolve(__dirname, '../bin'), "js2abc"); - let version_arg = isBcVersion ? "--bc-version" : "--bc-min-version" - execute(`${js2abc}`, [version_arg]); - } + return !this.options["record-type"]; + } - static isBcMinVersion(): boolean { - if (!this.options) { - return false; - } - return this.options["bc-min-version"]; + static needRecordDtsType(): boolean { + if (!this.options) { + return false; } + return this.options["dts-type-record"]; + } - static getIncludedFiles(): string[] { - if (!this.options) { - return []; - } - - return this.options["included-files"]; + static enableTypeLog(): boolean { + if (!this.options) { + return false; } + return this.options["debug-type"]; + } - static needRecordType(): boolean { - if (!this.options) { - return false; - } - - return !this.options["record-type"]; + static getModulesDirMap(): string[] { + if (!this.options) { + return []; } - - static needRecordDtsType(): boolean { - if (!this.options) { - return false; - } - return this.options["dts-type-record"]; + let file = this.options["modules-dir-map"]; + if (file) { + let files = file.split(","); + return files; } + return []; + } - static enableTypeLog(): boolean { - if (!this.options) { - return false; - } - return this.options["debug-type"]; + static isMergeAbcFiles(): boolean { + if (!this.options) { + return false; + } + return this.options["merge-abc-files"]; + } + + static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { + this.options = commandLineArgs(ts2pandaOptions, { partial: true }); + if (this.options.help) { + this.showHelp(); + return undefined; } - static parseUserCmd(args: string[]): ts.ParsedCommandLine | undefined { - this.options = commandLineArgs(ts2pandaOptions, { partial: true }); - if (this.options.help) { - this.showHelp(); - return undefined; - } - - if (this.isBcVersion() || this.isBcMinVersion()) { - this.getVersion(this.isBcVersion()); - return undefined; - } - - if (!this.options._unknown) { - LOGE("options at least one file is needed"); - this.showHelp(); - return undefined; - } + if (this.isBcVersion() || this.isBcMinVersion()) { + this.getVersion(this.isBcVersion()); + return undefined; + } - this.parsedResult = ts.parseCommandLine(this.options._unknown!); - return this.parsedResult; + if (!this.options._unknown) { + LOGE("options at least one file is needed"); + this.showHelp(); + return undefined; } + this.parsedResult = ts.parseCommandLine(this.options._unknown!); + return this.parsedResult; + } + } diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index b323fc7b57b1b4b19bf7d1b31ca0b52fa3ff48bd..e1c5849eadb564dcf7fc2c52e78629a25bed011c 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; @@ -498,6 +496,9 @@ export class Compiler { case ts.SyntaxKind.ExportDeclaration: case ts.SyntaxKind.NotEmittedStatement: case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.EnumDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ModuleDeclaration: break; default: throw new Error("Statement " + this.getNodeName(stmt) + " is unimplemented"); @@ -515,18 +516,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 +535,6 @@ export class Compiler { && decl.parent.kind != ts.SyntaxKind.CatchClause) { this.pandaGen.loadAccumulator(decl, getVregisterCache(this.pandaGen, CacheList.undefined)); } - } lref.setValue(); } @@ -695,26 +689,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) { @@ -772,7 +756,7 @@ export class Compiler { compileExpression(expr: ts.Expression) { // Please keep order of cases the same as in types.ts - LOGD(this.debugTag, "compile expr:" + expr.kind); + LOGD(this.debugTag, "compile expr:" + this.getNodeName(expr)); switch (expr.kind) { case ts.SyntaxKind.NumericLiteral: // line 34 compileNumericLiteral(this.pandaGen, expr); @@ -872,6 +856,7 @@ export class Compiler { compileClassDeclaration(this, expr); break; case ts.SyntaxKind.PartiallyEmittedExpression: + case ts.SyntaxKind.AsExpression: break; default: throw new Error("Expression of type " + this.getNodeName(expr) + " is unimplemented"); @@ -1481,13 +1466,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 +1539,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.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 e4dd5dc0c6a34290e38ef6b1db101abba0b67565..b1f798d54e4de1999f3f3c1cbd23b2dd8895911f 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -17,17 +17,16 @@ 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, initiateTs2abcChildProcess, terminateWritePipe } from "./base/util"; +import { LiteralBuffer } from "./base/literal"; import { CmdOptions } from "./cmdOptions"; -import { - Compiler -} from "./compiler"; +import { Compiler } from "./compiler"; import { CompilerStatistics } from "./compilerStatistics"; 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 +40,10 @@ 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( @@ -59,7 +58,7 @@ export class PendingCompilationUnit { * It handles all dependencies and run passes. */ export class CompilerDriver { - private fileName: string; + private outputfileName: string; private passes: Pass[]; private compilationUnits: PandaGen[]; pendingCompilationUnits: PendingCompilationUnit[]; @@ -68,31 +67,34 @@ export class CompilerDriver { private statistics: CompilerStatistics; private needDumpHeader: boolean = true; private ts2abcProcess: any = undefined; + private recoderName: string; - constructor(fileName: string) { - this.fileName = fileName; + constructor(outputFileName: string, ts2abcProc: any, recoderName: string) { + this.outputfileName = outputFileName; // register passes here this.passes = [ new CacheExpander(), new IntrinsicExpander(), - new RegAlloc() + new RegAlloc(), ]; this.compilationUnits = []; this.pendingCompilationUnits = []; this.statistics = new CompilerStatistics(); - } - - initiateTs2abcChildProcess() { - this.ts2abcProcess = initiateTs2abc([this.fileName]); + this.ts2abcProcess = ts2abcProc; + this.recoderName = recoderName; } getTs2abcProcess(): any { if (this.ts2abcProcess === undefined) { - throw new Error("ts2abc hasn't been initiated") + throw new Error("ts2abc hasn't been initiated"); } return this.ts2abcProcess; } + setTs2abcProcess(ts2abcProc: any) { + this.ts2abcProcess = ts2abcProc; + } + getStatistics() { return this.statistics; } @@ -101,7 +103,15 @@ export class CompilerDriver { this.passes = passes; } - addCompilationUnit(decl: ts.FunctionLikeDeclaration, scope: Scope, recorder: Recorder): string { + getRecoderName(): string { + return this.recoderName; + } + + addCompilationUnit( + decl: ts.FunctionLikeDeclaration, + scope: Scope, + recorder: Recorder + ): string { let internalName = this.getFuncInternalName(decl, recorder); this.pendingCompilationUnits.push( new PendingCompilationUnit(decl, scope, internalName) @@ -118,10 +128,10 @@ export class CompilerDriver { } getASTStatistics(node: ts.Node, statics: number[]) { - node.forEachChild(childNode => { + node.forEachChild((childNode) => { statics[childNode.kind] = statics[childNode.kind] + 1; this.getASTStatistics(childNode, statics); - }) + }); } // sort all function in post order @@ -146,84 +156,90 @@ export class CompilerDriver { } compileForSyntaxCheck(node: ts.SourceFile): void { - let recorder = this.compilePrologue(node, false); - checkDuplicateDeclaration(recorder); - checkExportEntries(recorder); + try { + let recorder = this.compilePrologue(node, false); + checkDuplicateDeclaration(recorder); + } catch (err) { + if (CmdOptions.isMergeAbcFiles()) { + terminateWritePipe(this.getTs2abcProcess()); + } + throw err; + } } compile(node: ts.SourceFile): void { - if (CmdOptions.showASTStatistics()) { - let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); - - this.getASTStatistics(node, statics); - statics.forEach((element, idx) => { - if (element > 0) { - LOGD(this.kind2String(idx) + " = " + element); - } - }); + this.showASTStatistics(node); + if (!CmdOptions.isMergeAbcFiles()) { + let ts2abcProc: any = initiateTs2abcChildProcess(this.outputfileName); + this.setTs2abcProcess(ts2abcProc); } - let recorder = this.compilePrologue(node, true); + let recorder: Recorder; + try { + recorder = this.compilePrologue(node, true); + } catch (err) { + terminateWritePipe(this.getTs2abcProcess()); + throw err; + } - // initiate ts2abc if (!CmdOptions.isAssemblyMode()) { - this.initiateTs2abcChildProcess(); - let ts2abcProc = this.getTs2abcProcess(); - listenChildExit(ts2abcProc); - listenErrorEvent(ts2abcProc); - try { - Ts2Panda.dumpCmdOptions(ts2abcProc); + this.prePendingCompilationUnits(recorder); - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); - } - - Ts2Panda.dumpStringsArray(ts2abcProc); - Ts2Panda.dumpConstantPool(ts2abcProc); - - terminateWritePipe(ts2abcProc); - if (CmdOptions.isEnableDebugLog()) { - let jsonFileName = this.fileName.substring(0, this.fileName.lastIndexOf(".")).concat(".json"); - writeFileSync(jsonFileName, Ts2Panda.jsonString); - LOGD("Successfully generate ", `${jsonFileName}`); + if (!CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCommonFields(this.getTs2abcProcess(), this.outputfileName); + Ts2Panda.clearDumpData(); } if (CmdOptions.isOutputType()) { - let typeFileName = this.fileName.substring(0, this.fileName.lastIndexOf(".")).concat(".txt"); + let typeFileName = this.outputfileName.substring(0, this.outputfileName.lastIndexOf(".")).concat(".txt"); writeFileSync(typeFileName, Ts2Panda.dumpTypeLiteralArrayBuffer()); } - Ts2Panda.clearDumpData(); + // Ts2Panda.clearDumpData(); } catch (err) { - terminateWritePipe(ts2abcProc); + terminateWritePipe(this.getTs2abcProcess()); throw err; } } else { - for (let i = 0; i < this.pendingCompilationUnits.length; i++) { - let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); - } + this.prePendingCompilationUnits(recorder); } - PandaGen.clearLiteralArrayBuffer(); + if (!CmdOptions.isMergeAbcFiles()) { + PandaGen.clearRecoders(); + PandaGen.clearLiteralArrayBuffer(); + } + } + + private showASTStatistics(node: ts.SourceFile): void { + if (CmdOptions.showASTStatistics()) { + let statics: number[] = new Array(ts.SyntaxKind.Count).fill(0); + + this.getASTStatistics(node, statics); + statics.forEach((element, idx) => { + if (element > 0) { + LOGD(this.kind2String(idx) + " = " + element); + } + }); + } + } + + private prePendingCompilationUnits(recorder: Recorder): void { + for (let i = 0; i < this.pendingCompilationUnits.length; i++) { + let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; + this.compileImpl(unit.decl, unit.scope, unit.internalName, recorder); + } } - private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder): void { + private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder): void { let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); // for debug info DebugInfo.addDebugIns(scope, pandaGen, true); 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)); @@ -249,7 +265,12 @@ export class CompilerDriver { for (let i = 0; i < this.pendingCompilationUnits.length; i++) { let unit: PendingCompilationUnit = this.pendingCompilationUnits[i]; - this.compileUnitTestImpl(unit.decl, unit.scope, unit.internalName, recorder); + this.compileUnitTestImpl( + unit.decl, + unit.scope, + unit.internalName, + recorder + ); } if (literalBufferArray) { PandaGen.getLiteralArrayBuffer().forEach(val => literalBufferArray.push(val)); @@ -258,16 +279,10 @@ export class CompilerDriver { PandaGen.clearLiteralArrayBuffer(); } - private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, - internalName: string, recorder: Recorder) { + private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder) { 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(); @@ -288,7 +303,7 @@ export class CompilerDriver { private compilePrologue(node: ts.SourceFile, recordType: boolean) { let topLevelScope: GlobalScope | ModuleScope; if (CmdOptions.isModules()) { - topLevelScope = new ModuleScope(node); + topLevelScope = new ModuleScope(node, this.recoderName); } else { topLevelScope = new GlobalScope(node); } @@ -300,12 +315,19 @@ 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) { - this.addCompilationUnit(variableScope.getBindingNode(), variableScope, recorder); + this.addCompilationUnit( + variableScope.getBindingNode(), + variableScope, + recorder + ); } return recorder; @@ -337,6 +359,12 @@ export class CompilerDriver { return idx; } + getRecoderFuncName(funcName: string): string { + let recoderName: string = this.getRecoderName(); + funcName = `${recoderName}.${funcName}` + return funcName; + } + /** * Internal name is used to indentify a function in panda file * Runtime uses this name to bind code and a Function object @@ -351,29 +379,31 @@ export class CompilerDriver { } else { let funcNode = node; name = (recorder.getScopeOfNode(funcNode)).getFuncName(); - if (name == '') { - return `#${this.getFuncId(funcNode)}#`; - } - - if (name == "func_main_0") { - return `#${this.getFuncId(funcNode)}#${name}`; - } - - let funcNameMap = recorder.getFuncNameMap(); - if (funcNameMap.has(name)) { - let freq = funcNameMap.get(name); - if (freq > 1) { - name = `#${this.getFuncId(funcNode)}#${name}`; + if (name == "") { + if ((ts.isFunctionDeclaration(node) && hasExportKeywordModifier(node) && hasDefaultKeywordModifier(node)) + || ts.isExportAssignment(findOuterNodeOfParenthesis(node))) { + return 'default'; } + name = `#${this.getFuncId(funcNode)}#`; + } else if (name == "func_main_0") { + name = `#${this.getFuncId(funcNode)}#${name}`; } else { - throw new Error("the function name is missing from the name map"); - } + let funcNameMap = recorder.getFuncNameMap(); + if (funcNameMap.has(name)) { + let freq = funcNameMap.get(name); + if (freq > 1) { + name = `#${this.getFuncId(funcNode)}#${name}`; + } + } else { + throw new Error("the function name is missing from the name map"); + } - if (name.lastIndexOf(".") != -1) { - name = `#${this.getFuncId(funcNode)}#` + if (name.lastIndexOf(".") != -1) { + name = `#${this.getFuncId(funcNode)}#`; + } } } - return name; + return this.getRecoderFuncName(name); } getInternalNameForCtor(node: ts.ClassLikeDeclaration, ctor: ts.ConstructorDeclaration) { diff --git a/ts2panda/src/debuginfo.ts b/ts2panda/src/debuginfo.ts index 8e3b5c8fed18353e0feaff1f4675b2eca1972a78..4b34759b1c5d43022038615b846febf288f02f6a 100644 --- a/ts2panda/src/debuginfo.ts +++ b/ts2panda/src/debuginfo.ts @@ -379,7 +379,7 @@ export class DebugInfo { public static setSourceFileDebugInfo(pandaGen: PandaGen, node: ts.SourceFile | ts.FunctionLikeDeclaration) { let sourceFile = jshelpers.getSourceFileOfNode(node); - pandaGen.setSourceFileDebugInfo(sourceFile.fileName); + pandaGen.setSourceFileName(sourceFile.fileName); if (CmdOptions.isDebugMode()) { if (ts.isSourceFile(node)) { diff --git a/ts2panda/src/ecmaModule.ts b/ts2panda/src/ecmaModule.ts new file mode 100644 index 0000000000000000000000000000000000000000..13509b65893606d553114b4201edb76f32e2414c --- /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 c18cab39dc057896cf695d6ed7f4b1d3f92c6c6d..2ff281e88df7387a6ae55e7a98bf235d823ed7e6 100644 --- a/ts2panda/src/hoisting.ts +++ b/ts2panda/src/hoisting.ts @@ -14,7 +14,6 @@ */ import * as ts from "typescript"; -import { hasExportKeywordModifier, hasDefaultKeywordModifier } from "./base/util"; import { CacheList, getVregisterCache } from "./base/vregisterCache"; import { Compiler } from "./compiler"; import { CompilerDriver } from "./compilerDriver"; @@ -27,14 +26,14 @@ import { GlobalScope, LocalScope, ModuleScope, + ModuleVarKind, Scope, VarDecl, VariableScope } from "./scope"; -import { LocalVariable } from "./variable"; export function hoisting(rootNode: ts.SourceFile | ts.FunctionLikeDeclaration, pandaGen: PandaGen, - recorder: Recorder, compiler: Compiler) { + recorder: Recorder, compiler: Compiler) { let variableScope = recorder.getScopeOfNode(rootNode); let hoistDecls = recorder.getHoistDeclsOfScope(variableScope); @@ -59,7 +58,11 @@ export function hoistVar(decl: VarDecl, scope: Scope, pandaGen: PandaGen) { } else if (scope instanceof FunctionScope || scope instanceof ModuleScope) { let v = scope.findLocal(name)!; pandaGen.loadAccumulator(NodeKind.FirstNodeOfFunction, getVregisterCache(pandaGen, CacheList.undefined)); - pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + if (decl.isModule !== ModuleVarKind.NOT) { + pandaGen.storeModuleVariable(NodeKind.FirstNodeOfFunction, name); + } else { + pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + } } else { throw new Error("Wrong scope to hoist"); } @@ -74,19 +77,13 @@ export function hoistFunction(decl: FuncDecl, scope: Scope, pandaGen: PandaGen, pandaGen.defineFunction(NodeKind.FirstNodeOfFunction, decl.node, internalName, env); pandaGen.storeGlobalVar(NodeKind.FirstNodeOfFunction, funcName); } else if ((scope instanceof FunctionScope) || (scope instanceof LocalScope) || (scope instanceof ModuleScope)) { - let hasExport: boolean = hasExportKeywordModifier(decl.node); - let hasDefault: boolean = hasDefaultKeywordModifier(decl.node); let v = scope.findLocal(funcName)!; - if (hasExport && scope instanceof ModuleScope) { - (v).setExport(); - if (hasDefault) { - (v).setExportedName("default"); - } else { - (v).setExportedName(v.getName()); - } - } pandaGen.defineFunction(NodeKind.FirstNodeOfFunction, decl.node, internalName, env); - pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + if (decl.isModule !== ModuleVarKind.NOT) { + pandaGen.storeModuleVariable(NodeKind.FirstNodeOfFunction, funcName); + } else { + pandaGen.storeAccToLexEnv(NodeKind.FirstNodeOfFunction, scope, 0, v, true); + } } else { throw new Error("Wrong scope to hoist"); } diff --git a/ts2panda/src/index.ts b/ts2panda/src/index.ts index 19cc5075fadb8af7c479d97f610eef1b8a076ac3..618ef8507a983ac8a9457cb177a30b04bb790d07 100644 --- a/ts2panda/src/index.ts +++ b/ts2panda/src/index.ts @@ -14,79 +14,49 @@ */ import * as ts from "typescript"; +import { + checkIsGlobalDeclaration, + initiateTs2abcChildProcess, + isSourceFileFromLibrary +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { CompilerDriver } from "./compilerDriver"; import * as diag from "./diagnostic"; import { LOGD, LOGE } from "./log"; +import { PandaGen } from "./pandagen"; +import { Record } from "./pandasm"; import { Pass } from "./pass"; import { CacheExpander } from "./pass/cacheExpander"; import { ICPass } from "./pass/ICPass"; import { RegAlloc } from "./regAllocator"; -import { setGlobalStrict, setGlobalDeclare, isGlobalDeclare } from "./strictMode"; +import { setGlobalDeclare, setGlobalStrict } from "./strictMode"; +import { Ts2Panda } from "./ts2panda"; import { TypeChecker } from "./typeChecker"; -import { TypeRecorder } from "./typeRecorder"; import jshelpers = require("./jshelpers"); import path = require("path"); -function checkIsGlobalDeclaration(sourceFile: ts.SourceFile) { - for (let statement of sourceFile.statements) { - if (statement.modifiers) { - for (let modifier of statement.modifiers) { - if (modifier.kind === ts.SyntaxKind.ExportKeyword) { - return false; - } - } - } else if (statement.kind === ts.SyntaxKind.ExportAssignment) { - return false; - } else if (statement.kind === ts.SyntaxKind.ImportKeyword || statement.kind === ts.SyntaxKind.ImportDeclaration) { - return false; - } - } - return true; -} - -function generateDTs(node: ts.SourceFile, options: ts.CompilerOptions) { - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); - setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); - if (CmdOptions.isVariantBytecode()) { - LOGD("variant bytecode dump"); - let passes: Pass[] = [ - new CacheExpander(), - new ICPass(), - new RegAlloc() - ]; - compilerDriver.setCustomPasses(passes); - } - compilerDriver.compile(node); - compilerDriver.showStatistics(); -} - function main(fileNames: string[], options: ts.CompilerOptions) { - let program = ts.createProgram(fileNames, options); + let program: ts.Program = ts.createProgram(fileNames, options); let typeChecker = TypeChecker.getInstance(); typeChecker.setTypeChecker(program.getTypeChecker()); - if (CmdOptions.needRecordDtsType()) { - for (let sourceFile of program.getSourceFiles()) { - if (sourceFile.isDeclarationFile && !program.isSourceFileDefaultLibrary(sourceFile)) { - setGlobalDeclare(checkIsGlobalDeclaration(sourceFile)); - generateDTs(sourceFile, options); - } - } + let outputFileName: string = CmdOptions.getOutputFileName(); + let ts2abcProc: any + if (CmdOptions.isMergeAbcFiles()) { + ts2abcProc = initiateTs2abcChildProcess(outputFileName); } + generateDTs(program, outputFileName, options, ts2abcProc); + let emitResult = program.emit( - undefined, - undefined, - undefined, - undefined, + undefined, undefined, undefined, undefined, { before: [ (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); + let recoderName: string = getRecoderName(node.fileName); + let outputBinName = getOutputFileName(node, outputFileName); + let compilerDriver = new CompilerDriver(outputBinName, ts2abcProc, recoderName); compilerDriver.compileForSyntaxCheck(node); return node; } @@ -95,55 +65,24 @@ function main(fileNames: string[], options: ts.CompilerOptions) { after: [ (ctx: ts.TransformationContext) => { return (node: ts.SourceFile) => { - if (ts.getEmitHelpers(node)) { - const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - const text: string = printer.printNode(ts.EmitHint.Unspecified, node, node); - let newNode = ts.createSourceFile(node.fileName, text, options.target!); - node = newNode; - } - let outputBinName = getOutputBinName(node); - let compilerDriver = new CompilerDriver(outputBinName); - setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); - if (CmdOptions.isVariantBytecode()) { - LOGD("variant bytecode dump"); - let passes: Pass[] = [ - new CacheExpander(), - new ICPass(), - new RegAlloc() - ]; - compilerDriver.setCustomPasses(passes); - } - compilerDriver.compile(node); - compilerDriver.showStatistics(); - return node; + return ts2abcTransform(node, outputFileName, options, ts2abcProc); } } ] } ); - let allDiagnostics = ts - .getPreEmitDiagnostics(program) - .concat(emitResult.diagnostics); - - allDiagnostics.forEach(diagnostic => { - diag.printDiagnostic(diagnostic); - }); -} - -function getOutputBinName(node: ts.SourceFile) { - let outputBinName = CmdOptions.getOutputBinName(); - let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); - let inputFileName = CmdOptions.getInputFileName(); - if (/^win/.test(require('os').platform())) { - var inputFileTmps = inputFileName.split(path.sep); - inputFileName = path.posix.join(...inputFileTmps); + if (preDiagnostics(program, emitResult)) { + return; } - if (fileName != inputFileName) { - outputBinName = fileName + ".abc"; + if (!CmdOptions.isAssemblyMode()) { + if (CmdOptions.isMergeAbcFiles()) { + Ts2Panda.dumpCommonFields(ts2abcProc, outputFileName); + PandaGen.clearRecoders(); + PandaGen.clearLiteralArrayBuffer(); + } } - return outputBinName; } namespace Compiler { @@ -157,11 +96,93 @@ namespace Compiler { module: ts.ModuleKind.ES2015, strictNullChecks: true, skipLibCheck: true, - alwaysStrict: true + alwaysStrict: true, + importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve }; } } +function generateDTs(program: ts.Program, outputFileName: string, options: ts.CompilerOptions, ts2abcProc: any): void { + if (CmdOptions.needRecordDtsType()) { + for (let sourceFile of program.getSourceFiles()) { + if (sourceFile.isDeclarationFile && !isSourceFileFromLibrary(program, sourceFile)) { + setGlobalDeclare(checkIsGlobalDeclaration(sourceFile)); + ts2abcTransform(sourceFile, outputFileName, options, ts2abcProc); + } + } + } +} + +function ts2abcTransform(node: ts.SourceFile, outputFileName: string, options: ts.CompilerOptions, ts2abcProc: any): ts.SourceFile { + let sourceFileName: string = node.fileName; + let recoderName: string = getRecoderName(sourceFileName); + // console.error("-----------------sourceFileName: ", sourceFileName); + // console.error("-----------------recoderName: ", recoderName); + let recoder: Record = new Record(recoderName, sourceFileName); + let recoders: Array = PandaGen.getRecoders(); + recoders.push(recoder); + if (ts.getEmitHelpers(node)) { + const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + const text: string = printer.printNode(ts.EmitHint.Unspecified, node, node); + let newNode = ts.createSourceFile(node.fileName, text, options.target!); + node = newNode; + } + let newOutputFileName: string = getOutputFileName(node, outputFileName); + let compilerDriver = new CompilerDriver(newOutputFileName, ts2abcProc, recoderName); + setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(node, options)); + if (CmdOptions.isVariantBytecode()) { + LOGD("variant bytecode dump"); + let passes: Pass[] = [ + new CacheExpander(), + new ICPass(), + new RegAlloc() + ]; + compilerDriver.setCustomPasses(passes); + } + compilerDriver.compile(node); + compilerDriver.showStatistics(); + return node; +} + +function preDiagnostics(program: ts.Program, emitResult: ts.EmitResult): boolean { + let hasDiagnostics: boolean = false; + let allDiagnostics: ts.Diagnostic[] = ts + .getPreEmitDiagnostics(program) + .concat(emitResult.diagnostics); + + allDiagnostics.forEach((diagnostic: ts.Diagnostic) => { + diag.printDiagnostic(diagnostic); + hasDiagnostics = true; + }); + return hasDiagnostics; +} + +export function getRecoderName(sourceFileName: string): string { + let recoderName: string = sourceFileName.substring(0, sourceFileName.lastIndexOf(".")); + let recoderDirInfo: string[] = CmdOptions.getModulesDirMap(); + if (recoderDirInfo.length) { + let index: number = recoderDirInfo.indexOf(sourceFileName); + if (index !== -1) { + recoderName = recoderDirInfo[index + 1]; + } + } + + return recoderName; +} + +function getOutputFileName(node: ts.SourceFile, outputFileName: string): string { + let fileName = node.fileName.substring(0, node.fileName.lastIndexOf('.')); + let inputFileName = CmdOptions.getInputFileName(); + if (/^win/.test(require('os').platform())) { + var inputFileTmps = inputFileName.split(path.sep); + inputFileName = path.posix.join(...inputFileTmps); + } + if (fileName != inputFileName) { + outputFileName = fileName + ".abc"; + } + return outputFileName; +} + function run(args: string[], options?: ts.CompilerOptions): void { let parsed = CmdOptions.parseUserCmd(args); if (!parsed) { @@ -174,13 +195,13 @@ function run(args: string[], options?: ts.CompilerOptions): void { } } try { - let files: string[] = parsed.fileNames; - main(files.concat(CmdOptions.getIncludedFiles()), parsed.options); + main(parsed.fileNames, parsed.options); } catch (err) { if (err instanceof diag.DiagnosticError) { - let diagnostic = diag.getDiagnostic(err.code); + let diagError: diag.DiagnosticError = err; + let diagnostic: ts.DiagnosticMessage | undefined = diag.getDiagnostic(diagError.code); if (diagnostic != undefined) { - let diagnosticLog = diag.createDiagnostic(err.file, err.irnode, diagnostic, ...err.args); + let diagnosticLog = diag.createDiagnostic(diagError.file, diagError.irnode, diagnostic, ...diagError.args); diag.printDiagnostic(diagnosticLog); } } else if (err instanceof SyntaxError) { diff --git a/ts2panda/src/lexenv.ts b/ts2panda/src/lexenv.ts index d4c1cc77760c973702b96b8a651974effd2fb03f..7069bb0432fe6567f8997fed03d069389155fe82 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 8e1ea468a7997abc8d56396a510f4141e71c6a66..b8110b4fec2113badcb78ebb9cd12aa92fe4cfaf 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 d7b0bfceb7e66f4b1721e37373cd78d29550fcc6..7b47ce6c9f7785f9ed3f6f6ba39887ba26258b84 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, @@ -173,6 +173,7 @@ import { VariableAcessStore } from "./lexenv"; import { LOGE } from "./log"; +import { Record } from "./pandasm"; import { FunctionScope, LoopScope, @@ -200,12 +201,13 @@ export class PandaGen { // for debug info private variableDebugInfoArray: VariableDebugInfo[] = []; private firstStmt: ts.Statement | undefined; - private sourceFileDebugInfo: string = ""; + private sourceFileName: string = ""; private sourceCodeDebugInfo: string | undefined; private icSize: number = 0; private callType: number = 0; private static literalArrayBuffer: Array = new Array(); + private static recoders: Array = new Array(); constructor(internalName: string, parametersCount: number, scope: Scope | undefined = undefined) { this.internalName = internalName; @@ -246,12 +248,12 @@ export class PandaGen { this.sourceCodeDebugInfo = code; } - public getSourceFileDebugInfo() { - return this.sourceFileDebugInfo; + public getSourceFileName() { + return this.sourceFileName; } - public setSourceFileDebugInfo(sourceFile: string) { - this.sourceFileDebugInfo = sourceFile; + public setSourceFileName(sourceFile: string) { + this.sourceFileName = sourceFile; } static getLiteralArrayBuffer() { @@ -262,6 +264,14 @@ export class PandaGen { PandaGen.literalArrayBuffer = []; } + static getRecoders() { + return PandaGen.recoders; + } + + static clearRecoders() { + PandaGen.recoders = []; + } + getParameterLength() { if (this.scope instanceof FunctionScope) { return this.scope.getParameterLength(); @@ -874,6 +884,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 +1094,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 565615a2f5f02e75553723fec2af9ccf9d17fbee..356d9a6df480ab1be22654d1495ac92ebe333200 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; @@ -110,25 +110,16 @@ export class Function { export class Record { public name: string; - public whole_line: string; - public bound_left: number; - public bound_right: number; - public line_number: number; public metadata: Metadata; + public source_file: string; constructor( name: string, - whole_line: string, - bound_left: number, - bound_right: number, - line_number: number + source_file: string ) { this.name = name; - this.whole_line = whole_line; - this.bound_left = bound_left; - this.bound_right = bound_right; - this.line_number = line_number; this.metadata = new Metadata(); + this.source_file = source_file; } } @@ -208,6 +199,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 670bd357f2cb17b733691f9442c546a9a33a013d..66eb504d2ebf5605a312ef615d8e2e5a494d9322 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,8 @@ import { TypeChecker } from "./typeChecker"; import { VarDeclarationKind } from "./variable"; import { TypeRecorder } from "./typeRecorder"; import { PandaGen } from "./pandagen"; +import path = require("path"); +import { getRecoderName } from "./index"; export class Recorder { node: ts.Node; @@ -62,10 +69,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 +123,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 +139,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 +178,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 +212,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 +224,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 +247,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 +265,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 +276,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 +299,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 +345,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 +356,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 +386,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 +404,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 +416,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 +424,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 +435,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 +458,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 +468,178 @@ export class Recorder { return exportStmt; } - private recordFuncDecl(node: ts.FunctionDeclaration, scope: Scope) { + private getModulSpecifierName(node: ts.Node, dependentFile: string): string { + if (CmdOptions.getModulesDirMap() != []) { + let currentSourceFile = jshelpers.getSourceFileOfNode(node).fileName; + let absPath = currentSourceFile.substring(0, currentSourceFile.lastIndexOf('/')); + let dependentAbsFile = path.join(absPath, dependentFile); + + let amiFileName = getRecoderName(dependentAbsFile); + if (amiFileName !== dependentAbsFile.substring(0, dependentAbsFile.lastIndexOf("."))) { + return amiFileName; + } + } + return dependentFile; + } + + 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; + } + if (!ts.isStringLiteral(node.moduleSpecifier)) { + throw new Error("moduleSpecifier must be a stringLiteral"); + } + let moduleRequest: string = this.getModulSpecifierName(node, jshelpers.getTextOfIdentifierOrLiteral(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) { + if (!ts.isStringLiteral(node.moduleSpecifier)) { + throw new Error("moduleSpecifier must be a stringLiteral"); + } + let moduleRequest: string = this.getModulSpecifierName(node, jshelpers.getTextOfIdentifierOrLiteral(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 +797,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 +834,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 79a59c04865401021aba827a91071010202e6d23..bf08b06cdcb3fee28333ae7aed3d2248144f5d55 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, moduleName: string) { super(); - this.node = node ? node : undefined; + this.node = node; + this.moduleRecord = new SourceTextModuleRecord(moduleName); + } + + 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 982d1ab35dd80d43d486a00a5184c8284fd87401..fad9e5eed6e219ca50fa96404358c4b145abe16e 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); @@ -84,7 +89,8 @@ export function compileClassDeclaration(compiler: Compiler, stmt: ts.ClassLikeDe } if (ts.isMethodDeclaration(prop.getValue())) { - let methodLiteral = new Literal(LiteralTag.METHOD, compiler.getCompilerDriver().getFuncInternalName(prop.getValue(), compiler.getRecorder())); + let internalName = compiler.getCompilerDriver().getFuncInternalName(prop.getValue(), compiler.getRecorder()); + let methodLiteral = new Literal(LiteralTag.METHOD, internalName); let affiliateLiteral = new Literal(LiteralTag.METHODAFFILIATE, getParamLengthOfFunc(prop.getValue())); classBuffer.addLiterals(methodLiteral, affiliateLiteral); } else { @@ -113,15 +119,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 } } @@ -233,7 +254,8 @@ function createClassLiteralBuf(compiler: Compiler, classBuffer: LiteralBuffer, let ctorNode = compiler.getRecorder().getCtorOfClass(stmt); let internalName = compiler.getCompilerDriver().getInternalNameForCtor(stmt, ctorNode); - + let recoderName: string = compiler.getCompilerDriver().getRecoderName(); + internalName = `${recoderName}.${internalName}` let pandaGen = compiler.getPandaGen(); let parameterLength = getParameterLength4Ctor(stmt); let buffIdx = classLiteralBuf.length - 1; @@ -499,6 +521,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 +542,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 185e3a2df366f5fa3369b44b7e2d68d8dd127b38..0ffeffdf3a7b6b1fbb837ca65ebd521a13a9ce7e 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 42b09db21ea3cbc61e3a2d34db731a325edbddff..ea59eefab31f48b766d5911945d03355b652a112 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 6e0d6e7cd998823d434bf796f1d7ba567171bcc9..390b1ce7d18f583b19c2dd41e7ec56a8099a06e7 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -13,14 +13,23 @@ * limitations under the License. */ +import { writeFileSync } from "fs"; +import { LiteralBuffer } from "./base/literal"; +import { + escapeUnicode, + getRangeStartVregPos, + isRangeInst, + terminateWritePipe +} from "./base/util"; import { CmdOptions } from "./cmdOptions"; import { DebugPosInfo } from "./debuginfo"; +import { SourceTextModuleRecord } from "./ecmaModule"; import { - Imm, - IRNode, - Label, - OperandType, - VReg + Imm, + IRNode, + Label, + OperandType, + VReg } from "./irnodes"; import { LOGD } from "./log"; import { PandaGen } from "./pandagen"; @@ -30,16 +39,17 @@ import { ExportedSymbol2Type, Function, Ins, - Signature + IndirectExportEntry, + LocalExportEntry, + ModuleRecord, + NamespaceImportEntry, + RegularImportEntry, + Record, + Signature, + TypeOfVreg } from "./pandasm"; +import { ModuleScope } from "./scope"; import { generateCatchTables } from "./statement/tryStatement"; -import { - escapeUnicode, - isRangeInst, - getRangeStartVregPos -} from "./base/util"; -import { TypeOfVreg } from "./pandasm"; -import { LiteralBuffer } from "./base/literal"; const dollarSign: RegExp = /\$/g; @@ -48,13 +58,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() { } @@ -130,7 +141,7 @@ export class Ts2Panda { static dumpStringsArray(ts2abc: any) { let strings_arr = Array.from(Ts2Panda.strings); - strings_arr.forEach(function(str) { + strings_arr.forEach(function (str: string) { let strObject = { "type": JsonType.string, "string": str @@ -172,6 +183,10 @@ export class Ts2Panda { "literalArray": literalArray } let jsonLiteralArrUnicode = escapeUnicode(JSON.stringify(literalArrayObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonLiteralArrUnicode; + } + jsonLiteralArrUnicode = "$" + jsonLiteralArrUnicode.replace(dollarSign, '#$') + "$"; if (CmdOptions.isEnableDebugLog()) { Ts2Panda.jsonString += jsonLiteralArrUnicode; @@ -180,6 +195,23 @@ export class Ts2Panda { }); } + static dumpRecoder(ts2abc: any): void { + let recoders: Record[] = PandaGen.getRecoders(); + + recoders.forEach(function (recoder: Record) { + let recoderObject = { + "type": JsonType.record, + "rec_body": recoder + } + let jsonRecoderUnicode = escapeUnicode(JSON.stringify(recoderObject, null, 2)); + if (CmdOptions.isEnableDebugLog()) { + Ts2Panda.jsonString += jsonRecoderUnicode; + } + jsonRecoderUnicode = "$" + jsonRecoderUnicode.replace(dollarSign, '#$') + "$"; + ts2abc.stdio[3].write(jsonRecoderUnicode + '\n'); + }); + } + static dumpCmdOptions(ts2abc: any): void { let options = { "type": JsonType.options, @@ -201,7 +233,7 @@ export class Ts2Panda { let funcName = pg.internalName; let funcSignature = Ts2Panda.getFuncSignature(pg); let funcInsnsAndRegsNum = Ts2Panda.getFuncInsnsAndRegsNum(pg); - let sourceFile = pg.getSourceFileDebugInfo(); + let sourceFile = pg.getSourceFileName(); let callType = pg.getCallType(); let typeRecord = pg.getLocals(); let typeInfo = new Array(); @@ -218,7 +250,7 @@ export class Ts2Panda { let exportedTypes = PandaGen.getExportedTypes(); let exportedSymbol2Types = exportedTypes.size == 0 ? undefined : new Array(); - if (funcName == "func_main_0") { + if (funcName.indexOf("func_main_0") !== -1) { exportedTypes.forEach((type: number, symbol: string) => { let exportedSymbol2Type = new ExportedSymbol2Type(symbol, type); exportedSymbol2Types!.push(exportedSymbol2Type); @@ -227,13 +259,19 @@ export class Ts2Panda { let declareddTypes = PandaGen.getDeclaredTypes(); let declaredSymbol2Types = declareddTypes.size == 0 ? undefined : new Array(); - if (funcName == "func_main_0") { + if (funcName.indexOf("func_main_0") !== -1) { declareddTypes.forEach((type: number, symbol: string) => { let declaredSymbol2Type = new DeclaredSymbol2Type(symbol, type); declaredSymbol2Types!.push(declaredSymbol2Type); }) } + if (pg.getScope() instanceof ModuleScope) { + Ts2Panda.moduleRecordlist.push( + makeModuleRecord((pg.getScope()).module()) + ); + } + let variables, sourceCode; if (CmdOptions.isDebugMode()) { variables = pg.getVariableDebugInfoArray(); @@ -284,8 +322,71 @@ 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 = []; + } + + static dumpCommonFields(ts2abcProc: any, outputFileName: string) { + Ts2Panda.dumpCmdOptions(ts2abcProc); + Ts2Panda.dumpStringsArray(ts2abcProc); + Ts2Panda.dumpConstantPool(ts2abcProc); + Ts2Panda.dumpRecoder(ts2abcProc); + Ts2Panda.dumpModuleRecords(ts2abcProc); + + terminateWritePipe(ts2abcProc); + if (CmdOptions.isEnableDebugLog()) { + let jsonFileName = outputFileName.substring(0, outputFileName.lastIndexOf(".")).concat(".json"); + writeFileSync(jsonFileName, Ts2Panda.jsonString); + LOGD("Successfully generate ", `${jsonFileName}`); + } + Ts2Panda.clearDumpData(); } } + +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 5563f6dfead7b6694efec3e7d6c0ad4f026be703..c7210551122b12d54fd34373eafdf3c45f5cfcc4 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 795fda099aa820287af95bc61ec1e981a6c8638a..9b414d761efbe5189714ea43198c7cefea79fccc 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/tests/lexenv.test.ts b/ts2panda/tests/lexenv.test.ts index 64bd73f9d4065c49f6ce477b14ae48779665b5af..f7a82c52eae73409d65e6ac312a460cf24d3f5f8 100644 --- a/ts2panda/tests/lexenv.test.ts +++ b/ts2panda/tests/lexenv.test.ts @@ -116,7 +116,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test CompilerDriver.scanFunctions-with-empty", function () { let source: string = ``; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); recorder.record(); @@ -144,7 +145,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { var funcExpression = function() { } `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); recorder.record(); @@ -191,7 +193,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { let source: string = ` `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); @@ -215,7 +218,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { var funcExt = function() { } `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); @@ -269,7 +273,8 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { }))) `; let sourceFile = creatAstFromSnippet(source); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest',undefined, recoderName); let globalScope = new GlobalScope(sourceFile); let recorder = new Recorder(sourceFile, globalScope, compilerDriver, false, false); diff --git a/ts2panda/tests/utils/base.ts b/ts2panda/tests/utils/base.ts index 94b1a99f008d1b9c5645fe9bea47d3f522c74227..4c727a51644e8f125125edc47e5af6a212061e94 100644 --- a/ts2panda/tests/utils/base.ts +++ b/ts2panda/tests/utils/base.ts @@ -143,7 +143,8 @@ export function compileAllSnippet(snippet: string, passes?: Pass[], literalBuffe let sourceFile = creatAstFromSnippet(snippet); jshelpers.bindSourceFile(sourceFile, {}); setGlobalStrict(jshelpers.isEffectiveStrictModeSourceFile(sourceFile, compileOptions)); - let compilerDriver = new CompilerDriver('UnitTest'); + const recoderName: string = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")); + let compilerDriver = new CompilerDriver('UnitTest', undefined, recoderName); if (!passes) { passes = []; diff --git a/ts2panda/ts2abc/ts2abc.cpp b/ts2panda/ts2abc/ts2abc.cpp index b9918d6e0a16aee79fccce8927751ef9e7125b85..835c94e23bf4b5a59da273504bdc2982fd655826 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; @@ -62,17 +61,11 @@ namespace { } // pandasm hellpers -static panda::pandasm::Record MakeRecordDefinition(const std::string &name, const std::string &wholeLine, - size_t boundLeft, size_t boundRight, size_t lineNumber) +static panda::pandasm::Record MakeRecordDefinition(const std::string &name) { auto record = panda::pandasm::Record( name, - LANG_EXT, - boundLeft, - boundRight, - wholeLine, - IS_DEFINED, - lineNumber); + LANG_EXT); return record; } @@ -287,28 +280,7 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) recordName = record["name"].asString(); } - std::string wholeLine = ""; - if (record.isMember("whole_line") && record["whole_line"].isString()) { - wholeLine = ParseString(record["whole_line"].asString()); - } - - int boundLeft = -1; - if (record.isMember("bound_left") && record["bound_left"].isInt()) { - boundLeft = record["bound_left"].asInt(); - } - - int boundRight = -1; - if (record.isMember("bound_right") && record["bound_right"].isInt()) { - boundRight = record["bound_right"].asInt(); - } - - int lineNumber = -1; - if (record.isMember("line_number") && record["line_number"].isInt()) { - lineNumber = record["line_number"].asInt(); - } - - auto pandaRecord = MakeRecordDefinition(recordName, wholeLine, static_cast(boundLeft), - static_cast(boundRight), static_cast(lineNumber)); + auto pandaRecord = MakeRecordDefinition(recordName); if (record.isMember("metadata") && record["metadata"].isObject()) { auto metadata = record["metadata"]; @@ -320,6 +292,10 @@ static panda::pandasm::Record ParseRecord(const Json::Value &record) } } + if (record.isMember("source_file") && record["source_file"].isString()) { + pandaRecord.source_file = record["source_file"].asString(); + } + return pandaRecord; } @@ -819,20 +795,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 +842,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 +934,101 @@ 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 +1065,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 691e87a0de11bf81af137d734610d46d65c92005..4da99b73a8cac58eb4ab50baeb42eb325056cffe 100644 --- a/ts2panda/ts2abc/ts2abc.h +++ b/ts2panda/ts2abc/ts2abc.h @@ -33,6 +33,7 @@ enum class JsonType { RECORD, STRING, LITERALBUFFER, + MODULE, OPTIONS };