diff --git a/.eslintrc.json b/.eslintrc.json index 9819c020f..d1365a24a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,10 +1,4 @@ { - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "project": ["tsconfig.json", "tsconfig.build.json", "packages/@glimmer/vm/tsconfig.json"] - }, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", @@ -13,203 +7,9 @@ "plugin:import/errors", "prettier" ], - "plugins": ["@typescript-eslint", "prettier", "qunit"], - "settings": { - "import/resolver": { - "typescript": {} - }, - "import/parsers": { - "@typescript-eslint/parser": [".js", ".ts", ".d.ts"] - }, - "node": { - "allowModules": ["@glimmer/debug", "@glimmer/local-debug-flags"], - "tryExtensions": [".js", ".ts", ".d.ts", ".json"] - } - }, - "ignorePatterns": ["dist", "ts-dist", "node_modules", "tmp"], - "rules": { - "n/no-missing-import": "off", - "n/no-unsupported-features/es-builtins": [ - "error", - { - "version": "16.0.0" - } - ], - // disabled because we still have a few commented tests - "qunit/no-commented-tests": "off", - // disabled due to false positives - "qunit/no-global-expect": "off", - // disabled because we still use this pattern everywhere - "qunit/no-global-module-test": "off", - // disabled due to false positives - "qunit/no-global-stop-start": "off", - "import/no-extraneous-dependencies": ["error"], - // this is handled by import/no-extraneous-dependencies - "n/no-extraneous-import": "off", - "prettier/prettier": "error", - "accessor-pairs": "error", - "array-callback-return": "error", - "block-scoped-var": "error", - "callback-return": "error", - "capitalized-comments": "off", - "class-methods-use-this": "off", - "complexity": "off", - "consistent-return": "error", - "consistent-this": "error", - "default-case": "error", - "dot-notation": [ - "error", - { - "allowKeywords": true - } - ], - "eqeqeq": "error", - "func-name-matching": "error", - "func-names": "off", - "func-style": ["error", "declaration"], - "global-require": "off", - "guard-for-in": "error", - "handle-callback-err": "error", - "id-blacklist": "error", - "id-length": "off", - "id-match": "error", - "init-declarations": "off", - "line-comment-position": "error", - "lines-around-directive": "error", - "max-depth": "off", - "max-lines": "off", - "max-nested-callbacks": "error", - "max-params": "off", - "new-cap": "error", - "newline-after-var": "off", - "newline-before-return": "off", - "no-alert": "error", - "no-await-in-loop": "off", - "no-bitwise": "error", - "no-caller": "error", - "no-catch-shadow": "error", - "no-console": "error", - "no-continue": "error", - "no-div-regex": "error", - "no-duplicate-imports": "error", - "no-else-return": "error", - "no-eq-null": "error", - "no-eval": "error", - "no-extend-native": "error", - "no-extra-bind": "error", - "no-extra-label": "error", - "no-implicit-globals": "off", - "no-implied-eval": "error", - "no-inline-comments": "error", - "no-invalid-this": "error", - "no-iterator": "error", - "no-label-var": "error", - "no-labels": "error", - "no-lone-blocks": "error", - "no-lonely-if": "error", - "no-loop-func": "error", - "no-magic-numbers": "off", - "no-mixed-requires": "error", - "no-multi-assign": "error", - "no-multi-spaces": "error", - "no-multi-str": "error", - "no-native-reassign": "error", - "no-negated-condition": "error", - "no-negated-in-lhs": "error", - "no-nested-ternary": "error", - "no-new": "error", - "no-new-func": "error", - "no-new-object": "error", - "no-new-require": "error", - "no-new-wrappers": "error", - "no-octal-escape": "error", - "no-param-reassign": "off", - "no-path-concat": "off", - "no-plusplus": "off", - "no-process-env": "off", - "no-process-exit": "off", - "no-proto": "error", - "no-restricted-globals": "error", - "no-restricted-imports": "error", - "no-restricted-modules": "error", - "no-restricted-properties": "error", - "no-restricted-syntax": "error", - "no-return-assign": "error", - "no-return-await": "error", - "no-script-url": "error", - "no-self-compare": "error", - "no-sequences": "error", - "no-shadow": "error", - "no-sync": "off", - "no-template-curly-in-string": "error", - "no-ternary": "off", - "no-throw-literal": "error", - "no-undef-init": "error", - "no-undefined": "off", - "no-unmodified-loop-condition": "error", - "no-unneeded-ternary": "error", - "no-unused-expressions": "error", - "no-unused-labels": "error", - "no-use-before-define": "off", - "no-useless-call": "error", - "no-useless-computed-key": "error", - "no-useless-concat": "error", - "no-useless-constructor": "error", - "no-useless-rename": "error", - "no-useless-return": "error", - "no-var": "error", - "no-void": "error", - "no-warning-comments": "error", - "object-shorthand": "error", - "one-var": "off", - "operator-assignment": "error", - "prefer-const": "off", - "prefer-destructuring": [ - "error", - { - "array": false, - "object": false - } - ], - "prefer-numeric-literals": "error", - "prefer-promise-reject-errors": "error", - "prefer-reflect": "error", - "prefer-rest-params": "error", - "prefer-spread": "error", - "prefer-template": "off", - "radix": "error", - "require-await": "error", - "require-jsdoc": "off", - "sort-imports": "off", - "sort-keys": "off", - "sort-vars": "off", - "spaced-comment": ["error", "always"], - "strict": "off", - "symbol-description": "error", - "valid-jsdoc": "off", - "vars-on-top": "error", - "yoda": ["error", "never"], - - // replace ESLint rules with TypeScript-compatible rules - "camelcase": "off", - - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "no-empty-function": "off", - "@typescript-eslint/no-empty-function": "error", - "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error" - }, + "ignorePatterns": ["dist", "ts-dist", "node_modules", "tmp", "**/node_modules", "**/dist"], "overrides": [ { - "parserOptions": { - "project": "./tsconfig.json" - }, - "files": [ - "packages/@glimmer/compiler/**/*.ts", - "packages/@glimmer/syntax/lib/**/*.ts", - "packages/@glimmer/syntax/index.ts" - ], "extends": [ // "plugin:@typescript-eslint/recommended-requiring-type-checking", "eslint:recommended", @@ -219,24 +19,22 @@ "plugin:qunit/recommended", "prettier" ], - "plugins": ["simple-import-sort"], + "files": [ + "packages/@glimmer/compiler/**/*.ts", + "packages/@glimmer/syntax/lib/**/*.ts", + "packages/@glimmer/syntax/index.ts" + ], + "parserOptions": { + "project": "./tsconfig.json" + }, "rules": { - "prefer-const": ["off"], - "simple-import-sort/imports": ["error"], - "simple-import-sort/exports": ["error"], - "import/order": "off", - "sort-imports": "off", - "import/first": ["error"], - "import/newline-after-import": ["error"], - "import/no-duplicates": ["error"], - "import/export": "off", - "qunit/no-global-expect": ["off"], - // this is handled by import/errors - "n/no-extraneous-import": "off", - "@typescript-eslint/unbound-method": [ + "@typescript-eslint/ban-types": [ "error", { - "ignoreStatic": true + "extendDefaults": true, + "types": { + "object": false + } } ], "@typescript-eslint/no-explicit-any": [ @@ -245,15 +43,16 @@ "ignoreRestArgs": true } ], - "@typescript-eslint/ban-types": [ + "@typescript-eslint/unbound-method": [ "error", { - "extendDefaults": true, - "types": { - "object": false - } + "ignoreStatic": true } - ] + ], + // this is handled by import/errors + "n/no-extraneous-import": "off", + "prefer-const": ["off"], + "qunit/no-global-expect": ["off"] } }, { @@ -262,12 +61,16 @@ "sourceType": "module" }, "rules": { - "no-useless-constructor": "off", - "n/no-missing-import": "off" + "n/no-missing-import": "off", + "no-useless-constructor": "off" } }, // node files { + "env": { + "es6": true, + "node": true + }, "files": [ ".eslintrc.js", "ember-cli-build.js", @@ -278,10 +81,6 @@ "build/**/*.js", "server/**/*.js" ], - "env": { - "es6": true, - "node": true - }, "rules": { "no-console": "off" } @@ -293,21 +92,20 @@ "n/no-unsupported-features/es-syntax": [ "error", { - "version": ">=16.0.0", - "ignores": [] + "ignores": [], + "version": ">=16.0.0" } ], - "no-process-exit": "off", "n/shebang": "off" } }, { "env": { - "es6": true, - "browser": true + "browser": true, + "es6": true }, - "files": ["benchmark/**/*.js", "benchmark/**/*.d.ts"], "extends": ["plugin:import/errors"], + "files": ["benchmark/**/*.js", "benchmark/**/*.d.ts"], "parserOptions": { "sourceType": "module" }, @@ -317,15 +115,15 @@ } }, { - "files": ["packages/build-utils/@glimmer/vm-babel-plugins/test/**/*.js"], "env": { "es6": true, - "node": true, - "mocha": true + "mocha": true, + "node": true }, + "files": ["packages/build-utils/@glimmer/vm-babel-plugins/test/**/*.js"], "rules": { - "n/no-unsupported-features/es-syntax": "off", "n/no-unpublished-import": "off", + "n/no-unsupported-features/es-syntax": "off", "no-console": "off" } }, @@ -345,38 +143,33 @@ // "tsconfigRootDir": __dirname // }, "rules": { - "n/no-missing-import": "off", - "n/no-unsupported-features/es-syntax": "off", - "n/no-unsupported-features/node-builtins": "off", + "@typescript-eslint/consistent-type-assertions": "error", "@typescript-eslint/naming-convention": [ "error", { - "selector": ["parameter"], "format": ["camelCase", "PascalCase"], - "leadingUnderscore": "allow" + "leadingUnderscore": "allow", + "selector": ["parameter"] }, { - "selector": "variable", + "format": null, "modifiers": ["const"], - "format": null + "selector": "variable" }, { - "selector": ["typeLike"], "format": ["PascalCase"], - "leadingUnderscore": "allow" + "leadingUnderscore": "allow", + "selector": ["typeLike"] }, { - "selector": ["typeAlias"], - "format": ["PascalCase", "UPPER_CASE"] + "format": ["PascalCase", "UPPER_CASE"], + "selector": ["typeAlias"] } ], - "@typescript-eslint/consistent-type-assertions": "error", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-inferrable-types": "error", "@typescript-eslint/no-require-imports": "error", "@typescript-eslint/no-unused-vars": "off", - - "callback-return": "off", "consistent-return": "off", "consistent-this": "off", "constructor-super": "off", @@ -386,6 +179,9 @@ "func-style": "off", "guard-for-in": "off", "line-comment-position": "off", + "n/no-missing-import": "off", + "n/no-unsupported-features/es-syntax": "off", + "n/no-unsupported-features/node-builtins": "off", "new-cap": "off", "no-bitwise": "off", "no-case-declarations": "off", @@ -419,7 +215,6 @@ "no-warning-comments": "off", "object-shorthand": "off", "operator-assignment": "off", - "prefer-reflect": "off", "prefer-rest-params": "off", "prefer-spread": "off", "spaced-comment": "off" @@ -438,5 +233,206 @@ "n/no-extraneous-import": "warn" } } - ] + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "project": ["tsconfig.json", "tsconfig.build.json", "packages/@glimmer/vm/tsconfig.json"] + }, + "plugins": ["@typescript-eslint", "prettier", "qunit", "simple-import-sort", "unused-imports"], + "root": true, + "rules": { + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-function": "error", + "@typescript-eslint/no-unused-vars": "error", + "accessor-pairs": "error", + "array-callback-return": "error", + "block-scoped-var": "error", + // replace ESLint rules with TypeScript-compatible rules + "camelcase": "off", + "capitalized-comments": "off", + "class-methods-use-this": "off", + "complexity": "off", + "consistent-return": "error", + "consistent-this": "error", + "default-case": "error", + "dot-notation": [ + "error", + { + "allowKeywords": true + } + ], + "eqeqeq": "error", + "func-name-matching": "error", + "func-names": "off", + "func-style": ["error", "declaration"], + "guard-for-in": "error", + "id-denylist": "error", + "id-length": "off", + "id-match": "error", + "import/export": "off", + "import/first": ["error"], + "import/newline-after-import": ["error"], + "import/no-duplicates": ["error"], + "import/no-extraneous-dependencies": ["error"], + "import/order": "off", + "init-declarations": "off", + "max-depth": "off", + "max-lines": "off", + "max-nested-callbacks": "error", + "max-params": "off", + "n/callback-return": "error", + "n/global-require": "off", + "n/handle-callback-err": "error", + // this is handled by import/no-extraneous-dependencies + "n/no-extraneous-import": "off", + "n/no-missing-import": "off", + "n/no-mixed-requires": "error", + "n/no-new-require": "error", + "n/no-path-concat": "off", + "n/no-process-env": "off", + "n/no-process-exit": "off", + "n/no-restricted-import": "error", + "n/no-sync": "off", + "n/no-unsupported-features/es-builtins": [ + "error", + { + "version": "16.0.0" + } + ], + "new-cap": "error", + "no-alert": "error", + "no-array-constructor": "off", + "no-await-in-loop": "off", + "no-bitwise": "error", + "no-caller": "error", + "no-console": "error", + "no-continue": "error", + "no-div-regex": "error", + "no-duplicate-imports": "error", + "no-else-return": "error", + "no-empty-function": "off", + "no-eq-null": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-global-assign": "error", + "no-implicit-globals": "off", + "no-implied-eval": "error", + "no-inline-comments": "error", + "no-invalid-this": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-lonely-if": "error", + "no-loop-func": "error", + "no-magic-numbers": "off", + "no-multi-assign": "error", + "no-multi-spaces": "error", + "no-multi-str": "error", + "no-negated-condition": "error", + "no-nested-ternary": "error", + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-param-reassign": "off", + "no-plusplus": "off", + "no-proto": "error", + "no-restricted-globals": "error", + "no-restricted-imports": "error", + "no-restricted-properties": "error", + "no-restricted-syntax": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow": "error", + "no-template-curly-in-string": "error", + "no-ternary": "off", + "no-throw-literal": "error", + "no-undef-init": "error", + "no-undefined": "off", + "no-unmodified-loop-condition": "error", + "no-unneeded-ternary": "error", + "no-unsafe-negation": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-unused-vars": "off", + "no-use-before-define": "off", + "no-useless-call": "error", + "no-useless-computed-key": "error", + "no-useless-concat": "error", + "no-useless-constructor": "error", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-var": "error", + "no-void": "error", + "no-warning-comments": "error", + "object-shorthand": "error", + "one-var": "off", + "operator-assignment": "error", + "prefer-const": "off", + "prefer-destructuring": [ + "error", + { + "array": false, + "object": false + } + ], + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "prefer-template": "off", + "prettier/prettier": "error", + // disabled because we still have a few commented tests + "qunit/no-commented-tests": "off", + // disabled due to false positives + "qunit/no-global-expect": "off", + // disabled because we still use this pattern everywhere + "qunit/no-global-module-test": "off", + // disabled due to false positives + "qunit/no-global-stop-start": "off", + "radix": "error", + "require-await": "error", + "require-jsdoc": "off", + "simple-import-sort/exports": ["error"], + "simple-import-sort/imports": ["error"], + "sort-imports": "off", + "sort-keys": "off", + "sort-vars": "off", + "spaced-comment": ["error", "always"], + "strict": "off", + "symbol-description": "error", + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "warn", + { + "args": "after-used", + "argsIgnorePattern": "^_", + "vars": "all", + "varsIgnorePattern": "^_" + } + ], + "valid-jsdoc": "off", + "vars-on-top": "error", + "yoda": ["error", "never"] + }, + "settings": { + "import/parsers": { + "@typescript-eslint/parser": [".js", ".ts", ".d.ts"] + }, + "import/resolver": { + "typescript": {} + }, + "node": { + "allowModules": ["@glimmer/debug", "@glimmer/local-debug-flags"], + "tryExtensions": [".js", ".ts", ".d.ts", ".json"] + } + } } diff --git a/.vscode/settings.json b/.vscode/settings.json index 3a4ecc79d..7013eda9b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,10 @@ "files.exclude": { "**/.DS_Store": true, "**/.git": true, + "dist/**": true, "node_modules/**": true, + "**/node_modules/**": true, + "**/dist/**": true, "tmp/**": true }, "files.watcherExclude": { diff --git a/benchmark/benchmarks/krausest/lib/index.js b/benchmark/benchmarks/krausest/lib/index.js index 5d5cba2a6..ff342d56a 100644 --- a/benchmark/benchmarks/krausest/lib/index.js +++ b/benchmark/benchmarks/krausest/lib/index.js @@ -1,9 +1,9 @@ import { createBenchmark } from '@glimmer/benchmark-env'; -import ApplicationTemplate from './components/Application.hbs'; import Application from './components/Application'; -import RowTemplate from './components/Row.hbs'; +import ApplicationTemplate from './components/Application.hbs'; import Row from './components/Row'; +import RowTemplate from './components/Row.hbs'; import buildData from './utils/data'; /** diff --git a/benchmark/bin/build.js b/benchmark/bin/build.js index 9de79a355..d36a720a0 100644 --- a/benchmark/bin/build.js +++ b/benchmark/bin/build.js @@ -1,2 +1,3 @@ const build = require('../lib/build'); + build(); diff --git a/benchmark/lib/build.js b/benchmark/lib/build.js index 9a60485ae..e4a8b22b8 100644 --- a/benchmark/lib/build.js +++ b/benchmark/lib/build.js @@ -1,9 +1,9 @@ /* eslint-disable n/no-unpublished-require */ +const path = require('path'); const rollup = require('rollup'); const sourcemap = require('rollup-plugin-sourcemaps'); const terser = require('@rollup/plugin-terser'); const strip = require('@rollup/plugin-strip'); -const path = require('path'); const fs = require('fs-extra'); const symlinkOrCopy = require('symlink-or-copy').sync; diff --git a/bin/run-node-tests.mjs b/bin/run-node-tests.mjs index c3369b537..106d0528d 100755 --- a/bin/run-node-tests.mjs +++ b/bin/run-node-tests.mjs @@ -1,4 +1,5 @@ import path from 'node:path'; + import { execaSync } from 'execa'; const __dirname = new URL('.', import.meta.url).pathname; diff --git a/bin/sync-npm-owners.mjs b/bin/sync-npm-owners.mjs index 75ad94a62..92b5e4f75 100755 --- a/bin/sync-npm-owners.mjs +++ b/bin/sync-npm-owners.mjs @@ -4,10 +4,11 @@ // glimmer-engine. import { execSync } from 'node:child_process'; -import { globSync } from 'glob'; import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; +import { globSync } from 'glob'; + const __dirname = new URL('.', import.meta.url).pathname; const manifest = resolve(__dirname, '../package.json'); let name = JSON.parse(readFileSync(manifest)).name; diff --git a/build/broccoli/build-packages.js b/build/broccoli/build-packages.js index dc3d25b66..54b1de38f 100644 --- a/build/broccoli/build-packages.js +++ b/build/broccoli/build-packages.js @@ -6,12 +6,12 @@ const merge = require('broccoli-merge-trees'); const Rollup = require('broccoli-rollup'); const sourcemaps = require('rollup-plugin-sourcemaps'); const UnwatchedDir = require('broccoli-source').UnwatchedDir; +const debugMacros = require('babel-plugin-debug-macros'); +const Project = require('../utils/project'); const transpileToES5 = require('./transpile-to-es5'); const writePackageJSON = require('./write-package-json'); const writeLicense = require('./write-license'); -const debugMacros = require('babel-plugin-debug-macros'); -const Project = require('../utils/project'); const project = Project.from('packages'); module.exports = function buildPackages(es2017, matrix) { diff --git a/build/broccoli/build-tests.js b/build/broccoli/build-tests.js index 0d3d262d3..692871917 100644 --- a/build/broccoli/build-tests.js +++ b/build/broccoli/build-tests.js @@ -4,8 +4,8 @@ const path = require('path'); const merge = require('broccoli-merge-trees'); const funnel = require('broccoli-funnel'); const concat = require('broccoli-concat'); -const transpileToES5 = require('./transpile-to-es5'); const babel = require('broccoli-babel-transpiler'); +const transpileToES5 = require('./transpile-to-es5'); /** * For development, this returns a Broccoli tree with: diff --git a/build/broccoli/write-license.js b/build/broccoli/write-license.js index c50cd8a62..0ab3ee6b3 100644 --- a/build/broccoli/write-license.js +++ b/build/broccoli/write-license.js @@ -1,7 +1,7 @@ 'use strict'; -const writeFile = require('broccoli-file-creator'); const { readFileSync } = require('fs'); +const writeFile = require('broccoli-file-creator'); const LICENSE = readFileSync('./LICENSE', 'utf8'); diff --git a/build/broccoli/write-smoke-test.js b/build/broccoli/write-smoke-test.js index a027e9907..0a0c7f793 100644 --- a/build/broccoli/write-smoke-test.js +++ b/build/broccoli/write-smoke-test.js @@ -1,6 +1,6 @@ -const Plugin = require('broccoli-plugin'); const fs = require('fs'); const path = require('path'); +const Plugin = require('broccoli-plugin'); /** * Writes a TypeScript file that imports each package. This file can be passed @@ -33,6 +33,8 @@ class TypesSmokeTestWriter extends Plugin { noUnusedLocals: true, noUnusedParameters: true, noImplicitReturns: true, + useDefineForClassFields: true, + exactOptionalPropertyTypes: true, newLine: 'LF', noEmit: true, diff --git a/build/debug.js b/build/debug.js index f10a58003..bcba305a0 100644 --- a/build/debug.js +++ b/build/debug.js @@ -1,10 +1,10 @@ // @ts-check // eslint-disable-next-line n/no-missing-require -const { normalizeAll, buildEnum, buildMetas, strip } = require('../dist/@glimmer/debug'); const fs = require('fs'); const toml = require('toml'); const prettier = require('prettier'); +const { normalizeAll, buildEnum, buildMetas, strip } = require('@glimmer/debug'); function parse(file) { let opcodes = fs.readFileSync(file, { encoding: 'utf8' }); diff --git a/build/utils/project.js b/build/utils/project.js index a7716a949..09c7b3916 100644 --- a/build/utils/project.js +++ b/build/utils/project.js @@ -5,8 +5,8 @@ */ const fs = require('fs'); -const glob = require('glob'); const path = require('path'); +const glob = require('glob'); const DAGMap = require('dag-map').default; /** diff --git a/lib/local-linker/index.js b/lib/local-linker/index.js index 42653f108..910b31997 100644 --- a/lib/local-linker/index.js +++ b/lib/local-linker/index.js @@ -1,8 +1,8 @@ 'use strict'; +const path = require('path'); const fs = require('fs-extra'); const symlinkOrCopy = require('symlink-or-copy').sync; -const path = require('path'); const rootDir = path.resolve(__dirname, '../..'); diff --git a/package.json b/package.json index 06c7de422..9b377d59b 100644 --- a/package.json +++ b/package.json @@ -88,6 +88,7 @@ "eslint-config-prettier": "^8.8.0", "eslint-import-resolver-typescript": "^3.5.5", "eslint-plugin-import": "^2.27.5", + "eslint-plugin-unused-imports": "^2.0.0", "eslint-plugin-n": "^15.7.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-qunit": "^7.3.4", diff --git a/packages/@glimmer/benchmark-env/index.ts b/packages/@glimmer/benchmark-env/index.ts index be9c80be3..05c0d359e 100644 --- a/packages/@glimmer/benchmark-env/index.ts +++ b/packages/@glimmer/benchmark-env/index.ts @@ -1,4 +1,3 @@ -export { default as createCell } from './src/create-cell'; export { default as createBenchmark } from './src/create-benchmark'; - +export { default as createCell } from './src/create-cell'; export { Benchmark, Cell, ComponentArgs, UpdateBenchmark } from './src/interfaces'; diff --git a/packages/@glimmer/benchmark-env/src/benchmark/args-proxy.ts b/packages/@glimmer/benchmark-env/src/benchmark/args-proxy.ts index f419c4e56..5f0c40722 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/args-proxy.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/args-proxy.ts @@ -1,5 +1,6 @@ -import { CapturedNamedArguments, CapturedArguments } from '@glimmer/interfaces'; +import { CapturedArguments, CapturedNamedArguments, Reference } from '@glimmer/interfaces'; import { valueForRef } from '@glimmer/reference'; + import { ComponentArgs } from '../interfaces'; class ArgsProxy implements ProxyHandler { @@ -17,7 +18,7 @@ class ArgsProxy implements ProxyHandler { ): PropertyDescriptor | undefined { let desc: PropertyDescriptor | undefined; if (typeof p === 'string' && p in target) { - const value = valueForRef(target[p]); + const value = valueForRef(target[p] as Reference); desc = { enumerable: true, configurable: false, @@ -34,7 +35,7 @@ class ArgsProxy implements ProxyHandler { get(target: CapturedNamedArguments, p: PropertyKey): any { if (typeof p === 'string' && p in target) { - return valueForRef(target[p]); + return valueForRef(target[p] as Reference); } } diff --git a/packages/@glimmer/benchmark-env/src/benchmark/basic-component-manager.ts b/packages/@glimmer/benchmark-env/src/benchmark/basic-component-manager.ts index 90d65964e..7852c6daa 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/basic-component-manager.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/basic-component-manager.ts @@ -1,7 +1,8 @@ -import { WithCreateInstance, Dict, VMArguments, Template, Owner } from '@glimmer/interfaces'; +import { Dict, Owner, Template, VMArguments, WithCreateInstance } from '@glimmer/interfaces'; +import { getComponentTemplate } from '@glimmer/manager'; import { createConstRef, Reference } from '@glimmer/reference'; import { EMPTY_ARGS } from '@glimmer/runtime'; -import { getComponentTemplate } from '@glimmer/manager'; + import { ComponentArgs } from '../interfaces'; import argsProxy from './args-proxy'; diff --git a/packages/@glimmer/benchmark-env/src/benchmark/create-env-delegate.ts b/packages/@glimmer/benchmark-env/src/benchmark/create-env-delegate.ts index 2b9c7f0bd..6ba481bb4 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/create-env-delegate.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/create-env-delegate.ts @@ -1,6 +1,6 @@ -import { EnvironmentDelegate } from '@glimmer/runtime'; -import { Destroyable, Destructor, RenderResult } from '@glimmer/interfaces'; import setGlobalContext from '@glimmer/global-context'; +import { Destroyable, Destructor, RenderResult } from '@glimmer/interfaces'; +import { EnvironmentDelegate } from '@glimmer/runtime'; type Queue = (() => void)[]; diff --git a/packages/@glimmer/benchmark-env/src/benchmark/create-registry.ts b/packages/@glimmer/benchmark-env/src/benchmark/create-registry.ts index cfc95e98f..ea2a8c3cd 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/create-registry.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/create-registry.ts @@ -1,20 +1,20 @@ import { - ResolvedComponentDefinition, - InternalModifierManager, Dict, - ModifierDefinitionState, - HelperDefinitionState, Helper, + HelperDefinitionState, + InternalModifierManager, + ModifierDefinitionState, + ResolvedComponentDefinition, + SimpleElement, } from '@glimmer/interfaces'; -import { programCompilationContext } from '@glimmer/opcode-compiler'; -import { artifacts, RuntimeOpImpl } from '@glimmer/program'; -import { SimpleElement } from '@glimmer/interfaces'; import { getComponentTemplate, getInternalComponentManager, setInternalHelperManager, setInternalModifierManager, } from '@glimmer/manager'; +import { programCompilationContext } from '@glimmer/opcode-compiler'; +import { artifacts, RuntimeOpImpl } from '@glimmer/program'; import { UpdateBenchmark } from '../interfaces'; import renderBenchmark from './render-benchmark'; diff --git a/packages/@glimmer/benchmark-env/src/benchmark/on-modifier.ts b/packages/@glimmer/benchmark-env/src/benchmark/on-modifier.ts index db2c93af6..f01c1a82d 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/on-modifier.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/on-modifier.ts @@ -1,8 +1,12 @@ -import { CapturedArguments, InternalModifierManager, Owner } from '@glimmer/interfaces'; +import { + CapturedArguments, + InternalModifierManager, + Owner, + SimpleElement, +} from '@glimmer/interfaces'; import { Reference, valueForRef } from '@glimmer/reference'; import { castToBrowser } from '@glimmer/util'; import { createUpdatableTag } from '@glimmer/validator'; -import { SimpleElement } from '@glimmer/interfaces'; interface OnModifierState { element: SimpleElement; diff --git a/packages/@glimmer/benchmark-env/src/benchmark/render-benchmark.ts b/packages/@glimmer/benchmark-env/src/benchmark/render-benchmark.ts index 2f4c04979..f4afcba7f 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/render-benchmark.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/render-benchmark.ts @@ -1,16 +1,16 @@ -import { SimpleElement } from '@glimmer/interfaces'; import { + CompileTimeCompilationContext, Dict, - RuntimeResolver, ResolvedComponentDefinition, RuntimeArtifacts, - CompileTimeCompilationContext, + RuntimeResolver, + SimpleElement, } from '@glimmer/interfaces'; -import { NewElementBuilder, runtimeContext, renderComponent, renderSync } from '@glimmer/runtime'; +import { NewElementBuilder, renderComponent, renderSync, runtimeContext } from '@glimmer/runtime'; +import { UpdateBenchmark } from '../interfaces'; import createEnvDelegate, { registerResult } from './create-env-delegate'; import { measureRender } from './util'; -import { UpdateBenchmark } from '../interfaces'; export default async function renderBenchmark( artifacts: RuntimeArtifacts, diff --git a/packages/@glimmer/benchmark-env/src/benchmark/util.ts b/packages/@glimmer/benchmark-env/src/benchmark/util.ts index e128e816b..4537b2179 100644 --- a/packages/@glimmer/benchmark-env/src/benchmark/util.ts +++ b/packages/@glimmer/benchmark-env/src/benchmark/util.ts @@ -1,6 +1,5 @@ -import { CompileTimeComponent } from '@glimmer/interfaces'; +import { CompileTimeCompilationContext, CompileTimeComponent } from '@glimmer/interfaces'; import { unwrapHandle } from '@glimmer/util'; -import { CompileTimeCompilationContext } from '@glimmer/interfaces'; export function compileEntry(entry: CompileTimeComponent, context: CompileTimeCompilationContext) { return unwrapHandle(entry.compilable!.compile(context)); diff --git a/packages/@glimmer/benchmark-env/src/create-benchmark.ts b/packages/@glimmer/benchmark-env/src/create-benchmark.ts index 4ed6c365d..d7974f840 100644 --- a/packages/@glimmer/benchmark-env/src/create-benchmark.ts +++ b/packages/@glimmer/benchmark-env/src/create-benchmark.ts @@ -1,11 +1,12 @@ import { setComponentTemplate, setInternalComponentManager } from '@glimmer/manager'; -import { Benchmark } from './interfaces'; -import createRegistry from './benchmark/create-registry'; -import onModifier from './benchmark/on-modifier'; -import basicComponentManager from './benchmark/basic-component-manager'; import { templateFactory } from '@glimmer/opcode-compiler'; import { templateOnlyComponent } from '@glimmer/runtime'; +import basicComponentManager from './benchmark/basic-component-manager'; +import createRegistry from './benchmark/create-registry'; +import onModifier from './benchmark/on-modifier'; +import { Benchmark } from './interfaces'; + export default function createBenchmark(): Benchmark { const registry = createRegistry(); registry.registerModifier('on', {}, onModifier); diff --git a/packages/@glimmer/benchmark-env/src/create-cell.ts b/packages/@glimmer/benchmark-env/src/create-cell.ts index 491118374..35720b7a5 100644 --- a/packages/@glimmer/benchmark-env/src/create-cell.ts +++ b/packages/@glimmer/benchmark-env/src/create-cell.ts @@ -1,11 +1,12 @@ import { - tagMetaFor, consumeTag, dirtyTagFor, - TagMeta, tagFor, + TagMeta, + tagMetaFor, UpdatableTag, } from '@glimmer/validator'; + import { Cell } from './interfaces'; class CellImpl implements Cell { diff --git a/packages/@glimmer/benchmark-env/src/interfaces.ts b/packages/@glimmer/benchmark-env/src/interfaces.ts index 8966b9d42..13a0a24fe 100644 --- a/packages/@glimmer/benchmark-env/src/interfaces.ts +++ b/packages/@glimmer/benchmark-env/src/interfaces.ts @@ -1,5 +1,4 @@ -import { Dict, SerializedTemplateWithLazyBlock } from '@glimmer/interfaces'; -import { SimpleElement } from '@glimmer/interfaces'; +import { Dict, SerializedTemplateWithLazyBlock, SimpleElement } from '@glimmer/interfaces'; /** * This abstracts a tracked root. diff --git a/packages/@glimmer/compiler/lib/builder/builder-interface.ts b/packages/@glimmer/compiler/lib/builder/builder-interface.ts index 69f29cc95..21944f20c 100644 --- a/packages/@glimmer/compiler/lib/builder/builder-interface.ts +++ b/packages/@glimmer/compiler/lib/builder/builder-interface.ts @@ -1,5 +1,5 @@ import { Dict, DictValue, Option, PresentArray } from '@glimmer/interfaces'; -import { assertNever, dict, expect, isPresent } from '@glimmer/util'; +import { assertNever, dict, expect, isPresentArray } from '@glimmer/util'; export type BuilderParams = BuilderExpression[]; export type BuilderHash = Option>; @@ -314,7 +314,7 @@ function extractBlockHead(name: string): NormalizedHead { throw new Error(`Unexpected missing # in block head`); } - return normalizeDottedPath(result[2]); + return normalizeDottedPath(result[2] as string); } function normalizeCallHead(name: string): NormalizedHead { @@ -324,13 +324,13 @@ function normalizeCallHead(name: string): NormalizedHead { throw new Error(`Unexpected missing () in call head`); } - return normalizeDottedPath(result[1]); + return normalizeDottedPath(result[1] as string); } function normalizePath(head: string, tail: string[] = []): NormalizedHead { let pathHead = normalizePathHead(head); - if (isPresent(tail)) { + if (isPresentArray(tail)) { return { type: ExpressionKind.GetPath, path: { @@ -349,11 +349,11 @@ function normalizePath(head: string, tail: string[] = []): NormalizedHead { function normalizeDottedPath(whole: string): NormalizedHead { let { kind, name: rest } = normalizePathHead(whole); - let [name, ...tail] = rest.split('.'); + let [name, ...tail] = rest.split('.') as [string, ...string[]]; let variable: Variable = { kind, name, mode: 'loose' }; - if (isPresent(tail)) { + if (isPresentArray(tail)) { return { type: ExpressionKind.GetPath, path: { head: variable, tail } }; } else { return { type: ExpressionKind.GetVar, variable }; @@ -503,12 +503,12 @@ function normalizeAttr(attr: BuilderAttr): { expr: NormalizedAttr; trusted: bool function mapObject, Out>( object: T, - callback: (value: DictValue, key: keyof T) => Out + mapper: (value: DictValue, key: keyof T) => Out ): { [P in keyof T]: Out } { let out = dict() as { [P in keyof T]?: Out }; Object.keys(object).forEach((k: K) => { - out[k] = callback(object[k] as DictValue, k); + out[k] = mapper(object[k] as DictValue, k); }); return out as { [P in keyof T]: Out }; @@ -537,13 +537,7 @@ export function isElement(input: [string, ...unknown[]]): input is BuilderElemen export function extractElement(input: string): Option { let match = /^<([a-z0-9\-][a-zA-Z0-9\-]*)>$/.exec(input); - return match ? match[1] : null; -} - -export function extractAngleInvocation(input: string): Option { - let match = /^<(@[a-zA-Z0-9]*|[A-Z][a-zA-Z0-9\-]*)>$/.exec(input[0]); - - return match ? match[1] : null; + return match?.[1] ?? null; } export function isAngleInvocation(input: [string, ...unknown[]]): input is InvocationElement { diff --git a/packages/@glimmer/compiler/lib/builder/builder.ts b/packages/@glimmer/compiler/lib/builder/builder.ts index 2adc9d66c..7f5337f1d 100644 --- a/packages/@glimmer/compiler/lib/builder/builder.ts +++ b/packages/@glimmer/compiler/lib/builder/builder.ts @@ -10,7 +10,15 @@ import { VariableResolutionContext, WireFormat, } from '@glimmer/interfaces'; -import { assert, assertNever, dict, exhausted, expect, isPresent, values } from '@glimmer/util'; +import { + assert, + assertNever, + dict, + exhausted, + expect, + isPresentArray, + values, +} from '@glimmer/util'; import { Builder, @@ -131,7 +139,7 @@ class LocalSymbols implements Symbols { local(name: string): number { if (name in this.locals) { - return this.locals[name]; + return this.locals[name] as number; } else { return this.parent.local(name); } @@ -318,7 +326,11 @@ function buildKeyword( let params = buildParams(normalized.params, symbols); let childSymbols = symbols.child(normalized.blockParams || []); - let block = buildBlock(normalized.blocks.default, childSymbols, childSymbols.paramSymbols); + let block = buildBlock( + normalized.blocks['default'] as NormalizedBlock, + childSymbols, + childSymbols.paramSymbols + ); let inverse = normalized.blocks['else'] ? buildBlock(normalized.blocks['else'], symbols, []) : null; @@ -390,7 +402,7 @@ export function buildAngleInvocation( return [ Op.Component, buildExpression(head, VariableResolutionContext.ResolveAsComponentHead, symbols), - isPresent(paramList) ? paramList : null, + isPresentArray(paramList) ? paramList : null, args, [['default'], [[blockList, []]]], ]; @@ -423,7 +435,7 @@ export function buildElementParams( } } - return { params, args: isPresent(keys) && isPresent(values) ? [keys, values] : null }; + return { params, args: isPresentArray(keys) && isPresentArray(values) ? [keys, values] : null }; } export function extractNamespace(name: string): Option { @@ -695,7 +707,7 @@ export function buildParams( exprs: Option, symbols: Symbols ): Option { - if (exprs === null || !isPresent(exprs)) return null; + if (exprs === null || !isPresentArray(exprs)) return null; return exprs.map((e) => buildExpression(e, 'Strict', symbols)) as WireFormat.Core.ConcatParams; } @@ -712,10 +724,10 @@ export function buildHash(exprs: Option, symbols: Symbols): Wire let out: [string[], WireFormat.Expression[]] = [[], []]; - Object.keys(exprs).forEach((key) => { + for (const [key, value] of Object.entries(exprs)) { out[0].push(key); - out[1].push(buildExpression(exprs[key], 'Strict', symbols)); - }); + out[1].push(buildExpression(value, 'Strict', symbols)); + } return out as WireFormat.Core.Hash; } @@ -728,17 +740,17 @@ export function buildBlocks( let keys: string[] = []; let values: WireFormat.SerializedInlineBlock[] = []; - Object.keys(blocks).forEach((name) => { + for (const [name, block] of Object.entries(blocks)) { keys.push(name); if (name === 'default') { let symbols = parent.child(blockParams || []); - values.push(buildBlock(blocks[name], symbols, symbols.paramSymbols)); + values.push(buildBlock(block, symbols, symbols.paramSymbols)); } else { - values.push(buildBlock(blocks[name], parent, [])); + values.push(buildBlock(block, parent, [])); } - }); + } return [keys, values]; } diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/impl.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/impl.ts index 186a0d0c0..da56ece29 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/impl.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/impl.ts @@ -199,12 +199,12 @@ export class Keywords = ne let path = getCalleeExpression(node); if (path && path.type === 'Path' && path.ref.type === 'Free' && isKeyword(path.ref.name)) { - let { name } = path.ref; + let { name } = path.ref as { name: keyof typeof KEYWORDS_TYPES }; let usedType = this._type; - let validTypes = KEYWORDS_TYPES[name]; + let validTypes: readonly KeywordType[] = KEYWORDS_TYPES[name]; - if (validTypes.indexOf(usedType) === -1) { + if (!validTypes.includes(usedType)) { return Err( generateSyntaxError( `The \`${name}\` keyword was used incorrectly. It was used as ${ @@ -230,7 +230,7 @@ const typesToReadableName = { Modifier: 'a modifier', }; -function generateTypesMessage(name: string, types: KeywordType[]): string { +function generateTypesMessage(name: string, types: readonly KeywordType[]): string { return types .map((type) => { switch (type) { diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/has-block.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/has-block.ts index 1471b0fe1..429fba45d 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/has-block.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/keywords/utils/has-block.ts @@ -19,7 +19,7 @@ function assertHasBlockKeyword(type: string) { if (!positionals || positionals.isEmpty()) { return Ok(SourceSlice.synthetic('default')); } else if (positionals.exprs.length === 1) { - let positional = positionals.exprs[0]; + let positional = positionals.exprs[0] as ASTv2.ExpressionNode; if (ASTv2.isLiteral(positional, 'string')) { return Ok(positional.toSlice()); } else { diff --git a/packages/@glimmer/compiler/lib/passes/1-normalization/visitors/expressions.ts b/packages/@glimmer/compiler/lib/passes/1-normalization/visitors/expressions.ts index 40ba76192..24770f783 100644 --- a/packages/@glimmer/compiler/lib/passes/1-normalization/visitors/expressions.ts +++ b/packages/@glimmer/compiler/lib/passes/1-normalization/visitors/expressions.ts @@ -1,6 +1,6 @@ import { PresentArray } from '@glimmer/interfaces'; import { ASTv2, KEYWORDS_TYPES } from '@glimmer/syntax'; -import { isPresent } from '@glimmer/util'; +import { getLast, isPresentArray } from '@glimmer/util'; import { AnyOptionalList, PresentList } from '../../../shared/list'; import { Ok, Result, ResultArray } from '../../../shared/result'; @@ -56,8 +56,8 @@ export class NormalizeExpressions { let ref = this.VariableReference(path.ref); let { tail } = path; - if (isPresent(tail)) { - let tailLoc = tail[0].loc.extend(tail[tail.length - 1].loc); + if (isPresentArray(tail)) { + let tailLoc = tail[0].loc.extend(getLast(tail).loc); return Ok( new mir.PathExpression({ loc: path.loc, diff --git a/packages/@glimmer/compiler/lib/passes/2-encoding/expressions.ts b/packages/@glimmer/compiler/lib/passes/2-encoding/expressions.ts index 3deee5d6c..b6a920dd9 100644 --- a/packages/@glimmer/compiler/lib/passes/2-encoding/expressions.ts +++ b/packages/@glimmer/compiler/lib/passes/2-encoding/expressions.ts @@ -1,6 +1,6 @@ import { PresentArray, SexpOpcodes, WireFormat } from '@glimmer/interfaces'; import { ASTv2 } from '@glimmer/syntax'; -import { assertPresent, isPresent, mapPresent } from '@glimmer/util'; +import { assertPresentArray, isPresentArray, mapPresentArray } from '@glimmer/util'; import * as mir from './mir'; @@ -113,7 +113,7 @@ export class ExpressionEncoder { } Tail({ members }: mir.Tail): PresentArray { - return mapPresent(members, (member) => member.chars); + return mapPresentArray(members, (member) => member.chars); } Args({ positional, named }: mir.Args): WireFormat.Core.Args { @@ -131,7 +131,7 @@ export class ExpressionEncoder { NamedArguments({ entries: pairs }: mir.NamedArguments): WireFormat.Core.Hash { let list = pairs.toArray(); - if (isPresent(list)) { + if (isPresentArray(list)) { let names: string[] = []; let values: WireFormat.Expression[] = []; @@ -141,8 +141,8 @@ export class ExpressionEncoder { values.push(value); } - assertPresent(names); - assertPresent(values); + assertPresentArray(names); + assertPresentArray(values); return [names, values]; } else { diff --git a/packages/@glimmer/compiler/lib/shared/list.ts b/packages/@glimmer/compiler/lib/shared/list.ts index bed137ef6..5b1f94e05 100644 --- a/packages/@glimmer/compiler/lib/shared/list.ts +++ b/packages/@glimmer/compiler/lib/shared/list.ts @@ -1,5 +1,5 @@ import { Option, PresentArray } from '@glimmer/interfaces'; -import { isPresent, mapPresent } from '@glimmer/util'; +import { isPresentArray, mapPresentArray } from '@glimmer/util'; export interface OptionalList { map(callback: (input: T) => U): MapList>; @@ -19,7 +19,7 @@ export class PresentList implements OptionalList { } map(callback: (input: T) => U): MapList> { - let result = mapPresent(this.list, callback); + let result = mapPresentArray(this.list, callback); return new PresentList(result) as MapList; } @@ -71,7 +71,7 @@ export class EmptyList implements OptionalList { // export type OptionalList = PresentList | EmptyList; export function OptionalList(value: readonly T[]): AnyOptionalList { - if (isPresent(value)) { + if (isPresentArray(value)) { return new PresentList(value); } else { return new EmptyList(); diff --git a/packages/@glimmer/compiler/lib/shared/result.ts b/packages/@glimmer/compiler/lib/shared/result.ts index f774eeb92..ee62bfe05 100644 --- a/packages/@glimmer/compiler/lib/shared/result.ts +++ b/packages/@glimmer/compiler/lib/shared/result.ts @@ -133,11 +133,11 @@ export type MaybeResult = T | Result; export class MapIntoResultArray { constructor(private items: T[]) {} - map(callback: (item: T) => Result): Result { + map(mapper: (item: T) => Result): Result { let out = new ResultArray(); for (let item of this.items) { - out.add(callback(item)); + out.add(mapper(item)); } return out.toArray(); diff --git a/packages/@glimmer/compiler/lib/wire-format-debug.ts b/packages/@glimmer/compiler/lib/wire-format-debug.ts index 949f357de..0d84fe45f 100644 --- a/packages/@glimmer/compiler/lib/wire-format-debug.ts +++ b/packages/@glimmer/compiler/lib/wire-format-debug.ts @@ -301,7 +301,7 @@ export default class WireFormatDebugger { if (blocks === null) return null; return blocks[0].reduce((accum, key, index) => { - accum[key] = this.formatBlock(blocks[1][index]); + accum[key] = this.formatBlock(blocks[1][index] as SerializedInlineBlock); return accum; }, dict()); } diff --git a/packages/@glimmer/compiler/test/location-test.ts b/packages/@glimmer/compiler/test/location-test.ts index 2c0d60693..1f51bf6b8 100644 --- a/packages/@glimmer/compiler/test/location-test.ts +++ b/packages/@glimmer/compiler/test/location-test.ts @@ -56,10 +56,10 @@ const cases: Dict<[string, number | null][]> = { QUnit.module('locations - position'); -Object.keys(cases).forEach((string) => { +for (const [string, testCase] of Object.entries(cases)) { let source = new Source(string); - for (let [span, offset] of cases[string]) { + for (let [span, offset] of testCase) { let [line, column] = span.split(':').map((i) => parseInt(i, 10)); if (offset === null) continue; @@ -68,15 +68,15 @@ Object.keys(cases).forEach((string) => { assert.deepEqual(source.hbsPosFor(unwrap(offset)), { line, column }); }); } -}); +} QUnit.module('locations - location'); -Object.keys(cases).forEach((string) => { +for (const [string, testCase] of Object.entries(cases)) { let source = new Source(string); - for (let [span, offset] of cases[string]) { - let [line, column] = span.split(':').map((i) => parseInt(i, 10)); + for (let [span, offset] of testCase) { + let [line, column] = span.split(':').map((i) => parseInt(i, 10)) as [number, number]; if (offset === null) continue; @@ -84,4 +84,4 @@ Object.keys(cases).forEach((string) => { assert.deepEqual(source.offsetFor(line, column).offset, offset); }); } -}); +} diff --git a/packages/@glimmer/debug/index.ts b/packages/@glimmer/debug/index.ts index 973d18b7b..b05cc9709 100644 --- a/packages/@glimmer/debug/index.ts +++ b/packages/@glimmer/debug/index.ts @@ -1,4 +1,4 @@ -export * from './lib/stack-check'; +export { debug, debugSlice, logOpcode } from './lib/debug'; export * from './lib/metadata'; export { opcodeMetadata } from './lib/opcode-metadata'; -export { debug, debugSlice, logOpcode } from './lib/debug'; +export * from './lib/stack-check'; diff --git a/packages/@glimmer/debug/lib/debug.ts b/packages/@glimmer/debug/lib/debug.ts index 08c289d30..fc947a916 100644 --- a/packages/@glimmer/debug/lib/debug.ts +++ b/packages/@glimmer/debug/lib/debug.ts @@ -10,6 +10,7 @@ import { import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; import { decodeHandle, decodeImmediate, LOCAL_LOGGER } from '@glimmer/util'; import { $fp, $pc, $ra, $s0, $s1, $sp, $t0, $t1, $v0, Register } from '@glimmer/vm'; + import { opcodeMetadata } from './opcode-metadata'; import { Primitive } from './stack-check'; diff --git a/packages/@glimmer/debug/lib/metadata.ts b/packages/@glimmer/debug/lib/metadata.ts index 76b27de5d..f9c235660 100644 --- a/packages/@glimmer/debug/lib/metadata.ts +++ b/packages/@glimmer/debug/lib/metadata.ts @@ -1,4 +1,4 @@ -import { Option, Dict } from '@glimmer/interfaces'; +import { Dict, Option, PresentArray } from '@glimmer/interfaces'; const tuple = (...args: T) => args; @@ -55,10 +55,11 @@ export interface RawOperandMetadata { notes?: string; } -export type RawOperandFormat = string | string[]; +export type OperandName = `${string}:${string}`; +export type RawOperandFormat = OperandName | PresentArray; export function normalize(key: string, input: RawOperandMetadata): NormalizedMetadata { - let name; + let name: string; if (input.format === undefined) { throw new Error(`Missing format in ${JSON.stringify(input)}`); @@ -105,15 +106,15 @@ function hasRest(input: string[]): boolean { return input.some((s) => s.slice(-3) === '...'); } -function operands(input: string[]): OperandList { +function operands(input: `${string}:${string}`[]): OperandList { if (!Array.isArray(input)) { throw new Error(`Expected operands array, got ${JSON.stringify(input)}`); } return input.map(op) as OperandList; } -function op(input: string): Operand { - let [name, type] = input.split(':'); +function op(input: `${string}:${string}`): Operand { + let [name, type] = input.split(':') as [string, string]; if (isOperandType(type)) { return { name, type }; @@ -135,8 +136,8 @@ export function normalizeAll(parsed: { export function normalizeParsed(parsed: Dict): Dict { let out = Object.create(null) as Dict; - for (let key of Object.keys(parsed)) { - out[key] = normalize(key, parsed[key]); + for (const [key, value] of Object.entries(parsed)) { + out[key] = normalize(key, value); } return out; @@ -152,8 +153,8 @@ export function buildEnum( let last: number; - Object.keys(parsed).forEach((key, i) => { - e.push(` ${parsed[key].name} = ${offset + i},`); + Object.values(parsed).forEach((value, i) => { + e.push(` ${value.name} = ${offset + i},`); last = i; }); @@ -190,7 +191,7 @@ export function strip(strings: TemplateStringsArray, ...args: unknown[]) { out += `${string}${dynamic}`; } - out = out.match(/^\s*?\n?([\s\S]*?)\n?\s*$/)![1]; + out = out.match(/^\s*?\n?([\s\S]*?)\n?\s*$/)![1] as string; let min = 9007199254740991; // Number.MAX_SAFE_INTEGER isn't available on IE11 @@ -212,13 +213,13 @@ export function strip(strings: TemplateStringsArray, ...args: unknown[]) { export const META_KIND = tuple('METADATA', 'MACHINE_METADATA'); export type META_KIND = (typeof META_KIND)[number]; -export function buildSingleMeta( +export function buildSingleMeta>( kind: META_KIND, - all: Dict, - key: keyof typeof all + all: D, + key: keyof D ): string { let e = kind === 'MACHINE_METADATA' ? 'MachineOp' : 'Op'; - return `${kind}[${e}.${all[key].name}] = ${stringify(all[key], 0)};`; + return `${kind}[${e}.${all[key]!.name}] = ${stringify(all[key], 0)};`; } function stringify(o: unknown, pad: number): string { diff --git a/packages/@glimmer/debug/lib/opcode-metadata.ts b/packages/@glimmer/debug/lib/opcode-metadata.ts index 19f04f946..99dc79db4 100644 --- a/packages/@glimmer/debug/lib/opcode-metadata.ts +++ b/packages/@glimmer/debug/lib/opcode-metadata.ts @@ -1,6 +1,7 @@ /* This file is generated by build/debug.js */ import { MachineOp, Op, Option } from '@glimmer/interfaces'; + import { NormalizedMetadata } from './metadata'; function fillNulls(count: number): T[] { diff --git a/packages/@glimmer/debug/lib/stack-check.ts b/packages/@glimmer/debug/lib/stack-check.ts index eaac646ca..82e28e800 100644 --- a/packages/@glimmer/debug/lib/stack-check.ts +++ b/packages/@glimmer/debug/lib/stack-check.ts @@ -1,5 +1,13 @@ -import { Option, Dict, BlockSymbolTable, ProgramSymbolTable, Maybe } from '@glimmer/interfaces'; -import { SimpleElement, SimpleDocumentFragment, SimpleNode } from '@glimmer/interfaces'; +import { + BlockSymbolTable, + Dict, + Maybe, + Option, + ProgramSymbolTable, + SimpleDocumentFragment, + SimpleElement, + SimpleNode, +} from '@glimmer/interfaces'; export interface Checker { type: T; @@ -155,19 +163,14 @@ class PropertyChecker implements Checker { if (typeof obj !== 'object') return false; if (obj === null || obj === undefined) return false; - return Object.keys(this.checkers).every((k) => { - if (!(k in obj)) return false; - - let value = (obj as Dict)[k]; - let checker = this.checkers[k]; - - return checker.validate(value); - }); + return Object.entries(this.checkers).every(([k, checker]) => + k in obj ? checker.validate((obj as Dict)[k]) : false + ); } expected(): string { - let pairs = Object.keys(this.checkers).map((k) => { - return `${k}: ${this.checkers[k].expected()}`; + let pairs = Object.entries(this.checkers).map(([k, checker]) => { + return `${k}: ${checker.expected()}`; }); return `{ ${pairs.join(',')} }`; @@ -287,11 +290,29 @@ export function CheckDict(obj: Checker): Checker> { return new DictChecker(obj); } -export function check(value: unknown, checker: Checker): T { +function defaultMessage(value: unknown, expected: string): string { + return `Got ${value}, expected:\n${expected}`; +} + +export function check( + value: unknown, + checker: Checker, + message?: (value: unknown, expected: string) => string +): T; +export function check(value: T, checker: (value: T) => asserts value is U): U; +export function check( + value: unknown, + checker: Checker | ((value: unknown) => void), + message: (value: unknown, expected: string) => string = defaultMessage +): T { + if (typeof checker === 'function') { + checker(value); + return value as T; + } if (checker.validate(value)) { return value; } else { - throw new Error(`Got ${value}, expected:\n${checker.expected()}`); + throw new Error(message(value, checker.expected())); } } diff --git a/packages/@glimmer/destroyable/index.ts b/packages/@glimmer/destroyable/index.ts index d06d2d57b..63f7de663 100644 --- a/packages/@glimmer/destroyable/index.ts +++ b/packages/@glimmer/destroyable/index.ts @@ -1,7 +1,7 @@ import { DEBUG } from '@glimmer/env'; +import { scheduleDestroy, scheduleDestroyed } from '@glimmer/global-context'; import { Destroyable, Destructor } from '@glimmer/interfaces'; import { debugToString } from '@glimmer/util'; -import { scheduleDestroy, scheduleDestroyed } from '@glimmer/global-context'; const enum DestroyingState { Live = 0, @@ -41,9 +41,7 @@ function push(collection: OneOrMany, newItem: T): OneOrMany function iterate(collection: OneOrMany, fn: (item: T) => void) { if (Array.isArray(collection)) { - for (let i = 0; i < collection.length; i++) { - fn(collection[i]); - } + collection.forEach(fn); } else if (collection !== null) { fn(collection); } diff --git a/packages/@glimmer/destroyable/test/destroyables-test.ts b/packages/@glimmer/destroyable/test/destroyables-test.ts index 03d27f092..4999067c6 100644 --- a/packages/@glimmer/destroyable/test/destroyables-test.ts +++ b/packages/@glimmer/destroyable/test/destroyables-test.ts @@ -1,16 +1,17 @@ +import { DEBUG } from '@glimmer/env'; +import { GlobalContext, testOverrideGlobalContext } from '@glimmer/global-context'; + import { - registerDestructor, - unregisterDestructor, + assertDestroyablesDestroyed, associateDestroyableChild, destroy, - isDestroying, - isDestroyed, destroyChildren, enableDestroyableTracking, - assertDestroyablesDestroyed, + isDestroyed, + isDestroying, + registerDestructor, + unregisterDestructor, } from '..'; -import { DEBUG } from '@glimmer/env'; -import { testOverrideGlobalContext, GlobalContext } from '@glimmer/global-context'; const { module, test } = QUnit; diff --git a/packages/@glimmer/dom-change-list/index.ts b/packages/@glimmer/dom-change-list/index.ts index 92de93926..f4b73104b 100644 --- a/packages/@glimmer/dom-change-list/index.ts +++ b/packages/@glimmer/dom-change-list/index.ts @@ -1,4 +1,4 @@ -export * from './lib/tree-construction'; export * from './lib/dom-operations'; export * from './lib/node-tokens'; export * from './lib/tree-builder'; +export * from './lib/tree-construction'; diff --git a/packages/@glimmer/dom-change-list/lib/dom-operations.ts b/packages/@glimmer/dom-change-list/lib/dom-operations.ts index eb56a04de..04ef0c432 100644 --- a/packages/@glimmer/dom-change-list/lib/dom-operations.ts +++ b/packages/@glimmer/dom-change-list/lib/dom-operations.ts @@ -9,7 +9,8 @@ import { SimpleElement, SimpleNode, } from '@glimmer/interfaces'; -import { dict, assert, assign } from '@glimmer/util'; +import { assert, assign, dict } from '@glimmer/util'; + import { NodeTokensImpl } from './node-tokens'; export enum ConstructionOperation { @@ -42,13 +43,14 @@ export class Constants { private set = dict(); get(s: string): number { - if (this.set[s] !== undefined) { - return this.set[s]; + let index = this.set[s]; + + if (index === undefined) { + index = this.strings.length; + this.strings.push(s); + this.set[s] = index; } - let index = this.strings.length; - this.strings.push(s); - this.set[s] = index; return index; } @@ -139,24 +141,24 @@ export function run(opcodes: ReadonlyArray, options: RunOptions) { }); while (offset < end) { - let value = opcodes[offset]; + let value = opcodes[offset]!; let size = sizeof(value); let opcode = opcodeof(value); - let func = ConstructionOperations[opcode]; + let func = ConstructionOperations[opcode]!; switch (size) { case 0: func(state); break; case 1: - func(state, opcodes[offset + 1]); + func(state, opcodes[offset + 1]!); break; case 2: - func(state, opcodes[offset + 1], opcodes[offset + 2]); + func(state, opcodes[offset + 1]!, opcodes[offset + 2]!); break; case 3: - func(state, opcodes[offset + 1], opcodes[offset + 2], opcodes[offset + 3]); + func(state, opcodes[offset + 1]!, opcodes[offset + 2]!, opcodes[offset + 3]!); break; } @@ -175,7 +177,7 @@ const ConstructionOperations: ConstructionFunction[] = [ if (state.constructing) flush(state); - let el = document.createElementNS(constants[namespace] as ElementNamespace, constants[tag]); + let el = document.createElementNS(constants[namespace] as ElementNamespace, constants[tag]!); state.constructing = el; state.tokens.register(el); }, @@ -184,7 +186,7 @@ const ConstructionOperations: ConstructionFunction[] = [ (state) => { if (state.constructing) flush(state); state.elements.pop(); - state.parent = state.elements[state.elements.length - 1]; + state.parent = state.elements[state.elements.length - 1]!; }, /* (SetAttribute name value namespace) */ @@ -198,8 +200,8 @@ const ConstructionOperations: ConstructionFunction[] = [ constructing!.setAttributeNS( constants[namespace] as AttrNamespace, - constants[name], - constants[value] + constants[name]!, + constants[value]! ); }, @@ -208,7 +210,7 @@ const ConstructionOperations: ConstructionFunction[] = [ let { constants, document, parent, nextSibling, constructing } = state; let parentElement = constructing ? flush(state) : parent; - let textNode = document.createTextNode(constants[text]); + let textNode = document.createTextNode(constants[text]!); parentElement.insertBefore(textNode, nextSibling); state.tokens.register(textNode); }, @@ -217,7 +219,7 @@ const ConstructionOperations: ConstructionFunction[] = [ (state, text) => { let { constants, document, parent, nextSibling } = state; let parentElement = state.constructing ? flush(state) : parent; - let commentNode = document.createComment(constants[text]); + let commentNode = document.createComment(constants[text]!); parentElement.insertBefore(commentNode, nextSibling); state.tokens.register(commentNode); }, diff --git a/packages/@glimmer/dom-change-list/lib/node-tokens.ts b/packages/@glimmer/dom-change-list/lib/node-tokens.ts index d14cc0203..7e4e7194c 100644 --- a/packages/@glimmer/dom-change-list/lib/node-tokens.ts +++ b/packages/@glimmer/dom-change-list/lib/node-tokens.ts @@ -10,6 +10,6 @@ export class NodeTokensImpl implements NodeTokens { } reify(token: NodeToken): SimpleNode { - return this.nodes[token]; + return this.nodes[token]!; } } diff --git a/packages/@glimmer/dom-change-list/lib/tree-builder.ts b/packages/@glimmer/dom-change-list/lib/tree-builder.ts index 220a58131..d101d28fb 100644 --- a/packages/@glimmer/dom-change-list/lib/tree-builder.ts +++ b/packages/@glimmer/dom-change-list/lib/tree-builder.ts @@ -1,13 +1,14 @@ import { - Option, - NodeTokens, Dict, Namespace, NodeToken, - SimpleElement, - SimpleDocumentFragment, + NodeTokens, + Option, SimpleDocument, + SimpleDocumentFragment, + SimpleElement, } from '@glimmer/interfaces'; + import { HTML } from './dom-operations'; import { DOMTreeConstruction } from './tree-construction'; @@ -152,6 +153,6 @@ export class TreeBuilder { let { contexts } = this; let { length } = contexts; - return length ? contexts[length - 1] : null; + return length ? contexts[length - 1]! : null; } } diff --git a/packages/@glimmer/dom-change-list/lib/tree-construction.ts b/packages/@glimmer/dom-change-list/lib/tree-construction.ts index 6d92373b1..e797ac02e 100644 --- a/packages/@glimmer/dom-change-list/lib/tree-construction.ts +++ b/packages/@glimmer/dom-change-list/lib/tree-construction.ts @@ -1,13 +1,14 @@ -import { NodeTokensImpl } from './node-tokens'; -import { HTML, OperationsBuilder, run } from './dom-operations'; import { Namespace, + NodeToken, SimpleDocument, - SimpleElement, SimpleDocumentFragment, - NodeToken, + SimpleElement, } from '@glimmer/interfaces'; +import { HTML, OperationsBuilder, run } from './dom-operations'; +import { NodeTokensImpl } from './node-tokens'; + // https://github.com/whatwg/dom/issues/270 export class DOMTreeConstruction { diff --git a/packages/@glimmer/dom-change-list/test/change-list-test.ts b/packages/@glimmer/dom-change-list/test/change-list-test.ts index 455852d6a..5af567211 100644 --- a/packages/@glimmer/dom-change-list/test/change-list-test.ts +++ b/packages/@glimmer/dom-change-list/test/change-list-test.ts @@ -1,15 +1,15 @@ -import { DOMTreeConstruction, NodeTokensImpl } from '..'; - -import { TestCase, module, test } from './test-case'; -import { Builder as TestBuilder, toHTML, toHTMLNS } from './support'; import { Namespace, SimpleDocument, - SimpleElement, SimpleDocumentFragment, + SimpleElement, } from '@glimmer/interfaces'; import createDocument from '@simple-dom/document'; +import { DOMTreeConstruction, NodeTokensImpl } from '..'; +import { Builder as TestBuilder, toHTML, toHTMLNS } from './support'; +import { module, test, TestCase } from './test-case'; + const SVG = Namespace.SVG; const XLINK = Namespace.XLink; @@ -21,7 +21,7 @@ export class ChangeListTest extends TestCase { protected declare tree: Builder; protected declare construction: DOMTreeConstruction; - before() { + override before() { this.document = createDocument(); this.parent = this.document.createElement('div'); this.construction = new DOMTreeConstruction(); diff --git a/packages/@glimmer/dom-change-list/test/support.ts b/packages/@glimmer/dom-change-list/test/support.ts index f410ce161..885f02ce9 100644 --- a/packages/@glimmer/dom-change-list/test/support.ts +++ b/packages/@glimmer/dom-change-list/test/support.ts @@ -1,16 +1,19 @@ -import { Option, NodeTokens } from '@glimmer/interfaces'; -import { DOMTreeConstruction, TreeBuilder } from '..'; import { - Namespace, AttrNamespace, + Namespace, + NodeTokens, NodeType, - SimpleElement, - SimpleDocumentFragment, + Option, + PresentArray, SimpleAttr, + SimpleDocumentFragment, + SimpleElement, } from '@glimmer/interfaces'; import Serializer from '@simple-dom/serializer'; import voidMap from '@simple-dom/void-map'; +import { DOMTreeConstruction, TreeBuilder } from '..'; + export const SVG = Namespace.SVG; export const XLINK = Namespace.XLink; @@ -27,7 +30,7 @@ export function toHTMLNS(parent: SimpleElement | SimpleDocumentFragment) { } class NamespacedHTMLSerializer extends Serializer { - openTag(element: SimpleElement): string { + override openTag(element: SimpleElement): string { if (element.namespaceURI === SVG) { return ''; } else { @@ -35,7 +38,7 @@ class NamespacedHTMLSerializer extends Serializer { } } - closeTag(element: SimpleElement): string { + override closeTag(element: SimpleElement): string { if (element.namespaceURI === SVG) { return ''; } else { @@ -43,7 +46,7 @@ class NamespacedHTMLSerializer extends Serializer { } } - attr(original: SimpleAttr): string { + override attr(original: SimpleAttr): string { let attr: { name: string; value: Option; specified: boolean }; if (original.namespaceURI === XLINK) { attr = { @@ -65,10 +68,10 @@ export interface ExpectedToken { } export class Builder { - protected expected: ExpectedToken[] = []; + protected expected: PresentArray; constructor(protected tree: DOMTreeConstruction | TreeBuilder) { - this.expected[0] = { type: 'element', value: '' }; + this.expected = [{ type: 'element', value: '' }]; } appendTo(parent: SimpleElement | SimpleDocumentFragment) { diff --git a/packages/@glimmer/dom-change-list/test/tree-builder-test.ts b/packages/@glimmer/dom-change-list/test/tree-builder-test.ts index 780fa328c..604b47481 100644 --- a/packages/@glimmer/dom-change-list/test/tree-builder-test.ts +++ b/packages/@glimmer/dom-change-list/test/tree-builder-test.ts @@ -1,9 +1,9 @@ -import { DOMTreeConstruction, NodeTokensImpl, TreeBuilder } from '..'; - -import { TestCase, module, test } from './test-case'; -import { XLINK, Builder as TestBuilder, toHTML, toHTMLNS } from './support'; -import createHTMLDocument from '@simple-dom/document'; import { SimpleDocument, SimpleDocumentFragment, SimpleElement } from '@glimmer/interfaces'; +import createHTMLDocument from '@simple-dom/document'; + +import { DOMTreeConstruction, NodeTokensImpl, TreeBuilder } from '..'; +import { Builder as TestBuilder, toHTML, toHTMLNS, XLINK } from './support'; +import { module, test, TestCase } from './test-case'; @module('[dom-change-list] TreeBuilder') export class ChangeListTest extends TestCase { @@ -14,7 +14,7 @@ export class ChangeListTest extends TestCase { protected declare builder: TreeBuilder; protected declare construction: DOMTreeConstruction; - before() { + override before() { this.document = createHTMLDocument(); this.parent = this.document.createElement('div'); this.construction = new DOMTreeConstruction(); diff --git a/packages/@glimmer/encoder/lib/encoder.ts b/packages/@glimmer/encoder/lib/encoder.ts index 4a9d500f4..e9380f41b 100644 --- a/packages/@glimmer/encoder/lib/encoder.ts +++ b/packages/@glimmer/encoder/lib/encoder.ts @@ -1,11 +1,11 @@ import { DEBUG } from '@glimmer/env'; import { CompilerBuffer, - Operand, + InstructionEncoder, MachineOp, Op, - InstructionEncoder, OpcodeSize, + Operand, } from '@glimmer/interfaces'; export class InstructionEncoderImpl implements InstructionEncoder { diff --git a/packages/@glimmer/integration-tests/index.ts b/packages/@glimmer/integration-tests/index.ts index 1e00222c9..79c351a10 100644 --- a/packages/@glimmer/integration-tests/index.ts +++ b/packages/@glimmer/integration-tests/index.ts @@ -6,17 +6,17 @@ export * from './lib/dom/simple-utils'; export * from './lib/markers'; export * from './lib/modes/env'; export * from './lib/modes/jit/delegate'; -export * from './lib/modes/jit/resolver'; export * from './lib/modes/jit/register'; +export * from './lib/modes/jit/resolver'; export * from './lib/modes/node/env'; export * from './lib/modes/rehydration/delegate'; export * from './lib/modes/rehydration/partial-rehydration-delegate'; export * from './lib/render-test'; export * from './lib/snapshot'; export * from './lib/suites'; +export * from './lib/test-helpers/define'; export * from './lib/test-helpers/module'; export * from './lib/test-helpers/strings'; export * from './lib/test-helpers/test'; export * from './lib/test-helpers/tracked'; export * from './lib/test-helpers/tracked-object'; -export * from './lib/test-helpers/define'; diff --git a/packages/@glimmer/integration-tests/lib/components.ts b/packages/@glimmer/integration-tests/lib/components.ts index 42c1be85e..d7eeb0bfa 100644 --- a/packages/@glimmer/integration-tests/lib/components.ts +++ b/packages/@glimmer/integration-tests/lib/components.ts @@ -1,3 +1,3 @@ -export * from './components/types'; export * from './components/emberish-curly'; export * from './components/emberish-glimmer'; +export * from './components/types'; diff --git a/packages/@glimmer/integration-tests/lib/components/emberish-curly.ts b/packages/@glimmer/integration-tests/lib/components/emberish-curly.ts index 7164e70d8..28c9f96e1 100644 --- a/packages/@glimmer/integration-tests/lib/components/emberish-curly.ts +++ b/packages/@glimmer/integration-tests/lib/components/emberish-curly.ts @@ -9,10 +9,10 @@ import { ElementOperations, Environment, InternalComponentCapabilities, - Reference, Option, Owner, PreparedArguments, + Reference, Template, VMArguments, WithCreateInstance, @@ -28,8 +28,9 @@ import { valueForRef, } from '@glimmer/reference'; import { reifyNamed, reifyPositional } from '@glimmer/runtime'; -import { EMPTY_ARRAY, assign, keys, unwrapTemplate } from '@glimmer/util'; -import { DirtyableTag, consumeTag, createTag, dirtyTag, dirtyTagFor } from '@glimmer/validator'; +import { assign, EMPTY_ARRAY, keys, unwrapTemplate } from '@glimmer/util'; +import { consumeTag, createTag, DirtyableTag, dirtyTag, dirtyTagFor } from '@glimmer/validator'; + import { TestJitRuntimeResolver } from '../modes/jit/resolver'; import { TestComponentConstructor } from './types'; @@ -181,7 +182,7 @@ export class EmberishCurlyComponentManager let count = Math.min(positionalParams.length, args.positional.length); for (let i = 0; i < count; i++) { - let name = positionalParams[i]; + let name = positionalParams[i] as string; if (named[name]) { throw new Error( @@ -227,7 +228,7 @@ export class EmberishCurlyComponentManager if (dyn) { for (let i = 0; i < dyn.length; i++) { - let name = dyn[i]; + let name = dyn[i] as string; component.set(name, valueForRef(dynamicScope.get(name))); } } @@ -273,8 +274,7 @@ export class EmberishCurlyComponentManager let bindings = component.attributeBindings; if (bindings) { - for (let i = 0; i < bindings.length; i++) { - let attribute = bindings[i]; + for (const attribute of bindings) { let reference = childRefFor(selfRef, attribute); operations.setAttribute(attribute, reference, false, null); diff --git a/packages/@glimmer/integration-tests/lib/components/emberish-glimmer.ts b/packages/@glimmer/integration-tests/lib/components/emberish-glimmer.ts index 819117723..75decb61a 100644 --- a/packages/@glimmer/integration-tests/lib/components/emberish-glimmer.ts +++ b/packages/@glimmer/integration-tests/lib/components/emberish-glimmer.ts @@ -1,7 +1,7 @@ -import { Dict, Owner, ComponentManager, Arguments } from '@glimmer/interfaces'; import { destroy, isDestroyed, isDestroying, registerDestructor } from '@glimmer/destroyable'; -import { setOwner } from '@glimmer/owner'; +import { Arguments, ComponentManager, Dict, Owner } from '@glimmer/interfaces'; import { componentCapabilities, setComponentManager } from '@glimmer/manager'; +import { setOwner } from '@glimmer/owner'; export type Args = Dict; diff --git a/packages/@glimmer/integration-tests/lib/components/types.ts b/packages/@glimmer/integration-tests/lib/components/types.ts index c71a31ae4..f89a773d6 100644 --- a/packages/@glimmer/integration-tests/lib/components/types.ts +++ b/packages/@glimmer/integration-tests/lib/components/types.ts @@ -1,8 +1,9 @@ -import { GlimmerishComponent } from './emberish-glimmer'; -import { EmberishCurlyComponent } from './emberish-curly'; import { Dict } from '@glimmer/interfaces'; import { TemplateOnlyComponent } from '@glimmer/runtime'; +import { EmberishCurlyComponent } from './emberish-curly'; +import { GlimmerishComponent } from './emberish-glimmer'; + export type ComponentKind = 'Glimmer' | 'Curly' | 'Dynamic' | 'TemplateOnly' | 'Custom' | 'unknown'; export interface TestComponentConstructor { diff --git a/packages/@glimmer/integration-tests/lib/dom/assertions.ts b/packages/@glimmer/integration-tests/lib/dom/assertions.ts index 333cc0261..c2f1885c8 100644 --- a/packages/@glimmer/integration-tests/lib/dom/assertions.ts +++ b/packages/@glimmer/integration-tests/lib/dom/assertions.ts @@ -1,27 +1,28 @@ -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; -import { Dict } from '@glimmer/interfaces'; -import { dict, assign } from '@glimmer/util'; +import { Dict, SimpleElement, SimpleNode } from '@glimmer/interfaces'; +import { assign, dict, isSimpleElement } from '@glimmer/util'; export interface DebugElement { - element: SimpleElement | null; + element: SimpleElement | null | undefined; description: string; } -function isDebugElement(el: SimpleElement | DebugElement): el is DebugElement { +function isDebugElement(el: SimpleNode | Node | DebugElement): el is DebugElement { return !(el as any).nodeType; } -function extract(element: EqualsElement): DebugElement { - if (element === null) { - return { element: null, description: 'element' }; - } else if (isDebugElement(element)) { - return element; +function extract(node: EqualsElement): DebugElement { + if (node === null || node === undefined) { + return { element: node, description: 'element' }; + } else if (isDebugElement(node)) { + return node; + } else if (isSimpleElement(node)) { + return { element: node, description: `${node.tagName}` }; } else { - return { element, description: 'element' }; + return { element: null, description: `${node.constructor.name}` }; } } -export type EqualsElement = SimpleElement | null | DebugElement; +export type EqualsElement = SimpleNode | Node | null | undefined | DebugElement; export function equalsElement( input: EqualsElement, @@ -31,12 +32,14 @@ export function equalsElement( ) { let { element, description } = extract(input); - if (element === null) { + if (element === null || element === undefined) { QUnit.assert.pushResult({ result: false, actual: element, expected: true, - message: `failed - expected ${description} to not be null`, + message: `failed - expected ${description} to be present (it was ${ + element === null ? 'null' : 'missing' + })`, }); return; } @@ -51,15 +54,14 @@ export function equalsElement( let expectedAttrs: Dict = dict(); let expectedCount = 0; - for (let prop in attributes) { + for (let [prop, expected] of Object.entries(attributes)) { expectedCount++; - let expected = attributes[prop]; let matcher: Matcher = isMatcher(expected) ? expected : equalsAttr(expected); expectedAttrs[prop] = matcher; QUnit.assert.pushResult({ - result: expectedAttrs[prop].match(element && element.getAttribute(prop)), + result: matcher.match(element && element.getAttribute(prop)), actual: matcher.fail(element && element.getAttribute(prop)), expected: matcher.fail(element && element.getAttribute(prop)), message: `Expected ${description}'s ${prop} attribute ${matcher.expected()}`, @@ -68,8 +70,8 @@ export function equalsElement( let actualAttributes = dict(); if (element) { - for (let i = 0, l = element.attributes.length; i < l; i++) { - actualAttributes[element.attributes[i].name] = element.attributes[i].value; + for (const attribute of Array.from(element.attributes)) { + actualAttributes[attribute.name] = attribute.value; } } diff --git a/packages/@glimmer/integration-tests/lib/dom/simple-utils.ts b/packages/@glimmer/integration-tests/lib/dom/simple-utils.ts index b6e523a5e..20c3e507f 100644 --- a/packages/@glimmer/integration-tests/lib/dom/simple-utils.ts +++ b/packages/@glimmer/integration-tests/lib/dom/simple-utils.ts @@ -1,19 +1,20 @@ import { - SimpleElement, - SimpleDocumentFragment, InsertPosition, - SimpleNode, + Maybe, NodeType, + Option, SerializableElement, SerializableNode, SimpleComment, - SimpleText, SimpleDocument, + SimpleDocumentFragment, + SimpleElement, + SimpleNode, + SimpleText, } from '@glimmer/interfaces'; +import { clearElement } from '@glimmer/util'; import Serializer from '@simple-dom/serializer'; import voidMap from '@simple-dom/void-map'; -import { Option } from '@glimmer/interfaces'; -import { clearElement } from '@glimmer/util'; export function toInnerHTML(parent: SimpleElement | SimpleDocumentFragment): string { let serializer = new Serializer(voidMap); @@ -47,7 +48,7 @@ export function castToBrowser(node: null): null; export function castToBrowser( node: N ): CastableBrowserDom>; -export function castToBrowser( +export function castToBrowser( node: SimpleNode, nodeType: 'Node' ): CastToBrowserDom['Node']['browser']; @@ -160,7 +161,7 @@ export function replaceHTML(parent: SimpleElement, value: string): void { parent.insertAdjacentHTML(InsertPosition.afterbegin, value); } -export function assertElement(node: Option): SimpleElement { +export function assertingElement(node: Maybe): SimpleElement { if (!node || node.nodeType !== NodeType.ELEMENT_NODE) { throw new Error(`Expected element, got ${node}`); } @@ -168,14 +169,18 @@ export function assertElement(node: Option): SimpleElement { return node; } -export function hasAttribute(parent: SimpleElement, attr: string): boolean { - let attrs = parent.attributes; +export function isSimpleElement(node: Maybe): node is SimpleElement { + return !node || node.nodeType !== NodeType.ELEMENT_NODE; +} - for (let i = 0; i < attrs.length; i++) { - if (attrs[i].name === attr) return true; +export function assertElement(node: Maybe): asserts node is SimpleElement { + if (!isSimpleElement(node)) { + throw new Error(`Expected element, got ${node}`); } +} - return false; +export function hasAttribute(parent: SimpleElement, attr: string): boolean { + return Array.from(parent.attributes).some((parentAttr) => parentAttr.name === attr); } export function firstElementChild(parent: SimpleElement): Option { @@ -209,23 +214,23 @@ export function elementId(element: SimpleElement): Option { } class TextSerializer extends Serializer { - openTag(_element: SerializableElement) { + override openTag(_element: SerializableElement) { return ''; } - closeTag(_element: SerializableElement) { + override closeTag(_element: SerializableElement) { return ''; } - text(text: SerializableNode) { + override text(text: SerializableNode) { return text.nodeValue || ''; } - comment(_comment: SerializableNode) { + override comment(_comment: SerializableNode) { return ''; } - rawHTMLSection(_content: SerializableNode): never { + override rawHTMLSection(_content: SerializableNode): never { throw new Error('Unexpected raw HTML section in serialized text'); } } diff --git a/packages/@glimmer/integration-tests/lib/helpers.ts b/packages/@glimmer/integration-tests/lib/helpers.ts index 5aa1488a1..8f985eee5 100644 --- a/packages/@glimmer/integration-tests/lib/helpers.ts +++ b/packages/@glimmer/integration-tests/lib/helpers.ts @@ -1,6 +1,6 @@ -import { Dict, CapturedArguments } from '@glimmer/interfaces'; -import { Reference, createComputeRef } from '@glimmer/reference'; -import { reifyPositional, reifyNamed } from '@glimmer/runtime'; +import { CapturedArguments, Dict } from '@glimmer/interfaces'; +import { createComputeRef, Reference } from '@glimmer/reference'; +import { reifyNamed, reifyPositional } from '@glimmer/runtime'; export type UserHelper = (args: ReadonlyArray, named: Dict) => unknown; diff --git a/packages/@glimmer/integration-tests/lib/modes/env.ts b/packages/@glimmer/integration-tests/lib/modes/env.ts index 555751f36..eed49cfe2 100644 --- a/packages/@glimmer/integration-tests/lib/modes/env.ts +++ b/packages/@glimmer/integration-tests/lib/modes/env.ts @@ -1,11 +1,15 @@ -import { EnvironmentDelegate } from '@glimmer/runtime'; +import setGlobalContext from '@glimmer/global-context'; import { Destroyable, Destructor, Dict, Option } from '@glimmer/interfaces'; import { IteratorDelegate } from '@glimmer/reference'; -import setGlobalContext from '@glimmer/global-context'; -import { consumeTag, tagFor, dirtyTagFor } from '@glimmer/validator'; +import { EnvironmentDelegate } from '@glimmer/runtime'; +import { consumeTag, dirtyTagFor, tagFor } from '@glimmer/validator'; -let scheduledDestroyables: Destroyable[] = []; -let scheduledDestructors: Destructor[] = []; +interface Scheduled { + destroyable: Destroyable; + destructor: Destructor; +} + +let scheduled: Scheduled[] = []; let scheduledFinishDestruction: (() => void)[] = []; let actualDeprecations: string[] = []; @@ -27,9 +31,8 @@ QUnit.assert.validateDeprecations = function (...expectedDeprecations: (string | }); } - for (let i = 0; i < actualDeprecations.length; i++) { - let actual = actualDeprecations[i]; - let expected = expectedDeprecations[i]; + actualDeprecations.forEach((actual, i) => { + let expected = expectedDeprecations[i] as string | RegExp; let result = expected instanceof RegExp ? Boolean(actual.match(expected)) : actual === expected; @@ -39,7 +42,7 @@ QUnit.assert.validateDeprecations = function (...expectedDeprecations: (string | expected, message: `Deprecation ${i + 1} matches: "${actual}"`, }); - } + }); actualDeprecations = []; }; @@ -72,8 +75,7 @@ setGlobalContext({ scheduleRevalidate() {}, scheduleDestroy(destroyable: T, destructor: Destructor) { - scheduledDestroyables.push(destroyable); - scheduledDestructors.push(destructor); + scheduled.push({ destroyable, destructor }); }, scheduleDestroyed(fn: () => void) { @@ -193,14 +195,13 @@ export const BaseEnv: EnvironmentDelegate = { enableDebugTooling: false, onTransactionCommit() { - for (let i = 0; i < scheduledDestroyables.length; i++) { - scheduledDestructors[i](scheduledDestroyables[i]); + for (const { destroyable, destructor } of scheduled) { + destructor(destroyable); } scheduledFinishDestruction.forEach((fn) => fn()); - scheduledDestroyables = []; - scheduledDestructors = []; + scheduled = []; scheduledFinishDestruction = []; }, }; diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/compilation-context.ts b/packages/@glimmer/integration-tests/lib/modes/jit/compilation-context.ts index 86d58642a..252e80b5d 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/compilation-context.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/compilation-context.ts @@ -1,10 +1,11 @@ import { CompileTimeResolver, - Option, - ResolvedComponentDefinition, HelperDefinitionState, ModifierDefinitionState, + Option, + ResolvedComponentDefinition, } from '@glimmer/interfaces'; + import { TestJitRuntimeResolver } from './resolver'; export default class JitCompileTimeLookup implements CompileTimeResolver { diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/delegate.ts b/packages/@glimmer/integration-tests/lib/modes/jit/delegate.ts index b8492fb5d..9f1eabb87 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/delegate.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/delegate.ts @@ -1,4 +1,3 @@ -import { PrecompileOptions } from '@glimmer/syntax'; import { CapturedRenderNode, CompileTimeCompilationContext, @@ -6,12 +5,17 @@ import { Dict, DynamicScope, ElementBuilder, + ElementNamespace, Environment, HandleResult, Helper, Option, RenderResult, RuntimeContext, + SimpleDocument, + SimpleDocumentFragment, + SimpleElement, + SimpleText, } from '@glimmer/interfaces'; import { programCompilationContext } from '@glimmer/opcode-compiler'; import { artifacts, RuntimeOpImpl } from '@glimmer/program'; @@ -30,15 +34,9 @@ import { renderSync, runtimeContext, } from '@glimmer/runtime'; -import { ASTPluginBuilder } from '@glimmer/syntax'; +import { ASTPluginBuilder, PrecompileOptions } from '@glimmer/syntax'; import { assign, castToBrowser, castToSimple, expect, unwrapTemplate } from '@glimmer/util'; -import { - ElementNamespace, - SimpleDocument, - SimpleDocumentFragment, - SimpleElement, - SimpleText, -} from '@glimmer/interfaces'; + import { preprocess } from '../../compile'; import { ComponentKind, ComponentTypes } from '../../components'; import { UserHelper } from '../../helpers'; diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/register.ts b/packages/@glimmer/integration-tests/lib/modes/jit/register.ts index d679e3803..10766f964 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/register.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/register.ts @@ -1,29 +1,30 @@ -import { TestJitRegistry } from './registry'; import { - Option, + CurriedType, Helper as GlimmerHelper, InternalModifierManager, - TemplateFactory, + Option, ResolutionTimeConstants, - CurriedType, + TemplateFactory, } from '@glimmer/interfaces'; +import { + getInternalComponentManager, + setComponentTemplate, + setInternalHelperManager, + setInternalModifierManager, +} from '@glimmer/manager'; +import { CurriedValue, curry, templateOnlyComponent } from '@glimmer/runtime'; + +import { createTemplate } from '../../compile'; +import { ComponentKind, ComponentTypes } from '../../components'; import { EmberishCurlyComponent } from '../../components/emberish-curly'; import { GlimmerishComponent } from '../../components/emberish-glimmer'; -import { UserHelper, createHelperRef } from '../../helpers'; +import { createHelperRef, UserHelper } from '../../helpers'; import { TestModifierConstructor, TestModifierDefinitionState, TestModifierManager, } from '../../modifiers'; -import { ComponentKind, ComponentTypes } from '../../components'; -import { CurriedValue, curry, templateOnlyComponent } from '@glimmer/runtime'; -import { createTemplate } from '../../compile'; -import { - getInternalComponentManager, - setComponentTemplate, - setInternalHelperManager, - setInternalModifierManager, -} from '@glimmer/manager'; +import { TestJitRegistry } from './registry'; export function registerTemplateOnlyComponent( registry: TestJitRegistry, diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/registry.ts b/packages/@glimmer/integration-tests/lib/modes/jit/registry.ts index 8f3bc2eaf..297612928 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/registry.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/registry.ts @@ -1,15 +1,15 @@ import { CompilableProgram, - ResolvedComponentDefinition, + HelperDefinitionState, + InternalComponentManager, Invocation, + ModifierDefinitionState, Option, + ResolvedComponentDefinition, Template, - HelperDefinitionState, - ModifierDefinitionState, - InternalComponentManager, } from '@glimmer/interfaces'; -import { assert, dict } from '@glimmer/util'; import { getComponentTemplate } from '@glimmer/manager'; +import { assert, dict } from '@glimmer/util'; // This is used to replicate a requirement of Ember's template referrers, which // assign the `owner` to the template meta. The requirement is that the template @@ -38,7 +38,7 @@ export class TypedRegistry { } get(name: string): Option { - return this.byName[name]; + return this.byName[name] ?? null; } register(name: string, value: T): void { diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/render.ts b/packages/@glimmer/integration-tests/lib/modes/jit/render.ts index 817b1e1cc..9c1579fee 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/render.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/render.ts @@ -1,11 +1,12 @@ -import { JitTestDelegateContext } from './delegate'; -import { PrecompileOptions } from '@glimmer/syntax'; -import { Reference } from '@glimmer/reference'; import { ElementBuilder, RenderResult } from '@glimmer/interfaces'; -import { preprocess } from '../../compile'; +import { Reference } from '@glimmer/reference'; import { renderMain, renderSync } from '@glimmer/runtime'; +import { PrecompileOptions } from '@glimmer/syntax'; import { unwrapTemplate } from '@glimmer/util'; +import { preprocess } from '../../compile'; +import { JitTestDelegateContext } from './delegate'; + export function renderTemplate( src: string, { runtime, program }: JitTestDelegateContext, diff --git a/packages/@glimmer/integration-tests/lib/modes/jit/resolver.ts b/packages/@glimmer/integration-tests/lib/modes/jit/resolver.ts index 1dddaa972..f83e640ea 100644 --- a/packages/@glimmer/integration-tests/lib/modes/jit/resolver.ts +++ b/packages/@glimmer/integration-tests/lib/modes/jit/resolver.ts @@ -1,10 +1,11 @@ import { - RuntimeResolver, + HelperDefinitionState, + ModifierDefinitionState, Option, ResolvedComponentDefinition, - ModifierDefinitionState, - HelperDefinitionState, + RuntimeResolver, } from '@glimmer/interfaces'; + import { TestJitRegistry } from './registry'; export class TestJitRuntimeResolver implements RuntimeResolver { diff --git a/packages/@glimmer/integration-tests/lib/modes/node/env.ts b/packages/@glimmer/integration-tests/lib/modes/node/env.ts index 6e8f63a69..cf1c9b5de 100644 --- a/packages/@glimmer/integration-tests/lib/modes/node/env.ts +++ b/packages/@glimmer/integration-tests/lib/modes/node/env.ts @@ -1,10 +1,10 @@ -import { GlimmerTreeChanges, GlimmerTreeConstruction } from '@glimmer/interfaces'; +import { GlimmerTreeChanges, GlimmerTreeConstruction, SimpleDocument } from '@glimmer/interfaces'; import createHTMLDocument from '@simple-dom/document'; -import { SimpleDocument } from '@glimmer/interfaces'; -import { JitRenderDelegate } from '../jit/delegate'; -import { RenderTest } from '../../render-test'; + +import { assertingElement, toInnerHTML } from '../../dom/simple-utils'; import RenderDelegate, { RenderDelegateOptions } from '../../render-delegate'; -import { toInnerHTML, assertElement } from '../../dom/simple-utils'; +import { RenderTest } from '../../render-test'; +import { JitRenderDelegate } from '../jit/delegate'; export interface NodeEnvironmentOptions { document: SimpleDocument; @@ -13,7 +13,7 @@ export interface NodeEnvironmentOptions { } export class NodeJitRenderDelegate extends JitRenderDelegate { - static style = 'node jit'; + static override style = 'node jit'; constructor(options: RenderDelegateOptions = {}) { options.doc = options.doc || createHTMLDocument(); @@ -26,13 +26,13 @@ export class AbstractNodeTest extends RenderTest { super(delegate); } - assertHTML(html: string) { + override assertHTML(html: string) { let serialized = toInnerHTML(this.element); this.assert.strictEqual(serialized, html); } - assertComponent(html: string) { - let el = assertElement(this.element.firstChild); + override assertComponent(html: string) { + let el = assertingElement(this.element.firstChild); if (this.testType !== 'Glimmer') { this.assert.strictEqual(el.getAttribute('class'), 'ember-view'); diff --git a/packages/@glimmer/integration-tests/lib/modes/rehydration/builder.ts b/packages/@glimmer/integration-tests/lib/modes/rehydration/builder.ts index 7b8c73234..087aec207 100644 --- a/packages/@glimmer/integration-tests/lib/modes/rehydration/builder.ts +++ b/packages/@glimmer/integration-tests/lib/modes/rehydration/builder.ts @@ -1,11 +1,10 @@ -import { Cursor, ElementBuilder, Environment } from '@glimmer/interfaces'; +import { Cursor, ElementBuilder, Environment, NodeType, SimpleNode } from '@glimmer/interfaces'; import { RehydrateBuilder } from '@glimmer/runtime'; -import { NodeType, SimpleNode } from '@glimmer/interfaces'; export class DebugRehydrationBuilder extends RehydrateBuilder { clearedNodes: SimpleNode[] = []; - remove(node: SimpleNode) { + override remove(node: SimpleNode) { let next = super.remove(node); if (node.nodeType !== NodeType.COMMENT_NODE) { diff --git a/packages/@glimmer/integration-tests/lib/modes/rehydration/delegate.ts b/packages/@glimmer/integration-tests/lib/modes/rehydration/delegate.ts index a2e97b905..f1e72e686 100644 --- a/packages/@glimmer/integration-tests/lib/modes/rehydration/delegate.ts +++ b/packages/@glimmer/integration-tests/lib/modes/rehydration/delegate.ts @@ -2,24 +2,23 @@ import { Cursor, Dict, ElementBuilder, + ElementNamespace, Environment, Helper, Option, RenderResult, -} from '@glimmer/interfaces'; -import { serializeBuilder } from '@glimmer/node'; -import { createConstRef, Reference } from '@glimmer/reference'; -import { ASTPluginBuilder, PrecompileOptions } from '@glimmer/syntax'; -import { assign, castToSimple } from '@glimmer/util'; -import createHTMLDocument from '@simple-dom/document'; -import { - ElementNamespace, SimpleDocument, SimpleDocumentFragment, SimpleElement, SimpleNode, SimpleText, } from '@glimmer/interfaces'; +import { serializeBuilder } from '@glimmer/node'; +import { createConstRef, Reference } from '@glimmer/reference'; +import { ASTPluginBuilder, PrecompileOptions } from '@glimmer/syntax'; +import { assign, castToSimple } from '@glimmer/util'; +import createHTMLDocument from '@simple-dom/document'; + import { ComponentKind } from '../../components'; import { replaceHTML, toInnerHTML } from '../../dom/simple-utils'; import { UserHelper } from '../../helpers'; diff --git a/packages/@glimmer/integration-tests/lib/modes/rehydration/partial-rehydration-delegate.ts b/packages/@glimmer/integration-tests/lib/modes/rehydration/partial-rehydration-delegate.ts index bf0d717c5..9364d3123 100644 --- a/packages/@glimmer/integration-tests/lib/modes/rehydration/partial-rehydration-delegate.ts +++ b/packages/@glimmer/integration-tests/lib/modes/rehydration/partial-rehydration-delegate.ts @@ -1,8 +1,8 @@ -import { Dict, RenderResult } from '@glimmer/interfaces'; +import { Dict, RenderResult, SimpleElement } from '@glimmer/interfaces'; import { renderComponent, renderSync } from '@glimmer/runtime'; -import { RehydrationDelegate } from './delegate'; -import { SimpleElement } from '@glimmer/interfaces'; + import { DebugRehydrationBuilder } from './builder'; +import { RehydrationDelegate } from './delegate'; export class PartialRehydrationDelegate extends RehydrationDelegate { registerTemplateOnlyComponent(name: string, layout: string) { diff --git a/packages/@glimmer/integration-tests/lib/modifiers.ts b/packages/@glimmer/integration-tests/lib/modifiers.ts index db3d83b62..f15d06260 100644 --- a/packages/@glimmer/integration-tests/lib/modifiers.ts +++ b/packages/@glimmer/integration-tests/lib/modifiers.ts @@ -1,15 +1,15 @@ -import { SimpleElement } from '@glimmer/interfaces'; +import { registerDestructor } from '@glimmer/destroyable'; import { + CapturedArguments, + Destroyable, Dict, - Option, InternalModifierManager, - Destroyable, - CapturedArguments, + Option, Owner, + SimpleElement, } from '@glimmer/interfaces'; -import { UpdatableTag, createUpdatableTag } from '@glimmer/validator'; -import { registerDestructor } from '@glimmer/destroyable'; -import { reifyPositional, reifyNamed } from '@glimmer/runtime'; +import { reifyNamed, reifyPositional } from '@glimmer/runtime'; +import { createUpdatableTag, UpdatableTag } from '@glimmer/validator'; export interface TestModifierConstructor { new (): TestModifierInstance; diff --git a/packages/@glimmer/integration-tests/lib/render-delegate.ts b/packages/@glimmer/integration-tests/lib/render-delegate.ts index be42f07d3..acff99aa9 100644 --- a/packages/@glimmer/integration-tests/lib/render-delegate.ts +++ b/packages/@glimmer/integration-tests/lib/render-delegate.ts @@ -1,24 +1,23 @@ import { - SimpleElement, - SimpleText, - ElementNamespace, - SimpleDocumentFragment, - SimpleDocument, -} from '@glimmer/interfaces'; -import { ASTPluginBuilder } from '@glimmer/syntax'; -import { ComponentKind, ComponentTypes } from './components'; -import { UserHelper } from './helpers'; -import { - Dict, - RenderResult, - Environment, Cursor, + Dict, + DynamicScope, ElementBuilder, + ElementNamespace, + Environment, Helper, - DynamicScope, + RenderResult, + SimpleDocument, + SimpleDocumentFragment, + SimpleElement, + SimpleText, } from '@glimmer/interfaces'; import { Reference } from '@glimmer/reference'; import { EnvironmentDelegate } from '@glimmer/runtime'; +import { ASTPluginBuilder } from '@glimmer/syntax'; + +import { ComponentKind, ComponentTypes } from './components'; +import { UserHelper } from './helpers'; export interface RenderDelegateOptions { doc?: SimpleDocument | Document | undefined; diff --git a/packages/@glimmer/integration-tests/lib/render-test.ts b/packages/@glimmer/integration-tests/lib/render-test.ts index e58c0524b..9606035b1 100644 --- a/packages/@glimmer/integration-tests/lib/render-test.ts +++ b/packages/@glimmer/integration-tests/lib/render-test.ts @@ -1,16 +1,20 @@ +import { destroy } from '@glimmer/destroyable'; import { + ComponentDefinitionState, Dict, + DynamicScope, + Helper, Maybe, Option, RenderResult, - Helper, - ComponentDefinitionState, - DynamicScope, + SimpleElement, + SimpleNode, } from '@glimmer/interfaces'; +import { inTransaction } from '@glimmer/runtime'; import { ASTPluginBuilder } from '@glimmer/syntax'; +import { assert, clearElement, dict, expect, isPresent } from '@glimmer/util'; import { dirtyTagFor } from '@glimmer/validator'; -import { assert, clearElement, dict, expect } from '@glimmer/util'; -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; + import { ComponentBlueprint, ComponentKind, @@ -19,13 +23,14 @@ import { GLIMMER_TEST_COMPONENT, } from './components'; import { assertElementShape, assertEmberishElement } from './dom/assertions'; -import { assertElement, toInnerHTML } from './dom/simple-utils'; +import { assertingElement, toInnerHTML } from './dom/simple-utils'; import { UserHelper } from './helpers'; import { TestModifierConstructor } from './modifiers'; import RenderDelegate from './render-delegate'; import { equalTokens, isServerMarker, NodesSnapshot, normalizeSnapshot } from './snapshot'; -import { destroy } from '@glimmer/destroyable'; -import { inTransaction } from '@glimmer/runtime'; + +type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; +type Present = Exclude; export interface IRenderTest { readonly count: Count; @@ -464,6 +469,110 @@ export class RenderTest implements IRenderTest { this.assertStableNodes(); } + protected guard(condition: any, message: string): asserts condition { + if (condition) { + this.assert.ok(condition, message); + } else { + throw Error(`Guard Failed: message`); + } + } + + protected guardWith( + desc: { [P in K]: T }, + { condition }: { condition: (value: T) => value is U } + ): U { + let [description, value] = Object.entries(desc)[0] as [string, T]; + + if (condition(value)) { + this.assert.ok( + condition(value), + `${description} satisfied ${condition.name ?? '{anonymous guard}'}` + ); + return value; + } else { + throw Error( + `Guard Failed: ${description} didn't satisfy ${condition.name ?? '{anonymous guard}'}` + ); + } + } + + protected guardPresent(desc: { [P in K]: T }): Present { + let [description, value] = Object.entries(desc)[0] as [string, T]; + + let missing = value === undefined || value === null; + + if (missing) { + throw Error(`Guard Failed: ${description} was not present (was ${String(value)})`); + } + + this.assert.ok(!missing, `${description} was present`); + + return value as Present; + } + + protected guardArray[], K extends string>(desc: { [P in K]: T }): { + [K in keyof T]: Present; + }; + protected guardArray( + desc: { [P in K]: Iterable | ArrayLike }, + options: { min: N } + ): Expand>>; + protected guardArray( + desc: { [P in K]: Iterable | ArrayLike }, + options: { min: N; condition: (value: T) => value is U } + ): Expand>; + protected guardArray>(desc: { [P in K]: A }): Expand< + NTuple> + >; + protected guardArray(desc: { + [P in K]: Iterable | ArrayLike; + }): Present[]; + protected guardArray( + desc: { + [P in K]: Iterable | ArrayLike; + }, + options: { condition: (value: T) => value is U; min?: number } + ): U[]; + protected guardArray( + desc: Record | ArrayLike>, + options?: { + min?: Maybe; + condition?: (value: unknown) => boolean; + } + ): unknown[] { + let [message, list] = Object.entries(desc)[0] as [string, unknown[]]; + + let array: unknown[] = Array.from(list); + let condition: (value: unknown) => boolean; + + if (typeof options?.min === 'number') { + if (array.length < options.min) { + throw Error( + `Guard Failed: expected to have at least ${options.min} (of ${message}), but got ${array.length}` + ); + } + + array = array.slice(0, options.min); + condition = (value) => value !== null && value !== undefined; + message = `${message}: ${options.min} present elements`; + } else if (options?.condition) { + condition = options.condition; + } else { + condition = isPresent; + message = `${message}: all are present`; + } + + let succeeds = array.every(condition); + + if (succeeds) { + this.assert.ok(succeeds, message); + } else { + throw Error(`Guard Failed: ${message}`); + } + + return array; + } + protected assertHTML(html: string, elementOrMessage?: SimpleElement | string, message?: string) { if (typeof elementOrMessage === 'object') { equalTokens(elementOrMessage || this.element, html, message ? `${html} (${message})` : html); @@ -474,7 +583,7 @@ export class RenderTest implements IRenderTest { } protected assertComponent(content: string, attrs: Object = {}) { - let element = assertElement(this.element.firstChild); + let element = assertingElement(this.element.firstChild); switch (this.testType) { case 'Glimmer': @@ -520,3 +629,70 @@ function uniq(arr: any[]) { return accum; }, []); } + +type NTuple = T['length'] extends N + ? T + : NTuple; + +export function guardArray[], K extends string>(desc: { [P in K]: T }): { + [K in keyof T]: Present; +}; +export function guardArray( + desc: { [P in K]: Iterable | ArrayLike }, + options: { min: N } +): Expand>>; +export function guardArray( + desc: { [P in K]: Iterable | ArrayLike }, + options: { min: N; condition: (value: T) => value is U } +): Expand>; +export function guardArray>(desc: { + [P in K]: A; +}): Expand>>; +export function guardArray(desc: { + [P in K]: Iterable | ArrayLike; +}): Present[]; +export function guardArray( + desc: { + [P in K]: Iterable | ArrayLike; + }, + options: { condition: (value: T) => value is U; min?: number } +): U[]; +export function guardArray( + desc: Record | ArrayLike>, + options?: { + min?: Maybe; + condition?: (value: unknown) => boolean; + } +): unknown[] { + let [message, list] = Object.entries(desc)[0] as [string, unknown[]]; + + let array: unknown[] = Array.from(list); + let condition: (value: unknown) => boolean; + + if (typeof options?.min === 'number') { + if (array.length < options.min) { + throw Error( + `Guard Failed: expected to have at least ${options.min} (of ${message}), but got ${array.length}` + ); + } + + array = array.slice(0, options.min); + condition = (value) => value !== null && value !== undefined; + message = `${message}: ${options.min} present elements`; + } else if (options?.condition) { + condition = options.condition; + } else { + condition = isPresent; + message = `${message}: all are present`; + } + + let succeeds = array.every(condition); + + if (succeeds) { + QUnit.assert.ok(succeeds, message); + } else { + throw Error(`Guard Failed: ${message}`); + } + + return array; +} diff --git a/packages/@glimmer/integration-tests/lib/snapshot.ts b/packages/@glimmer/integration-tests/lib/snapshot.ts index df8c2de73..20317401f 100644 --- a/packages/@glimmer/integration-tests/lib/snapshot.ts +++ b/packages/@glimmer/integration-tests/lib/snapshot.ts @@ -1,7 +1,7 @@ -import { Option } from '@glimmer/interfaces'; +import { NodeType, Option, SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { castToSimple } from '@glimmer/util'; -import { NodeType, SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { EndTag, Token, tokenize } from 'simple-html-tokenizer'; + import { replaceHTML, toInnerHTML } from './dom/simple-utils'; export type IndividualSnapshot = 'up' | 'down' | SimpleNode; @@ -177,7 +177,7 @@ class SnapshotIterator { peek(): Option { if (this.pos >= this.snapshot.length) return null; - return this.snapshot[this.pos]; + return this.snapshot[this.pos] as IndividualSnapshot; } next(): Option { @@ -197,7 +197,7 @@ class SnapshotIterator { } private nextNode(): IndividualSnapshot { - let token = this.snapshot[this.pos++]; + let token = this.snapshot[this.pos++] as IndividualSnapshot; if (token === 'down') { this.depth++; diff --git a/packages/@glimmer/integration-tests/lib/suites.ts b/packages/@glimmer/integration-tests/lib/suites.ts index 59300c5aa..a3ecce2e8 100644 --- a/packages/@glimmer/integration-tests/lib/suites.ts +++ b/packages/@glimmer/integration-tests/lib/suites.ts @@ -1,15 +1,15 @@ export * from './suites/components'; +export * from './suites/custom-dom-helper'; export * from './suites/debugger'; export * from './suites/each'; export * from './suites/emberish-components'; +export * from './suites/entry-point'; export * from './suites/has-block'; export * from './suites/has-block-params'; export * from './suites/in-element'; export * from './suites/initial-render'; export * from './suites/scope'; export * from './suites/shadowing'; +export * from './suites/ssr'; export * from './suites/with-dynamic-vars'; export * from './suites/yield'; -export * from './suites/ssr'; -export * from './suites/entry-point'; -export * from './suites/custom-dom-helper'; diff --git a/packages/@glimmer/integration-tests/lib/suites/components.ts b/packages/@glimmer/integration-tests/lib/suites/components.ts index 9c3b58654..8963a9ba2 100644 --- a/packages/@glimmer/integration-tests/lib/suites/components.ts +++ b/packages/@glimmer/integration-tests/lib/suites/components.ts @@ -1,11 +1,12 @@ import { Dict, Owner } from '@glimmer/interfaces'; + +import { GlimmerishComponent } from '../components'; +import { assertElementShape } from '../dom/assertions'; +import { assertingElement } from '../dom/simple-utils'; import { RenderTest } from '../render-test'; import { test } from '../test-decorator'; -import { GlimmerishComponent } from '../components'; import { strip, stripTight } from '../test-helpers/strings'; import { tracked } from '../test-helpers/tracked'; -import { assertElement } from '../dom/simple-utils'; -import { assertElementShape } from '../dom/assertions'; export class TemplateOnlyComponents extends RenderTest { static suiteName = 'TemplateOnly'; @@ -436,7 +437,7 @@ export class GlimmerishComponents extends RenderTest { constructor(owner: Owner, args: Dict) { super(owner, args); - this.Foo = args.Foo; + this.Foo = args['Foo']; } } this.registerComponent('Glimmer', 'TestHarness', '', TestHarness); @@ -456,7 +457,7 @@ export class GlimmerishComponents extends RenderTest { constructor(owner: Owner, args: Dict) { super(owner, args); - this.Foo = args.Foo; + this.Foo = args['Foo']; } } this.registerComponent('Glimmer', 'TestHarness', '', TestHarness); @@ -476,7 +477,7 @@ export class GlimmerishComponents extends RenderTest { constructor(owner: Owner, args: Dict) { super(owner, args); - this.Foo = args.Foo; + this.Foo = args['Foo']; } } this.registerComponent('Glimmer', 'TestHarness', 'world', TestHarness); @@ -497,7 +498,7 @@ export class GlimmerishComponents extends RenderTest { constructor(owner: Owner, args: Dict) { super(owner, args); - this.Foo = args.Foo; + this.Foo = args['Foo']; } } @@ -730,7 +731,7 @@ export class GlimmerishComponents extends RenderTest { { components: [{ name: 'Foo', child: 'Bar', mount: el, data: { wat: 'Wat' } }] } ); - let first = assertElement(el.firstChild); + let first = assertingElement(el.firstChild); assertElementShape(first, 'div', { 'data-bar': 'Bar' }, 'Hello World'); this.rerender({ components: [{ name: 'Foo', child: 'Bar', mount: el, data: { wat: 'Wat' } }] }); diff --git a/packages/@glimmer/integration-tests/lib/suites/custom-dom-helper.ts b/packages/@glimmer/integration-tests/lib/suites/custom-dom-helper.ts index d85c9e259..6ff152213 100644 --- a/packages/@glimmer/integration-tests/lib/suites/custom-dom-helper.ts +++ b/packages/@glimmer/integration-tests/lib/suites/custom-dom-helper.ts @@ -1,12 +1,13 @@ -import { AbstractNodeTest, NodeJitRenderDelegate } from '../modes/node/env'; -import { test } from '../test-decorator'; +import { precompile } from '@glimmer/compiler'; +import { Cursor, ElementBuilder, Environment } from '@glimmer/interfaces'; import { NodeDOMTreeConstruction, serializeBuilder } from '@glimmer/node'; -import { RenderTest } from '../render-test'; -import { Environment, Cursor, ElementBuilder } from '@glimmer/interfaces'; + import { blockStack } from '../dom/blocks'; -import { strip } from '../test-helpers/strings'; import { toInnerHTML } from '../dom/simple-utils'; -import { precompile } from '@glimmer/compiler'; +import { AbstractNodeTest, NodeJitRenderDelegate } from '../modes/node/env'; +import { RenderTest } from '../render-test'; +import { test } from '../test-decorator'; +import { strip } from '../test-helpers/strings'; export class DOMHelperTests extends AbstractNodeTest { static suiteName = 'Server-side rendering in Node.js (normal)'; @@ -36,15 +37,15 @@ export class CompilationTests extends RenderTest { } export class JitSerializationDelegate extends NodeJitRenderDelegate { - static style = 'jit serialization'; + static override style = 'jit serialization'; - getElementBuilder(env: Environment, cursor: Cursor): ElementBuilder { + override getElementBuilder(env: Environment, cursor: Cursor): ElementBuilder { return serializeBuilder(env, cursor); } } export class SerializedDOMHelperTests extends DOMHelperTests { - static suiteName = 'Server-side rendering in Node.js (serialize)'; + static override suiteName = 'Server-side rendering in Node.js (serialize)'; @test 'The compiler can handle unescaped HTML'() { @@ -103,7 +104,7 @@ export class SerializedDOMHelperTests extends DOMHelperTests { `); } - assertHTML(html: string) { + override assertHTML(html: string) { let b = blockStack(); let serialized = toInnerHTML(this.element); this.assert.strictEqual(serialized, `${b(0)}${html}${b(0)}`); diff --git a/packages/@glimmer/integration-tests/lib/suites/debugger.ts b/packages/@glimmer/integration-tests/lib/suites/debugger.ts index 75debb0cd..1b3e22cb3 100644 --- a/packages/@glimmer/integration-tests/lib/suites/debugger.ts +++ b/packages/@glimmer/integration-tests/lib/suites/debugger.ts @@ -1,5 +1,6 @@ +import { resetDebuggerCallback, setDebuggerCallback } from '@glimmer/runtime'; + import { RenderTest } from '../render-test'; -import { setDebuggerCallback, resetDebuggerCallback } from '@glimmer/runtime'; import { test } from '../test-decorator'; export class DebuggerSuite extends RenderTest { diff --git a/packages/@glimmer/integration-tests/lib/suites/each.ts b/packages/@glimmer/integration-tests/lib/suites/each.ts index e8402be69..013f3adb5 100644 --- a/packages/@glimmer/integration-tests/lib/suites/each.ts +++ b/packages/@glimmer/integration-tests/lib/suites/each.ts @@ -1,9 +1,10 @@ +import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; +import { beginTestSteps, endTestSteps, verifySteps } from '@glimmer/util'; +import { consumeTag, createTag, dirtyTag } from '@glimmer/validator'; + import { RenderTest } from '../render-test'; import { test } from '../test-decorator'; import { tracked } from '../test-helpers/tracked'; -import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; -import { beginTestSteps, endTestSteps, verifySteps } from '@glimmer/util'; -import { createTag, consumeTag, dirtyTag } from '@glimmer/validator'; export class EachSuite extends RenderTest { static suiteName = '#each'; @@ -374,7 +375,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #1, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[1]; @@ -404,7 +405,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #2, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[0]; @@ -434,7 +435,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #3, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[0]; @@ -464,7 +465,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #4, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[1]; @@ -498,7 +499,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #5, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[1]; @@ -530,7 +531,7 @@ export class EachSuite extends RenderTest { 'When re-iterated via swap #6, the original references are updated'() { if (!LOCAL_DEBUG) return; - let arr = [1, 2, 3, 4, 5, 6, 7, 8]; + let arr = numbers(); this.render(`{{#each this.arr as |item|}}{{item}}{{/each}}`, { arr }); let a = arr[1]; @@ -780,3 +781,16 @@ class Val { function val(i: number): Val { return new Val(i); } + +function numbers() { + return [1, 2, 3, 4, 5, 6, 7, 8] as [ + number, + number, + number, + number, + number, + number, + number, + number + ]; +} diff --git a/packages/@glimmer/integration-tests/lib/suites/emberish-components.ts b/packages/@glimmer/integration-tests/lib/suites/emberish-components.ts index 7bffd75ff..e7c99214c 100644 --- a/packages/@glimmer/integration-tests/lib/suites/emberish-components.ts +++ b/packages/@glimmer/integration-tests/lib/suites/emberish-components.ts @@ -1,10 +1,11 @@ -import { RenderTest, Count } from '../render-test'; -import { test } from '../test-decorator'; import { SimpleElement } from '@glimmer/interfaces'; + import { EmberishCurlyComponent } from '../components'; -import { classes, assertEmberishElement } from '../dom/assertions'; -import { assertElement, toInnerHTML } from '../dom/simple-utils'; +import { assertEmberishElement, classes } from '../dom/assertions'; +import { assertingElement, toInnerHTML } from '../dom/simple-utils'; +import { Count, RenderTest } from '../render-test'; import { equalTokens } from '../snapshot'; +import { test } from '../test-decorator'; export class EmberishComponentTests extends RenderTest { static suiteName = 'Emberish'; @@ -310,7 +311,7 @@ export class EmberishComponentTests extends RenderTest { this.render(``); - let wrapperElement = assertElement(this.element.firstChild); + let wrapperElement = assertingElement(this.element.firstChild); assertEmberishElement(wrapperElement, 'div', { 'data-foo': 'bar' }); equalTokens(toInnerHTML(wrapperElement), '

Hello world!

'); diff --git a/packages/@glimmer/integration-tests/lib/suites/entry-point.ts b/packages/@glimmer/integration-tests/lib/suites/entry-point.ts index 580870b96..60d0470ff 100644 --- a/packages/@glimmer/integration-tests/lib/suites/entry-point.ts +++ b/packages/@glimmer/integration-tests/lib/suites/entry-point.ts @@ -1,10 +1,11 @@ -import { DynamicScopeImpl } from '@glimmer/runtime'; import { createPrimitiveRef } from '@glimmer/reference'; +import { DynamicScopeImpl } from '@glimmer/runtime'; import { castToBrowser } from '@glimmer/util'; -import { RenderTest, Count } from '../render-test'; + import { ComponentKind } from '../components/types'; -import { test } from '../test-decorator'; import { JitRenderDelegate } from '../modes/jit/delegate'; +import { Count, RenderTest } from '../render-test'; +import { test } from '../test-decorator'; import { defineComponent } from '../test-helpers/define'; export class EntryPointTest extends RenderTest { @@ -12,7 +13,7 @@ export class EntryPointTest extends RenderTest { declare readonly testType: ComponentKind; - readonly count = new Count(); + override readonly count = new Count(); @test 'an entry point'() { diff --git a/packages/@glimmer/integration-tests/lib/suites/has-block-params.ts b/packages/@glimmer/integration-tests/lib/suites/has-block-params.ts index 052ed1843..ab408a1a6 100644 --- a/packages/@glimmer/integration-tests/lib/suites/has-block-params.ts +++ b/packages/@glimmer/integration-tests/lib/suites/has-block-params.ts @@ -1,6 +1,6 @@ +import { GlimmerishComponent } from '../components'; import { RenderTest } from '../render-test'; import { test } from '../test-decorator'; -import { GlimmerishComponent } from '../components'; export class HasBlockParamsHelperSuite extends RenderTest { static suiteName = 'has-block-params'; diff --git a/packages/@glimmer/integration-tests/lib/suites/in-element.ts b/packages/@glimmer/integration-tests/lib/suites/in-element.ts index 0f22fc5b7..20ed71800 100644 --- a/packages/@glimmer/integration-tests/lib/suites/in-element.ts +++ b/packages/@glimmer/integration-tests/lib/suites/in-element.ts @@ -1,13 +1,14 @@ +import { destroy } from '@glimmer/destroyable'; import { AST } from '@glimmer/syntax'; import { assign } from '@glimmer/util'; + +import { GlimmerishComponent } from '../components/emberish-glimmer'; +import { equalsElement } from '../dom/assertions'; +import { replaceHTML } from '../dom/simple-utils'; import { RenderTest } from '../render-test'; import { test } from '../test-decorator'; -import { equalsElement } from '../dom/assertions'; import { stripTight } from '../test-helpers/strings'; -import { replaceHTML } from '../dom/simple-utils'; -import { GlimmerishComponent } from '../components/emberish-glimmer'; import { tracked } from '../test-helpers/tracked'; -import { destroy } from '@glimmer/destroyable'; export class InElementSuite extends RenderTest { static suiteName = '#in-element'; @@ -424,34 +425,37 @@ export class InElementSuite extends RenderTest { } ); - equalsElement(roots[0].element, 'div', {}, '

foo

'); - equalsElement(roots[1].element, 'div', {}, '

bar

'); - equalsElement(roots[2].element, 'div', {}, '

baz

'); + const [first, second, third] = roots; + this.guard(first && second && third, 'the roots exists'); + + equalsElement(first.element, 'div', {}, '

foo

'); + equalsElement(second.element, 'div', {}, '

bar

'); + equalsElement(third?.element, 'div', {}, '

baz

'); this.assertHTML(''); this.assertStableRerender(); - roots[0].value = 'qux!'; + first.value = 'qux!'; this.rerender(); - equalsElement(roots[0].element, 'div', {}, '

qux!

'); - equalsElement(roots[1].element, 'div', {}, '

bar

'); - equalsElement(roots[2].element, 'div', {}, '

baz

'); + equalsElement(first.element, 'div', {}, '

qux!

'); + equalsElement(second.element, 'div', {}, '

bar

'); + equalsElement(third.element, 'div', {}, '

baz

'); this.assertHTML(''); this.assertStableRerender(); - roots[1].value = 'derp'; + second.value = 'derp'; this.rerender(); - equalsElement(roots[0].element, 'div', {}, '

qux!

'); - equalsElement(roots[1].element, 'div', {}, '

derp

'); - equalsElement(roots[2].element, 'div', {}, '

baz

'); + equalsElement(first.element, 'div', {}, '

qux!

'); + equalsElement(second.element, 'div', {}, '

derp

'); + equalsElement(third.element, 'div', {}, '

baz

'); this.assertHTML(''); this.assertStableRerender(); - roots[0].value = 'foo'; - roots[1].value = 'bar'; + first.value = 'foo'; + second.value = 'bar'; this.rerender(); - equalsElement(roots[0].element, 'div', {}, '

foo

'); - equalsElement(roots[1].element, 'div', {}, '

bar

'); - equalsElement(roots[2].element, 'div', {}, '

baz

'); + equalsElement(first.element, 'div', {}, '

foo

'); + equalsElement(second.element, 'div', {}, '

bar

'); + equalsElement(third.element, 'div', {}, '

baz

'); this.assertHTML(''); this.assertStableRerender(); this.testType = 'TemplateOnly'; @@ -514,7 +518,7 @@ export class InElementSuite extends RenderTest { let destroyed = 0; class DestroyMeComponent extends GlimmerishComponent { - willDestroy() { + override willDestroy() { super.willDestroy(); destroyed++; } diff --git a/packages/@glimmer/integration-tests/lib/suites/initial-render.ts b/packages/@glimmer/integration-tests/lib/suites/initial-render.ts index d6798416c..8fff3b67e 100644 --- a/packages/@glimmer/integration-tests/lib/suites/initial-render.ts +++ b/packages/@glimmer/integration-tests/lib/suites/initial-render.ts @@ -1,9 +1,10 @@ import { Namespace, SimpleElement } from '@glimmer/interfaces'; -import { RenderTest } from '../render-test'; -import { test } from '../test-decorator'; import { castToBrowser, checkNode, strip, unwrap } from '@glimmer/util'; -import { firstElementChild, getElementsByTagName } from '../dom/simple-utils'; + import { assertNodeTagName } from '../dom/assertions'; +import { firstElementChild, getElementsByTagName } from '../dom/simple-utils'; +import { RenderTest } from '../render-test'; +import { test } from '../test-decorator'; export class InitialRenderSuite extends RenderTest { static suiteName = 'initial render'; @@ -491,14 +492,16 @@ export class InitialRenderSuite extends RenderTest { } let options = getElementsByTagName(selectNode, 'option'); let selected: SimpleElement[] = []; - for (let i = 0; i < options.length; i++) { - let option = options[i]; + + for (const option of options) { // TODO: This is a real discrepancy with SimpleDOM if ((option as any).selected) { selected.push(option); } } + let [first, second] = this.guardArray({ selected }, { min: 2 }); + this.assertHTML(strip` `; + static override suiteName = `[emberjs/ember.js#15675] Template `; attrs = 'type="range" value={{this.value}} min={{this.min}} max={{this.max}}'; } @@ -72,17 +72,17 @@ jitSuite( // Ember Components attributeBindings class EmberInputRangeComponent extends EmberishCurlyComponent { - tagName = 'input'; + override tagName = 'input'; type = 'range'; } jitSuite( class EmberComponentRangeTests extends RangeTests { - static suiteName = `Components - [emberjs/ember.js#15675] - type value min max`; + static override suiteName = `Components - [emberjs/ember.js#15675] - type value min max`; component(): EmberishCurlyComponentFactory { return class extends EmberInputRangeComponent { - attributeBindings = ['type', 'value', 'min', 'max']; + override attributeBindings = ['type', 'value', 'min', 'max']; } as any; } @@ -104,7 +104,7 @@ jitSuite( jitSuite( class BasicComponentImplicitAttributesRangeTest extends RangeTests { - static suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes `; + static override suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes `; attrs = 'type="range" value="%x" min="-5" max="50"'; renderRange(value: number): void { @@ -121,7 +121,7 @@ jitSuite( jitSuite( class BasicComponentSplattributesLastRangeTest extends RangeTests { - static suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes last `; + static override suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes last `; attrs = 'type="range" value="%x" min="-5" max="50"'; renderRange(value: number): void { @@ -138,7 +138,7 @@ jitSuite( jitSuite( class BasicComponentSplattributesFirstRangeTest extends RangeTests { - static suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes first `; + static override suiteName = `integration - GlimmerComponent - [emberjs/ember.js#15675] ...attributes first `; attrs = 'type="text" min="-5" max="50"'; renderRange(value: number): void { diff --git a/packages/@glimmer/integration-tests/test/invalid-html-test.ts b/packages/@glimmer/integration-tests/test/invalid-html-test.ts index 4fa32b105..c9349f053 100644 --- a/packages/@glimmer/integration-tests/test/invalid-html-test.ts +++ b/packages/@glimmer/integration-tests/test/invalid-html-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, test, jitSuite, preprocess, syntaxErrorFor } from '..'; +import { jitSuite, preprocess, RenderTest, syntaxErrorFor, test } from '..'; class CompileErrorTests extends RenderTest { static suiteName = 'compile errors'; diff --git a/packages/@glimmer/integration-tests/test/jit-suites-test.ts b/packages/@glimmer/integration-tests/test/jit-suites-test.ts index c7902f19e..0318ff493 100644 --- a/packages/@glimmer/integration-tests/test/jit-suites-test.ts +++ b/packages/@glimmer/integration-tests/test/jit-suites-test.ts @@ -1,18 +1,18 @@ import { - jitSuite, - GlimmerishComponents, - TemplateOnlyComponents, DebuggerSuite, EachSuite, EmberishComponentTests, + GlimmerishComponents, HasBlockParamsHelperSuite, HasBlockSuite, InElementSuite, + jitComponentSuite, + jitSuite, ScopeSuite, ShadowingSuite, + TemplateOnlyComponents, WithDynamicVarsSuite, YieldSuite, - jitComponentSuite, } from '..'; jitSuite(DebuggerSuite); diff --git a/packages/@glimmer/integration-tests/test/keywords/log-test.ts b/packages/@glimmer/integration-tests/test/keywords/log-test.ts index 565e4c3f6..a720610d9 100644 --- a/packages/@glimmer/integration-tests/test/keywords/log-test.ts +++ b/packages/@glimmer/integration-tests/test/keywords/log-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, test, jitSuite } from '../..'; +import { jitSuite, RenderTest, test } from '../..'; class LogTest extends RenderTest { static suiteName = '{{log}} keyword'; diff --git a/packages/@glimmer/integration-tests/test/lexical-scope-test.ts b/packages/@glimmer/integration-tests/test/lexical-scope-test.ts index 9119183fa..df50effef 100644 --- a/packages/@glimmer/integration-tests/test/lexical-scope-test.ts +++ b/packages/@glimmer/integration-tests/test/lexical-scope-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, test, jitSuite, defineComponent } from '..'; +import { defineComponent, jitSuite, RenderTest, test } from '..'; class LexicalScopeTest extends RenderTest { static suiteName = 'loose mode: lexical scope'; diff --git a/packages/@glimmer/integration-tests/test/managers/helper-manager-test.ts b/packages/@glimmer/integration-tests/test/managers/helper-manager-test.ts index 959a46531..752a20c11 100644 --- a/packages/@glimmer/integration-tests/test/managers/helper-manager-test.ts +++ b/packages/@glimmer/integration-tests/test/managers/helper-manager-test.ts @@ -1,16 +1,17 @@ +import { Arguments, Owner } from '@glimmer/interfaces'; import { helperCapabilities, setHelperManager, setModifierManager } from '@glimmer/manager'; + import { + defineComponent, + GlimmerishComponent, + jitSuite, RenderTest, test, - jitSuite, - GlimmerishComponent, - tracked, - defineComponent, - trackedObj, TestHelper, TestHelperManager, + tracked, + trackedObj, } from '../..'; -import { Arguments, Owner } from '@glimmer/interfaces'; class HelperManagerTest extends RenderTest { static suiteName = 'Helper Managers'; @@ -122,13 +123,13 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('hello'); - args.value = 'there'; + args['value'] = 'there'; this.rerender(); assert.strictEqual(count, 2, 'rendered twice'); this.assertHTML('there'); - args.unused = 'unused2'; + args['unused'] = 'unused2'; this.rerender(); assert.strictEqual(count, 3, 'rendered thrice'); @@ -142,7 +143,7 @@ class HelperManagerTest extends RenderTest { let obj = () => { count++; - return trackedState.value; + return trackedState['value']; }; this.renderComponent(defineComponent({ obj }, '{{obj}}')); @@ -150,7 +151,7 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('hello'); - trackedState.value = 'there'; + trackedState['value'] = 'there'; this.rerender(); this.assertHTML('there'); assert.strictEqual(count, 2, 'rendered twice'); @@ -170,7 +171,7 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('hello'); - args.unused = 'unused2'; + args['unused'] = 'unused2'; this.rerender(); assert.strictEqual(count, 1, 'rendered once'); @@ -183,7 +184,7 @@ class HelperManagerTest extends RenderTest { let obj = (_x: string, options: Record) => { count++; - return options.namedOpt; + return options['namedOpt']; }; let args = trackedObj({ value: 'hello', used: 'used' }); @@ -192,7 +193,7 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('used'); - args.used = 'there'; + args['used'] = 'there'; this.rerender(); assert.strictEqual(count, 2, 'rendered twice'); @@ -232,7 +233,7 @@ class HelperManagerTest extends RenderTest { this.assertHTML('result: default value'); assert.strictEqual(count, 1, 'rendered once'); - args.value = 'value'; + args['value'] = 'value'; this.rerender(); this.assertHTML('result: value'); @@ -245,7 +246,7 @@ class HelperManagerTest extends RenderTest { class Hello extends TestHelper { value() { count++; - return this.args.named.foo; + return this.args.named['foo']; } } @@ -261,7 +262,7 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('123'); - args.foo = 456; + args['foo'] = 456; this.rerender(); assert.strictEqual(count, 2, 'rendered twice'); @@ -290,7 +291,7 @@ class HelperManagerTest extends RenderTest { assert.strictEqual(count, 1, 'rendered once'); this.assertHTML('123'); - args.foo = 456; + args['foo'] = 456; this.rerender(); assert.strictEqual(count, 2, 'rendered twice'); @@ -337,7 +338,7 @@ class HelperManagerTest extends RenderTest { return 'hello'; } - willDestroy() { + override willDestroy() { assert.ok(true, 'destructor called'); } } @@ -416,7 +417,7 @@ class HelperManagerTest extends RenderTest { @test 'capabilities helper function must be used to generate capabilities'(assert: Assert) { class OverrideTestHelperManager extends TestHelperManager { - capabilities = { + override capabilities = { hasValue: true, hasDestroyable: true, hasScheduledEffect: false, diff --git a/packages/@glimmer/integration-tests/test/managers/modifier-manager-test.ts b/packages/@glimmer/integration-tests/test/managers/modifier-manager-test.ts index 73f529a3c..a64077098 100644 --- a/packages/@glimmer/integration-tests/test/managers/modifier-manager-test.ts +++ b/packages/@glimmer/integration-tests/test/managers/modifier-manager-test.ts @@ -1,9 +1,9 @@ import { Arguments, ModifierManager, Owner } from '@glimmer/interfaces'; -import { RenderTest, test, jitSuite, tracked, defineComponent, trackedObj } from '../..'; - -import { setModifierManager, modifierCapabilities } from '@glimmer/manager'; +import { modifierCapabilities, setModifierManager } from '@glimmer/manager'; import { getOwner, setOwner } from '@glimmer/owner'; +import { defineComponent, jitSuite, RenderTest, test, tracked, trackedObj } from '../..'; + abstract class CustomModifier { static create( this: This, @@ -35,9 +35,9 @@ abstract class ModifierManagerTest extends RenderTest { @test 'can register a custom element modifier and render it'() { let foo = this.defineModifier( class extends CustomModifier { - didInsertElement() {} - didUpdate() {} - willDestroyElement() {} + override didInsertElement() {} + override didUpdate() {} + override willDestroyElement() {} } ); @@ -51,15 +51,15 @@ abstract class ModifierManagerTest extends RenderTest { @test 'custom lifecycle hooks'(assert: Assert) { let foo = this.defineModifier( class extends CustomModifier { - didInsertElement() { + override didInsertElement() { assert.step('Called didInsertElement'); assert.strictEqual(this.args.positional[0], true, 'gets initial args'); } - didUpdate() { + override didUpdate() { assert.step('Called didUpdate'); assert.strictEqual(this.args.positional[0], 'true', 'gets updated args'); } - willDestroyElement() { + override willDestroyElement() { assert.step('Called willDestroyElement'); } } @@ -76,15 +76,15 @@ abstract class ModifierManagerTest extends RenderTest { this.assertHTML(`

hello world

`); assert.verifySteps(['Called didInsertElement']); - args.truthy = 'true'; + args['truthy'] = 'true'; this.rerender(); assert.verifySteps(['Called didUpdate']); - args.truthy = false; + args['truthy'] = false; this.rerender(); assert.verifySteps(['Called willDestroyElement']); - args.truthy = true; + args['truthy'] = true; this.rerender(); assert.verifySteps(['Called didInsertElement']); } @@ -92,7 +92,7 @@ abstract class ModifierManagerTest extends RenderTest { @test 'associates manager even through an inheritance structure'(assert: Assert) { let Foo = this.defineModifier( class extends CustomModifier { - didInsertElement() { + override didInsertElement() { assert.step('Foo didInsertElement'); assert.strictEqual(this.args.positional[0], true, 'gets initial args'); } @@ -100,7 +100,7 @@ abstract class ModifierManagerTest extends RenderTest { ); class Bar extends Foo { - didInsertElement() { + override didInsertElement() { super.didInsertElement(); assert.step('Bar didInsertElement'); assert.strictEqual(this.args.positional[0], true, 'gets initial args'); @@ -121,7 +121,7 @@ abstract class ModifierManagerTest extends RenderTest { class extends CustomModifier { savedElement?: Element; - didInsertElement() { + override didInsertElement() { // consume first positional argument (ensures updates run) // eslint-disable-next-line no-unused-expressions this.args.positional[0]; @@ -130,11 +130,11 @@ abstract class ModifierManagerTest extends RenderTest { this.savedElement = this.element; } - didUpdate() { + override didUpdate() { assert.strictEqual(this.element, this.savedElement); } - willDestroyElement() { + override willDestroyElement() { assert.strictEqual(this.element, this.savedElement); } } @@ -146,7 +146,7 @@ abstract class ModifierManagerTest extends RenderTest { this.renderComponent(Main, args); this.assertHTML(`

hello world

`); - args.truthy = 'true'; + args['truthy'] = 'true'; this.rerender(); } @@ -163,14 +163,14 @@ abstract class ModifierManagerTest extends RenderTest { let foo = this.defineModifier( class extends CustomModifier { - didInsertElement() { + override didInsertElement() { // track the count of the first item // eslint-disable-next-line no-unused-expressions trackedOne.count; insertCount++; } - didUpdate() { + override didUpdate() { // track the count of the second item // eslint-disable-next-line no-unused-expressions trackedTwo.count; @@ -222,9 +222,9 @@ abstract class ModifierManagerTest extends RenderTest { this.foo = 456; } - didInsertElement() {} - didUpdate() {} - willDestroyElement() {} + override didInsertElement() {} + override didUpdate() {} + override willDestroyElement() {} } let foo = this.defineModifier(Foo); @@ -320,7 +320,7 @@ class ModifierManagerTest322 extends ModifierManagerTest { let foo = this.defineModifier( class extends CustomModifier { - didInsertElement() { + override didInsertElement() { insertCount++; // consume the second positional @@ -328,7 +328,7 @@ class ModifierManagerTest322 extends ModifierManagerTest { this.args.positional[1]; } - didUpdate() { + override didUpdate() { updateCount++; // consume the second positional @@ -357,11 +357,11 @@ class ModifierManagerTest322 extends ModifierManagerTest { assert.strictEqual(insertCount, 1); assert.strictEqual(updateCount, 0); - args.positionOne = 'no first?'; + args['positionOne'] = 'no first?'; this.rerender(); assert.strictEqual(updateCount, 0); - args.positionTwo = 'YASSSSSSS!!!'; + args['positionTwo'] = 'YASSSSSSS!!!'; this.rerender(); assert.strictEqual(updateCount, 1); } @@ -372,15 +372,17 @@ class ModifierManagerTest322 extends ModifierManagerTest { let foo = this.defineModifier( class extends CustomModifier { - didInsertElement() { + override didInsertElement() { insertCount++; // consume the second positional // eslint-disable-next-line no-unused-expressions - this.args.named.qux; + // consume the second positional + // eslint-disable-next-line no-unused-expressions + this.args.named['qux']; } - didUpdate() { + override didUpdate() { updateCount++; } } @@ -403,11 +405,11 @@ class ModifierManagerTest322 extends ModifierManagerTest { assert.strictEqual(insertCount, 1); assert.strictEqual(updateCount, 0); - args.bar = 'other bar'; + args['bar'] = 'other bar'; this.rerender(); assert.strictEqual(updateCount, 0); - args.qux = 'quuuuxxxxxx'; + args['qux'] = 'quuuuxxxxxx'; this.rerender(); assert.strictEqual(updateCount, 1); } diff --git a/packages/@glimmer/integration-tests/test/modifiers-test.ts b/packages/@glimmer/integration-tests/test/modifiers-test.ts index 0b28c9842..495ba36da 100644 --- a/packages/@glimmer/integration-tests/test/modifiers-test.ts +++ b/packages/@glimmer/integration-tests/test/modifiers-test.ts @@ -1,21 +1,20 @@ -import { RenderTest, jitSuite, test, Count } from '..'; -import { Dict } from '@glimmer/interfaces'; -import { SimpleElement } from '@glimmer/interfaces'; -import { Option } from '@glimmer/interfaces'; +import { Dict, Option, SimpleElement } from '@glimmer/interfaces'; + +import { Count, jitSuite, RenderTest, test } from '..'; class BaseModifier { element?: SimpleElement; - didInsertElement(_params: unknown[], _hash: Dict) {} - willDestroyElement() {} - didUpdate(_params: unknown[], _hash: Dict) {} + didInsertElement(_params: unknown[], _hash: Dict): void {} + willDestroyElement(): void {} + didUpdate(_params: unknown[], _hash: Dict): void {} } abstract class AbstractInsertable extends BaseModifier { - abstract didInsertElement(_params: unknown[], _hash: Dict): void; + abstract override didInsertElement(_params: unknown[], _hash: Dict): void; } abstract class AbstractDestroyable extends BaseModifier { - abstract willDestroyElement(): void; + abstract override willDestroyElement(): void; } class ModifierTests extends RenderTest { @@ -147,7 +146,7 @@ class ModifierTests extends RenderTest { modifierNamedArgs = namedArgs; modifiedElement = this.element; } - didUpdate(params: unknown[], namedArgs: Dict) { + override didUpdate(params: unknown[], namedArgs: Dict) { modifierParams = params; modifierNamedArgs = namedArgs; modifiedElement = this.element; @@ -189,7 +188,7 @@ class ModifierTests extends RenderTest { modifierNamedArgs = namedArgs; modifiedElement = this.element; } - didUpdate(params: unknown[], namedArgs: Dict) { + override didUpdate(params: unknown[], namedArgs: Dict) { modifierParams = params; modifierNamedArgs = namedArgs; modifiedElement = this.element; @@ -230,7 +229,7 @@ class ModifierTests extends RenderTest { modifierNamedArgs = namedArgs; modifiedElement = this.element; } - didUpdate(params: unknown[], namedArgs: Dict) { + override didUpdate(params: unknown[], namedArgs: Dict) { modifierParams = params; modifierNamedArgs = namedArgs; modifiedElement = this.element; @@ -462,11 +461,11 @@ class ModifierTests extends RenderTest { @test 'with params'(assert: Assert, count: Count) { class Foo extends BaseModifier { - didInsertElement([bar]: string[]) { + override didInsertElement([bar]: string[]) { count.expect('didInsertElement'); assert.strictEqual(bar, 'bar'); } - didUpdate([foo]: string[]) { + override didUpdate([foo]: string[]) { count.expect('didUpdate'); assert.strictEqual(foo, 'foo'); } @@ -479,11 +478,11 @@ class ModifierTests extends RenderTest { @test 'with hash'(assert: Assert, count: Count) { class Foo extends BaseModifier { - didInsertElement(_params: unknown[], { bar }: Dict) { + override didInsertElement(_params: unknown[], { bar }: Dict) { count.expect('didInsertElement'); assert.strictEqual(bar, 'bar'); } - didUpdate(_params: unknown[], { bar }: Dict) { + override didUpdate(_params: unknown[], { bar }: Dict) { count.expect('didUpdate'); assert.strictEqual(bar, 'foo'); } @@ -496,12 +495,12 @@ class ModifierTests extends RenderTest { @test 'with hash and params'(assert: Assert, count: Count) { class Foo extends BaseModifier { - didInsertElement([baz]: string[], { bar }: Dict) { + override didInsertElement([baz]: string[], { bar }: Dict) { count.expect('didInsertElement'); assert.strictEqual(bar, 'bar'); assert.strictEqual(baz, 'baz'); } - didUpdate([foo]: string[], { bar }: Dict) { + override didUpdate([foo]: string[], { bar }: Dict) { count.expect('didUpdate'); assert.strictEqual(bar, 'foo'); assert.strictEqual(foo, 'foo'); diff --git a/packages/@glimmer/integration-tests/test/modifiers/dynamic-modifiers-test.ts b/packages/@glimmer/integration-tests/test/modifiers/dynamic-modifiers-test.ts index ea26892bd..96bdeddcc 100644 --- a/packages/@glimmer/integration-tests/test/modifiers/dynamic-modifiers-test.ts +++ b/packages/@glimmer/integration-tests/test/modifiers/dynamic-modifiers-test.ts @@ -1,12 +1,12 @@ import { - RenderTest, - test, - jitSuite, + defineComponent, + defineSimpleHelper, defineSimpleModifier, - syntaxErrorFor, GlimmerishComponent, - defineSimpleHelper, - defineComponent, + jitSuite, + RenderTest, + syntaxErrorFor, + test, } from '../..'; class DynamicModifiersResolutionModeTest extends RenderTest { @@ -42,9 +42,9 @@ class DynamicModifiersResolutionModeTest extends RenderTest { @test 'Can pass curried modifier as argument and invoke dynamically'() { - const foo = defineSimpleModifier( - (element: Element, [value]: string[]) => (element.innerHTML = value) - ); + const foo = defineSimpleModifier((element: Element, [value]: [string]): void => { + element.innerHTML = value; + }); this.registerComponent('TemplateOnly', 'Foo', '
'); this.render('', { foo }); diff --git a/packages/@glimmer/integration-tests/test/modifiers/on-test.ts b/packages/@glimmer/integration-tests/test/modifiers/on-test.ts index 656db5414..69e4c473d 100644 --- a/packages/@glimmer/integration-tests/test/modifiers/on-test.ts +++ b/packages/@glimmer/integration-tests/test/modifiers/on-test.ts @@ -1,6 +1,6 @@ -import { castToBrowser, expect, HAS_NATIVE_PROXY } from '@glimmer/util'; import { getInternalModifierManager } from '@glimmer/manager'; import { on } from '@glimmer/runtime'; +import { castToBrowser, expect, HAS_NATIVE_PROXY } from '@glimmer/util'; import { jitSuite, RenderTest, test } from '../..'; diff --git a/packages/@glimmer/integration-tests/test/node-suites-node-test.ts b/packages/@glimmer/integration-tests/test/node-suites-node-test.ts index 91d2a86ef..33ffde87f 100644 --- a/packages/@glimmer/integration-tests/test/node-suites-node-test.ts +++ b/packages/@glimmer/integration-tests/test/node-suites-node-test.ts @@ -1,14 +1,14 @@ import { + CompilationTests, + DOMHelperTests, + JitSerializationDelegate, nodeComponentSuite, + NodeJitRenderDelegate, nodeSuite, + SerializedDOMHelperTests, ServerSideComponentSuite, ServerSideSuite, suite, - DOMHelperTests, - NodeJitRenderDelegate, - SerializedDOMHelperTests, - JitSerializationDelegate, - CompilationTests, } from '..'; nodeSuite(ServerSideSuite); diff --git a/packages/@glimmer/integration-tests/test/owner-test.ts b/packages/@glimmer/integration-tests/test/owner-test.ts index b88ef440d..d8a25f603 100644 --- a/packages/@glimmer/integration-tests/test/owner-test.ts +++ b/packages/@glimmer/integration-tests/test/owner-test.ts @@ -5,22 +5,23 @@ import { WithCreateInstance, WithSubOwner, } from '@glimmer/interfaces'; +import { setInternalComponentManager } from '@glimmer/manager'; +import { NULL_REFERENCE, Reference } from '@glimmer/reference'; + import { - test, - suite, + createTemplate, + defineComponent, EmberishCurlyComponent, - RenderTest, + GlimmerishComponent, JitRenderDelegate, - createTemplate, + RenderTest, + suite, + test, TestJitRuntimeResolver, - GlimmerishComponent, - defineComponent, } from '..'; -import { NULL_REFERENCE, Reference } from '@glimmer/reference'; -import { setInternalComponentManager } from '@glimmer/manager'; class OwnerJitRuntimeResolver extends TestJitRuntimeResolver { - lookupComponent(name: string, owner: () => void): ResolvedComponentDefinition | null { + override lookupComponent(name: string, owner: () => void): ResolvedComponentDefinition | null { if (typeof owner === 'function') owner(); return super.lookupComponent(name, owner); @@ -28,7 +29,7 @@ class OwnerJitRuntimeResolver extends TestJitRuntimeResolver { } class OwnerJitRenderDelegate extends JitRenderDelegate { - protected resolver = new OwnerJitRuntimeResolver(this.registry); + protected override resolver = new OwnerJitRuntimeResolver(this.registry); } const CAPABILITIES = { @@ -88,7 +89,7 @@ setInternalComponentManager(new MountManager(), MountComponent); function defineMountComponent(owner: object, scope: Record, template: string) { return defineComponent(scope, template, { definition: class extends MountComponent { - static owner = owner; + static override owner = owner; }, }); } @@ -113,13 +114,13 @@ class OwnerTest extends RenderTest { @test 'owner can be used per-template in compile time resolver'(assert: Assert) { class FooBar extends EmberishCurlyComponent { - layout = createTemplate('')(() => { + override layout = createTemplate('')(() => { assert.step('foo-bar owner called'); }); } class FooBaz extends EmberishCurlyComponent { - layout = createTemplate('')(() => { + override layout = createTemplate('')(() => { assert.step('foo-baz owner called'); }); } @@ -143,7 +144,7 @@ class OwnerTest extends RenderTest { 'FooBaz', null, class FooBaz extends EmberishCurlyComponent { - layout = createTemplate('')(() => { + override layout = createTemplate('')(() => { assert.step('foo-baz owner called'); }); } @@ -155,7 +156,7 @@ class OwnerTest extends RenderTest { 'FooBar', null, class FooBar extends EmberishCurlyComponent { - layout = createTemplate('')(() => { + override layout = createTemplate('')(() => { assert.step('foo-bar owner called'); }); } diff --git a/packages/@glimmer/integration-tests/test/partial-rehydration-test.ts b/packages/@glimmer/integration-tests/test/partial-rehydration-test.ts index fff103338..1c9e37ed8 100644 --- a/packages/@glimmer/integration-tests/test/partial-rehydration-test.ts +++ b/packages/@glimmer/integration-tests/test/partial-rehydration-test.ts @@ -1,16 +1,17 @@ +import { castToSimple } from '@glimmer/util'; + import { - PartialRehydrationDelegate, - test, - RenderTest, - suite, + CLOSE, content, OPEN, - CLOSE, - replaceHTML, + PartialRehydrationDelegate, qunitFixture, + RenderTest, + replaceHTML, stripTight, + suite, + test, } from '..'; -import { castToSimple } from '@glimmer/util'; export class PartialRehydrationTest extends RenderTest { static suiteName = 'partial rehydration'; diff --git a/packages/@glimmer/integration-tests/test/precompile-test.ts b/packages/@glimmer/integration-tests/test/precompile-test.ts index 8dad38d55..abf75b412 100644 --- a/packages/@glimmer/integration-tests/test/precompile-test.ts +++ b/packages/@glimmer/integration-tests/test/precompile-test.ts @@ -1,11 +1,11 @@ import { precompile } from '@glimmer/compiler'; import { SerializedTemplateWithLazyBlock } from '@glimmer/interfaces'; -import { unwrapTemplate } from '@glimmer/util'; import { templateFactory, TemplateFactoryWithIdAndMeta, TemplateWithIdAndReferrer, } from '@glimmer/opcode-compiler'; +import { unwrapTemplate } from '@glimmer/util'; let serializedTemplate: SerializedTemplateWithLazyBlock; let serializedTemplateNoId: SerializedTemplateWithLazyBlock; diff --git a/packages/@glimmer/integration-tests/test/smoke-test.ts b/packages/@glimmer/integration-tests/test/smoke-test.ts index 726fff0bd..4badfef87 100644 --- a/packages/@glimmer/integration-tests/test/smoke-test.ts +++ b/packages/@glimmer/integration-tests/test/smoke-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, test, jitSuite } from '..'; +import { jitSuite, RenderTest, test } from '..'; class SmokeTests extends RenderTest { static suiteName = 'Smoke Tests'; diff --git a/packages/@glimmer/integration-tests/test/strict-mode-test.ts b/packages/@glimmer/integration-tests/test/strict-mode-test.ts index 576be6619..50bf9a62d 100644 --- a/packages/@glimmer/integration-tests/test/strict-mode-test.ts +++ b/packages/@glimmer/integration-tests/test/strict-mode-test.ts @@ -1,17 +1,17 @@ +import { array, concat, fn, get, hash, on } from '@glimmer/runtime'; import { castToBrowser } from '@glimmer/util'; -import { on, fn, hash, array, get, concat } from '@glimmer/runtime'; import { - RenderTest, - test, - jitSuite, - GlimmerishComponent, - trackedObj, defineComponent, defineSimpleHelper, defineSimpleModifier, + GlimmerishComponent, + jitSuite, + RenderTest, syntaxErrorFor, + test, TestHelper, + trackedObj, } from '..'; class GeneralStrictModeTest extends RenderTest { @@ -125,7 +125,7 @@ class GeneralStrictModeTest extends RenderTest { this.assertHTML('Hello, world!'); this.assertStableRerender(); - args.Bar = 'bar'; + args['Bar'] = 'bar'; this.assert.throws(() => { this.rerender(); @@ -164,7 +164,7 @@ class GeneralStrictModeTest extends RenderTest { this.assertHTML('Hello, world!'); this.assertStableRerender(); - args.Bar = 'bar'; + args['Bar'] = 'bar'; this.assert.throws(() => { this.rerender(); @@ -203,7 +203,7 @@ class GeneralStrictModeTest extends RenderTest { this.assertHTML('Hello, world!'); this.assertStableRerender(); - args.Bar = 'bar'; + args['Bar'] = 'bar'; this.assert.throws(() => { this.rerender(); @@ -708,7 +708,7 @@ class DynamicStrictModeTest extends RenderTest { return 'Hello, world!'; } - willDestroy() { + override willDestroy() { assert.step('willDestroy 1 called'); } } @@ -718,7 +718,7 @@ class DynamicStrictModeTest extends RenderTest { return 'Hello, earth!'; } - willDestroy() { + override willDestroy() { assert.step('willDestroy 2 called'); } } @@ -730,14 +730,14 @@ class DynamicStrictModeTest extends RenderTest { this.assertHTML('Hello, world!'); this.assertStableRerender(); - args.helper = Helper2; + args['helper'] = Helper2; this.rerender(); this.assertHTML('Hello, earth!'); this.assertStableRerender(); assert.verifySteps(['willDestroy 1 called']); - args.helper = undefined; + args['helper'] = undefined; this.rerender(); this.assertHTML(''); @@ -752,7 +752,7 @@ class DynamicStrictModeTest extends RenderTest { return `Hello, ${this.args.positional[0]}!`; } - willDestroy() { + override willDestroy() { assert.step('willDestroy 1 called'); } } @@ -762,7 +762,7 @@ class DynamicStrictModeTest extends RenderTest { return `Goodbye, ${this.args.positional[0]}!`; } - willDestroy() { + override willDestroy() { assert.step('willDestroy 2 called'); } } @@ -775,14 +775,14 @@ class DynamicStrictModeTest extends RenderTest { this.assertHTML('Hello, world!'); this.assertStableRerender(); - args.helper = Helper2; + args['helper'] = Helper2; this.rerender(); this.assertHTML('Goodbye, world!'); this.assertStableRerender(); assert.verifySteps(['willDestroy 1 called']); - args.helper = undefined; + args['helper'] = undefined; this.rerender(); this.assertHTML(''); @@ -818,7 +818,7 @@ class DynamicStrictModeTest extends RenderTest { @test 'Can pass modifier as argument and invoke dynamically (with args)'() { const foo = defineSimpleModifier( - (element: Element, [value]: string[]) => (element.innerHTML = value) + (element: Element, [value]: [string]) => (element.innerHTML = value) ); const Foo = defineComponent({}, '
'); const Bar = defineComponent({ foo, Foo }, ''); @@ -845,7 +845,7 @@ class DynamicStrictModeTest extends RenderTest { @test 'Can pass curried modifier as argument and invoke dynamically'() { const foo = defineSimpleModifier( - (element: Element, [value]: string[]) => (element.innerHTML = value) + (element: Element, [value]: [string]) => (element.innerHTML = value) ); const Foo = defineComponent({}, '
'); const Bar = defineComponent({ foo, Foo }, ''); @@ -966,14 +966,14 @@ class DynamicStrictModeTest extends RenderTest { this.assertHTML('
Hello, world!
'); this.assertStableRerender(); - args.modifier = modifier2; + args['modifier'] = modifier2; this.rerender(); this.assertHTML('
Hello, earth!
'); this.assertStableRerender(); assert.verifySteps(['willDestroy 1 called']); - args.modifier = undefined; + args['modifier'] = undefined; this.rerender(); this.assertHTML('
Hello, earth!
'); @@ -1007,14 +1007,14 @@ class DynamicStrictModeTest extends RenderTest { this.assertHTML('
Hello, world!
'); this.assertStableRerender(); - args.modifier = modifier2; + args['modifier'] = modifier2; this.rerender(); this.assertHTML('
Goodbye, world!
'); this.assertStableRerender(); assert.verifySteps(['willDestroy 1 called']); - args.modifier = undefined; + args['modifier'] = undefined; this.rerender(); this.assertHTML('
Goodbye, world!
'); @@ -1047,12 +1047,12 @@ class DynamicStrictModeTest extends RenderTest { this.assertHTML('
Hello, world!
'); this.assertStableRerender(); - args.inSpace = true; + args['inSpace'] = true; this.rerender(); this.assertHTML('
Hello, Nebula!
'); this.assertStableRerender(); - args.name = 'Luna'; + args['name'] = 'Luna'; this.rerender(); this.assertHTML('
Hello, Luna!
'); this.assertStableRerender(); diff --git a/packages/@glimmer/integration-tests/test/style-warnings-test.ts b/packages/@glimmer/integration-tests/test/style-warnings-test.ts index 8d976e679..000fcb7f4 100644 --- a/packages/@glimmer/integration-tests/test/style-warnings-test.ts +++ b/packages/@glimmer/integration-tests/test/style-warnings-test.ts @@ -1,6 +1,7 @@ -import { testOverrideGlobalContext, GlobalContext } from '@glimmer/global-context'; +import { GlobalContext, testOverrideGlobalContext } from '@glimmer/global-context'; + +import { jitSuite, RenderTest, test } from '..'; import { assert } from './support'; -import { RenderTest, test, jitSuite } from '..'; let warnings = 0; let originalContext: GlobalContext | null; diff --git a/packages/@glimmer/integration-tests/test/syntax/argument-less-helper-paren-less-invoke-test.ts b/packages/@glimmer/integration-tests/test/syntax/argument-less-helper-paren-less-invoke-test.ts index 874daece4..6945b1763 100644 --- a/packages/@glimmer/integration-tests/test/syntax/argument-less-helper-paren-less-invoke-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/argument-less-helper-paren-less-invoke-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, jitSuite, test, defineSimpleHelper } from '../..'; +import { defineSimpleHelper, jitSuite, RenderTest, test } from '../..'; class ArgumentLessHelperParenLessInvokeTest extends RenderTest { static suiteName = 'argument-less helper paren-less invoke'; diff --git a/packages/@glimmer/integration-tests/test/syntax/general-errors-test.ts b/packages/@glimmer/integration-tests/test/syntax/general-errors-test.ts index 779917d92..c96967583 100644 --- a/packages/@glimmer/integration-tests/test/syntax/general-errors-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/general-errors-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, jitSuite, test, preprocess, syntaxErrorFor } from '../..'; +import { jitSuite, preprocess, RenderTest, syntaxErrorFor, test } from '../..'; class SyntaxErrors extends RenderTest { static suiteName = 'general syntax errors'; diff --git a/packages/@glimmer/integration-tests/test/syntax/if-unless-test.ts b/packages/@glimmer/integration-tests/test/syntax/if-unless-test.ts index f8ce10fd9..481fd2af1 100644 --- a/packages/@glimmer/integration-tests/test/syntax/if-unless-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/if-unless-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, jitSuite, test, preprocess, syntaxErrorFor } from '../..'; +import { jitSuite, preprocess, RenderTest, syntaxErrorFor, test } from '../..'; let types = ['if', 'unless']; diff --git a/packages/@glimmer/integration-tests/test/syntax/keyword-errors-test.ts b/packages/@glimmer/integration-tests/test/syntax/keyword-errors-test.ts index 28998c57e..fb2d2c22f 100644 --- a/packages/@glimmer/integration-tests/test/syntax/keyword-errors-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/keyword-errors-test.ts @@ -1,15 +1,15 @@ -import { RenderTest, jitSuite, test, preprocess } from '../..'; -import { KEYWORDS_TYPES } from '@glimmer/syntax'; +import { KEYWORDS_TYPES, KeywordType } from '@glimmer/syntax'; -const KEYWORDS = Object.keys(KEYWORDS_TYPES); +import { jitSuite, preprocess, RenderTest, test } from '../..'; -const BLOCK_KEYWORDS = KEYWORDS.filter((key) => KEYWORDS_TYPES[key].indexOf('Block') !== -1); +type KeywordName = keyof typeof KEYWORDS_TYPES; +const TYPES: Record = KEYWORDS_TYPES; +const KEYWORDS = Object.keys(KEYWORDS_TYPES) as KeywordName[]; -const APPEND_KEYWORDS = KEYWORDS.filter((key) => KEYWORDS_TYPES[key].indexOf('Append') !== -1); - -const CALL_KEYWORDS = KEYWORDS.filter((key) => KEYWORDS_TYPES[key].indexOf('Call') !== -1); - -const MODIFIER_KEYWORDS = KEYWORDS.filter((key) => KEYWORDS_TYPES[key].indexOf('Modifier') !== -1); +const BLOCK_KEYWORDS = KEYWORDS.filter((key) => TYPES[key].includes('Block')); +const APPEND_KEYWORDS = KEYWORDS.filter((key) => TYPES[key].includes('Append')); +const CALL_KEYWORDS = KEYWORDS.filter((key) => TYPES[key].includes('Call')); +const MODIFIER_KEYWORDS = KEYWORDS.filter((key) => TYPES[key].includes('Modifier')); for (let keyword of KEYWORDS) { class KeywordSyntaxErrors extends RenderTest { diff --git a/packages/@glimmer/integration-tests/test/syntax/named-blocks-test.ts b/packages/@glimmer/integration-tests/test/syntax/named-blocks-test.ts index 702306e79..c66c7427d 100644 --- a/packages/@glimmer/integration-tests/test/syntax/named-blocks-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/named-blocks-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, jitSuite, test, preprocess, syntaxErrorFor } from '../..'; +import { jitSuite, preprocess, RenderTest, syntaxErrorFor, test } from '../..'; class NamedBlocksSyntaxErrors extends RenderTest { static suiteName = 'named blocks syntax errors'; diff --git a/packages/@glimmer/integration-tests/test/syntax/yield-keywords-test.ts b/packages/@glimmer/integration-tests/test/syntax/yield-keywords-test.ts index 5e9094b06..d5c81c635 100644 --- a/packages/@glimmer/integration-tests/test/syntax/yield-keywords-test.ts +++ b/packages/@glimmer/integration-tests/test/syntax/yield-keywords-test.ts @@ -1,4 +1,4 @@ -import { RenderTest, jitSuite, test, preprocess, syntaxErrorFor } from '../..'; +import { jitSuite, preprocess, RenderTest, syntaxErrorFor, test } from '../..'; class NamedBlocksSyntaxErrors extends RenderTest { static suiteName = 'yield keywords syntax errors'; diff --git a/packages/@glimmer/integration-tests/test/updating-content-matrix-test.ts b/packages/@glimmer/integration-tests/test/updating-content-matrix-test.ts index 9a998a7fc..7da8e1303 100644 --- a/packages/@glimmer/integration-tests/test/updating-content-matrix-test.ts +++ b/packages/@glimmer/integration-tests/test/updating-content-matrix-test.ts @@ -1,6 +1,7 @@ +import { Namespace, SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { SafeString } from '@glimmer/runtime'; -import { RenderTest, jitSuite, RenderTestConstructor } from '..'; -import { SimpleElement, SimpleNode, Namespace } from '@glimmer/interfaces'; + +import { jitSuite, RenderTest, RenderTestConstructor } from '..'; import RenderDelegate from '../lib/render-delegate'; const SVG_NAMESPACE = Namespace.SVG; diff --git a/packages/@glimmer/integration-tests/test/updating-modifiers-test.ts b/packages/@glimmer/integration-tests/test/updating-modifiers-test.ts index 603931892..120b38d9d 100644 --- a/packages/@glimmer/integration-tests/test/updating-modifiers-test.ts +++ b/packages/@glimmer/integration-tests/test/updating-modifiers-test.ts @@ -1,5 +1,6 @@ -import { RenderTest, test, jitSuite } from '..'; import { SimpleElement } from '@glimmer/interfaces'; + +import { jitSuite, RenderTest, test } from '..'; import { assert } from './support'; function makeSyncDataAttrModifier(hooks: string[]) { diff --git a/packages/@glimmer/integration-tests/test/updating-svg-test.ts b/packages/@glimmer/integration-tests/test/updating-svg-test.ts index f6b304bfd..e7bd65d5c 100644 --- a/packages/@glimmer/integration-tests/test/updating-svg-test.ts +++ b/packages/@glimmer/integration-tests/test/updating-svg-test.ts @@ -1,6 +1,6 @@ -import { RenderTest, test, jitSuite } from '..'; -import { assertNodeTagName } from '..'; import { Namespace, SimpleElement } from '@glimmer/interfaces'; + +import { assertNodeTagName, jitSuite, RenderTest, test } from '..'; import { assert } from './support'; const SVG_NAMESPACE = Namespace.SVG; @@ -112,7 +112,10 @@ class UpdatingSvgTest extends RenderTest { let assertNamespaces = () => { if (assertNodeTagName(this.element.firstChild, 'svg')) { assert.strictEqual(this.element.firstChild.namespaceURI, SVG_NAMESPACE); - let attr = this.element.firstChild.attributes[0]; + let [attr] = this.guardArray( + { attributes: this.element.firstChild.attributes }, + { min: 1 } + ); assert.strictEqual(attr.namespaceURI, XLINK_NAMESPACE); } }; @@ -191,10 +194,10 @@ class UpdatingSvgTest extends RenderTest { content: '', }); - let assertNamespaces = (callback: (svg: SimpleElement) => void) => { + let assertNamespaces = (withElement: (svg: SimpleElement) => void) => { if (assertNodeTagName(this.element.firstChild, 'svg')) { assert.strictEqual(this.element.firstChild.namespaceURI, SVG_NAMESPACE); - callback(this.element.firstChild as SimpleElement); + withElement(this.element.firstChild as SimpleElement); } if (assertNodeTagName(this.element.lastChild, 'div')) { assert.strictEqual(this.element.lastChild.namespaceURI, XHTML_NAMESPACE); @@ -313,10 +316,10 @@ class UpdatingSvgTest extends RenderTest { 'expression nested inside a namespaced context.root element'() { this.render('{{this.content}}', { content: 'Maurice' }); - let assertSvg = (callback?: (svg: SVGSVGElement) => void) => { + let assertSvg = (withSVG?: (svg: SVGSVGElement) => void) => { if (assertNodeTagName(this.element.firstChild, 'svg')) { assert.strictEqual(this.element.firstChild.namespaceURI, SVG_NAMESPACE); - if (callback) callback(this.element.firstChild); + if (withSVG) withSVG(this.element.firstChild); } }; diff --git a/packages/@glimmer/integration-tests/test/updating-test.ts b/packages/@glimmer/integration-tests/test/updating-test.ts index 43f81820b..2bf87db2a 100644 --- a/packages/@glimmer/integration-tests/test/updating-test.ts +++ b/packages/@glimmer/integration-tests/test/updating-test.ts @@ -1,19 +1,24 @@ -import { Option } from '@glimmer/interfaces'; -import { createConstRef, createPrimitiveRef, createComputeRef } from '@glimmer/reference'; -import { RenderTest, test, jitSuite, JitRenderDelegate, GlimmerishComponent, tracked } from '..'; import { associateDestroyableChild, registerDestructor } from '@glimmer/destroyable'; +import { Option, SimpleElement, SimpleNode } from '@glimmer/interfaces'; +import { createComputeRef, createConstRef, createPrimitiveRef } from '@glimmer/reference'; import { SafeString } from '@glimmer/runtime'; +import { expect } from '@glimmer/util'; +import { consumeTag, createTag, dirtyTag } from '@glimmer/validator'; + import { assertNodeTagName, getElementByClassName, getElementsByTagName, + GlimmerishComponent, + JitRenderDelegate, + jitSuite, + RenderTest, stripTight, + test, + tracked, trimLines, } from '..'; -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { assert } from './support'; -import { expect } from '@glimmer/util'; -import { createTag, consumeTag, dirtyTag } from '@glimmer/validator'; function makeSafeString(value: string): SafeString { return new SafeStringImpl(value); @@ -2019,7 +2024,7 @@ class UpdatingTest extends RenderTest { 'DestroyableComponent', '{{@item}}', class extends GlimmerishComponent { - willDestroy() { + override willDestroy() { destroyCount++; } } @@ -2057,7 +2062,7 @@ class UpdatingTest extends RenderTest { 'DestroyableComponent', '{{@item}}', class extends GlimmerishComponent { - willDestroy() { + override willDestroy() { destroyCount++; } } diff --git a/packages/@glimmer/interfaces/index.d.ts b/packages/@glimmer/interfaces/index.d.ts index 3521d32e2..aa17c3e75 100644 --- a/packages/@glimmer/interfaces/index.d.ts +++ b/packages/@glimmer/interfaces/index.d.ts @@ -1,25 +1,27 @@ -export * from './lib/core'; +import * as WireFormat from './lib/compile/wire-format'; + +export * from './lib/array'; export * from './lib/compile'; export * from './lib/components'; -export * from './lib/curry'; -export * from './lib/managers'; export * from './lib/content'; -export * from './lib/array'; +export * from './lib/core'; +export * from './lib/curry'; +export * from './lib/dom/attributes'; export * from './lib/dom/bounds'; export * from './lib/dom/changes'; -export * from './lib/dom/attributes'; export * from './lib/dom/simple'; export * from './lib/dom/tree-construction'; +export * from './lib/managers'; export * from './lib/program'; +export * from './lib/references'; export * from './lib/runtime'; +export * from './lib/runtime/vm'; export * from './lib/serialize'; +export * from './lib/stack'; +export * from './lib/tags'; export * from './lib/template'; export * from './lib/tier1/symbol-table'; +export * from './lib/type-utils'; export * from './lib/vm-opcodes'; -export * from './lib/runtime/vm'; -export * from './lib/stack'; -export * from './lib/references'; -export * from './lib/tags'; -import * as WireFormat from './lib/compile/wire-format'; export { WireFormat }; diff --git a/packages/@glimmer/interfaces/lib/compile/encoder.d.ts b/packages/@glimmer/interfaces/lib/compile/encoder.d.ts index 71c2fa50f..ff3f00966 100644 --- a/packages/@glimmer/interfaces/lib/compile/encoder.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/encoder.d.ts @@ -1,11 +1,10 @@ -import { CompileTimeConstants, CompileTimeHeap } from '../program'; -import { Dict, Option } from '../core'; +import { CompileTimeComponent } from '../..'; +import { Option } from '../core'; +import { CompileTimeConstants } from '../program'; +import { HandleResult, NamedBlocks } from '../template'; +import { MachineOp, Op } from '../vm-opcodes'; import { SingleBuilderOperand } from './operands'; -import { NamedBlocks, HandleResult } from '../template'; -import { Op, MachineOp } from '../vm-opcodes'; import * as WireFormat from './wire-format'; -import { InternalComponentCapabilities } from '../managers/internal/component'; -import { CompileTimeComponent } from '../..'; // These values are used in the same space as standard opcodes, so we need to // start them at a higher value to prevent collisions diff --git a/packages/@glimmer/interfaces/lib/compile/index.d.ts b/packages/@glimmer/interfaces/lib/compile/index.d.ts index 22f95df78..5b8833fad 100644 --- a/packages/@glimmer/interfaces/lib/compile/index.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/index.d.ts @@ -1,4 +1,4 @@ export * from './encoder'; +export * from './instruction-encoder'; export * from './operands'; export * from './wire-format'; -export * from './instruction-encoder'; diff --git a/packages/@glimmer/interfaces/lib/compile/instruction-encoder.d.ts b/packages/@glimmer/interfaces/lib/compile/instruction-encoder.d.ts index 5aa25e0b6..de4cea4fa 100644 --- a/packages/@glimmer/interfaces/lib/compile/instruction-encoder.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/instruction-encoder.d.ts @@ -1,6 +1,6 @@ +import { CompilerBuffer } from '../template'; import { MachineOp, Op } from '../vm-opcodes'; import { Operand } from './operands'; -import { CompilerBuffer } from '../template'; export const enum OpcodeSize { ARG_SHIFT = 8, diff --git a/packages/@glimmer/interfaces/lib/compile/operands.d.ts b/packages/@glimmer/interfaces/lib/compile/operands.d.ts index de22857aa..6e4d9c5cc 100644 --- a/packages/@glimmer/interfaces/lib/compile/operands.d.ts +++ b/packages/@glimmer/interfaces/lib/compile/operands.d.ts @@ -1,6 +1,6 @@ -import * as WireFormat from './wire-format'; -import { SymbolTable } from '../tier1/symbol-table'; import { CompilableTemplate } from '../template'; +import { SymbolTable } from '../tier1/symbol-table'; +import * as WireFormat from './wire-format'; export const enum HighLevelOperand { Label = 1, diff --git a/packages/@glimmer/interfaces/lib/components.d.ts b/packages/@glimmer/interfaces/lib/components.d.ts index 89fbfc8de..5b3c40d6e 100644 --- a/packages/@glimmer/interfaces/lib/components.d.ts +++ b/packages/@glimmer/interfaces/lib/components.d.ts @@ -1,10 +1,10 @@ // eslint-disable-next-line n/no-extraneous-import -import { Reference } from './references'; -import { InternalComponentCapability, InternalComponentManager } from './managers'; import { Dict } from './core'; +import { InternalComponentCapability, InternalComponentManager } from './managers'; +import { Reference } from './references'; +import { ScopeSlot } from './runtime'; import { CompilableProgram } from './template'; import { ProgramSymbolTable } from './tier1/symbol-table'; -import { ScopeSlot } from './runtime'; export type ComponentDefinitionState = object; export type ComponentInstanceState = unknown; diff --git a/packages/@glimmer/interfaces/lib/core.d.ts b/packages/@glimmer/interfaces/lib/core.d.ts index 552126ef4..020d09794 100644 --- a/packages/@glimmer/interfaces/lib/core.d.ts +++ b/packages/@glimmer/interfaces/lib/core.d.ts @@ -1,7 +1,7 @@ -export type Present = {} | void; +export type Present = Exclude; export type Option = T | null; export type Maybe = Option | undefined | void; -export type FIXME = T; +export type FIXME = T; export type Dict = Record; diff --git a/packages/@glimmer/interfaces/lib/dom/attributes.d.ts b/packages/@glimmer/interfaces/lib/dom/attributes.d.ts index 3b9214839..63b40368b 100644 --- a/packages/@glimmer/interfaces/lib/dom/attributes.d.ts +++ b/packages/@glimmer/interfaces/lib/dom/attributes.d.ts @@ -1,17 +1,17 @@ import { + AttrNamespace, + SimpleComment, + SimpleDocumentFragment, SimpleElement, SimpleNode, SimpleText, - SimpleComment, - SimpleDocumentFragment, - AttrNamespace, } from '@simple-dom/interface'; -import { Option, Maybe } from '../core'; -import { Bounds, Cursor } from './bounds'; + +import { Maybe, Option } from '../core'; import { ElementOperations, Environment, ModifierInstance } from '../runtime'; -import { GlimmerTreeConstruction, GlimmerTreeChanges } from './changes'; import { Stack } from '../stack'; -import { InternalModifierManager } from '../managers'; +import { Bounds, Cursor } from './bounds'; +import { GlimmerTreeChanges, GlimmerTreeConstruction } from './changes'; export interface LiveBlock extends Bounds { openElement(element: SimpleElement): void; diff --git a/packages/@glimmer/interfaces/lib/dom/bounds.d.ts b/packages/@glimmer/interfaces/lib/dom/bounds.d.ts index d590c3700..b874718a0 100644 --- a/packages/@glimmer/interfaces/lib/dom/bounds.d.ts +++ b/packages/@glimmer/interfaces/lib/dom/bounds.d.ts @@ -1,4 +1,5 @@ import { SimpleElement, SimpleNode } from '@simple-dom/interface'; + import { Option } from '../core'; export interface Bounds { diff --git a/packages/@glimmer/interfaces/lib/dom/changes.d.ts b/packages/@glimmer/interfaces/lib/dom/changes.d.ts index c8a10045e..538345674 100644 --- a/packages/@glimmer/interfaces/lib/dom/changes.d.ts +++ b/packages/@glimmer/interfaces/lib/dom/changes.d.ts @@ -5,6 +5,7 @@ import { SimpleNode, SimpleText, } from '@simple-dom/interface'; + import { Option } from '../core'; import { Bounds } from './bounds'; diff --git a/packages/@glimmer/interfaces/lib/managers.d.ts b/packages/@glimmer/interfaces/lib/managers.d.ts index dd02f7376..813403eb5 100644 --- a/packages/@glimmer/interfaces/lib/managers.d.ts +++ b/packages/@glimmer/interfaces/lib/managers.d.ts @@ -1,5 +1,5 @@ export * from './managers/capabilities'; export * from './managers/component'; export * from './managers/helper'; -export * from './managers/modifier'; export * from './managers/internal'; +export * from './managers/modifier'; diff --git a/packages/@glimmer/interfaces/lib/managers/component.d.ts b/packages/@glimmer/interfaces/lib/managers/component.d.ts index 864cd040e..41c0f24b0 100644 --- a/packages/@glimmer/interfaces/lib/managers/component.d.ts +++ b/packages/@glimmer/interfaces/lib/managers/component.d.ts @@ -1,5 +1,5 @@ -import { Capabilities } from './capabilities'; import { Arguments } from '../runtime'; +import { Capabilities } from './capabilities'; export interface ComponentCapabilitiesVersions { '3.4': { diff --git a/packages/@glimmer/interfaces/lib/managers/internal/component.d.ts b/packages/@glimmer/interfaces/lib/managers/internal/component.d.ts index 5bd39e8a0..e61d63485 100644 --- a/packages/@glimmer/interfaces/lib/managers/internal/component.d.ts +++ b/packages/@glimmer/interfaces/lib/managers/internal/component.d.ts @@ -1,18 +1,19 @@ // eslint-disable-next-line n/no-extraneous-import import { SimpleElement } from '@simple-dom/interface'; -import { PreparedArguments, ComponentInstanceState } from '../../components'; -import { Option, Destroyable } from '../../core'; + +import { ComponentInstanceState, PreparedArguments } from '../../components'; +import { Destroyable, Option } from '../../core'; import { Bounds } from '../../dom/bounds'; +import { Reference } from '../../references'; +import { Owner } from '../../runtime'; import { CapturedArguments, VMArguments } from '../../runtime/arguments'; +import { RenderNode } from '../../runtime/debug-render-tree'; import { ElementOperations } from '../../runtime/element'; import { Environment } from '../../runtime/environment'; +import { DynamicScope } from '../../runtime/scope'; import { RuntimeResolver } from '../../serialize'; import { CompilableProgram } from '../../template'; import { ProgramSymbolTable } from '../../tier1/symbol-table'; -import { DynamicScope } from '../../runtime/scope'; -import { RenderNode } from '../../runtime/debug-render-tree'; -import { Owner } from '../../runtime'; -import { Reference } from '../../references'; /** * Describes the capabilities of a particular component. The capabilities are diff --git a/packages/@glimmer/interfaces/lib/managers/internal/modifier.d.ts b/packages/@glimmer/interfaces/lib/managers/internal/modifier.d.ts index 384b7d129..ac163e53f 100644 --- a/packages/@glimmer/interfaces/lib/managers/internal/modifier.d.ts +++ b/packages/@glimmer/interfaces/lib/managers/internal/modifier.d.ts @@ -1,8 +1,9 @@ import { SimpleElement } from '@simple-dom/interface'; -import { Owner } from '../../runtime'; + import { Destroyable } from '../../core'; -import { ModifierDefinitionState, ModifierInstanceState } from '../../runtime/modifier'; +import { Owner } from '../../runtime'; import { CapturedArguments } from '../../runtime/arguments'; +import { ModifierDefinitionState, ModifierInstanceState } from '../../runtime/modifier'; import { UpdatableTag } from '../../tags'; export interface InternalModifierManager< diff --git a/packages/@glimmer/interfaces/lib/program.d.ts b/packages/@glimmer/interfaces/lib/program.d.ts index b21e1cc39..a556545fd 100644 --- a/packages/@glimmer/interfaces/lib/program.d.ts +++ b/packages/@glimmer/interfaces/lib/program.d.ts @@ -1,10 +1,10 @@ -import { STDLib, ContainingMetadata, Template } from './template'; import { Encoder } from './compile'; -import { Op } from './vm-opcodes'; -import { CompileTimeResolver, ResolvedComponentDefinition } from './serialize'; -import { ComponentDefinitionState, ComponentDefinition } from './components'; -import { HelperDefinitionState, Owner } from './runtime'; +import { ComponentDefinition, ComponentDefinitionState } from './components'; +import { HelperDefinitionState } from './runtime'; import { ModifierDefinitionState } from './runtime/modifier'; +import { CompileTimeResolver, ResolvedComponentDefinition } from './serialize'; +import { ContainingMetadata, STDLib, Template } from './template'; +import { Op } from './vm-opcodes'; export type CreateRuntimeOp = (heap: CompileTimeHeap) => RuntimeOp; diff --git a/packages/@glimmer/interfaces/lib/runtime/arguments.d.ts b/packages/@glimmer/interfaces/lib/runtime/arguments.d.ts index aae2efbfc..1aea3f276 100644 --- a/packages/@glimmer/interfaces/lib/runtime/arguments.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/arguments.d.ts @@ -52,8 +52,7 @@ export interface CapturedBlockArguments { get(name: string): Option; } -export interface CapturedNamedArguments { - [key: string]: Reference; +export interface CapturedNamedArguments extends Record { [CAPTURED_ARGS]: true; } diff --git a/packages/@glimmer/interfaces/lib/runtime/debug-render-tree.d.ts b/packages/@glimmer/interfaces/lib/runtime/debug-render-tree.d.ts index 4e00b515b..4791eb985 100644 --- a/packages/@glimmer/interfaces/lib/runtime/debug-render-tree.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/debug-render-tree.d.ts @@ -1,4 +1,5 @@ import { SimpleElement, SimpleNode } from '@simple-dom/interface'; + import { Bounds } from '../dom/bounds'; import { Arguments, CapturedArguments } from './arguments'; diff --git a/packages/@glimmer/interfaces/lib/runtime/environment.d.ts b/packages/@glimmer/interfaces/lib/runtime/environment.d.ts index d601414c2..0ab74c0ac 100644 --- a/packages/@glimmer/interfaces/lib/runtime/environment.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/environment.d.ts @@ -1,11 +1,11 @@ import { SimpleDocument } from '@simple-dom/interface'; + +import { WithCreateInstance } from '../..'; import { ComponentDefinitionState, ComponentInstance, ComponentInstanceState } from '../components'; import { Option } from '../core'; import { GlimmerTreeChanges, GlimmerTreeConstruction } from '../dom/changes'; import { DebugRenderTree } from './debug-render-tree'; -import { Owner } from './owner'; import { ModifierInstance } from './modifier'; -import { WithCreateInstance } from '../..'; export interface EnvironmentOptions { document?: SimpleDocument; diff --git a/packages/@glimmer/interfaces/lib/runtime/render.d.ts b/packages/@glimmer/interfaces/lib/runtime/render.d.ts index edf94c1a9..d9c0fb033 100644 --- a/packages/@glimmer/interfaces/lib/runtime/render.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/render.d.ts @@ -1,4 +1,5 @@ import { SimpleElement, SimpleNode } from '@simple-dom/interface'; + import { RichIteratorResult } from '../core'; import { Bounds } from '../dom/bounds'; import { Environment } from './environment'; diff --git a/packages/@glimmer/interfaces/lib/runtime/runtime.d.ts b/packages/@glimmer/interfaces/lib/runtime/runtime.d.ts index 5a61218a3..59d54744c 100644 --- a/packages/@glimmer/interfaces/lib/runtime/runtime.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/runtime.d.ts @@ -1,7 +1,6 @@ -import { Environment } from './environment'; -import { RuntimeHeap, RuntimeConstants, RuntimeOp, ResolutionTimeConstants } from '../program'; +import { ResolutionTimeConstants, RuntimeConstants, RuntimeHeap, RuntimeOp } from '../program'; import { RuntimeResolver } from '../serialize'; -import { Owner } from './owner'; +import { Environment } from './environment'; /** The Runtime is the set of static structures that contain the compiled diff --git a/packages/@glimmer/interfaces/lib/runtime/scope.d.ts b/packages/@glimmer/interfaces/lib/runtime/scope.d.ts index 225ce6d9d..b38da55bb 100644 --- a/packages/@glimmer/interfaces/lib/runtime/scope.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/scope.d.ts @@ -1,9 +1,9 @@ -import { CompilableBlock } from '../template'; // eslint-disable-next-line n/no-extraneous-import -import { Option, Dict } from '../core'; +import { Dict, Option } from '../core'; +import { Reference } from '../references'; +import { CompilableBlock } from '../template'; import { BlockSymbolTable } from '../tier1/symbol-table'; import { Owner } from './owner'; -import { Reference } from '../references'; export type Block = CompilableBlock | number; diff --git a/packages/@glimmer/interfaces/lib/runtime/vm.d.ts b/packages/@glimmer/interfaces/lib/runtime/vm.d.ts index 1d63ab658..4ac7bd933 100644 --- a/packages/@glimmer/interfaces/lib/runtime/vm.d.ts +++ b/packages/@glimmer/interfaces/lib/runtime/vm.d.ts @@ -1,10 +1,10 @@ -import { Environment } from './environment'; import { Destroyable } from '../core'; -import { DynamicScope } from './scope'; -import { Owner } from './owner'; import { GlimmerTreeChanges } from '../dom/changes'; -import { ExceptionHandler } from './render'; import { Reference } from '../references'; +import { Environment } from './environment'; +import { Owner } from './owner'; +import { ExceptionHandler } from './render'; +import { DynamicScope } from './scope'; /** * This is used in the Glimmer Embedding API. In particular, embeddings * provide helpers through the `CompileTimeLookup` interface, and the diff --git a/packages/@glimmer/interfaces/lib/serialize.d.ts b/packages/@glimmer/interfaces/lib/serialize.d.ts index 634f3761a..c4fdb30e3 100644 --- a/packages/@glimmer/interfaces/lib/serialize.d.ts +++ b/packages/@glimmer/interfaces/lib/serialize.d.ts @@ -49,13 +49,11 @@ * the `RuntimeResolver` to do dynamic resolution when necessary. */ -import { Option } from './core'; -import { ProgramSymbolTable } from './tier1/symbol-table'; import { ComponentDefinitionState, ComponentInstanceState } from './components'; -import { CompilableProgram, Template, HandleResult } from './template'; -import { CompileTimeCompilationContext } from './program'; -import { Owner, ModifierDefinitionState, HelperDefinitionState } from './runtime'; +import { Option } from './core'; import { InternalComponentCapability, InternalComponentManager } from './managers'; +import { HelperDefinitionState, ModifierDefinitionState, Owner } from './runtime'; +import { CompilableProgram, Template } from './template'; export interface CompileTimeComponent { handle: number; diff --git a/packages/@glimmer/interfaces/lib/template.d.ts b/packages/@glimmer/interfaces/lib/template.d.ts index 7e7ccb82d..cf8bd3dc5 100644 --- a/packages/@glimmer/interfaces/lib/template.d.ts +++ b/packages/@glimmer/interfaces/lib/template.d.ts @@ -1,13 +1,8 @@ -import { Operand, SerializedTemplateBlock, SerializedInlineBlock, BlockOperand } from './compile'; +import { Operand, SerializedInlineBlock, SerializedTemplateBlock } from './compile'; import { EncoderError } from './compile/encoder'; import { Option } from './core'; import { InternalComponentCapabilities } from './managers/internal/component'; -import { - ConstantPool, - SerializedHeap, - CompileTimeCompilationContext, - CreateRuntimeOp, -} from './program'; +import { CompileTimeCompilationContext, ConstantPool, SerializedHeap } from './program'; import { Owner } from './runtime'; import { BlockSymbolTable, ProgramSymbolTable, SymbolTable } from './tier1/symbol-table'; @@ -84,7 +79,7 @@ export interface ResolvedLayout { export type OkHandle = number; export interface ErrHandle { handle: number; - errors: EncoderError[]; + errors: PresentArray; } export type HandleResult = OkHandle | ErrHandle; diff --git a/packages/@glimmer/interfaces/lib/type-utils.d.ts b/packages/@glimmer/interfaces/lib/type-utils.d.ts new file mode 100644 index 000000000..1f4c4f9fa --- /dev/null +++ b/packages/@glimmer/interfaces/lib/type-utils.d.ts @@ -0,0 +1 @@ +export type Expand = T extends infer O ? { [K in keyof O]: O[K] } : never; diff --git a/packages/@glimmer/manager/index.ts b/packages/@glimmer/manager/index.ts index a9fdf6129..76e393524 100644 --- a/packages/@glimmer/manager/index.ts +++ b/packages/@glimmer/manager/index.ts @@ -1,23 +1,23 @@ export { - setInternalHelperManager, - setInternalModifierManager, - setInternalComponentManager, + getInternalComponentManager, getInternalHelperManager, getInternalModifierManager, - getInternalComponentManager, + hasInternalComponentManager, hasInternalHelperManager, hasInternalModifierManager, - hasInternalComponentManager, + setInternalComponentManager, + setInternalHelperManager, + setInternalModifierManager, } from './lib/internal/index'; -export { setHelperManager, setModifierManager, setComponentManager } from './lib/public/index'; export { componentCapabilities, CustomComponentManager } from './lib/public/component'; -export { modifierCapabilities, CustomModifierManager } from './lib/public/modifier'; export { - helperCapabilities, + CustomHelperManager, hasDestroyable, hasValue, - CustomHelperManager, + helperCapabilities, } from './lib/public/helper'; +export { setComponentManager, setHelperManager, setModifierManager } from './lib/public/index'; +export { CustomModifierManager, modifierCapabilities } from './lib/public/modifier'; export { getComponentTemplate, setComponentTemplate } from './lib/public/template'; -export { capabilityFlagsFrom, hasCapability, managerHasCapability } from './lib/util/capabilities'; export { getCustomTagFor, setCustomTagFor } from './lib/util/args-proxy'; +export { capabilityFlagsFrom, hasCapability, managerHasCapability } from './lib/util/capabilities'; diff --git a/packages/@glimmer/manager/lib/internal/defaults.ts b/packages/@glimmer/manager/lib/internal/defaults.ts index f769195bf..445a4950c 100644 --- a/packages/@glimmer/manager/lib/internal/defaults.ts +++ b/packages/@glimmer/manager/lib/internal/defaults.ts @@ -1,11 +1,11 @@ -import { buildCapabilities } from '../util/capabilities'; - import type { CapturedArguments as Arguments, HelperCapabilities, HelperManagerWithValue, } from '@glimmer/interfaces'; +import { buildCapabilities } from '../util/capabilities'; + type FnArgs = | [...Args['positional'], Args['named']] | [...Args['positional']]; diff --git a/packages/@glimmer/manager/lib/internal/index.ts b/packages/@glimmer/manager/lib/internal/index.ts index aef6014a9..2a41ad827 100644 --- a/packages/@glimmer/manager/lib/internal/index.ts +++ b/packages/@glimmer/manager/lib/internal/index.ts @@ -1,11 +1,12 @@ import { DEBUG } from '@glimmer/env'; -import { debugToString, _WeakSet } from '@glimmer/util'; import { + Helper, InternalComponentManager, InternalModifierManager, - Helper, Owner, } from '@glimmer/interfaces'; +import { debugToString } from '@glimmer/util'; + import { CustomHelperManager } from '../public/helper'; import { FunctionHelperManager } from './defaults'; diff --git a/packages/@glimmer/manager/lib/public/component.ts b/packages/@glimmer/manager/lib/public/component.ts index a71b2054f..c45eb93d9 100644 --- a/packages/@glimmer/manager/lib/public/component.ts +++ b/packages/@glimmer/manager/lib/public/component.ts @@ -1,3 +1,4 @@ +import { registerDestructor } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { Arguments, @@ -17,9 +18,9 @@ import { VMArguments, } from '@glimmer/interfaces'; import { createConstRef, Reference } from '@glimmer/reference'; -import { registerDestructor } from '@glimmer/destroyable'; -import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; + import { argsProxyFor } from '../util/args-proxy'; +import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; import { ManagerFactory } from './index'; const CAPABILITIES = { diff --git a/packages/@glimmer/manager/lib/public/helper.ts b/packages/@glimmer/manager/lib/public/helper.ts index 9d1e24194..2b60f02f8 100644 --- a/packages/@glimmer/manager/lib/public/helper.ts +++ b/packages/@glimmer/manager/lib/public/helper.ts @@ -13,8 +13,8 @@ import { } from '@glimmer/interfaces'; import { createComputeRef, createConstRef, UNDEFINED_REFERENCE } from '@glimmer/reference'; -import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; import { argsProxyFor } from '../util/args-proxy'; +import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; import { ManagerFactory } from './index'; export function helperCapabilities( diff --git a/packages/@glimmer/manager/lib/public/index.ts b/packages/@glimmer/manager/lib/public/index.ts index 3766b9672..25a14d47d 100644 --- a/packages/@glimmer/manager/lib/public/index.ts +++ b/packages/@glimmer/manager/lib/public/index.ts @@ -1,13 +1,13 @@ -import { _WeakSet } from '@glimmer/util'; import { ComponentManager, HelperManager, ModifierManager, Owner } from '@glimmer/interfaces'; + import { setInternalComponentManager, setInternalHelperManager, setInternalModifierManager, } from '../internal/index'; import { CustomComponentManager } from './component'; -import { CustomModifierManager } from './modifier'; import { CustomHelperManager } from './helper'; +import { CustomModifierManager } from './modifier'; type Manager = ComponentManager | ModifierManager | HelperManager; diff --git a/packages/@glimmer/manager/lib/public/modifier.ts b/packages/@glimmer/manager/lib/public/modifier.ts index 78242032d..45686a779 100644 --- a/packages/@glimmer/manager/lib/public/modifier.ts +++ b/packages/@glimmer/manager/lib/public/modifier.ts @@ -1,3 +1,4 @@ +import { registerDestructor } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { Arguments, @@ -7,15 +8,15 @@ import { ModifierCapabilitiesVersions, ModifierManager, Owner, + SimpleElement, UpdatableTag, } from '@glimmer/interfaces'; -import { registerDestructor } from '@glimmer/destroyable'; import { valueForRef } from '@glimmer/reference'; import { castToBrowser, dict } from '@glimmer/util'; import { createUpdatableTag, untrack } from '@glimmer/validator'; -import { SimpleElement } from '@glimmer/interfaces'; -import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; + import { argsProxyFor } from '../util/args-proxy'; +import { buildCapabilities, FROM_CAPABILITIES } from '../util/capabilities'; import { ManagerFactory } from '.'; export function modifierCapabilities( @@ -159,8 +160,8 @@ export function reifyArgs({ named, positional }: CapturedArguments): { } { let reifiedNamed = dict(); - for (let key in named) { - reifiedNamed[key] = valueForRef(named[key]); + for (const [key, value] of Object.entries(named)) { + reifiedNamed[key] = valueForRef(value); } let reifiedPositional = positional.map(valueForRef); diff --git a/packages/@glimmer/manager/lib/public/template.ts b/packages/@glimmer/manager/lib/public/template.ts index 985995379..47eae6873 100644 --- a/packages/@glimmer/manager/lib/public/template.ts +++ b/packages/@glimmer/manager/lib/public/template.ts @@ -1,6 +1,6 @@ import { DEBUG } from '@glimmer/env'; -import { debugToString } from '@glimmer/util'; import { TemplateFactory } from '@glimmer/interfaces'; +import { debugToString } from '@glimmer/util'; const TEMPLATES: WeakMap = new WeakMap(); diff --git a/packages/@glimmer/manager/lib/util/args-proxy.ts b/packages/@glimmer/manager/lib/util/args-proxy.ts index 3ce14fc9a..54d46609c 100644 --- a/packages/@glimmer/manager/lib/util/args-proxy.ts +++ b/packages/@glimmer/manager/lib/util/args-proxy.ts @@ -32,7 +32,7 @@ function convertToInt(prop: number | string | symbol): number | null { function tagForNamedArg(namedArgs: CapturedNamedArguments, key: string): Tag { return track(() => { if (key in namedArgs) { - valueForRef(namedArgs[key]); + valueForRef(namedArgs[key]!); } }); } @@ -48,7 +48,7 @@ function tagForPositionalArg(positionalArgs: CapturedPositionalArguments, key: s if (parsed !== null && parsed < positionalArgs.length) { // consume the tag of the referenced index - valueForRef(positionalArgs[parsed]); + valueForRef(positionalArgs[parsed]!); } }); } @@ -115,7 +115,7 @@ class PositionalArgsProxy implements ProxyHandler<[]> { const parsed = convertToInt(prop); if (parsed !== null && parsed < positional.length) { - return valueForRef(positional[parsed]); + return valueForRef(positional[parsed]!); } return (target as any)[prop]; @@ -194,7 +194,7 @@ if (HAS_NATIVE_PROXY) { enumerable: true, configurable: true, get() { - return valueForRef(named[name]); + return valueForRef(named[name]!); }, }); }); diff --git a/packages/@glimmer/manager/lib/util/capabilities.ts b/packages/@glimmer/manager/lib/util/capabilities.ts index f81740994..632a05958 100644 --- a/packages/@glimmer/manager/lib/util/capabilities.ts +++ b/packages/@glimmer/manager/lib/util/capabilities.ts @@ -1,17 +1,17 @@ +import { check, CheckNumber } from '@glimmer/debug'; import { DEBUG } from '@glimmer/env'; -import { _WeakSet } from '@glimmer/util'; import { Capabilities, InternalComponentCapabilities, + InternalComponentCapability, InternalComponentManager, - WithUpdateHook, - WithPrepareArgs, WithCreateInstance, WithDynamicLayout, - InternalComponentCapability, + WithPrepareArgs, WithSubOwner, + WithUpdateHook, } from '@glimmer/interfaces'; -import { check, CheckNumber } from '@glimmer/debug'; +import { _WeakSet } from '@glimmer/util'; export const FROM_CAPABILITIES = DEBUG ? new _WeakSet() : undefined; diff --git a/packages/@glimmer/manager/test/capabilities-test.ts b/packages/@glimmer/manager/test/capabilities-test.ts index df24ad034..5c1609dfb 100644 --- a/packages/@glimmer/manager/test/capabilities-test.ts +++ b/packages/@glimmer/manager/test/capabilities-test.ts @@ -1,4 +1,5 @@ import { InternalComponentCapability } from '@glimmer/interfaces'; + import { capabilityFlagsFrom, managerHasCapability } from '..'; QUnit.module('Capabilities Bitmaps'); diff --git a/packages/@glimmer/manager/test/managers-test.ts b/packages/@glimmer/manager/test/managers-test.ts index 3b91183a3..d99cd838f 100644 --- a/packages/@glimmer/manager/test/managers-test.ts +++ b/packages/@glimmer/manager/test/managers-test.ts @@ -10,21 +10,21 @@ import { UNDEFINED_REFERENCE } from '@glimmer/reference'; import { createUpdatableTag } from '@glimmer/validator'; import { - setInternalComponentManager, + componentCapabilities, + CustomComponentManager, + CustomHelperManager, + CustomModifierManager, getInternalComponentManager, - setInternalModifierManager, - getInternalModifierManager, - setInternalHelperManager, getInternalHelperManager, + getInternalModifierManager, + helperCapabilities, + modifierCapabilities, setComponentManager, - setModifierManager, setHelperManager, - componentCapabilities, - modifierCapabilities, - helperCapabilities, - CustomComponentManager, - CustomModifierManager, - CustomHelperManager, + setInternalComponentManager, + setInternalHelperManager, + setInternalModifierManager, + setModifierManager, } from '..'; const { module, test } = QUnit; diff --git a/packages/@glimmer/node/lib/node-dom-helper.ts b/packages/@glimmer/node/lib/node-dom-helper.ts index a4362a5dd..fed42ebfa 100644 --- a/packages/@glimmer/node/lib/node-dom-helper.ts +++ b/packages/@glimmer/node/lib/node-dom-helper.ts @@ -1,7 +1,6 @@ -import { Bounds, Option } from '@glimmer/interfaces'; +import { Bounds, Option, SimpleDocument, SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { ConcreteBounds, DOMTreeConstruction } from '@glimmer/runtime'; import createHTMLDocument from '@simple-dom/document'; -import { SimpleDocument, SimpleElement, SimpleNode } from '@glimmer/interfaces'; export default class NodeDOMTreeConstruction extends DOMTreeConstruction { protected declare document: SimpleDocument; // Hides property on base class @@ -10,21 +9,25 @@ export default class NodeDOMTreeConstruction extends DOMTreeConstruction { } // override to prevent usage of `this.document` until after the constructor - protected setupUselessElement() {} + protected override setupUselessElement() {} - insertHTMLBefore(parent: SimpleElement, reference: Option, html: string): Bounds { + override insertHTMLBefore( + parent: SimpleElement, + reference: Option, + html: string + ): Bounds { let raw = this.document.createRawHTMLSection!(html); parent.insertBefore(raw, reference); return new ConcreteBounds(parent, raw, raw); } // override to avoid SVG detection/work when in node (this is not needed in SSR) - createElement(tag: string) { + override createElement(tag: string) { return this.document.createElement(tag); } // override to avoid namespace shenanigans when in node (this is not needed in SSR) - setAttribute(element: SimpleElement, name: string, value: string) { + override setAttribute(element: SimpleElement, name: string, value: string) { element.setAttribute(name, value); } } diff --git a/packages/@glimmer/node/lib/serialize-builder.ts b/packages/@glimmer/node/lib/serialize-builder.ts index 7d607f7cb..35e03c735 100644 --- a/packages/@glimmer/node/lib/serialize-builder.ts +++ b/packages/@glimmer/node/lib/serialize-builder.ts @@ -1,14 +1,15 @@ import type { Bounds, - Environment, - Option, ElementBuilder, + Environment, Maybe, ModifierInstance, + Option, + SimpleElement, + SimpleNode, + SimpleText, } from '@glimmer/interfaces'; -import { ConcreteBounds, NewElementBuilder } from '@glimmer/runtime'; -import { RemoteLiveBlock } from '@glimmer/runtime'; -import type { SimpleElement, SimpleNode, SimpleText } from '@glimmer/interfaces'; +import { ConcreteBounds, NewElementBuilder, RemoteLiveBlock } from '@glimmer/runtime'; const TEXT_NODE = 3; @@ -29,7 +30,7 @@ function currentNode( class SerializeBuilder extends NewElementBuilder implements ElementBuilder { private serializeBlockDepth = 0; - __openBlock(): void { + override __openBlock(): void { let { tagName } = this.element; if (tagName !== 'TITLE' && tagName !== 'SCRIPT' && tagName !== 'STYLE') { @@ -40,7 +41,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { super.__openBlock(); } - __closeBlock(): void { + override __closeBlock(): void { let { tagName } = this.element; super.__closeBlock(); @@ -51,7 +52,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { } } - __appendHTML(html: string): Bounds { + override __appendHTML(html: string): Bounds { let { tagName } = this.element; if (tagName === 'TITLE' || tagName === 'SCRIPT' || tagName === 'STYLE') { @@ -79,7 +80,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { return new ConcreteBounds(this.element, first, last); } - __appendText(string: string): SimpleText { + override __appendText(string: string): SimpleText { let { tagName } = this.element; let current = currentNode(this); @@ -94,7 +95,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { return super.__appendText(string); } - closeElement(): Option { + override closeElement(): Option { if (NEEDS_EXTRA_CLOSE.has(this.element)) { NEEDS_EXTRA_CLOSE.delete(this.element); super.closeElement(); @@ -103,7 +104,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { return super.closeElement(); } - openElement(tag: string) { + override openElement(tag: string) { if (tag === 'tr') { if ( this.element.tagName !== 'TBODY' && @@ -123,7 +124,7 @@ class SerializeBuilder extends NewElementBuilder implements ElementBuilder { return super.openElement(tag); } - pushRemoteElement( + override pushRemoteElement( element: SimpleElement, cursorId: string, insertBefore: Maybe = null diff --git a/packages/@glimmer/opcode-compiler/index.ts b/packages/@glimmer/opcode-compiler/index.ts index e306b1ab9..39dec0290 100644 --- a/packages/@glimmer/opcode-compiler/index.ts +++ b/packages/@glimmer/opcode-compiler/index.ts @@ -1,28 +1,20 @@ -export * from './lib/program-context'; - +export { compilable, compileStatements } from './lib/compilable-template'; export { debugCompiler } from './lib/compiler'; - -export { compileStatements, compilable } from './lib/compilable-template'; - export * from './lib/opcode-builder/context'; export * from './lib/opcode-builder/delegate'; - export { - InvokeStaticBlockWithStack as invokeStaticBlockWithStack, InvokeStaticBlock as invokeStaticBlock, + InvokeStaticBlockWithStack as invokeStaticBlockWithStack, } from './lib/opcode-builder/helpers/blocks'; -export { compileStd } from './lib/opcode-builder/helpers/stdlib'; export { meta } from './lib/opcode-builder/helpers/shared'; - +export { compileStd } from './lib/opcode-builder/helpers/stdlib'; export { StdLib } from './lib/opcode-builder/stdlib'; - +export * from './lib/program-context'; export { - default as templateFactory, templateCacheCounters, + default as templateFactory, TemplateFactoryWithIdAndMeta, TemplateWithIdAndReferrer, } from './lib/template'; - -export { WrappedBuilder } from './lib/wrapped-component'; - export { EMPTY_BLOCKS } from './lib/utils'; +export { WrappedBuilder } from './lib/wrapped-component'; diff --git a/packages/@glimmer/opcode-compiler/lib/compilable-template.ts b/packages/@glimmer/opcode-compiler/lib/compilable-template.ts index ac46b64dc..b7a9d1769 100644 --- a/packages/@glimmer/opcode-compiler/lib/compilable-template.ts +++ b/packages/@glimmer/opcode-compiler/lib/compilable-template.ts @@ -1,29 +1,30 @@ import { - Option, - LayoutWithContext, - ContainingMetadata, - SerializedInlineBlock, - WireFormat, - SymbolTable, - CompilableTemplate, - Statement, - CompileTimeCompilationContext, + BlockSymbolTable, + BuilderOp, CompilableBlock, CompilableProgram, + CompilableTemplate, + CompileTimeCompilationContext, + ContainingMetadata, HandleResult, - BlockSymbolTable, - SerializedBlock, - BuilderOp, HighLevelOp, + LayoutWithContext, + Option, + SerializedBlock, + SerializedInlineBlock, + Statement, + SymbolTable, + WireFormat, } from '@glimmer/interfaces'; -import { meta } from './opcode-builder/helpers/shared'; -import { EMPTY_ARRAY } from '@glimmer/util'; -import { templateCompilationContext } from './opcode-builder/context'; import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; +import { EMPTY_ARRAY } from '@glimmer/util'; + import { debugCompiler } from './compiler'; -import { STATEMENTS } from './syntax/statements'; -import { HighLevelStatementOp } from './syntax/compilers'; +import { templateCompilationContext } from './opcode-builder/context'; import { encodeOp } from './opcode-builder/encoder'; +import { meta } from './opcode-builder/helpers/shared'; +import { HighLevelStatementOp } from './syntax/compilers'; +import { STATEMENTS } from './syntax/statements'; export const PLACEHOLDER_HANDLE = -1; @@ -91,8 +92,8 @@ export function compileStatements( encodeOp(encoder, constants, resolver, meta, op as BuilderOp | HighLevelOp); } - for (let i = 0; i < statements.length; i++) { - sCompiler.compile(pushOp, statements[i]); + for (const statement of statements) { + sCompiler.compile(pushOp, statement); } let handle = context.encoder.commit(meta.size); diff --git a/packages/@glimmer/opcode-compiler/lib/compiler.ts b/packages/@glimmer/opcode-compiler/lib/compiler.ts index 5a3797017..13021ab78 100644 --- a/packages/@glimmer/opcode-compiler/lib/compiler.ts +++ b/packages/@glimmer/opcode-compiler/lib/compiler.ts @@ -1,5 +1,5 @@ import { debugSlice } from '@glimmer/debug'; -import { TemplateCompilationContext, HandleResult } from '@glimmer/interfaces'; +import { HandleResult, TemplateCompilationContext } from '@glimmer/interfaces'; import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; import { extractHandle } from '@glimmer/util'; diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/context.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/context.ts index 1db58ffd0..5d5289ca0 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/context.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/context.ts @@ -1,13 +1,14 @@ import { - CompileTimeResolver, - ContainingMetadata, - TemplateCompilationContext, CompileTimeArtifacts, CompileTimeCompilationContext, + CompileTimeResolver, + ContainingMetadata, CreateRuntimeOp, + TemplateCompilationContext, } from '@glimmer/interfaces'; -import { EncoderImpl } from './encoder'; + import { CompileTimeCompilationContextImpl } from '../program-context'; +import { EncoderImpl } from './encoder'; export function programCompilationContext( artifacts: CompileTimeArtifacts, diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/delegate.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/delegate.ts index a51d71acc..bcc066479 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/delegate.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/delegate.ts @@ -1,4 +1,4 @@ -import { InternalComponentCapabilities, Option, CompileTimeComponent } from '@glimmer/interfaces'; +import { CompileTimeComponent, InternalComponentCapabilities, Option } from '@glimmer/interfaces'; export const DEFAULT_CAPABILITIES: InternalComponentCapabilities = { dynamicLayout: true, diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts index 3fc3a63e9..308605910 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/encoder.ts @@ -1,30 +1,41 @@ import { InstructionEncoderImpl } from '@glimmer/encoder'; +import { DEBUG } from '@glimmer/env'; import { + BuilderOp, + BuilderOpcode, CompileTimeConstants, - Operand, CompileTimeHeap, - Op, - BuilderOpcode, - HighLevelBuilderOpcode, - MachineOp, - SingleBuilderOperand, - Encoder, - HighLevelResolutionOpcode, - HighLevelOp, - OpcodeSize, - InstructionEncoder, + CompileTimeResolver, + ContainingMetadata, Dict, + Encoder, EncoderError, HandleResult, - BuilderOp, - CompileTimeResolver, - ContainingMetadata, + HighLevelBuilderOpcode, + HighLevelOp, HighLevelOperand, - STDLib, + HighLevelResolutionOpcode, + InstructionEncoder, + MachineOp, + Op, + OpcodeSize, + Operand, ResolutionTimeConstants, + SingleBuilderOperand, + STDLib, } from '@glimmer/interfaces'; +import { + assert, + dict, + EMPTY_STRING_ARRAY, + encodeHandle, + expect, + isPresentArray, + Stack, +} from '@glimmer/util'; import { isMachineOp } from '@glimmer/vm'; -import { Stack, dict, expect, EMPTY_STRING_ARRAY, encodeHandle, assert } from '@glimmer/util'; + +import { compilableBlock } from '../compilable-template'; import { resolveComponent, resolveComponentOrHelper, @@ -33,8 +44,6 @@ import { resolveOptionalComponentOrHelper, resolveOptionalHelper, } from './helpers/resolution'; -import { compilableBlock } from '../compilable-template'; -import { DEBUG } from '@glimmer/env'; export class Labels { labels: Dict = dict(); @@ -50,9 +59,9 @@ export class Labels { patch(heap: CompileTimeHeap): void { let { targets, labels } = this; - for (let i = 0; i < targets.length; i++) { - let { at, target } = targets[i]; - let address = labels[target] - at; + + for (const { at, target } of targets) { + let address = labels[target]! - at; assert(heap.getbyaddr(at) === -1, 'Expected heap to contain a placeholder, but it did not'); @@ -97,7 +106,7 @@ export function encodeOp( let freeVar = op[1]; let name = expect(meta.upvars, 'BUG: attempted to resolve value but no upvars found')[ freeVar - ]; + ]!; let andThen = op[2]; @@ -160,7 +169,7 @@ export class EncoderImpl implements Encoder { this.heap.push(MachineOp.Return | OpcodeSize.MACHINE_MASK); this.heap.finishMalloc(handle, size); - if (this.errors.length) { + if (isPresentArray(this.errors)) { return { errors: this.errors, handle }; } else { return handle; diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/blocks.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/blocks.ts index 35794b680..c67f71c7f 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/blocks.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/blocks.ts @@ -1,9 +1,10 @@ import { MachineOp, Op, Option, WireFormat } from '@glimmer/interfaces'; import { $fp } from '@glimmer/vm'; -import { PushPrimitive } from './vm'; + +import { PushExpressionOp, PushStatementOp } from '../../syntax/compilers'; import { blockOperand, symbolTableOperand } from '../operands'; import { SimpleArgs } from './shared'; -import { PushExpressionOp, PushStatementOp } from '../../syntax/compilers'; +import { PushPrimitive } from './vm'; /** * Yield to a block located at a particular symbol location. diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts index f4dd8199d..ed39ed53f 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/components.ts @@ -2,20 +2,21 @@ import { CompilableProgram, CompileTimeComponent, HighLevelBuilderOpcode, + InternalComponentCapability, LayoutWithContext, MachineOp, NamedBlocks, - WireFormat, - Option, Op, - InternalComponentCapability, + Option, + WireFormat, } from '@glimmer/interfaces'; import { hasCapability } from '@glimmer/manager'; +import { EMPTY_STRING_ARRAY, reverse, unwrap } from '@glimmer/util'; import { $s0, $s1, $sp, SavedRegister } from '@glimmer/vm'; -import { EMPTY_STRING_ARRAY } from '@glimmer/util'; + import { PushExpressionOp, PushStatementOp } from '../../syntax/compilers'; import { namedBlocks } from '../../utils'; -import { labelOperand, layoutOperand, symbolTableOperand, isStrictMode } from '../operands'; +import { isStrictMode, labelOperand, layoutOperand, symbolTableOperand } from '../operands'; import { InvokeStaticBlock, PushYieldableBlock, YieldBlock } from './blocks'; import { Replayable } from './conditional'; import { expr } from './expr'; @@ -193,8 +194,7 @@ function InvokeStaticComponent( // Followed by the other blocks, if they exist and are referenced in the component. // Also store the index of the associated symbol. - for (let i = 0; i < blockNames.length; i++) { - let name = blockNames[i]; + for (const name of blockNames) { let symbol = symbols.indexOf(`&${name}`); if (symbol !== -1) { @@ -226,7 +226,7 @@ function InvokeStaticComponent( let val = named[1]; for (let i = 0; i < val.length; i++) { - let symbol = symbols.indexOf(names[i]); + let symbol = symbols.indexOf(unwrap(names[i])); expr(op, val[i]); argSymbols.push(symbol); @@ -249,7 +249,7 @@ function InvokeStaticComponent( let val = named[1]; for (let i = 0; i < val.length; i++) { - let name = names[i]; + let name = unwrap(names[i]); let symbol = symbols.indexOf(name); if (symbol !== -1) { @@ -287,8 +287,9 @@ function InvokeStaticComponent( // Going in reverse, now we pop the args/blocks off the stack, starting with // arguments, and assign them to their symbols in the new scope. - for (let i = argSymbols.length - 1; i >= 0; i--) { - let symbol = argSymbols[i]; + for (const symbol of reverse(argSymbols)) { + // for (let i = argSymbols.length - 1; i >= 0; i--) { + // let symbol = argSymbols[i]; if (symbol === -1) { // The expression was not bound to a local symbol, it was only pushed to be @@ -305,9 +306,7 @@ function InvokeStaticComponent( } // Finish up by popping off and assigning blocks - for (let i = blockSymbols.length - 1; i >= 0; i--) { - let symbol = blockSymbols[i]; - + for (const symbol of reverse(blockSymbols)) { op(Op.SetBlock, symbol + 1); } diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.ts index 561bd27d1..42c32f361 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/conditional.ts @@ -1,13 +1,15 @@ -import { labelOperand } from '../operands'; -import { Op, MachineOp, HighLevelBuilderOpcode } from '@glimmer/interfaces'; +import { HighLevelBuilderOpcode, MachineOp, Op } from '@glimmer/interfaces'; +import { unwrap } from '@glimmer/util'; + import { PushStatementOp } from '../../syntax/compilers'; +import { labelOperand } from '../operands'; export type When = (match: number, callback: () => void) => void; export function SwitchCases( op: PushStatementOp, bootstrap: () => void, - callback: (when: When) => void + matcher: (when: When) => void ): void { // Setup the switch DSL let clauses: Array<{ match: number; label: string; callback: () => void }> = []; @@ -19,7 +21,7 @@ export function SwitchCases( } // Call the callback - callback(when); + matcher(when); // Emit the opcodes for the switch op(Op.Enter, 1); @@ -35,7 +37,7 @@ export function SwitchCases( // Enumerate the clauses in reverse order. Earlier matches will // require fewer checks. for (let i = clauses.length - 1; i >= 0; i--) { - let clause = clauses[i]; + let clause = unwrap(clauses[i]); op(HighLevelBuilderOpcode.Label, clause.label); op(Op.Pop, 1); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/expr.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/expr.ts index addfa4835..cad768388 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/expr.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/expr.ts @@ -1,4 +1,5 @@ import { Op, WireFormat } from '@glimmer/interfaces'; + import { PushExpressionOp } from '../../syntax/compilers'; import { EXPRESSIONS } from '../../syntax/expressions'; import { PushPrimitive } from './vm'; diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/resolution.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/resolution.ts index a98bf3833..a4f318662 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/resolution.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/resolution.ts @@ -5,6 +5,7 @@ import { ContainingMetadata, Expressions, Owner, + ResolutionTimeConstants, ResolveComponentOp, ResolveComponentOrHelperOp, ResolveHelperOp, @@ -12,9 +13,8 @@ import { ResolveOptionalComponentOrHelperOp, ResolveOptionalHelperOp, SexpOpcodes, - ResolutionTimeConstants, } from '@glimmer/interfaces'; -import { assert, debugToString, expect } from '@glimmer/util'; +import { assert, debugToString, expect, unwrap } from '@glimmer/util'; function isGetLikeTuple(opcode: Expressions.Expression): opcode is Expressions.TupleExpression { return Array.isArray(opcode) && opcode.length === 2; @@ -123,7 +123,7 @@ export function resolveComponent( } else { let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let definition = resolver.lookupComponent(name, owner)!; if (DEBUG && (typeof definition !== 'object' || definition === null)) { @@ -164,7 +164,7 @@ export function resolveHelper( } else { let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let helper = resolver.lookupHelper(name, owner!)!; if (DEBUG && helper === null) { @@ -201,7 +201,7 @@ export function resolveModifier( then(constants.modifier(definition as object)); } else if (type === SexpOpcodes.GetStrictKeyword) { let { upvars } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let modifier = resolver.lookupBuiltInModifier(name); if (DEBUG && modifier === null) { @@ -213,7 +213,7 @@ export function resolveModifier( then(constants.modifier(modifier!, name)); } else { let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let modifier = resolver.lookupModifier(name, owner)!; if (DEBUG && modifier === null) { @@ -283,7 +283,7 @@ export function resolveComponentOrHelper( } else { let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let definition = resolver.lookupComponent(name, owner); if (definition !== null) { @@ -317,7 +317,7 @@ export function resolveOptionalHelper( ); let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let helper = resolver.lookupHelper(name, owner); if (helper) { @@ -382,7 +382,7 @@ export function resolveOptionalComponentOrHelper( } else { let { upvars, owner } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let definition = resolver.lookupComponent(name, owner); if (definition !== null) { @@ -407,7 +407,7 @@ function lookupBuiltInHelper( ): number { let { upvars } = assertResolverInvariants(meta); - let name = upvars[expr[1]]; + let name = unwrap(upvars[expr[1]]); let helper = resolver.lookupBuiltInHelper(name); if (DEBUG && helper === null) { diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts index 435bdbfbb..1db050524 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/shared.ts @@ -1,14 +1,15 @@ import { ContainingMetadata, LayoutWithContext, + NamedBlocks, Op, Option, WireFormat, - NamedBlocks, } from '@glimmer/interfaces'; import { EMPTY_ARRAY, EMPTY_STRING_ARRAY } from '@glimmer/util'; -import { PushYieldableBlock } from './blocks'; + import { PushExpressionOp, PushStatementOp } from '../../syntax/compilers'; +import { PushYieldableBlock } from './blocks'; import { expr } from './expr'; /** @@ -27,8 +28,8 @@ export function CompileArgs( atNames: boolean ): void { let blockNames: string[] = blocks.names; - for (let i = 0; i < blockNames.length; i++) { - PushYieldableBlock(op, blocks.get(blockNames[i])); + for (const name of blockNames) { + PushYieldableBlock(op, blocks.get(name)); } let count = CompilePositional(op, positional); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts index 35e615158..92f1da7dd 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/stdlib.ts @@ -1,19 +1,19 @@ -import { $s0 } from '@glimmer/vm'; - -import { invokePreparedComponent, InvokeBareComponent } from './components'; -import { StdLib } from '../stdlib'; -import { encodeOp, EncoderImpl } from '../encoder'; import { - ContentType, - Op, + BuilderOp, CompileTimeCompilationContext, + ContainingMetadata, + ContentType, HighLevelOp, - BuilderOp, MachineOp, - ContainingMetadata, + Op, } from '@glimmer/interfaces'; -import { SwitchCases } from './conditional'; +import { $s0 } from '@glimmer/vm'; + import { HighLevelStatementOp, PushStatementOp } from '../../syntax/compilers'; +import { encodeOp, EncoderImpl } from '../encoder'; +import { StdLib } from '../stdlib'; +import { InvokeBareComponent, invokePreparedComponent } from './components'; +import { SwitchCases } from './conditional'; import { CallDynamic } from './vm'; export function main(op: PushStatementOp): void { @@ -124,7 +124,7 @@ export const STDLIB_META: ContainingMetadata = { function build( program: CompileTimeCompilationContext, - callback: (op: PushStatementOp) => void + builder: (op: PushStatementOp) => void ): number { let { constants, heap, resolver } = program; let encoder = new EncoderImpl(heap, STDLIB_META); @@ -133,7 +133,7 @@ function build( encodeOp(encoder, constants, resolver, STDLIB_META, op as BuilderOp | HighLevelOp); } - callback(pushOp); + builder(pushOp); let result = encoder.commit(0); diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/vm.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/vm.ts index ad0d8faea..c73b9e84a 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/vm.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/helpers/vm.ts @@ -1,17 +1,18 @@ -import { $fp, $v0 } from '@glimmer/vm'; import { - Option, - Op, + CurriedType, MachineOp, - WireFormat, NonSmallIntOperand, - CurriedType, + Op, + Option, + WireFormat, } from '@glimmer/interfaces'; import { encodeImmediate, isSmallInt } from '@glimmer/util'; -import { SimpleArgs } from './shared'; +import { $fp, $v0 } from '@glimmer/vm'; + import { PushExpressionOp, PushStatementOp } from '../../syntax/compilers'; import { isStrictMode, nonSmallIntOperand } from '../operands'; import { expr } from './expr'; +import { SimpleArgs } from './shared'; export type Primitive = undefined | null | boolean | number | string; diff --git a/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts b/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts index 3265972d5..89cea5ea8 100644 --- a/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts +++ b/packages/@glimmer/opcode-compiler/lib/opcode-builder/operands.ts @@ -1,17 +1,17 @@ import { - LabelOperand, - SerializedInlineBlock, + BlockOperand, + CompilableTemplate, DebugSymbolsOperand, HighLevelOperand, - BlockOperand, - StdLibOperand, + IsStrictModeOperand, + LabelOperand, + LayoutOperand, NonSmallIntOperand, SerializedBlock, + SerializedInlineBlock, + StdLibOperand, SymbolTable, SymbolTableOperand, - CompilableTemplate, - LayoutOperand, - IsStrictModeOperand, } from '@glimmer/interfaces'; import { assert, isSmallInt } from '@glimmer/util'; diff --git a/packages/@glimmer/opcode-compiler/lib/program-context.ts b/packages/@glimmer/opcode-compiler/lib/program-context.ts index 2851ae181..1b2b0e3d3 100644 --- a/packages/@glimmer/opcode-compiler/lib/program-context.ts +++ b/packages/@glimmer/opcode-compiler/lib/program-context.ts @@ -1,13 +1,14 @@ import { - STDLib, + CompileTimeArtifacts, CompileTimeCompilationContext, - CompileTimeResolver, - CompileTimeHeap, CompileTimeConstants, - CompileTimeArtifacts, - ResolutionTimeConstants, + CompileTimeHeap, + CompileTimeResolver, CreateRuntimeOp, + ResolutionTimeConstants, + STDLib, } from '@glimmer/interfaces'; + import { compileStd } from './opcode-builder/helpers/stdlib'; export class CompileTimeCompilationContextImpl implements CompileTimeCompilationContext { diff --git a/packages/@glimmer/opcode-compiler/lib/syntax/compilers.ts b/packages/@glimmer/opcode-compiler/lib/syntax/compilers.ts index be2b44285..33d56e42b 100644 --- a/packages/@glimmer/opcode-compiler/lib/syntax/compilers.ts +++ b/packages/@glimmer/opcode-compiler/lib/syntax/compilers.ts @@ -1,5 +1,5 @@ import { BuilderOp, HighLevelOp, SexpOpcode, SexpOpcodeMap } from '@glimmer/interfaces'; -import { assert } from '@glimmer/util'; +import { assert, unwrap } from '@glimmer/util'; export type PushExpressionOp = (...op: BuilderOp | HighLevelOp) => void; @@ -30,7 +30,7 @@ export class Compilers(); diff --git a/packages/@glimmer/opcode-compiler/lib/template.ts b/packages/@glimmer/opcode-compiler/lib/template.ts index ac74df011..fdf9c31c6 100644 --- a/packages/@glimmer/opcode-compiler/lib/template.ts +++ b/packages/@glimmer/opcode-compiler/lib/template.ts @@ -10,6 +10,7 @@ import { TemplateOk, } from '@glimmer/interfaces'; import { assign } from '@glimmer/util'; + import { compilable } from './compilable-template'; import { WrappedBuilder } from './wrapped-component'; diff --git a/packages/@glimmer/opcode-compiler/lib/utils.ts b/packages/@glimmer/opcode-compiler/lib/utils.ts index 928b1cbe7..502ecf483 100644 --- a/packages/@glimmer/opcode-compiler/lib/utils.ts +++ b/packages/@glimmer/opcode-compiler/lib/utils.ts @@ -1,5 +1,5 @@ -import { NamedBlocks, Option, WireFormat, SerializedInlineBlock } from '@glimmer/interfaces'; -import { dict, assign } from '@glimmer/util'; +import { NamedBlocks, Option, SerializedInlineBlock, WireFormat } from '@glimmer/interfaces'; +import { assign, dict, enumerate, unwrap } from '@glimmer/util'; interface NamedBlocksDict { [key: string]: Option; @@ -49,8 +49,8 @@ export function namedBlocks(blocks: WireFormat.Core.Blocks): NamedBlocks { let [keys, values] = blocks; - for (let i = 0; i < keys.length; i++) { - out[keys[i]] = values[i]; + for (const [i, key] of enumerate(keys)) { + out[key] = unwrap(values[i]); } return new NamedBlocksImpl(out); diff --git a/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts b/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts index ec3ca272b..5e169095d 100644 --- a/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts +++ b/packages/@glimmer/opcode-compiler/lib/wrapped-component.ts @@ -1,20 +1,20 @@ import { - ProgramSymbolTable, + BuilderOp, CompilableProgram, - LayoutWithContext, - Option, CompileTimeCompilationContext, HandleResult, - BuilderOp, HighLevelOp, + LayoutWithContext, + Option, + ProgramSymbolTable, } from '@glimmer/interfaces'; - -import { templateCompilationContext } from './opcode-builder/context'; -import { meta } from './opcode-builder/helpers/shared'; -import { ATTRS_BLOCK, WrappedComponent } from './opcode-builder/helpers/components'; import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; + import { debugCompiler } from './compiler'; +import { templateCompilationContext } from './opcode-builder/context'; import { encodeOp } from './opcode-builder/encoder'; +import { ATTRS_BLOCK, WrappedComponent } from './opcode-builder/helpers/components'; +import { meta } from './opcode-builder/helpers/shared'; import { HighLevelStatementOp } from './syntax/compilers'; export class WrappedBuilder implements CompilableProgram { diff --git a/packages/@glimmer/program/index.ts b/packages/@glimmer/program/index.ts index d11873699..7cdcb1ccf 100644 --- a/packages/@glimmer/program/index.ts +++ b/packages/@glimmer/program/index.ts @@ -1,4 +1,4 @@ export * from './lib/constants'; -export * from './lib/program'; -export * from './lib/opcode'; export * from './lib/helpers'; +export * from './lib/opcode'; +export * from './lib/program'; diff --git a/packages/@glimmer/program/lib/constants.ts b/packages/@glimmer/program/lib/constants.ts index a77515c9c..29fd161e5 100644 --- a/packages/@glimmer/program/lib/constants.ts +++ b/packages/@glimmer/program/lib/constants.ts @@ -1,17 +1,16 @@ import { CompileTimeConstants, + ComponentDefinition, ComponentDefinitionState, ConstantPool, + HelperDefinitionState, InternalComponentCapability, - ComponentDefinition, + ModifierDefinitionState, ResolutionTimeConstants, ResolvedComponentDefinition, RuntimeConstants, - ModifierDefinitionState, - HelperDefinitionState, Template, } from '@glimmer/interfaces'; -import { assert, constants, expect, unwrapTemplate } from '@glimmer/util'; import { capabilityFlagsFrom, getComponentTemplate, @@ -21,6 +20,8 @@ import { managerHasCapability, } from '@glimmer/manager'; import { templateFactory } from '@glimmer/opcode-compiler'; +import { assert, constants, enumerate, expect, unwrapTemplate } from '@glimmer/util'; + import { DEFAULT_TEMPLATE } from './util/default-template'; const WELL_KNOWN_EMPTY_ARRAY: unknown = Object.freeze([]); @@ -81,8 +82,7 @@ export class RuntimeConstantsImpl implements RuntimeConstants { let handles = this.getValue(value) as number[]; let reified: T[] = new Array(handles.length); - for (let i = 0; i < handles.length; i++) { - let n = handles[i]; + for (const [i, n] of enumerate(handles)) { reified[i] = this.getValue(n); } @@ -316,8 +316,8 @@ export class ConstantsImpl let names: number[] = this.getValue(index); reified = new Array(names.length); - for (let i = 0; i < names.length; i++) { - reified[i] = this.getValue(names[i]); + for (const [i, name] of enumerate(names)) { + reified[i] = this.getValue(name); } reifiedArrs[index] = reified; diff --git a/packages/@glimmer/program/lib/helpers.ts b/packages/@glimmer/program/lib/helpers.ts index 4a35628e7..fce6d6536 100644 --- a/packages/@glimmer/program/lib/helpers.ts +++ b/packages/@glimmer/program/lib/helpers.ts @@ -1,4 +1,5 @@ import { CompileTimeArtifacts, RuntimeArtifacts } from '@glimmer/interfaces'; + import { ConstantsImpl } from './constants'; import { HeapImpl } from './program'; diff --git a/packages/@glimmer/program/lib/opcode.ts b/packages/@glimmer/program/lib/opcode.ts index 3c410e3a3..1704219a3 100644 --- a/packages/@glimmer/program/lib/opcode.ts +++ b/packages/@glimmer/program/lib/opcode.ts @@ -1,4 +1,4 @@ -import { OpcodeSize, RuntimeOp, OpcodeHeap } from '@glimmer/interfaces'; +import { OpcodeHeap, OpcodeSize, RuntimeOp } from '@glimmer/interfaces'; export class RuntimeOpImpl implements RuntimeOp { public offset = 0; diff --git a/packages/@glimmer/program/lib/program.ts b/packages/@glimmer/program/lib/program.ts index 10c7c4c5b..0bb7c9e08 100644 --- a/packages/@glimmer/program/lib/program.ts +++ b/packages/@glimmer/program/lib/program.ts @@ -1,15 +1,16 @@ import { CompileTimeHeap, - SerializedHeap, - RuntimeHeap, - StdLibOperand, + ResolutionTimeConstants, RuntimeConstants, + RuntimeHeap, RuntimeProgram, - ResolutionTimeConstants, + SerializedHeap, + StdLibOperand, } from '@glimmer/interfaces'; import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; +import { expect, unwrap } from '@glimmer/util'; + import { RuntimeOpImpl } from './opcode'; -import { assert } from '@glimmer/util'; const enum TableSlotState { Allocated, @@ -37,12 +38,11 @@ export class RuntimeHeapImpl implements RuntimeHeap { // may move it. However, it is legal to use this address // multiple times between compactions. getaddr(handle: number): number { - return this.table[handle]; + return unwrap(this.table[handle]); } getbyaddr(address: number): number { - assert(this.heap[address] !== undefined, 'Access memory out of bounds of the heap'); - return this.heap[address]; + return expect(this.heap[address], 'Access memory out of bounds of the heap'); } sizeof(handle: number): number { @@ -104,7 +104,7 @@ export class HeapImpl implements CompileTimeHeap, RuntimeHeap { } getbyaddr(address: number): number { - return this.heap[address]; + return unwrap(this.heap[address]); } setbyaddr(address: number, value: number) { @@ -134,7 +134,7 @@ export class HeapImpl implements CompileTimeHeap, RuntimeHeap { // may move it. However, it is legal to use this address // multiple times between compactions. getaddr(handle: number): number { - return this.handleTable[handle]; + return unwrap(this.handleTable[handle]); } sizeof(handle: number): number { @@ -157,8 +157,8 @@ export class HeapImpl implements CompileTimeHeap, RuntimeHeap { let { handleTable, handleState, heap } = this; for (let i = 0; i < length; i++) { - let offset = handleTable[i]; - let size = handleTable[i + 1] - offset; + let offset = unwrap(handleTable[i]); + let size = unwrap(handleTable[i + 1]) - unwrap(offset); let state = handleState[i]; if (state === TableSlotState.Purged) { @@ -171,7 +171,7 @@ export class HeapImpl implements CompileTimeHeap, RuntimeHeap { compactedSize += size; } else if (state === TableSlotState.Allocated) { for (let j = offset; j <= i + size; j++) { - heap[j - compactedSize] = heap[j]; + heap[j - compactedSize] = unwrap(heap[j]); } handleTable[i] = offset - compactedSize; @@ -220,7 +220,7 @@ function slice(arr: Int32Array, start: number, end: number): Int32Array { let ret = new Int32Array(end); for (; start < end; start++) { - ret[start] = arr[start]; + ret[start] = unwrap(arr[start]); } return ret; @@ -228,7 +228,7 @@ function slice(arr: Int32Array, start: number, end: number): Int32Array { function sizeof(table: number[], handle: number) { if (LOCAL_DEBUG) { - return table[handle + 1] - table[handle]; + return unwrap(table[handle + 1]) - unwrap(table[handle]); } else { return -1; } diff --git a/packages/@glimmer/reference/index.ts b/packages/@glimmer/reference/index.ts index 979bc571a..4f0f87fa3 100644 --- a/packages/@glimmer/reference/index.ts +++ b/packages/@glimmer/reference/index.ts @@ -1,33 +1,32 @@ export { - REFERENCE, - Reference, - createPrimitiveRef, - createConstRef, - createUnboundRef, + AbstractIterator, + createIteratorItemRef, + createIteratorRef, + IterationItem, + IteratorDelegate, + OpaqueIterationItem, + OpaqueIterator, +} from './lib/iterable'; +export { + childRefFor, + childRefFromParts, createComputeRef, + createConstRef, createDebugAliasRef, - createReadOnlyRef, createInvokableRef, - isInvokableRef, + createPrimitiveRef, + createReadOnlyRef, + createUnboundRef, + FALSE_REFERENCE, isConstRef, + isInvokableRef, isUpdatableRef, - valueForRef, - updateRef, - childRefFor, - childRefFromParts, - ReferenceEnvironment, - UNDEFINED_REFERENCE, NULL_REFERENCE, + REFERENCE, + Reference, + ReferenceEnvironment, TRUE_REFERENCE, - FALSE_REFERENCE, + UNDEFINED_REFERENCE, + updateRef, + valueForRef, } from './lib/reference'; - -export { - IterationItem, - OpaqueIterationItem, - OpaqueIterator, - AbstractIterator, - IteratorDelegate, - createIteratorRef, - createIteratorItemRef, -} from './lib/iterable'; diff --git a/packages/@glimmer/reference/lib/iterable.ts b/packages/@glimmer/reference/lib/iterable.ts index 72066eb40..6b241ad44 100644 --- a/packages/@glimmer/reference/lib/iterable.ts +++ b/packages/@glimmer/reference/lib/iterable.ts @@ -1,9 +1,10 @@ +import { DEBUG } from '@glimmer/env'; import { getPath, toIterator } from '@glimmer/global-context'; -import { Option, Dict } from '@glimmer/interfaces'; +import { Dict, Option } from '@glimmer/interfaces'; import { EMPTY_ARRAY, isObject } from '@glimmer/util'; -import { DEBUG } from '@glimmer/env'; -import { createTag, consumeTag, dirtyTag } from '@glimmer/validator'; -import { Reference, ReferenceEnvironment, valueForRef, createComputeRef } from './reference'; +import { consumeTag, createTag, dirtyTag } from '@glimmer/validator'; + +import { createComputeRef, Reference, ReferenceEnvironment, valueForRef } from './reference'; export interface IterationItem { key: unknown; diff --git a/packages/@glimmer/reference/lib/reference.ts b/packages/@glimmer/reference/lib/reference.ts index 01fe3f0f5..29019d278 100644 --- a/packages/@glimmer/reference/lib/reference.ts +++ b/packages/@glimmer/reference/lib/reference.ts @@ -3,9 +3,9 @@ import { getProp, setProp } from '@glimmer/global-context'; import { ComputeReference, ConstantReference, - Reference, InvokableReference, Option, + Reference, ReferenceSymbol, ReferenceType, UnboundReference, @@ -13,10 +13,10 @@ import { import { expect, isDict, symbol } from '@glimmer/util'; import { CONSTANT_TAG, + consumeTag, INITIAL, Revision, Tag, - consumeTag, track, validateTag, valueForTag, @@ -250,8 +250,8 @@ export function childRefFor(_parentRef: Reference, path: string): Reference { export function childRefFromParts(root: Reference, parts: string[]): Reference { let reference = root; - for (let i = 0; i < parts.length; i++) { - reference = childRefFor(reference, parts[i]); + for (const part of parts) { + reference = childRefFor(reference, part); } return reference; diff --git a/packages/@glimmer/reference/test/iterable-test.ts b/packages/@glimmer/reference/test/iterable-test.ts index f70d59f1a..c2aac559e 100644 --- a/packages/@glimmer/reference/test/iterable-test.ts +++ b/packages/@glimmer/reference/test/iterable-test.ts @@ -1,18 +1,17 @@ -import { module, test } from './utils/qunit'; +import { GlobalContext, testOverrideGlobalContext } from '@glimmer/global-context'; +import { symbol } from '@glimmer/util'; +import { consumeTag, VOLATILE_TAG } from '@glimmer/validator'; import { - createIteratorRef, createComputeRef, + createIteratorRef, OpaqueIterationItem, Reference, valueForRef, } from '..'; -import { symbol } from '@glimmer/util'; -import { testOverrideGlobalContext, GlobalContext } from '@glimmer/global-context'; -import { VOLATILE_TAG, consumeTag } from '@glimmer/validator'; - -import { TestContext } from './utils/template'; import objectValues from './utils/platform'; +import { module, test } from './utils/qunit'; +import { TestContext } from './utils/template'; class IterableWrapper { private iterable: Reference<{ next(): OpaqueIterationItem | null }>; diff --git a/packages/@glimmer/reference/test/references-test.ts b/packages/@glimmer/reference/test/references-test.ts index 85fbfde90..2c11fc9ce 100644 --- a/packages/@glimmer/reference/test/references-test.ts +++ b/packages/@glimmer/reference/test/references-test.ts @@ -1,21 +1,22 @@ +import { DEBUG } from '@glimmer/env'; +import { dict, unwrap } from '@glimmer/util'; +import { consumeTag, createTag, dirtyTag } from '@glimmer/validator'; + +import { GlobalContext, testOverrideGlobalContext } from '../../global-context'; import { + childRefFor, createComputeRef, - valueForRef, createConstRef, - childRefFor, - isUpdatableRef, - updateRef, + createDebugAliasRef, + createInvokableRef, createReadOnlyRef, createUnboundRef, - createInvokableRef, isInvokableRef, - createDebugAliasRef, + isUpdatableRef, + updateRef, + valueForRef, } from '..'; -import { createTag, dirtyTag, consumeTag } from '@glimmer/validator'; -import { dict } from '@glimmer/util'; -import { GlobalContext, testOverrideGlobalContext } from '../../global-context'; import { tracked } from './support'; -import { DEBUG } from '@glimmer/env'; const { module, test } = QUnit; @@ -25,7 +26,7 @@ class TrackedDict { get(key: string): T { consumeTag(this.tag); - return this.data[key]; + return unwrap(this.data[key]); } set(key: string, value: T) { diff --git a/packages/@glimmer/reference/test/utils/template.ts b/packages/@glimmer/reference/test/utils/template.ts index d5d9b175c..506bf2746 100644 --- a/packages/@glimmer/reference/test/utils/template.ts +++ b/packages/@glimmer/reference/test/utils/template.ts @@ -52,7 +52,7 @@ class ObjectIterator extends BoundedIterator { return this.values[position]; } - memoFor(position: number): unknown { + override memoFor(position: number): unknown { return this.keys[position]; } } diff --git a/packages/@glimmer/runtime/index.ts b/packages/@glimmer/runtime/index.ts index 0bac53dfd..6f1b145ef 100644 --- a/packages/@glimmer/runtime/index.ts +++ b/packages/@glimmer/runtime/index.ts @@ -1,44 +1,52 @@ /** * @deprecated use RichIteratorResult or TemplateIterator instead */ -import { RichIteratorResult } from '@glimmer/interfaces'; import './lib/bootstrap'; +import { RichIteratorResult } from '@glimmer/interfaces'; + export { clear, ConcreteBounds, CursorImpl } from './lib/bounds'; export { DebugCallback, resetDebuggerCallback, setDebuggerCallback, } from './lib/compiled/opcodes/debugger'; -export { curry, CurriedValue } from './lib/curried-value'; export { - TemplateOnlyComponentManager, TEMPLATE_ONLY_COMPONENT_MANAGER, TemplateOnlyComponentDefinition as TemplateOnlyComponent, templateOnlyComponent, + TemplateOnlyComponentManager, } from './lib/component/template-only'; +export { CurriedValue, curry } from './lib/curried-value'; export { default as DOMChanges, - DOMChangesImpl as IDOMChanges, DOMTreeConstruction, + DOMChangesImpl as IDOMChanges, isWhitespace, } from './lib/dom/helper'; export { normalizeProperty } from './lib/dom/props'; -export { DynamicScopeImpl, PartialScopeImpl } from './lib/scope'; export { - runtimeContext, - EnvironmentImpl, EnvironmentDelegate, + EnvironmentImpl, inTransaction, + runtimeContext, } from './lib/environment'; +export { default as array } from './lib/helpers/array'; +export { default as concat } from './lib/helpers/concat'; +export { default as fn } from './lib/helpers/fn'; +export { default as get } from './lib/helpers/get'; +export { default as hash } from './lib/helpers/hash'; +export { invokeHelper } from './lib/helpers/invoke'; +export { default as on } from './lib/modifiers/on'; export { renderComponent, renderMain, renderSync } from './lib/render'; +export { DynamicScopeImpl, PartialScopeImpl } from './lib/scope'; export { SafeString } from './lib/upsert'; -export { InternalVM, UpdatingVM, VM as LowLevelVM } from './lib/vm'; +export { InternalVM, VM as LowLevelVM, UpdatingVM } from './lib/vm'; export { + createCapturedArgs, EMPTY_ARGS, EMPTY_NAMED, EMPTY_POSITIONAL, - createCapturedArgs, reifyArgs, reifyNamed, reifyPositional, @@ -51,8 +59,8 @@ export { export { clientBuilder, NewElementBuilder, - UpdatableBlockImpl, RemoteLiveBlock, + UpdatableBlockImpl, } from './lib/vm/element-builder'; export { isSerializationFirstNode, @@ -60,18 +68,9 @@ export { rehydrationBuilder, SERIALIZATION_FIRST_NODE_STRING, } from './lib/vm/rehydrate-builder'; -export { invokeHelper } from './lib/helpers/invoke'; - -export { default as fn } from './lib/helpers/fn'; -export { default as hash } from './lib/helpers/hash'; -export { default as array } from './lib/helpers/array'; -export { default as get } from './lib/helpers/get'; -export { default as concat } from './lib/helpers/concat'; - -export { default as on } from './lib/modifiers/on'; // Currently we need to re-export these values for @glimmer/component // https://github.com/glimmerjs/glimmer.js/issues/319 -export { destroy, registerDestructor, isDestroying, isDestroyed } from '@glimmer/destroyable'; +export { destroy, isDestroyed, isDestroying, registerDestructor } from '@glimmer/destroyable'; export type IteratorResult = RichIteratorResult; diff --git a/packages/@glimmer/runtime/lib/bounds.ts b/packages/@glimmer/runtime/lib/bounds.ts index e07c89716..12f678151 100644 --- a/packages/@glimmer/runtime/lib/bounds.ts +++ b/packages/@glimmer/runtime/lib/bounds.ts @@ -1,5 +1,4 @@ -import { Bounds, Cursor, Option } from '@glimmer/interfaces'; -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; +import { Bounds, Cursor, Option, SimpleElement, SimpleNode } from '@glimmer/interfaces'; import { expect } from '@glimmer/util'; export class CursorImpl implements Cursor { diff --git a/packages/@glimmer/runtime/lib/compat/svg-inner-html-fix.ts b/packages/@glimmer/runtime/lib/compat/svg-inner-html-fix.ts index d4250a752..92a09ea7d 100644 --- a/packages/@glimmer/runtime/lib/compat/svg-inner-html-fix.ts +++ b/packages/@glimmer/runtime/lib/compat/svg-inner-html-fix.ts @@ -1,12 +1,14 @@ -import { Bounds, Option } from '@glimmer/interfaces'; -import { assert, castToBrowser, clearElement, unwrap } from '@glimmer/util'; import { + Bounds, InsertPosition, Namespace, + Option, SimpleDocument, SimpleElement, SimpleNode, } from '@glimmer/interfaces'; +import { assert, castToBrowser, clearElement, unwrap } from '@glimmer/util'; + import { DOMOperations, moveNodesBefore } from '../dom/operations'; export const SVG_NAMESPACE = Namespace.SVG; @@ -37,7 +39,11 @@ export function applySVGInnerHTMLFix( let div = document.createElement('div') as SimpleElement; return class DOMChangesWithSVGInnerHTMLFix extends DOMClass { - insertHTMLBefore(parent: SimpleElement, nextSibling: Option, html: string): Bounds { + override insertHTMLBefore( + parent: SimpleElement, + nextSibling: Option, + html: string + ): Bounds { if (html === '') { return super.insertHTMLBefore(parent, nextSibling, html); } diff --git a/packages/@glimmer/runtime/lib/compat/text-node-merging-fix.ts b/packages/@glimmer/runtime/lib/compat/text-node-merging-fix.ts index fef16d484..112874351 100644 --- a/packages/@glimmer/runtime/lib/compat/text-node-merging-fix.ts +++ b/packages/@glimmer/runtime/lib/compat/text-node-merging-fix.ts @@ -1,11 +1,13 @@ -import { Bounds, Option } from '@glimmer/interfaces'; import { + Bounds, InsertPosition, + Option, SimpleComment, SimpleDocument, SimpleElement, SimpleNode, } from '@glimmer/interfaces'; + import { DOMOperations } from '../dom/operations'; // Patch: Adjacent text node merging fix @@ -38,7 +40,11 @@ export function applyTextNodeMergingFix( this.uselessComment = document.createComment(''); } - insertHTMLBefore(parent: SimpleElement, nextSibling: Option, html: string): Bounds { + override insertHTMLBefore( + parent: SimpleElement, + nextSibling: Option, + html: string + ): Bounds { if (html === '') { return super.insertHTMLBefore(parent, nextSibling, html); } diff --git a/packages/@glimmer/runtime/lib/compiled/expressions/concat.ts b/packages/@glimmer/runtime/lib/compiled/expressions/concat.ts index ab0328280..954e77ff2 100644 --- a/packages/@glimmer/runtime/lib/compiled/expressions/concat.ts +++ b/packages/@glimmer/runtime/lib/compiled/expressions/concat.ts @@ -1,12 +1,13 @@ import { Dict, Maybe } from '@glimmer/interfaces'; -import { Reference, valueForRef, createComputeRef } from '@glimmer/reference'; +import { createComputeRef, Reference, valueForRef } from '@glimmer/reference'; +import { enumerate } from '@glimmer/util'; export function createConcatRef(partsRefs: Reference[]) { return createComputeRef(() => { let parts = new Array(); - for (let i = 0; i < partsRefs.length; i++) { - let value = valueForRef(partsRefs[i]) as Maybe; + for (const [i, ref] of enumerate(partsRefs)) { + let value = valueForRef(ref) as Maybe; if (value !== null && value !== undefined) { parts[i] = castToString(value); diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/-debug-strip.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/-debug-strip.ts index c6be9faa5..7d56c9922 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/-debug-strip.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/-debug-strip.ts @@ -1,37 +1,38 @@ import { + CheckArray, CheckBlockSymbolTable, + CheckDict, Checker, CheckFunction, CheckHandle, CheckInstanceof, CheckInterface, CheckNumber, - CheckProgramSymbolTable, - CheckUnknown, - wrap, + CheckObject, CheckOption, CheckOr, - CheckArray, - CheckDict, - CheckObject, + CheckProgramSymbolTable, CheckString, + CheckUnknown, + wrap, } from '@glimmer/debug'; import { + CapturedArguments, CompilableBlock, + CompilableProgram, ComponentDefinition, - InternalComponentManager, + ComponentInstance, ElementOperations, - Invocation, - Scope, Helper, - CapturedArguments, + InternalComponentManager, + Invocation, Option, + Scope, ScopeBlock, - CompilableProgram, - ComponentInstance, } from '@glimmer/interfaces'; -import { Reference, REFERENCE, OpaqueIterator, UNDEFINED_REFERENCE } from '@glimmer/reference'; -import { Tag, COMPUTE } from '@glimmer/validator'; +import { OpaqueIterator, REFERENCE, Reference, UNDEFINED_REFERENCE } from '@glimmer/reference'; +import { COMPUTE, Tag } from '@glimmer/validator'; + import { PartialScopeImpl } from '../../scope'; import { VMArgumentsImpl } from '../../vm/arguments'; import { ComponentElementOperations } from './component'; diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts index 5d14e0d44..2a5ff7c57 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/component.ts @@ -4,39 +4,41 @@ import { CheckHandle, CheckInstanceof, CheckInterface, + CheckOr, CheckProgramSymbolTable, CheckString, - CheckOr, } from '@glimmer/debug'; +import { registerDestructor } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { Bounds, + CapturedArguments, + CompilableProgram, ComponentDefinition, - InternalComponentCapability, ComponentDefinitionState, + ComponentInstance, ComponentInstanceState, - InternalComponentManager, + ComponentInstanceWithCreate, + CurriedType, Dict, DynamicScope, ElementOperations, + InternalComponentCapability, + InternalComponentManager, + ModifierInstance, Op, Option, + Owner, ProgramSymbolTable, Recast, ScopeSlot, + UpdatingOpcode, VMArguments, WithDynamicTagName, WithElementHook, WithUpdateHook, - CapturedArguments, - CompilableProgram, - ComponentInstance, - ModifierInstance, - ComponentInstanceWithCreate, - Owner, - CurriedType, - UpdatingOpcode, } from '@glimmer/interfaces'; +import { managerHasCapability } from '@glimmer/manager'; import { isConstRef, Reference, valueForRef } from '@glimmer/reference'; import { assert, @@ -44,14 +46,21 @@ import { debugToString, dict, EMPTY_STRING_ARRAY, + enumerate, expect, + unwrap, unwrapTemplate, } from '@glimmer/util'; import { $t0, $t1 } from '@glimmer/vm'; -import { registerDestructor } from '@glimmer/destroyable'; -import { managerHasCapability } from '@glimmer/manager'; -import { resolveComponent } from '../../component/resolve'; + import { hasCustomDebugRenderTreeLifecycle } from '../../component/interfaces'; +import { resolveComponent } from '../../component/resolve'; +import { + CurriedValue, + isCurriedType, + isCurriedValue, + resolveCurriedValue, +} from '../../curried-value'; import { APPEND_OPCODES } from '../../opcodes'; import createClassListRef from '../../references/class-list'; import { ARGS, CONSTANTS } from '../../symbols'; @@ -62,18 +71,12 @@ import { CheckArguments, CheckComponentDefinition, CheckComponentInstance, + CheckCurriedComponentDefinition, CheckFinishedComponentInstance, CheckInvocation, CheckReference, - CheckCurriedComponentDefinition, } from './-debug-strip'; import { UpdateDynamicAttributeOpcode } from './dom'; -import { - CurriedValue, - isCurriedType, - isCurriedValue, - resolveCurriedValue, -} from '../../curried-value'; /** * The VM creates a new ComponentInstance data structure for every component @@ -333,7 +336,7 @@ APPEND_OPCODES.add(Op.PrepareArgs, (vm, { op1: _state }) => { let names = Object.keys(named); for (let i = 0; i < names.length; i++) { - stack.push(named[names[i]]); + stack.push(named[unwrap(names[i])]); } args.setup(stack, names, blockNames, positionalCount, false); @@ -501,7 +504,7 @@ export class ComponentElementOperations implements ElementOperations { continue; } - let attr = this.attributes[name]; + let attr = unwrap(this.attributes[name]); if (name === 'class') { setDeferredAttr(vm, 'class', mergeClasses(this.classes), attr.namespace, attr.trusting); } else { @@ -522,7 +525,7 @@ function mergeClasses(classes: (string | Reference)[]): string | Reference { let callerNames = args.named.atNames; for (let i = callerNames.length - 1; i >= 0; i--) { - let atName = callerNames[i]; - let symbol = state.table.symbols.indexOf(callerNames[i]); + let atName = unwrap(callerNames[i]); + let symbol = state.table.symbols.indexOf(atName); let value = args.named.get(atName, true); if (symbol !== -1) scope.bindSymbol(symbol + 1, value); @@ -813,8 +816,8 @@ APPEND_OPCODES.add(Op.SetBlocks, (vm, { op1: _state }) => { let state = check(vm.fetchValue(_state), CheckFinishedComponentInstance); let { blocks } = check(vm.stack.peek(), CheckArguments); - for (let i = 0; i < blocks.names.length; i++) { - bindBlock(blocks.symbolNames[i], blocks.names[i], state, blocks, vm); + for (const [i] of enumerate(blocks.names)) { + bindBlock(unwrap(blocks.symbolNames[i]), unwrap(blocks.names[i]), state, blocks, vm); } }); diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/content.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/content.ts index 35b9eb5ce..b4fe77c6d 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/content.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/content.ts @@ -1,22 +1,22 @@ -import { isConstRef, valueForRef } from '@glimmer/reference'; import { check, - CheckString, - CheckSafeString, - CheckNode, CheckDocumentFragment, + CheckNode, + CheckSafeString, + CheckString, } from '@glimmer/debug'; +import { DEBUG } from '@glimmer/env'; +import { ContentType, CurriedType, Op } from '@glimmer/interfaces'; +import { hasInternalComponentManager, hasInternalHelperManager } from '@glimmer/manager'; +import { isConstRef, valueForRef } from '@glimmer/reference'; import { isObject } from '@glimmer/util'; +import { isCurriedType } from '../../curried-value'; +import { isEmpty, isFragment, isNode, isSafeString, shouldCoerce } from '../../dom/normalize'; import { APPEND_OPCODES } from '../../opcodes'; -import { CheckReference } from './-debug-strip'; -import { isEmpty, isSafeString, isFragment, isNode, shouldCoerce } from '../../dom/normalize'; import DynamicTextContent from '../../vm/content/text'; -import { ContentType, CurriedType, Op } from '@glimmer/interfaces'; +import { CheckReference } from './-debug-strip'; import { AssertFilter } from './vm'; -import { hasInternalComponentManager, hasInternalHelperManager } from '@glimmer/manager'; -import { DEBUG } from '@glimmer/env'; -import { isCurriedType } from '../../curried-value'; function toContentType(value: unknown) { if (shouldCoerce(value)) { diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts index 84638fbaf..3c6b6975c 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/debugger.ts @@ -1,6 +1,7 @@ import { Op, Scope } from '@glimmer/interfaces'; -import { Reference, childRefFor, valueForRef } from '@glimmer/reference'; -import { dict, decodeHandle } from '@glimmer/util'; +import { childRefFor, Reference, valueForRef } from '@glimmer/reference'; +import { decodeHandle, dict, unwrap } from '@glimmer/util'; + import { APPEND_OPCODES } from '../../opcodes'; import { CONSTANTS } from '../../symbols'; @@ -35,9 +36,8 @@ class ScopeInspector { private locals = dict(); constructor(private scope: Scope, symbols: string[], debugInfo: number[]) { - for (let i = 0; i < debugInfo.length; i++) { - let slot = debugInfo[i]; - let name = symbols[slot - 1]; + for (const slot of debugInfo) { + let name = unwrap(symbols[slot - 1]); let ref = scope.getSymbol(slot); this.locals[name] = ref; } @@ -46,7 +46,7 @@ class ScopeInspector { get(path: string): Reference { let { scope, locals } = this; let parts = path.split('.'); - let [head, ...tail] = path.split('.'); + let [head, ...tail] = path.split('.') as [string, ...string[]]; let evalScope = scope.getEvalScope()!; let ref: Reference; @@ -54,7 +54,7 @@ class ScopeInspector { if (head === 'this') { ref = scope.getSelf(); } else if (locals[head]) { - ref = locals[head]; + ref = unwrap(locals[head]); } else if (head.indexOf('@') === 0 && evalScope[head]) { ref = evalScope[head] as Reference; } else { diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts index 92ddfaf89..d291d2a0b 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/dom.ts @@ -1,43 +1,44 @@ -import { Reference, valueForRef, isConstRef, createComputeRef } from '@glimmer/reference'; -import { - Revision, - Tag, - valueForTag, - validateTag, - consumeTag, - CURRENT_TAG, -} from '@glimmer/validator'; import { check, - CheckString, CheckElement, - CheckOption, - CheckNode, CheckMaybe, + CheckNode, + CheckOption, + CheckString, } from '@glimmer/debug'; +import { associateDestroyableChild, destroy } from '@glimmer/destroyable'; +import { DEBUG } from '@glimmer/env'; import { - Op, - Option, - ModifierDefinition, - ModifierInstance, - Owner, CapturedPositionalArguments, CurriedType, - ModifierDefinitionState, Environment, - UpdatingVM, + ModifierDefinition, + ModifierDefinitionState, + ModifierInstance, + Op, + Option, + Owner, UpdatingOpcode, + UpdatingVM, } from '@glimmer/interfaces'; +import { createComputeRef, isConstRef, Reference, valueForRef } from '@glimmer/reference'; +import { assign, debugToString, expect, isObject } from '@glimmer/util'; +import { + consumeTag, + CURRENT_TAG, + Revision, + Tag, + validateTag, + valueForTag, +} from '@glimmer/validator'; import { $t0 } from '@glimmer/vm'; + +import { CurriedValue, isCurriedType, resolveCurriedValue } from '../../curried-value'; import { APPEND_OPCODES } from '../../opcodes'; -import { Assert } from './vm'; -import { DynamicAttribute } from '../../vm/attributes/dynamic'; -import { CheckReference, CheckArguments, CheckOperations } from './-debug-strip'; import { CONSTANTS } from '../../symbols'; -import { assign, debugToString, expect, isObject } from '@glimmer/util'; -import { CurriedValue, isCurriedType, resolveCurriedValue } from '../../curried-value'; -import { DEBUG } from '@glimmer/env'; -import { associateDestroyableChild, destroy } from '@glimmer/destroyable'; +import { DynamicAttribute } from '../../vm/attributes/dynamic'; +import { CheckArguments, CheckOperations, CheckReference } from './-debug-strip'; +import { Assert } from './vm'; APPEND_OPCODES.add(Op.Text, (vm, { op1: text }) => { vm.elements().appendText(vm[CONSTANTS].getValue(text)); diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts index 70686f600..7553415ce 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/expressions.ts @@ -1,3 +1,14 @@ +import { + check, + CheckBlockSymbolTable, + CheckHandle, + CheckMaybe, + CheckOption, + CheckOr, +} from '@glimmer/debug'; +import { _hasDestroyableChildren, associateDestroyableChild, destroy } from '@glimmer/destroyable'; +import { DEBUG } from '@glimmer/env'; +import { toBool } from '@glimmer/global-context'; import { CapturedPositionalArguments, CurriedType, @@ -11,43 +22,33 @@ import { VM as PublicVM, } from '@glimmer/interfaces'; import { - Reference, childRefFor, - UNDEFINED_REFERENCE, - TRUE_REFERENCE, + createComputeRef, FALSE_REFERENCE, + Reference, + TRUE_REFERENCE, + UNDEFINED_REFERENCE, valueForRef, - createComputeRef, } from '@glimmer/reference'; +import { assert, assign, debugToString, decodeHandle, isObject } from '@glimmer/util'; import { $v0 } from '@glimmer/vm'; + +import { isCurriedType, resolveCurriedValue } from '../../curried-value'; import { APPEND_OPCODES } from '../../opcodes'; +import createCurryRef from '../../references/curry-value'; +import { CONSTANTS } from '../../symbols'; +import { reifyPositional } from '../../vm/arguments'; import { createConcatRef } from '../expressions/concat'; -import { associateDestroyableChild, destroy, _hasDestroyableChildren } from '@glimmer/destroyable'; -import { assert, assign, debugToString, decodeHandle, isObject } from '@glimmer/util'; -import { toBool } from '@glimmer/global-context'; -import { - check, - CheckOption, - CheckHandle, - CheckBlockSymbolTable, - CheckOr, - CheckMaybe, -} from '@glimmer/debug'; import { CheckArguments, - CheckReference, + CheckCapturedArguments, CheckCompilableBlock, - CheckScope, CheckHelper, - CheckUndefinedReference, + CheckReference, + CheckScope, CheckScopeBlock, - CheckCapturedArguments, + CheckUndefinedReference, } from './-debug-strip'; -import { CONSTANTS } from '../../symbols'; -import { DEBUG } from '@glimmer/env'; -import createCurryRef from '../../references/curry-value'; -import { isCurriedType, resolveCurriedValue } from '../../curried-value'; -import { reifyPositional } from '../../vm/arguments'; export type FunctionExpression = (vm: PublicVM) => Reference; diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/lists.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/lists.ts index 5c20757f5..10a34b7f5 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/lists.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/lists.ts @@ -1,8 +1,9 @@ -import { createIteratorRef, valueForRef } from '@glimmer/reference'; -import { APPEND_OPCODES } from '../../opcodes'; -import { CheckReference, CheckIterator } from './-debug-strip'; import { check } from '@glimmer/debug'; import { Op } from '@glimmer/interfaces'; +import { createIteratorRef, valueForRef } from '@glimmer/reference'; + +import { APPEND_OPCODES } from '../../opcodes'; +import { CheckIterator, CheckReference } from './-debug-strip'; import { AssertFilter } from './vm'; APPEND_OPCODES.add(Op.EnterList, (vm, { op1: relativeStart, op2: elseTarget }) => { diff --git a/packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts b/packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts index ce09a2ab9..3f9dc6a7e 100644 --- a/packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts +++ b/packages/@glimmer/runtime/lib/compiled/opcodes/vm.ts @@ -1,45 +1,46 @@ +import { + check, + CheckBlockSymbolTable, + CheckHandle, + CheckInstanceof, + CheckNumber, + CheckOption, + CheckPrimitive, +} from '@glimmer/debug'; import { toBool } from '@glimmer/global-context'; -import { CompilableTemplate, Option, Op, UpdatingOpcode } from '@glimmer/interfaces'; +import { CompilableTemplate, Op, Option, UpdatingOpcode } from '@glimmer/interfaces'; import { - Reference, - valueForRef, - isConstRef, + createComputeRef, + createConstRef, createPrimitiveRef, - UNDEFINED_REFERENCE, + FALSE_REFERENCE, + isConstRef, NULL_REFERENCE, + Reference, TRUE_REFERENCE, - FALSE_REFERENCE, - createComputeRef, - createConstRef, + UNDEFINED_REFERENCE, + valueForRef, } from '@glimmer/reference'; +import { assert, decodeHandle, decodeImmediate, expect, isHandle, unwrap } from '@glimmer/util'; import { + beginTrackFrame, CONSTANT_TAG, + consumeTag, + endTrackFrame, + INITIAL, Revision, Tag, - valueForTag, validateTag, - INITIAL, - beginTrackFrame, - endTrackFrame, - consumeTag, + valueForTag, } from '@glimmer/validator'; -import { assert, decodeHandle, decodeImmediate, expect, isHandle } from '@glimmer/util'; -import { - CheckNumber, - check, - CheckInstanceof, - CheckOption, - CheckBlockSymbolTable, - CheckHandle, - CheckPrimitive, -} from '@glimmer/debug'; -import { stackAssert } from './assert'; + import { APPEND_OPCODES } from '../../opcodes'; +import { CONSTANTS } from '../../symbols'; import { UpdatingVM } from '../../vm'; +import { InternalVM } from '../../vm/append'; import { VMArgumentsImpl } from '../../vm/arguments'; import { CheckReference, CheckScope } from './-debug-strip'; -import { CONSTANTS } from '../../symbols'; -import { InternalVM } from '../../vm/append'; +import { stackAssert } from './assert'; APPEND_OPCODES.add(Op.ChildScope, (vm) => vm.pushChildScope()); @@ -174,7 +175,7 @@ APPEND_OPCODES.add(Op.InvokeYield, (vm) => { invokingScope = invokingScope.child(); for (let i = 0; i < localsCount; i++) { - invokingScope.bindSymbol(locals![i], args.at(i)); + invokingScope.bindSymbol(unwrap(locals[i]), args.at(i)); } } } diff --git a/packages/@glimmer/runtime/lib/component/resolve.ts b/packages/@glimmer/runtime/lib/component/resolve.ts index 47be5e8d1..db6cd66e4 100644 --- a/packages/@glimmer/runtime/lib/component/resolve.ts +++ b/packages/@glimmer/runtime/lib/component/resolve.ts @@ -3,8 +3,8 @@ import { ComponentDefinition, Option, Owner, - RuntimeResolver, ResolutionTimeConstants, + RuntimeResolver, } from '@glimmer/interfaces'; import { expect } from '@glimmer/util'; diff --git a/packages/@glimmer/runtime/lib/component/template-only.ts b/packages/@glimmer/runtime/lib/component/template-only.ts index a75e52633..eafbe3b37 100644 --- a/packages/@glimmer/runtime/lib/component/template-only.ts +++ b/packages/@glimmer/runtime/lib/component/template-only.ts @@ -1,6 +1,6 @@ import { InternalComponentCapabilities, InternalComponentManager } from '@glimmer/interfaces'; -import { NULL_REFERENCE, Reference } from '@glimmer/reference'; import { setInternalComponentManager } from '@glimmer/manager'; +import { NULL_REFERENCE, Reference } from '@glimmer/reference'; const CAPABILITIES: InternalComponentCapabilities = { dynamicLayout: false, diff --git a/packages/@glimmer/runtime/lib/curried-value.ts b/packages/@glimmer/runtime/lib/curried-value.ts index 321b531cd..44b531407 100644 --- a/packages/@glimmer/runtime/lib/curried-value.ts +++ b/packages/@glimmer/runtime/lib/curried-value.ts @@ -1,6 +1,6 @@ import { CapturedArguments, CurriedType, Owner } from '@glimmer/interfaces'; -import { symbol, _WeakSet } from '@glimmer/util'; import { Reference } from '@glimmer/reference'; +import { _WeakSet, symbol } from '@glimmer/util'; const TYPE: unique symbol = symbol('TYPE'); const INNER: unique symbol = symbol('INNER'); diff --git a/packages/@glimmer/runtime/lib/debug-render-tree.ts b/packages/@glimmer/runtime/lib/debug-render-tree.ts index e7108dd53..6e46d3601 100644 --- a/packages/@glimmer/runtime/lib/debug-render-tree.ts +++ b/packages/@glimmer/runtime/lib/debug-render-tree.ts @@ -6,7 +6,8 @@ import { Option, RenderNode, } from '@glimmer/interfaces'; -import { expect, assign, Stack } from '@glimmer/util'; +import { assign, expect, Stack } from '@glimmer/util'; + import { reifyArgs } from './vm/arguments'; interface InternalRenderNode extends RenderNode { diff --git a/packages/@glimmer/runtime/lib/dom/helper.ts b/packages/@glimmer/runtime/lib/dom/helper.ts index cdde0c496..e1c55d404 100644 --- a/packages/@glimmer/runtime/lib/dom/helper.ts +++ b/packages/@glimmer/runtime/lib/dom/helper.ts @@ -1,13 +1,16 @@ -import { GlimmerTreeChanges, GlimmerTreeConstruction, Option } from '@glimmer/interfaces'; -import { castToSimple } from '@glimmer/util'; import { AttrNamespace, ElementNamespace, + GlimmerTreeChanges, + GlimmerTreeConstruction, Namespace, + Option, SimpleDocument, SimpleElement, SimpleNode, } from '@glimmer/interfaces'; +import { castToSimple } from '@glimmer/util'; + import { applySVGInnerHTMLFix } from '../compat/svg-inner-html-fix'; import { applyTextNodeMergingFix } from '../compat/text-node-merging-fix'; import { BLACKLIST_TABLE, DOMOperations } from './operations'; @@ -105,7 +108,7 @@ export namespace DOM { export class DOMChangesImpl extends DOMOperations implements GlimmerTreeChanges { protected namespace: Option; - constructor(protected document: SimpleDocument) { + constructor(protected override document: SimpleDocument) { super(document); this.namespace = null; } diff --git a/packages/@glimmer/runtime/lib/dom/normalize.ts b/packages/@glimmer/runtime/lib/dom/normalize.ts index 34e5f1412..905f62e18 100644 --- a/packages/@glimmer/runtime/lib/dom/normalize.ts +++ b/packages/@glimmer/runtime/lib/dom/normalize.ts @@ -1,5 +1,4 @@ -import { Dict } from '@glimmer/interfaces'; -import { SimpleNode, SimpleDocumentFragment } from '@glimmer/interfaces'; +import { Dict, SimpleDocumentFragment, SimpleNode } from '@glimmer/interfaces'; export interface SafeString { toHTML(): string; diff --git a/packages/@glimmer/runtime/lib/dom/operations.ts b/packages/@glimmer/runtime/lib/dom/operations.ts index 5544ae0db..7c7e64e1a 100644 --- a/packages/@glimmer/runtime/lib/dom/operations.ts +++ b/packages/@glimmer/runtime/lib/dom/operations.ts @@ -1,16 +1,19 @@ import { - SimpleElement, - SimpleDocument, + Bounds, + Dict, + InsertPosition, Namespace, + Option, + SimpleComment, + SimpleDocument, + SimpleElement, SimpleNode, - InsertPosition, SimpleText, - SimpleComment, } from '@glimmer/interfaces'; -import { Dict, Option, Bounds } from '@glimmer/interfaces'; -import { ConcreteBounds } from '../bounds'; import { expect } from '@glimmer/util'; +import { ConcreteBounds } from '../bounds'; + // http://www.w3.org/TR/html/syntax.html#html-integration-point const SVG_INTEGRATION_POINTS = { foreignObject: 1, desc: 1, title: 1 }; diff --git a/packages/@glimmer/runtime/lib/dom/props.ts b/packages/@glimmer/runtime/lib/dom/props.ts index 8b1c2acce..a1a69741a 100644 --- a/packages/@glimmer/runtime/lib/dom/props.ts +++ b/packages/@glimmer/runtime/lib/dom/props.ts @@ -1,5 +1,4 @@ -import { Dict } from '@glimmer/interfaces'; -import { SimpleElement } from '@glimmer/interfaces'; +import { Dict, SimpleElement } from '@glimmer/interfaces'; /* * @method normalizeProperty diff --git a/packages/@glimmer/runtime/lib/dom/sanitized-values.ts b/packages/@glimmer/runtime/lib/dom/sanitized-values.ts index 4003693b2..1aa5e41e8 100644 --- a/packages/@glimmer/runtime/lib/dom/sanitized-values.ts +++ b/packages/@glimmer/runtime/lib/dom/sanitized-values.ts @@ -1,5 +1,5 @@ -import { Option } from '@glimmer/interfaces'; -import { SimpleElement } from '@glimmer/interfaces'; +import { Option, SimpleElement } from '@glimmer/interfaces'; + import { isSafeString, normalizeStringValue } from '../dom/normalize'; const badProtocols = ['javascript:', 'vbscript:']; diff --git a/packages/@glimmer/runtime/lib/environment.ts b/packages/@glimmer/runtime/lib/environment.ts index c31bcd3af..eb08ae430 100644 --- a/packages/@glimmer/runtime/lib/environment.ts +++ b/packages/@glimmer/runtime/lib/environment.ts @@ -1,25 +1,24 @@ import { DEBUG } from '@glimmer/env'; import { + ComponentInstanceWithCreate, Environment, EnvironmentOptions, GlimmerTreeChanges, GlimmerTreeConstruction, - Transaction, - TransactionSymbol, - RuntimeContext, - RuntimeResolver, + ModifierInstance, Option, RuntimeArtifacts, - ComponentInstanceWithCreate, - ModifierInstance, - InternalModifierManager, - ModifierInstanceState, + RuntimeContext, + RuntimeResolver, + Transaction, + TransactionSymbol, } from '@glimmer/interfaces'; +import { RuntimeProgramImpl } from '@glimmer/program'; import { assert, expect, symbol } from '@glimmer/util'; import { track, updateTag } from '@glimmer/validator'; -import { DOMChangesImpl, DOMTreeConstruction } from './dom/helper'; -import { RuntimeProgramImpl } from '@glimmer/program'; + import DebugRenderTree from './debug-render-tree'; +import { DOMChangesImpl, DOMTreeConstruction } from './dom/helper'; export const TRANSACTION: TransactionSymbol = symbol('TRANSACTION'); @@ -48,27 +47,17 @@ class TransactionImpl implements Transaction { commit() { let { createdComponents, updatedComponents } = this; - for (let i = 0; i < createdComponents.length; i++) { - let { manager, state } = createdComponents[i]; + for (const { manager, state } of createdComponents) { manager.didCreate(state); } - for (let i = 0; i < updatedComponents.length; i++) { - let { manager, state } = updatedComponents[i]; + for (const { manager, state } of updatedComponents) { manager.didUpdate(state); } let { scheduledInstallModifiers, scheduledUpdateModifiers } = this; - // Prevent a transpilation issue we guard against in Ember, the - // throw-if-closure-required issue - let manager: InternalModifierManager, state: ModifierInstanceState; - - for (let i = 0; i < scheduledInstallModifiers.length; i++) { - let modifier = scheduledInstallModifiers[i]; - manager = modifier.manager; - state = modifier.state; - + for (const { manager, state, definition } of scheduledInstallModifiers) { let modifierTag = manager.getTag(state); if (modifierTag !== null) { @@ -77,7 +66,7 @@ class TransactionImpl implements Transaction { () => manager.install(state), DEBUG && `- While rendering:\n (instance of a \`${ - modifier.definition.resolvedName || manager.getDebugName(modifier.definition.state) + definition.resolvedName || manager.getDebugName(definition.state) }\` modifier)` ); updateTag(modifierTag, tag); @@ -86,11 +75,7 @@ class TransactionImpl implements Transaction { } } - for (let i = 0; i < scheduledUpdateModifiers.length; i++) { - let modifier = scheduledUpdateModifiers[i]; - manager = modifier.manager; - state = modifier.state; - + for (const { manager, state, definition } of scheduledUpdateModifiers) { let modifierTag = manager.getTag(state); if (modifierTag !== null) { @@ -99,7 +84,7 @@ class TransactionImpl implements Transaction { () => manager.update(state), DEBUG && `- While rendering:\n (instance of a \`${ - modifier.definition.resolvedName || manager.getDebugName(modifier.definition.state) + definition.resolvedName || manager.getDebugName(definition.state) }\` modifier)` ); updateTag(modifierTag, tag); @@ -221,16 +206,16 @@ export function runtimeContext( }; } -export function inTransaction(env: Environment, cb: () => void): void { +export function inTransaction(env: Environment, block: () => void): void { if (!env[TRANSACTION]) { env.begin(); try { - cb(); + block(); } finally { env.commit(); } } else { - cb(); + block(); } } diff --git a/packages/@glimmer/runtime/lib/helpers/array.ts b/packages/@glimmer/runtime/lib/helpers/array.ts index a7dfd90da..1a9d81228 100644 --- a/packages/@glimmer/runtime/lib/helpers/array.ts +++ b/packages/@glimmer/runtime/lib/helpers/array.ts @@ -1,7 +1,8 @@ import { CapturedArguments } from '@glimmer/interfaces'; import { createComputeRef, Reference } from '@glimmer/reference'; -import { internalHelper } from './internal-helper'; + import { reifyPositional } from '../vm/arguments'; +import { internalHelper } from './internal-helper'; /** Use the `{{array}}` helper to create an array to pass as an option to your diff --git a/packages/@glimmer/runtime/lib/helpers/concat.ts b/packages/@glimmer/runtime/lib/helpers/concat.ts index 7615cb28d..6061d31da 100644 --- a/packages/@glimmer/runtime/lib/helpers/concat.ts +++ b/packages/@glimmer/runtime/lib/helpers/concat.ts @@ -1,7 +1,8 @@ import { CapturedArguments } from '@glimmer/interfaces'; import { createComputeRef } from '@glimmer/reference'; -import { internalHelper } from './internal-helper'; + import { reifyPositional } from '../vm/arguments'; +import { internalHelper } from './internal-helper'; const isEmpty = (value: unknown): boolean => { return value === null || value === undefined || typeof (value as object).toString !== 'function'; diff --git a/packages/@glimmer/runtime/lib/helpers/fn.ts b/packages/@glimmer/runtime/lib/helpers/fn.ts index 0d07c65ce..c7ea44101 100644 --- a/packages/@glimmer/runtime/lib/helpers/fn.ts +++ b/packages/@glimmer/runtime/lib/helpers/fn.ts @@ -1,3 +1,4 @@ +import { check } from '@glimmer/debug'; import { DEBUG } from '@glimmer/env'; import { CapturedArguments } from '@glimmer/interfaces'; import { @@ -8,8 +9,9 @@ import { valueForRef, } from '@glimmer/reference'; import { buildUntouchableThis } from '@glimmer/util'; -import { internalHelper } from './internal-helper'; + import { reifyPositional } from '../vm/arguments'; +import { internalHelper } from './internal-helper'; const context = buildUntouchableThis('`fn` helper'); @@ -78,9 +80,7 @@ const context = buildUntouchableThis('`fn` helper'); @public */ export default internalHelper(({ positional }: CapturedArguments) => { - let callbackRef = positional[0]; - - if (DEBUG) assertCallbackIsFn(callbackRef); + let callbackRef = check(positional[0], assertCallbackIsFn); return createComputeRef( () => { @@ -102,7 +102,7 @@ export default internalHelper(({ positional }: CapturedArguments) => { ); }); -function assertCallbackIsFn(callbackRef: Reference) { +function assertCallbackIsFn(callbackRef: Reference | undefined): asserts callbackRef is Reference { if ( !( callbackRef && diff --git a/packages/@glimmer/runtime/lib/helpers/get.ts b/packages/@glimmer/runtime/lib/helpers/get.ts index 741a98453..4dfec875f 100644 --- a/packages/@glimmer/runtime/lib/helpers/get.ts +++ b/packages/@glimmer/runtime/lib/helpers/get.ts @@ -1,7 +1,8 @@ import { getPath, setPath } from '@glimmer/global-context'; -import { isDict } from '@glimmer/util'; import { CapturedArguments } from '@glimmer/interfaces'; import { createComputeRef, UNDEFINED_REFERENCE, valueForRef } from '@glimmer/reference'; +import { isDict } from '@glimmer/util'; + import { internalHelper } from './internal-helper'; /** diff --git a/packages/@glimmer/runtime/lib/helpers/hash.ts b/packages/@glimmer/runtime/lib/helpers/hash.ts index c30845232..3b01170b0 100644 --- a/packages/@glimmer/runtime/lib/helpers/hash.ts +++ b/packages/@glimmer/runtime/lib/helpers/hash.ts @@ -1,10 +1,11 @@ +import { DEBUG } from '@glimmer/env'; +import { deprecate } from '@glimmer/global-context'; import { CapturedArguments, Dict } from '@glimmer/interfaces'; import { createComputeRef, Reference } from '@glimmer/reference'; -import { deprecate } from '@glimmer/global-context'; import { HAS_NATIVE_PROXY } from '@glimmer/util'; -import { internalHelper } from './internal-helper'; -import { DEBUG } from '@glimmer/env'; + import { reifyNamed } from '../vm/arguments'; +import { internalHelper } from './internal-helper'; let wrapHashProxy: (hash: Record) => Record; diff --git a/packages/@glimmer/runtime/lib/helpers/invoke.ts b/packages/@glimmer/runtime/lib/helpers/invoke.ts index 11e5e054c..9891c7725 100644 --- a/packages/@glimmer/runtime/lib/helpers/invoke.ts +++ b/packages/@glimmer/runtime/lib/helpers/invoke.ts @@ -1,12 +1,12 @@ +import { associateDestroyableChild, isDestroyed, isDestroying } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; -import { Cache, createCache, getValue } from '@glimmer/validator'; import { Arguments, InternalHelperManager } from '@glimmer/interfaces'; -import { debugToString } from '@glimmer/util'; import { getInternalHelperManager, hasDestroyable, hasValue } from '@glimmer/manager'; +import { getOwner } from '@glimmer/owner'; +import { debugToString } from '@glimmer/util'; +import { Cache, createCache, getValue } from '@glimmer/validator'; import { EMPTY_ARGS, EMPTY_NAMED, EMPTY_POSITIONAL } from '../vm/arguments'; -import { getOwner } from '@glimmer/owner'; -import { associateDestroyableChild, isDestroyed, isDestroying } from '@glimmer/destroyable'; let ARGS_CACHES = DEBUG ? new WeakMap>>() : undefined; diff --git a/packages/@glimmer/runtime/lib/modifiers/on.ts b/packages/@glimmer/runtime/lib/modifiers/on.ts index 6def339a1..d4e859ac8 100644 --- a/packages/@glimmer/runtime/lib/modifiers/on.ts +++ b/packages/@glimmer/runtime/lib/modifiers/on.ts @@ -1,3 +1,4 @@ +import { check, CheckFunction, CheckString } from '@glimmer/debug'; import { registerDestructor } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { @@ -8,8 +9,9 @@ import { } from '@glimmer/interfaces'; import { setInternalModifierManager } from '@glimmer/manager'; import { valueForRef } from '@glimmer/reference'; +import { buildUntouchableThis, expect } from '@glimmer/util'; import { createUpdatableTag, UpdatableTag } from '@glimmer/validator'; -import { buildUntouchableThis } from '@glimmer/util'; + import { reifyNamed } from '../vm/arguments'; const untouchableContext = buildUntouchableThis('`on` modifier'); @@ -95,40 +97,37 @@ export class OnModifierState { this.options = undefined; } - if ( - DEBUG && - (args.positional[0] === undefined || typeof valueForRef(args.positional[0]) !== 'string') - ) { - throw new Error( - 'You must pass a valid DOM event name as the first argument to the `on` modifier' - ); - } + let first = expect( + args.positional[0], + 'You must pass a valid DOM event name as the first argument to the `on` modifier' + ); + + let eventName = check( + valueForRef(first), + CheckString, + () => 'You must pass a valid DOM event name as the first argument to the `on` modifier' + ); - let eventName = valueForRef(args.positional[0]) as string; if (eventName !== this.eventName) { this.eventName = eventName; this.shouldUpdate = true; } - let userProvidedCallbackReference = args.positional[1]; - - if (DEBUG) { - if (args.positional[1] === undefined) { - throw new Error(`You must pass a function as the second argument to the \`on\` modifier.`); + const userProvidedCallbackReference = expect( + args.positional[1], + 'You must pass a function as the second argument to the `on` modifier' + ); + + const userProvidedCallback = check( + valueForRef(userProvidedCallbackReference), + CheckFunction, + (actual) => { + return `You must pass a function as the second argument to the \`on\` modifier; you passed ${ + actual === null ? 'null' : typeof actual + }. While rendering:\n\n${userProvidedCallbackReference.debugLabel}`; } + ) as EventListener; - let value = valueForRef(userProvidedCallbackReference); - - if (typeof value !== 'function') { - throw new Error( - `You must pass a function as the second argument to the \`on\` modifier; you passed ${ - value === null ? 'null' : typeof value - }. While rendering:\n\n${userProvidedCallbackReference.debugLabel}` - ); - } - } - - let userProvidedCallback = valueForRef(userProvidedCallbackReference) as EventListener; if (userProvidedCallback !== this.userProvidedCallback) { this.userProvidedCallback = userProvidedCallback; this.shouldUpdate = true; diff --git a/packages/@glimmer/runtime/lib/opcodes.ts b/packages/@glimmer/runtime/lib/opcodes.ts index cd7fbb9b0..9517d0d40 100644 --- a/packages/@glimmer/runtime/lib/opcodes.ts +++ b/packages/@glimmer/runtime/lib/opcodes.ts @@ -2,8 +2,9 @@ import { debug, logOpcode, opcodeMetadata, recordStackSize } from '@glimmer/debu import { Dict, Maybe, Op, Option, RuntimeOp } from '@glimmer/interfaces'; import { LOCAL_DEBUG, LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; import { valueForRef } from '@glimmer/reference'; -import { assert, fillNulls, LOCAL_LOGGER } from '@glimmer/util'; +import { assert, fillNulls, LOCAL_LOGGER, unwrap } from '@glimmer/util'; import { $fp, $pc, $ra, $sp } from '@glimmer/vm'; + import { isScopeReference } from './scope'; import { CONSTANTS, DESTROYABLE_STACK, INNER_VM, STACKS } from './symbols'; import { LowLevelVM, VM } from './vm'; @@ -155,7 +156,7 @@ export class AppendOpcodes { } evaluate(vm: VM, opcode: RuntimeOp, type: number) { - let operation = this.evaluateOpcode[type]; + let operation = unwrap(this.evaluateOpcode[type]); if (operation.syscall) { assert( diff --git a/packages/@glimmer/runtime/lib/references/class-list.ts b/packages/@glimmer/runtime/lib/references/class-list.ts index e160fec18..acb47e982 100644 --- a/packages/@glimmer/runtime/lib/references/class-list.ts +++ b/packages/@glimmer/runtime/lib/references/class-list.ts @@ -1,4 +1,4 @@ -import { Reference, createComputeRef, valueForRef } from '@glimmer/reference'; +import { createComputeRef, Reference, valueForRef } from '@glimmer/reference'; import { normalizeStringValue } from '../dom/normalize'; @@ -6,9 +6,8 @@ export default function createClassListRef(list: Reference[]) { return createComputeRef(() => { let ret: string[] = []; - for (let i = 0; i < list.length; i++) { - let ref = list[i]; - let value = normalizeStringValue(typeof ref === 'string' ? ref : valueForRef(list[i])); + for (const ref of list) { + let value = normalizeStringValue(typeof ref === 'string' ? ref : valueForRef(ref)); if (value) ret.push(value); } diff --git a/packages/@glimmer/runtime/lib/references/curry-value.ts b/packages/@glimmer/runtime/lib/references/curry-value.ts index e6598a92c..e2c65c630 100644 --- a/packages/@glimmer/runtime/lib/references/curry-value.ts +++ b/packages/@glimmer/runtime/lib/references/curry-value.ts @@ -10,6 +10,7 @@ import { } from '@glimmer/interfaces'; import { createComputeRef, Reference, valueForRef } from '@glimmer/reference'; import { expect, isObject } from '@glimmer/util'; + import { curry, isCurriedType } from '../curried-value'; export default function createCurryRef( diff --git a/packages/@glimmer/runtime/lib/render.ts b/packages/@glimmer/runtime/lib/render.ts index 1a2b8307d..d59b3c5ed 100644 --- a/packages/@glimmer/runtime/lib/render.ts +++ b/packages/@glimmer/runtime/lib/render.ts @@ -1,24 +1,25 @@ +import { DEBUG } from '@glimmer/env'; import { + CompilableProgram, + CompileTimeCompilationContext, + ComponentDefinitionState, DynamicScope, + ElementBuilder, Environment, + Owner, RenderResult, RichIteratorResult, - TemplateIterator, RuntimeContext, - ElementBuilder, - CompilableProgram, - CompileTimeCompilationContext, - ComponentDefinitionState, - Owner, + TemplateIterator, } from '@glimmer/interfaces'; import { childRefFor, createConstRef, Reference } from '@glimmer/reference'; import { expect, unwrapHandle } from '@glimmer/util'; +import { runInTrackingTransaction } from '@glimmer/validator'; + +import { inTransaction } from './environment'; +import { DynamicScopeImpl } from './scope'; import { ARGS, CONSTANTS } from './symbols'; import VM, { InternalVM } from './vm/append'; -import { DynamicScopeImpl } from './scope'; -import { inTransaction } from './environment'; -import { DEBUG } from '@glimmer/env'; -import { runInTrackingTransaction } from '@glimmer/validator'; class TemplateIteratorImpl implements TemplateIterator { constructor(private vm: InternalVM) {} diff --git a/packages/@glimmer/runtime/lib/scope.ts b/packages/@glimmer/runtime/lib/scope.ts index f2af0668d..675d8d83c 100644 --- a/packages/@glimmer/runtime/lib/scope.ts +++ b/packages/@glimmer/runtime/lib/scope.ts @@ -1,15 +1,15 @@ import { - DynamicScope, Dict, - PartialScope, - ScopeSlot, - ScopeBlock, + DynamicScope, Option, - Scope, Owner, + PartialScope, + Scope, + ScopeBlock, + ScopeSlot, } from '@glimmer/interfaces'; -import { assign } from '@glimmer/util'; import { Reference, UNDEFINED_REFERENCE } from '@glimmer/reference'; +import { assign, unwrap } from '@glimmer/util'; export class DynamicScopeImpl implements DynamicScope { private bucket: Dict; @@ -23,7 +23,7 @@ export class DynamicScopeImpl implements DynamicScope { } get(key: string): Reference { - return this.bucket[key]; + return unwrap(this.bucket[key]); } set(key: string, reference: Reference): Reference { diff --git a/packages/@glimmer/runtime/lib/vm.ts b/packages/@glimmer/runtime/lib/vm.ts index 39ac13672..e56c8c010 100644 --- a/packages/@glimmer/runtime/lib/vm.ts +++ b/packages/@glimmer/runtime/lib/vm.ts @@ -1,3 +1,3 @@ -export { default as VM, InternalVM } from './vm/append'; +export { InternalVM, default as VM } from './vm/append'; export { default as LowLevelVM } from './vm/low-level'; export { default as UpdatingVM } from './vm/update'; diff --git a/packages/@glimmer/runtime/lib/vm/append.ts b/packages/@glimmer/runtime/lib/vm/append.ts index 57cbc8966..1345a38e5 100644 --- a/packages/@glimmer/runtime/lib/vm/append.ts +++ b/packages/@glimmer/runtime/lib/vm/append.ts @@ -1,25 +1,26 @@ +import { associateDestroyableChild } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { assertGlobalContextWasSet } from '@glimmer/global-context'; import { CompilableTemplate, + CompileTimeCompilationContext, Destroyable, DynamicScope, ElementBuilder, Environment, Option, + Owner, PartialScope, RenderResult, + ResolutionTimeConstants, RichIteratorResult, RuntimeConstants, RuntimeContext, RuntimeHeap, RuntimeProgram, Scope, - CompileTimeCompilationContext, - VM as PublicVM, - ResolutionTimeConstants, - Owner, UpdatingOpcode, + VM as PublicVM, } from '@glimmer/interfaces'; import { LOCAL_SHOULD_LOG } from '@glimmer/local-debug-flags'; import { RuntimeOpImpl } from '@glimmer/program'; @@ -30,7 +31,7 @@ import { Reference, UNDEFINED_REFERENCE, } from '@glimmer/reference'; -import { assert, expect, LOCAL_LOGGER, Stack, unwrapHandle } from '@glimmer/util'; +import { assert, expect, LOCAL_LOGGER, reverse, Stack, unwrapHandle } from '@glimmer/util'; import { beginTrackFrame, endTrackFrame, resetTracking } from '@glimmer/validator'; import { $fp, @@ -46,7 +47,7 @@ import { Register, SyscallRegister, } from '@glimmer/vm'; -import { associateDestroyableChild } from '@glimmer/destroyable'; + import { BeginTrackFrameOpcode, EndTrackFrameOpcode, @@ -628,8 +629,7 @@ export default class VM implements PublicVM, InternalVM { bindDynamicScope(names: string[]) { let scope = this.dynamicScope(); - for (let i = names.length - 1; i >= 0; i--) { - let name = names[i]; + for (const name of reverse(names)) { scope.set(name, this.stack.pop>()); } } diff --git a/packages/@glimmer/runtime/lib/vm/arguments.ts b/packages/@glimmer/runtime/lib/vm/arguments.ts index bd3315492..9902453eb 100644 --- a/packages/@glimmer/runtime/lib/vm/arguments.ts +++ b/packages/@glimmer/runtime/lib/vm/arguments.ts @@ -23,9 +23,10 @@ import { UNDEFINED_REFERENCE, valueForRef, } from '@glimmer/reference'; -import { dict, emptyArray, EMPTY_STRING_ARRAY } from '@glimmer/util'; +import { dict, EMPTY_STRING_ARRAY, emptyArray, enumerate, unwrap } from '@glimmer/util'; import { CONSTANT_TAG, Tag } from '@glimmer/validator'; import { $sp } from '@glimmer/vm'; + import { CheckCompilableBlock, CheckReference, CheckScope } from '../compiled/opcodes/-debug-strip'; import { REGISTERS } from '../symbols'; import { EvaluationStack } from './stack'; @@ -301,13 +302,11 @@ export class NamedArgumentsImpl implements NamedArguments { let { names, references } = this; let map = dict(); - for (let i = 0; i < names.length; i++) { - let name = names[i]; - + for (const [i, name] of enumerate(names)) { if (DEBUG) { - map[name] = createDebugAliasRef!(`@${name}`, references[i]); + map[name] = createDebugAliasRef!(`@${name}`, unwrap(references[i])); } else { - map[name] = references[i]; + map[name] = unwrap(references[i]); } } @@ -321,8 +320,7 @@ export class NamedArgumentsImpl implements NamedArguments { let { names, length, stack } = this; let newNames = names.slice(); - for (let i = 0; i < keys.length; i++) { - let name = keys[i]; + for (const name of keys) { let idx = newNames.indexOf(name); if (idx === -1) { @@ -485,8 +483,8 @@ export function createCapturedArgs(named: Dict, positional: Reference export function reifyNamed(named: CapturedNamedArguments) { let reified = dict(); - for (let key in named) { - reified[key] = valueForRef(named[key]); + for (const [key, value] of Object.entries(named)) { + reified[key] = valueForRef(value); } return reified; diff --git a/packages/@glimmer/runtime/lib/vm/attributes/dynamic.ts b/packages/@glimmer/runtime/lib/vm/attributes/dynamic.ts index 9989e644c..79df2e6d0 100644 --- a/packages/@glimmer/runtime/lib/vm/attributes/dynamic.ts +++ b/packages/@glimmer/runtime/lib/vm/attributes/dynamic.ts @@ -1,18 +1,21 @@ +import { DEBUG } from '@glimmer/env'; +import { warnIfStyleNotTrusted } from '@glimmer/global-context'; import { + AttributeCursor, + AttributeOperation, + AttrNamespace, Dict, + ElementBuilder, Environment, + Namespace, Option, - ElementBuilder, - AttributeOperation, - AttributeCursor, + SimpleElement, } from '@glimmer/interfaces'; -import { warnIfStyleNotTrusted } from '@glimmer/global-context'; -import { AttrNamespace, Namespace, SimpleElement } from '@glimmer/interfaces'; +import { castToBrowser } from '@glimmer/util'; + import { normalizeStringValue } from '../../dom/normalize'; import { normalizeProperty } from '../../dom/props'; import { requiresSanitization, sanitizeAttributeValue } from '../../dom/sanitized-values'; -import { DEBUG } from '@glimmer/env'; -import { castToBrowser } from '@glimmer/util'; export function dynamicAttribute( element: SimpleElement, @@ -140,13 +143,13 @@ export class DefaultDynamicProperty extends DynamicAttribute { } export class SafeDynamicProperty extends DefaultDynamicProperty { - set(dom: ElementBuilder, value: unknown, env: Environment): void { + override set(dom: ElementBuilder, value: unknown, env: Environment): void { let { element, name } = this.attribute; let sanitized = sanitizeAttributeValue(element, name, value); super.set(dom, sanitized, env); } - update(value: unknown, env: Environment): void { + override update(value: unknown, env: Environment): void { let { element, name } = this.attribute; let sanitized = sanitizeAttributeValue(element, name, value); super.update(sanitized, env); @@ -154,13 +157,13 @@ export class SafeDynamicProperty extends DefaultDynamicProperty { } export class SafeDynamicAttribute extends SimpleDynamicAttribute { - set(dom: ElementBuilder, value: unknown, env: Environment): void { + override set(dom: ElementBuilder, value: unknown, env: Environment): void { let { element, name } = this.attribute; let sanitized = sanitizeAttributeValue(element, name, value); super.set(dom, sanitized, env); } - update(value: unknown, env: Environment): void { + override update(value: unknown, env: Environment): void { let { element, name } = this.attribute; let sanitized = sanitizeAttributeValue(element, name, value); super.update(sanitized, env); @@ -168,11 +171,11 @@ export class SafeDynamicAttribute extends SimpleDynamicAttribute { } export class InputValueDynamicAttribute extends DefaultDynamicProperty { - set(dom: ElementBuilder, value: unknown) { + override set(dom: ElementBuilder, value: unknown) { dom.__setProperty('value', normalizeStringValue(value)); } - update(value: unknown) { + override update(value: unknown) { let input = castToBrowser(this.attribute.element, ['input', 'textarea']); let currentValue = input.value; let normalizedValue = normalizeStringValue(value); @@ -183,13 +186,13 @@ export class InputValueDynamicAttribute extends DefaultDynamicProperty { } export class OptionSelectedDynamicAttribute extends DefaultDynamicProperty { - set(dom: ElementBuilder, value: unknown): void { + override set(dom: ElementBuilder, value: unknown): void { if (value !== null && value !== undefined && value !== false) { dom.__setProperty('selected', true); } } - update(value: unknown): void { + override update(value: unknown): void { let option = castToBrowser(this.attribute.element, 'option'); if (value) { @@ -234,12 +237,12 @@ let DebugStyleAttributeManager: { if (DEBUG) { DebugStyleAttributeManager = class extends SimpleDynamicAttribute { - set(dom: ElementBuilder, value: unknown, env: Environment): void { + override set(dom: ElementBuilder, value: unknown, env: Environment): void { warnIfStyleNotTrusted(value); super.set(dom, value, env); } - update(value: unknown, env: Environment): void { + override update(value: unknown, env: Environment): void { warnIfStyleNotTrusted(value); super.update(value, env); diff --git a/packages/@glimmer/runtime/lib/vm/content/text.ts b/packages/@glimmer/runtime/lib/vm/content/text.ts index 507b795ba..248bba6c4 100644 --- a/packages/@glimmer/runtime/lib/vm/content/text.ts +++ b/packages/@glimmer/runtime/lib/vm/content/text.ts @@ -1,7 +1,7 @@ -import { isEmpty, isString } from '../../dom/normalize'; -import { UpdatingOpcode } from '@glimmer/interfaces'; +import { SimpleText, UpdatingOpcode } from '@glimmer/interfaces'; import { Reference, valueForRef } from '@glimmer/reference'; -import { SimpleText } from '@glimmer/interfaces'; + +import { isEmpty, isString } from '../../dom/normalize'; export default class DynamicTextContent implements UpdatingOpcode { constructor( diff --git a/packages/@glimmer/runtime/lib/vm/element-builder.ts b/packages/@glimmer/runtime/lib/vm/element-builder.ts index 582b3c3cb..0e7d8aaa8 100644 --- a/packages/@glimmer/runtime/lib/vm/element-builder.ts +++ b/packages/@glimmer/runtime/lib/vm/element-builder.ts @@ -1,4 +1,6 @@ +import { destroy, registerDestructor } from '@glimmer/destroyable'; import { + AttrNamespace, Bounds, Cursor, CursorStackSymbol, @@ -9,21 +11,18 @@ import { GlimmerTreeConstruction, LiveBlock, Maybe, - Option, - UpdatableBlock, ModifierInstance, -} from '@glimmer/interfaces'; -import { assert, expect, Stack, symbol } from '@glimmer/util'; -import { - AttrNamespace, + Option, SimpleComment, SimpleDocumentFragment, SimpleElement, SimpleNode, SimpleText, + UpdatableBlock, } from '@glimmer/interfaces'; +import { assert, expect, Stack, symbol } from '@glimmer/util'; + import { clear, ConcreteBounds, CursorImpl, SingleNodeBounds } from '../bounds'; -import { destroy, registerDestructor } from '@glimmer/destroyable'; import { DynamicAttribute, dynamicAttribute } from './attributes/dynamic'; export interface FirstNode { diff --git a/packages/@glimmer/runtime/lib/vm/low-level.ts b/packages/@glimmer/runtime/lib/vm/low-level.ts index 715c169a1..79a6ad50a 100644 --- a/packages/@glimmer/runtime/lib/vm/low-level.ts +++ b/packages/@glimmer/runtime/lib/vm/low-level.ts @@ -1,9 +1,10 @@ -import { Option, RuntimeHeap, MachineOp, RuntimeProgram, RuntimeOp } from '@glimmer/interfaces'; -import { APPEND_OPCODES } from '../opcodes'; -import VM from './append'; +import { MachineOp, Option, RuntimeHeap, RuntimeOp, RuntimeProgram } from '@glimmer/interfaces'; import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; -import { MachineRegister, $pc, $ra, $fp, $sp } from '@glimmer/vm'; import { assert } from '@glimmer/util'; +import { $fp, $pc, $ra, $sp, MachineRegister } from '@glimmer/vm'; + +import { APPEND_OPCODES } from '../opcodes'; +import VM from './append'; export interface LowLevelRegisters { [MachineRegister.pc]: number; diff --git a/packages/@glimmer/runtime/lib/vm/rehydrate-builder.ts b/packages/@glimmer/runtime/lib/vm/rehydrate-builder.ts index 1dc49ba16..f39163721 100644 --- a/packages/@glimmer/runtime/lib/vm/rehydrate-builder.ts +++ b/packages/@glimmer/runtime/lib/vm/rehydrate-builder.ts @@ -1,15 +1,20 @@ -import { Bounds, ElementBuilder, Environment, Option, Maybe } from '@glimmer/interfaces'; -import { assert, castToBrowser, castToSimple, expect, Stack } from '@glimmer/util'; import { AttrNamespace, + Bounds, + ElementBuilder, + Environment, + Maybe, Namespace, NodeType, + Option, SimpleAttr, SimpleComment, SimpleElement, SimpleNode, SimpleText, } from '@glimmer/interfaces'; +import { assert, castToBrowser, castToSimple, expect, Stack } from '@glimmer/util'; + import { ConcreteBounds, CursorImpl } from '../bounds'; import { CURSOR_STACK, NewElementBuilder, RemoteLiveBlock } from './element-builder'; @@ -117,7 +122,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde currentCursor.nextSibling = null; } - pushElement( + override pushElement( /** called from parent constructor before we initialize this */ this: | RehydrateBuilder @@ -173,7 +178,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __openBlock(): void { + override __openBlock(): void { let { currentCursor } = this; if (currentCursor === null) return; @@ -197,7 +202,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __closeBlock(): void { + override __closeBlock(): void { let { currentCursor } = this; if (currentCursor === null) return; @@ -253,7 +258,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __appendNode(node: SimpleNode): SimpleNode { + override __appendNode(node: SimpleNode): SimpleNode { let { candidate } = this; // This code path is only used when inserting precisely one node. It needs more @@ -266,7 +271,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __appendHTML(html: string): Bounds { + override __appendHTML(html: string): Bounds { let candidateBounds = this.markerBounds(); if (candidateBounds) { @@ -316,7 +321,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __appendText(string: string): SimpleText { + override __appendText(string: string): SimpleText { let { candidate } = this; if (candidate) { @@ -345,7 +350,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - __appendComment(string: string): SimpleComment { + override __appendComment(string: string): SimpleComment { let _candidate = this.candidate; if (_candidate && isComment(_candidate)) { if (_candidate.nodeValue !== string) { @@ -361,7 +366,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return super.__appendComment(string); } - __openElement(tag: string): SimpleElement { + override __openElement(tag: string): SimpleElement { let _candidate = this.candidate; if (_candidate && isElement(_candidate) && isSameNodeType(_candidate, tag)) { @@ -379,7 +384,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return super.__openElement(tag); } - __setAttribute(name: string, value: string, namespace: Option): void { + override __setAttribute(name: string, value: string, namespace: Option): void { let unmatched = this.unmatchedAttributes; if (unmatched) { @@ -396,7 +401,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return super.__setAttribute(name, value, namespace); } - __setProperty(name: string, value: string): void { + override __setProperty(name: string, value: string): void { let unmatched = this.unmatchedAttributes; if (unmatched) { @@ -413,11 +418,11 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return super.__setProperty(name, value); } - __flushElement(parent: SimpleElement, constructing: SimpleElement): void { + override __flushElement(parent: SimpleElement, constructing: SimpleElement): void { let { unmatchedAttributes: unmatched } = this; if (unmatched) { - for (let i = 0; i < unmatched.length; i++) { - this.constructing!.removeAttribute(unmatched[i].name); + for (const attr of unmatched) { + this.constructing!.removeAttribute(attr.name); } this.unmatchedAttributes = null; } else { @@ -425,7 +430,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde } } - willCloseElement() { + override willCloseElement() { let { candidate, currentCursor } = this; if (candidate !== null) { @@ -447,7 +452,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return null; } - __pushRemoteElement( + override __pushRemoteElement( element: SimpleElement, cursorId: string, insertBefore: Maybe @@ -480,7 +485,7 @@ export class RehydrateBuilder extends NewElementBuilder implements ElementBuilde return this.pushLiveBlock(block, true); } - didAppendBounds(bounds: Bounds): Bounds { + override didAppendBounds(bounds: Bounds): Bounds { super.didAppendBounds(bounds); if (this.candidate) { let last = bounds.lastNode(); @@ -538,8 +543,7 @@ function isSameNodeType(candidate: SimpleElement, tag: string) { } function findByName(array: SimpleAttr[], name: string): SimpleAttr | undefined { - for (let i = 0; i < array.length; i++) { - let attr = array[i]; + for (const attr of array) { if (attr.name === name) return attr; } diff --git a/packages/@glimmer/runtime/lib/vm/render-result.ts b/packages/@glimmer/runtime/lib/vm/render-result.ts index 57c94c191..bf5071bad 100644 --- a/packages/@glimmer/runtime/lib/vm/render-result.ts +++ b/packages/@glimmer/runtime/lib/vm/render-result.ts @@ -1,6 +1,13 @@ -import { Environment, RenderResult, LiveBlock, UpdatingOpcode } from '@glimmer/interfaces'; import { associateDestroyableChild, registerDestructor } from '@glimmer/destroyable'; -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; +import { + Environment, + LiveBlock, + RenderResult, + SimpleElement, + SimpleNode, + UpdatingOpcode, +} from '@glimmer/interfaces'; + import { clear } from '../bounds'; import UpdatingVMImpl from './update'; diff --git a/packages/@glimmer/runtime/lib/vm/stack.ts b/packages/@glimmer/runtime/lib/vm/stack.ts index d86dffc64..01e595da1 100644 --- a/packages/@glimmer/runtime/lib/vm/stack.ts +++ b/packages/@glimmer/runtime/lib/vm/stack.ts @@ -1,5 +1,6 @@ import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; import { $fp, $sp, MachineRegister } from '@glimmer/vm'; + import { REGISTERS } from '../symbols'; import { initializeRegistersWithSP, LowLevelRegisters } from './low-level'; diff --git a/packages/@glimmer/runtime/lib/vm/update.ts b/packages/@glimmer/runtime/lib/vm/update.ts index f03fb573a..62c8ecd0b 100644 --- a/packages/@glimmer/runtime/lib/vm/update.ts +++ b/packages/@glimmer/runtime/lib/vm/update.ts @@ -1,3 +1,4 @@ +import { associateDestroyableChild, destroy, destroyChildren } from '@glimmer/destroyable'; import { DEBUG } from '@glimmer/env'; import { Bounds, @@ -10,9 +11,10 @@ import { Option, RuntimeContext, Scope, + SimpleComment, UpdatableBlock, - UpdatingVM, UpdatingOpcode, + UpdatingVM, } from '@glimmer/interfaces'; import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; import { @@ -22,10 +24,9 @@ import { updateRef, valueForRef, } from '@glimmer/reference'; -import { associateDestroyableChild, destroy, destroyChildren } from '@glimmer/destroyable'; -import { expect, Stack, logStep } from '@glimmer/util'; +import { expect, logStep, Stack, unwrap } from '@glimmer/util'; import { resetTracking, runInTrackingTransaction } from '@glimmer/validator'; -import { SimpleComment } from '@glimmer/interfaces'; + import { clear, move as moveBounds } from '../bounds'; import { InternalVM, VmInitCallback } from './append'; import { LiveBlockList, NewElementBuilder } from './element-builder'; @@ -156,7 +157,7 @@ export class TryOpcode extends BlockOpcode implements ExceptionHandler { protected declare bounds: UpdatableBlock; // Hides property on base class - evaluate(vm: UpdatingVMImpl) { + override evaluate(vm: UpdatingVMImpl) { vm.try(this.children, this); } @@ -237,7 +238,7 @@ export class ListBlockOpcode extends BlockOpcode { this.opcodeMap.set(opcode.key, opcode); } - evaluate(vm: UpdatingVMImpl) { + override evaluate(vm: UpdatingVMImpl) { let iterator = valueForRef(this.iterableRef); if (this.lastIterator !== iterator) { @@ -305,7 +306,7 @@ export class ListBlockOpcode extends BlockOpcode { // the position of the item's opcode, and determine if they are all // retained. for (let i = currentOpcodeIndex + 1; i < seenIndex; i++) { - if (children[i].retained === false) { + if (unwrap(children[i]).retained === false) { seenUnretained = true; break; } @@ -327,9 +328,7 @@ export class ListBlockOpcode extends BlockOpcode { } } - for (let i = 0; i < children.length; i++) { - let opcode = children[i]; - + for (const opcode of children) { if (opcode.retained === false) { this.deleteItem(opcode); } else { @@ -353,7 +352,7 @@ export class ListBlockOpcode extends BlockOpcode { children.push(opcode); } - private insertItem(item: OpaqueIterationItem, before: ListItemOpcode) { + private insertItem(item: OpaqueIterationItem, before: ListItemOpcode | undefined) { if (LOCAL_DEBUG) { logStep!('list-updates', ['insert', item.key]); } @@ -380,7 +379,11 @@ export class ListBlockOpcode extends BlockOpcode { }); } - private moveItem(opcode: ListItemOpcode, item: OpaqueIterationItem, before: ListItemOpcode) { + private moveItem( + opcode: ListItemOpcode, + item: OpaqueIterationItem, + before: ListItemOpcode | undefined + ) { let { children } = this; updateRef(opcode.memo, item.memo); diff --git a/packages/@glimmer/syntax/lib/generation/printer.ts b/packages/@glimmer/syntax/lib/generation/printer.ts index 40a119eb1..4d9cab3ef 100644 --- a/packages/@glimmer/syntax/lib/generation/printer.ts +++ b/packages/@glimmer/syntax/lib/generation/printer.ts @@ -11,7 +11,7 @@ voidTagNames.split(' ').forEach((tagName) => { voidMap[tagName] = true; }); -const NON_WHITESPACE = /\S/; +const NON_WHITESPACE = /^\S/; export interface PrinterOptions { entityEncoding: 'transformed' | 'raw'; @@ -42,7 +42,7 @@ export interface PrinterOptions { * - Link (component) */ function isVoidTag(tag: string): boolean { - return voidMap[tag.toLowerCase()] && tag[0].toLowerCase() === tag[0]; + return !!(voidMap[tag.toLowerCase()] && tag[0]?.toLowerCase() === tag[0]); } export default class Printer { @@ -66,7 +66,7 @@ export default class Printer { if (this.options.override !== undefined) { let result = this.options.override(node, this.options); if (typeof result === 'string') { - if (ensureLeadingWhitespace && result !== '' && NON_WHITESPACE.test(result[0])) { + if (ensureLeadingWhitespace && NON_WHITESPACE.test(result)) { result = ` ${result}`; } diff --git a/packages/@glimmer/syntax/lib/get-template-locals.ts b/packages/@glimmer/syntax/lib/get-template-locals.ts index 92ad5d2d2..036b24e9b 100644 --- a/packages/@glimmer/syntax/lib/get-template-locals.ts +++ b/packages/@glimmer/syntax/lib/get-template-locals.ts @@ -48,17 +48,13 @@ function tokensFromType( // // An ElementNode does not parse the "tag" in to a PathExpression // so we have to split on `.`, just like how `this` presence is checked. - if (tag.indexOf('.') !== -1) { - let [potentialLocal] = tag.split('.'); + if (tag.includes('.')) { + let [potentialLocal] = tag.split('.') as [string, ...string[]]; - if (scopedTokens.indexOf(potentialLocal) !== -1) { - return; - } + if (scopedTokens.includes(potentialLocal)) return; } - if (scopedTokens.indexOf(tag) !== -1) { - return; - } + if (scopedTokens.includes(tag)) return; return tag; } diff --git a/packages/@glimmer/syntax/lib/keywords.ts b/packages/@glimmer/syntax/lib/keywords.ts index 404cd2a0a..56b836359 100644 --- a/packages/@glimmer/syntax/lib/keywords.ts +++ b/packages/@glimmer/syntax/lib/keywords.ts @@ -8,7 +8,7 @@ export function isKeyword(word: string): boolean { * This includes the full list of keywords currently in use in the template * language, and where their valid usages are. */ -export const KEYWORDS_TYPES: { [key: string]: KeywordType[] } = { +export const KEYWORDS_TYPES = { component: ['Call', 'Append', 'Block'], debugger: ['Append'], 'each-in': ['Block'], @@ -31,4 +31,4 @@ export const KEYWORDS_TYPES: { [key: string]: KeywordType[] } = { unless: ['Call', 'Append', 'Block'], with: ['Block'], yield: ['Append'], -}; +} satisfies Record; diff --git a/packages/@glimmer/syntax/lib/parser.ts b/packages/@glimmer/syntax/lib/parser.ts index b1d89fb40..3cd0490f2 100644 --- a/packages/@glimmer/syntax/lib/parser.ts +++ b/packages/@glimmer/syntax/lib/parser.ts @@ -1,5 +1,5 @@ import { Option } from '@glimmer/interfaces'; -import { assert, assign, expect } from '@glimmer/util'; +import { asPresentArray, assert, assign, expect, getLast, unwrap } from '@glimmer/util'; import { EntityParser, EventedTokenizer, @@ -16,8 +16,6 @@ export type ParserNodeBuilder = Omit & loc: SourceOffset; }; -export type Element = ASTv1.Template | ASTv1.Block | ASTv1.ElementNode; - export interface Tag { readonly type: T; name: string; @@ -39,7 +37,7 @@ export interface Attribute { } export abstract class Parser { - protected elementStack: Element[] = []; + protected elementStack: ASTv1.ParentNode[] = []; private lines: string[]; readonly source: Source; public currentAttribute: Option = null; @@ -163,8 +161,8 @@ export abstract class Parser { return (this[node.type as T] as (node: HBS.Node) => HBS.Output)(node); } - currentElement(): Element { - return this.elementStack[this.elementStack.length - 1]; + currentElement(): ASTv1.ParentNode { + return getLast(asPresentArray(this.elementStack)); } sourceForNode(node: HBS.Node, endNode?: { loc: HBS.SourceLocation }): string { @@ -172,7 +170,7 @@ export abstract class Parser { let currentLine = firstLine - 1; let firstColumn = node.loc.start.column; let string = []; - let line; + let line: string; let lastLine: number; let lastColumn: number; @@ -187,7 +185,7 @@ export abstract class Parser { while (currentLine < lastLine) { currentLine++; - line = this.lines[currentLine]; + line = unwrap(this.lines[currentLine]); if (currentLine === firstLine) { if (firstLine === lastLine) { diff --git a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts b/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts index d71b29a09..d5737001d 100644 --- a/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts +++ b/packages/@glimmer/syntax/lib/parser/handlebars-node-visitors.ts @@ -1,4 +1,5 @@ import { Option, Recast } from '@glimmer/interfaces'; +import { getLast, isPresentArray, unwrap } from '@glimmer/util'; import { TokenizerState } from 'simple-html-tokenizer'; import { Parser, ParserNodeBuilder, Tag } from '../parser'; @@ -11,9 +12,9 @@ import { PathExpressionImplV1 } from '../v1/legacy-interop'; import b from '../v1/parser-builders'; export abstract class HandlebarsNodeVisitors extends Parser { - abstract appendToCommentData(s: string): void; - abstract beginAttributeValue(quoted: boolean): void; - abstract finishAttributeValue(): void; + abstract override appendToCommentData(s: string): void; + abstract override beginAttributeValue(quoted: boolean): void; + abstract override finishAttributeValue(): void; private get isTopLevel() { return this.elementStack.length === 0; @@ -51,7 +52,7 @@ export abstract class HandlebarsNodeVisitors extends Parser { } for (i = 0; i < l; i++) { - this.acceptNode(program.body[i]); + this.acceptNode(unwrap(program.body[i])); } // Ensure that that the element stack is balanced properly. @@ -383,18 +384,13 @@ export abstract class HandlebarsNodeVisitors extends Parser { } Hash(hash: HBS.Hash): ASTv1.Hash { - let pairs: ASTv1.HashPair[] = []; - - for (let i = 0; i < hash.pairs.length; i++) { - let pair = hash.pairs[i]; - pairs.push( - b.pair({ - key: pair.key, - value: this.acceptNode(pair.value), - loc: this.source.spanFor(pair.loc), - }) - ); - } + let pairs = hash.pairs.map((pair) => + b.pair({ + key: pair.key, + value: this.acceptNode(pair.value), + loc: this.source.spanFor(pair.loc), + }) + ); return b.hash(pairs, this.source.spanFor(hash.loc)); } @@ -432,13 +428,13 @@ function calculateRightStrippedOffsets(original: string, value: string) { // otherwise, return the number of newlines prior to // `value` - let difference = original.split(value)[0]; + let [difference] = original.split(value) as [string]; let lines = difference.split(/\n/); let lineCount = lines.length - 1; return { lines: lineCount, - columns: lines[lineCount].length, + columns: unwrap(lines[lineCount]).length, }; } @@ -517,7 +513,7 @@ function acceptCallNodes( // if there is no hash, position it as a collapsed node immediately after the last param (or the // path, if there are also no params) - let end = params.length > 0 ? params[params.length - 1].loc : path.loc; + let end = isPresentArray(params) ? getLast(params).loc : path.loc; let hash = node.hash ? compiler.Hash(node.hash) diff --git a/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts b/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts index 85331e5a0..685835625 100644 --- a/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts +++ b/packages/@glimmer/syntax/lib/parser/tokenizer-event-handlers.ts @@ -1,5 +1,5 @@ import { Option } from '@glimmer/interfaces'; -import { assertPresent, assign } from '@glimmer/util'; +import { assertPresentArray, assign, getFirst, getLast, isPresentArray } from '@glimmer/util'; import { parse, parseWithoutProcessing } from '@handlebars/parser'; import { EntityParser } from 'simple-html-tokenizer'; @@ -142,9 +142,9 @@ export class TokenizerEventHandlers extends HandlebarsNodeVisitors { let tag = this.finish(this.currentTag); let element = this.elementStack.pop() as ASTv1.ElementNode; - let parent = this.currentElement(); this.validateEndTag(tag, element, isVoid); + let parent = this.currentElement(); element.loc = element.loc.withEnd(this.offset()); parseElementBlockParams(element); @@ -242,21 +242,19 @@ export class TokenizerEventHandlers extends HandlebarsNodeVisitors { assembleConcatenatedValue( parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[] ): ASTv1.ConcatStatement { - for (let i = 0; i < parts.length; i++) { - let part: ASTv1.BaseNode = parts[i]; - + for (const part of parts) { if (part.type !== 'MustacheStatement' && part.type !== 'TextNode') { throw generateSyntaxError( 'Unsupported node in quoted attribute value: ' + part['type'], - part.loc + (part as ASTv1.BaseNode).loc ); } } - assertPresent(parts, `the concatenation parts of an element should not be empty`); + assertPresentArray(parts, `the concatenation parts of an element should not be empty`); - let first = parts[0]; - let last = parts[parts.length - 1]; + let first = getFirst(parts); + let last = getLast(parts); return b.concat(parts, this.source.spanFor(first.loc).extend(this.source.spanFor(last.loc))); } @@ -266,41 +264,39 @@ export class TokenizerEventHandlers extends HandlebarsNodeVisitors { element: ASTv1.ElementNode, selfClosing: boolean ): void { - let error; - if (voidMap[tag.name] && !selfClosing) { // EngTag is also called by StartTag for void and self-closing tags (i.e. // or
, so we need to check for that here. Otherwise, we would // throw an error for those cases. - error = `<${tag.name}> elements do not need end tags. You should remove it`; + throw generateSyntaxError( + `<${tag.name}> elements do not need end tags. You should remove it`, + tag.loc + ); } else if (element.tag === undefined) { - error = `Closing tag without an open tag`; + throw generateSyntaxError(`Closing tag without an open tag`, tag.loc); } else if (element.tag !== tag.name) { - error = `Closing tag did not match last open tag <${element.tag}> (on line ${element.loc.startPosition.line})`; - } - - if (error) { - throw generateSyntaxError(error, tag.loc); + throw generateSyntaxError( + `Closing tag did not match last open tag <${element.tag}> (on line ${element.loc.startPosition.line})`, + tag.loc + ); } } assembleAttributeValue( - parts: (ASTv1.MustacheStatement | ASTv1.TextNode)[], + parts: ASTv1.AttrPart[], isQuoted: boolean, isDynamic: boolean, span: SourceSpan - ): ASTv1.ConcatStatement | ASTv1.MustacheStatement | ASTv1.TextNode { + ): ASTv1.AttrValue { if (isDynamic) { if (isQuoted) { return this.assembleConcatenatedValue(parts); } else { - if ( - parts.length === 1 || - (parts.length === 2 && - parts[1].type === 'TextNode' && - (parts[1] as ASTv1.TextNode).chars === '/') - ) { - return parts[0]; + assertPresentArray(parts); + + const [head, a] = parts; + if (a === undefined || (a.type === 'TextNode' && a.chars === '/')) { + return head; } else { throw generateSyntaxError( `An unquoted attribute value must be a string or a mustache, ` + @@ -310,8 +306,10 @@ export class TokenizerEventHandlers extends HandlebarsNodeVisitors { ); } } + } else if (isPresentArray(parts)) { + return parts[0]; } else { - return parts.length > 0 ? parts[0] : b.text({ chars: '', loc: span }); + return b.text({ chars: '', loc: span }); } } } @@ -396,7 +394,7 @@ class CodemodEntityParser extends EntityParser { super({}); } - parse(): string | undefined { + override parse(): string | undefined { return undefined; } } @@ -449,8 +447,7 @@ export function preprocess( } if (options && options.plugins && options.plugins.ast) { - for (let i = 0, l = options.plugins.ast.length; i < l; i++) { - let transform = options.plugins.ast[i]; + for (const transform of options.plugins.ast) { let env: ASTPluginEnvironment = assign({}, options, { syntax }, { plugins: undefined }); let pluginResult = transform(env); diff --git a/packages/@glimmer/syntax/lib/source/loc/match.ts b/packages/@glimmer/syntax/lib/source/loc/match.ts index 41b6020f1..56c6811f4 100644 --- a/packages/@glimmer/syntax/lib/source/loc/match.ts +++ b/packages/@glimmer/syntax/lib/source/loc/match.ts @@ -1,4 +1,4 @@ -import { assert, isPresent } from '@glimmer/util'; +import { assert, isPresentArray } from '@glimmer/util'; import { CharPosition, HbsPosition, InvisiblePosition, OffsetKind, PositionData } from './offset'; @@ -37,7 +37,7 @@ class WhenList { first(kind: OffsetKind): Out | null { for (let when of this._whens) { let value = when.match(kind); - if (isPresent(value)) { + if (isPresentArray(value)) { return value[0]; } } @@ -121,7 +121,7 @@ class Matcher { let nesteds = this._whens.match(left); assert( - isPresent(nesteds), + isPresentArray(nesteds), `no match defined for (${left}, ${right}) and no AnyMatch defined either` ); diff --git a/packages/@glimmer/syntax/lib/source/location.ts b/packages/@glimmer/syntax/lib/source/location.ts index ff00c8814..704677ea4 100644 --- a/packages/@glimmer/syntax/lib/source/location.ts +++ b/packages/@glimmer/syntax/lib/source/location.ts @@ -1,5 +1,5 @@ import { PresentArray } from '@glimmer/interfaces'; -import { isPresent } from '@glimmer/util'; +import { isPresentArray } from '@glimmer/util'; import { SourceSpan } from './span'; @@ -56,7 +56,7 @@ export type LocatedWithOptionalPositions = { loc?: SourceLocation }; export function isLocatedWithPositionsArray( location: LocatedWithOptionalPositions[] ): location is PresentArray { - return isPresent(location) && location.every(isLocatedWithPositions); + return isPresentArray(location) && location.every(isLocatedWithPositions); } export function isLocatedWithPositions( diff --git a/packages/@glimmer/syntax/lib/source/span-list.ts b/packages/@glimmer/syntax/lib/source/span-list.ts index f65cff1d5..23a9931ab 100644 --- a/packages/@glimmer/syntax/lib/source/span-list.ts +++ b/packages/@glimmer/syntax/lib/source/span-list.ts @@ -1,5 +1,6 @@ // eslint-disable-next-line import/no-extraneous-dependencies import type { PresentArray } from '@glimmer/interfaces'; +import { getFirst, getLast, isPresentArray } from '@glimmer/util'; import { LocatedWithOptionalSpan, LocatedWithSpan } from './location'; import { SourceOffset, SourceSpan } from './span'; @@ -27,13 +28,12 @@ export class SpanList { } getRangeOffset(fallback: SourceSpan): SourceSpan { - if (this._span.length === 0) { - return fallback; - } else { - let first = this._span[0]; - let last = this._span[this._span.length - 1]; - + if (isPresentArray(this._span)) { + let first = getFirst(this._span); + let last = getLast(this._span); return first.extend(last); + } else { + return fallback; } } } @@ -42,9 +42,8 @@ export type HasSourceSpan = { loc: SourceSpan } | SourceSpan | [HasSourceSpan, . export function loc(span: HasSourceSpan): SourceSpan { if (Array.isArray(span)) { - let first = span[0]; - let last = span[span.length - 1]; - + let first = getFirst(span); + let last = getLast(span); return loc(first).extend(loc(last)); } else if (span instanceof SourceSpan) { return span; diff --git a/packages/@glimmer/syntax/lib/symbol-table.ts b/packages/@glimmer/syntax/lib/symbol-table.ts index ae086bfc9..706b7be5a 100644 --- a/packages/@glimmer/syntax/lib/symbol-table.ts +++ b/packages/@glimmer/syntax/lib/symbol-table.ts @@ -1,5 +1,5 @@ import { Core, Dict, SexpOpcodes } from '@glimmer/interfaces'; -import { dict } from '@glimmer/util'; +import { dict, unwrap } from '@glimmer/util'; import * as ASTv2 from './v2/api'; @@ -95,8 +95,7 @@ export class ProgramSymbolTable extends SymbolTable { } getDebugInfo(): Core.DebugInfo { - let locals = this.getLocalsMap(); - return Object.keys(locals).map((symbol) => locals[symbol]); + return Object.values(this.getLocalsMap()); } allocateFree(name: string, resolution: ASTv2.FreeVarResolution): number { @@ -172,8 +171,13 @@ export class BlockSymbolTable extends SymbolTable { } get(name: string): [number, boolean] { + let local = this.#get(name); + return local ? [local, false] : this.parent.get(name); + } + + #get(name: string): number | null { let slot = this.symbols.indexOf(name); - return slot === -1 ? this.parent.get(name) : [this.slots[slot], false]; + return slot === -1 ? null : unwrap(this.slots[slot]); } getLocalsMap(): Dict { @@ -183,8 +187,7 @@ export class BlockSymbolTable extends SymbolTable { } getDebugInfo(): Core.DebugInfo { - let locals = this.getLocalsMap(); - return Object.keys(locals).map((symbol) => locals[symbol]); + return Object.values(this.getLocalsMap()); } setHasDebugger(): void { diff --git a/packages/@glimmer/syntax/lib/traversal/errors.ts b/packages/@glimmer/syntax/lib/traversal/errors.ts index 6430f3ee2..4f778e53d 100644 --- a/packages/@glimmer/syntax/lib/traversal/errors.ts +++ b/packages/@glimmer/syntax/lib/traversal/errors.ts @@ -7,7 +7,7 @@ export interface TraversalError extends Error { key: string; node: ASTv1.Node; parent: Option; - stack: string | undefined; + stack?: string; } export interface TraversalErrorConstructor { @@ -32,7 +32,10 @@ const TraversalError: TraversalErrorConstructor = (function () { this.message = message; this.node = node; this.parent = parent; - this.stack = error.stack ?? ''; + + if (error.stack) { + this.stack = error.stack; + } } return TraversalError as unknown as TraversalErrorConstructor; diff --git a/packages/@glimmer/syntax/lib/traversal/traverse.ts b/packages/@glimmer/syntax/lib/traversal/traverse.ts index afc15eb54..44e8f8025 100644 --- a/packages/@glimmer/syntax/lib/traversal/traverse.ts +++ b/packages/@glimmer/syntax/lib/traversal/traverse.ts @@ -1,5 +1,5 @@ import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; -import { deprecate } from '@glimmer/util'; +import { deprecate, unwrap } from '@glimmer/util'; import * as ASTv1 from '../v1/api'; import visitorKeys, { VisitorKey, VisitorKeys } from '../v1/visitor-keys'; @@ -202,7 +202,7 @@ function visitArray( parentKey: string | null ) { for (let i = 0; i < array.length; i++) { - let node = array[i]; + let node = unwrap(array[i]); let path = new WalkerPath(node, parent, parentKey); let result = visitNode(visitor, path); if (result !== undefined) { diff --git a/packages/@glimmer/syntax/lib/traversal/walker.ts b/packages/@glimmer/syntax/lib/traversal/walker.ts index 52ebae0ab..89481fca2 100644 --- a/packages/@glimmer/syntax/lib/traversal/walker.ts +++ b/packages/@glimmer/syntax/lib/traversal/walker.ts @@ -8,7 +8,7 @@ export default class Walker { public stack: unknown[] = []; constructor(public order?: unknown) {} - visit(node: Option, callback: NodeCallback): void { + visit(node: Option, visitor: NodeCallback): void { if (!node) { return; } @@ -16,11 +16,11 @@ export default class Walker { this.stack.push(node); if (this.order === 'post') { - this.children(node, callback); - callback(node, this); + this.children(node, visitor); + visitor(node, this); } else { - callback(node, this); - this.children(node, callback); + visitor(node, this); + this.children(node, visitor); } this.stack.pop(); @@ -45,28 +45,20 @@ export default class Walker { } const visitors = { - Program(walker: Walker, node: ASTv1.Program, callback: NodeCallback) { - for (let i = 0; i < node.body.length; i++) { - walker.visit(node.body[i], callback); - } + Program(walker: Walker, node: ASTv1.Program, callback: NodeCallback) { + walkBody(walker, node.body, callback); }, Template(walker: Walker, node: ASTv1.Template, callback: NodeCallback) { - for (let i = 0; i < node.body.length; i++) { - walker.visit(node.body[i], callback); - } + walkBody(walker, node.body, callback); }, Block(walker: Walker, node: ASTv1.Block, callback: NodeCallback) { - for (let i = 0; i < node.body.length; i++) { - walker.visit(node.body[i], callback); - } + walkBody(walker, node.body, callback); }, ElementNode(walker: Walker, node: ASTv1.ElementNode, callback: NodeCallback) { - for (let i = 0; i < node.children.length; i++) { - walker.visit(node.children[i], callback); - } + walkBody(walker, node.children, callback); }, BlockStatement(walker: Walker, node: ASTv1.BlockStatement, callback: NodeCallback) { @@ -74,3 +66,13 @@ const visitors = { walker.visit(node.inverse || null, callback); }, } as const; + +function walkBody( + walker: Walker, + body: ASTv1.Statement[], + callback: NodeCallback +) { + for (const child of body) { + walker.visit(child, callback); + } +} diff --git a/packages/@glimmer/syntax/lib/utils.ts b/packages/@glimmer/syntax/lib/utils.ts index 05fe8483f..60f08864f 100644 --- a/packages/@glimmer/syntax/lib/utils.ts +++ b/packages/@glimmer/syntax/lib/utils.ts @@ -1,5 +1,5 @@ import { Option } from '@glimmer/interfaces'; -import { expect } from '@glimmer/util'; +import { expect, unwrap } from '@glimmer/util'; import { generateSyntaxError } from './syntax-error'; import * as ASTv1 from './v1/api'; @@ -24,19 +24,23 @@ function parseBlockParams(element: ASTv1.ElementNode): Option { let attrNames = []; for (let i = 0; i < l; i++) { - attrNames.push(element.attributes[i].name); + attrNames.push(unwrap(element.attributes[i]).name); } let asIndex = attrNames.indexOf('as'); - if (asIndex === -1 && attrNames.length > 0 && attrNames[attrNames.length - 1].charAt(0) === '|') { + if ( + asIndex === -1 && + attrNames.length > 0 && + unwrap(attrNames[attrNames.length - 1]).charAt(0) === '|' + ) { throw generateSyntaxError( 'Block parameters must be preceded by the `as` keyword, detected block parameters without `as`', element.loc ); } - if (asIndex !== -1 && l > asIndex && attrNames[asIndex + 1].charAt(0) === '|') { + if (asIndex !== -1 && l > asIndex && unwrap(attrNames[asIndex + 1]).charAt(0) === '|') { // Some basic validation, since we're doing the parsing ourselves let paramsString = attrNames.slice(asIndex).join(' '); if ( @@ -51,7 +55,7 @@ function parseBlockParams(element: ASTv1.ElementNode): Option { let params = []; for (let i = asIndex + 1; i < l; i++) { - let param = attrNames[i].replace(/\|/g, ''); + let param = unwrap(attrNames[i]).replace(/\|/g, ''); if (param !== '') { if (ID_INVERSE_PATTERN.test(param)) { throw generateSyntaxError( @@ -116,9 +120,9 @@ export function printLiteral(literal: ASTv1.Literal): string { } export function isUpperCase(tag: string): boolean { - return tag[0] === tag[0].toUpperCase() && tag[0] !== tag[0].toLowerCase(); + return tag[0] === tag[0]?.toUpperCase() && tag[0] !== tag[0]?.toLowerCase(); } export function isLowerCase(tag: string): boolean { - return tag[0] === tag[0].toLowerCase() && tag[0] !== tag[0].toUpperCase(); + return tag[0] === tag[0]?.toLowerCase() && tag[0] !== tag[0]?.toUpperCase(); } diff --git a/packages/@glimmer/syntax/lib/v1/legacy-interop.ts b/packages/@glimmer/syntax/lib/v1/legacy-interop.ts index 4b8032192..73882996e 100644 --- a/packages/@glimmer/syntax/lib/v1/legacy-interop.ts +++ b/packages/@glimmer/syntax/lib/v1/legacy-interop.ts @@ -1,3 +1,5 @@ +import { assertPresentArray, getFirst } from '@glimmer/util'; + import { SourceSpan } from '../source/span'; import { PathExpression, PathHead } from './nodes-v1'; import b from './public-builders'; @@ -38,7 +40,8 @@ export class PathExpressionImplV1 implements PathExpression { } else if (this.data) { firstPart = `@${this.parts[0]}`; } else { - firstPart = this.parts[0]; + assertPresentArray(this.parts); + firstPart = getFirst(this.parts); } let firstPartLoc = this.loc.collapse('start').sliceStartChars({ diff --git a/packages/@glimmer/syntax/lib/v1/nodes-v1.ts b/packages/@glimmer/syntax/lib/v1/nodes-v1.ts index d9d32e140..7c75e3b95 100644 --- a/packages/@glimmer/syntax/lib/v1/nodes-v1.ts +++ b/packages/@glimmer/syntax/lib/v1/nodes-v1.ts @@ -165,10 +165,11 @@ export type StatementName = export interface AttrNode extends BaseNode { type: 'AttrNode'; name: string; - value: TextNode | MustacheStatement | ConcatStatement; + value: AttrValue; } export type AttrValue = TextNode | MustacheStatement | ConcatStatement; +export type AttrPart = TextNode | MustacheStatement; export interface TextNode extends BaseNode { type: 'TextNode'; @@ -335,3 +336,5 @@ export type Literal = Nodes[LiteralName]; export type Expression = Nodes[ExpressionName]; export type Expressions = Pick; export type TopLevelStatement = Statement | Nodes['Block']; + +export type ParentNode = Template | Block | ElementNode; diff --git a/packages/@glimmer/syntax/lib/v1/public-builders.ts b/packages/@glimmer/syntax/lib/v1/public-builders.ts index 1fdeb9e6d..fcac65745 100644 --- a/packages/@glimmer/syntax/lib/v1/public-builders.ts +++ b/packages/@glimmer/syntax/lib/v1/public-builders.ts @@ -1,6 +1,6 @@ import { Dict, Option } from '@glimmer/interfaces'; import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; -import { assert, assign, deprecate, isPresent } from '@glimmer/util'; +import { asPresentArray, assert, assign, deprecate, isPresentArray } from '@glimmer/util'; import { SourceLocation, SourcePosition, SYNTHETIC_LOCATION } from '../source/location'; import { Source } from '../source/source'; @@ -150,7 +150,7 @@ function buildConcat( parts: (ASTv1.TextNode | ASTv1.MustacheStatement)[], loc?: SourceLocation ): ASTv1.ConcatStatement { - if (!isPresent(parts)) { + if (!isPresentArray(parts)) { throw new Error(`b.concat requires at least one part`); } @@ -285,7 +285,7 @@ function buildHead( original: string, loc: SourceLocation ): { head: ASTv1.PathHead; tail: string[] } { - let [head, ...tail] = original.split('.'); + let [head, ...tail] = asPresentArray(original.split('.')); let headNode: ASTv1.PathHead; if (head === 'this') { diff --git a/packages/@glimmer/syntax/lib/v2/builders.ts b/packages/@glimmer/syntax/lib/v2/builders.ts index 3f47444b9..f5d0ebb22 100644 --- a/packages/@glimmer/syntax/lib/v2/builders.ts +++ b/packages/@glimmer/syntax/lib/v2/builders.ts @@ -1,5 +1,5 @@ import type { PresentArray } from '@glimmer/interfaces'; -import { assert, assertPresent, assign } from '@glimmer/util'; +import { assert, assertPresentArray, assign } from '@glimmer/util'; import { SourceSlice } from '../source/slice'; import { SourceSpan } from '../source/span'; @@ -233,7 +233,7 @@ export class Builder { } interpolate(parts: ASTv2.ExpressionNode[], loc: SourceSpan): ASTv2.InterpolateExpression { - assertPresent(parts); + assertPresentArray(parts); return new ASTv2.InterpolateExpression({ loc, @@ -295,7 +295,6 @@ export class Builder { blockStatement( { - symbols, program, inverse = null, ...call diff --git a/packages/@glimmer/syntax/lib/v2/normalize.ts b/packages/@glimmer/syntax/lib/v2/normalize.ts index 32d6d48df..9bb2214db 100644 --- a/packages/@glimmer/syntax/lib/v2/normalize.ts +++ b/packages/@glimmer/syntax/lib/v2/normalize.ts @@ -1,5 +1,5 @@ import { PresentArray } from '@glimmer/interfaces'; -import { assert, assign, isPresent } from '@glimmer/util'; +import { asPresentArray, assert, assign, isPresentArray } from '@glimmer/util'; import Printer from '../generation/printer'; import { @@ -463,7 +463,7 @@ class ElementNormalizer { let { tag, selfClosing, comments } = element; let loc = this.ctx.loc(element.loc); - let [tagHead, ...rest] = tag.split('.'); + let [tagHead, ...rest] = asPresentArray(tag.split('.')); // the head, attributes and modifiers are in the current scope let path = this.classifyTag(tagHead, rest, element.loc); @@ -791,7 +791,7 @@ class Children { class TemplateChildren extends Children { assertTemplate(table: ProgramSymbolTable): ASTv2.Template { - if (isPresent(this.namedBlocks)) { + if (isPresentArray(this.namedBlocks)) { throw generateSyntaxError(`Unexpected named block at the top-level of a template`, this.loc); } @@ -801,7 +801,7 @@ class TemplateChildren extends Children { class BlockChildren extends Children { assertBlock(table: BlockSymbolTable): ASTv2.Block { - if (isPresent(this.namedBlocks)) { + if (isPresentArray(this.namedBlocks)) { throw generateSyntaxError(`Unexpected named block nested in a normal block`, this.loc); } @@ -827,7 +827,7 @@ class ElementChildren extends Children { ); } - if (isPresent(this.namedBlocks)) { + if (isPresentArray(this.namedBlocks)) { throw generateSyntaxError( `Unexpected named block inside <:${name.chars}> named block: named blocks cannot contain nested named blocks`, this.loc @@ -869,7 +869,7 @@ class ElementChildren extends Children { ); } - if (isPresent(this.namedBlocks)) { + if (isPresentArray(this.namedBlocks)) { let names = this.namedBlocks.map((b) => b.name); if (names.length === 1) { @@ -894,14 +894,14 @@ class ElementChildren extends Children { table: BlockSymbolTable, hasBlockParams: boolean ): PresentArray { - if (isPresent(this.namedBlocks) && this.hasSemanticContent) { + if (isPresentArray(this.namedBlocks) && this.hasSemanticContent) { throw generateSyntaxError( `Unexpected content inside <${name}> component invocation: when using named blocks, the tag cannot contain other content`, this.loc ); } - if (isPresent(this.namedBlocks)) { + if (isPresentArray(this.namedBlocks)) { if (hasBlockParams) { throw generateSyntaxError( `Unexpected block params list on <${name}> component invocation: when passing named blocks, the invocation tag cannot take block params`, diff --git a/packages/@glimmer/syntax/package.json b/packages/@glimmer/syntax/package.json index a1d61040f..b4e32346b 100644 --- a/packages/@glimmer/syntax/package.json +++ b/packages/@glimmer/syntax/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@glimmer/local-debug-flags": "workspace:^", - "@types/qunit": "^2.9.0" + "@types/qunit": "^2.19.5" } } diff --git a/packages/@glimmer/syntax/test/loc-node-test.ts b/packages/@glimmer/syntax/test/loc-node-test.ts index 5ec42f0cf..e6f465995 100644 --- a/packages/@glimmer/syntax/test/loc-node-test.ts +++ b/packages/@glimmer/syntax/test/loc-node-test.ts @@ -1,4 +1,6 @@ -import { preprocess as parse, AST } from '..'; +import { guardArray } from '@glimmer/integration-tests'; + +import { AST, preprocess as parse } from '..'; import { SourceLocation } from '../lib/v1/api'; QUnit.module('[glimmer-syntax] Parser - Location Info'); @@ -293,7 +295,10 @@ data-barf="herpy" let [, div] = ast.body; if (assertNodeType(div, 'ElementNode')) { - let [dataFoo, dataDerp, dataBarf, dataQux, dataSomethingBoolean, dataHurky] = div.attributes; + let [dataFoo, dataDerp, dataBarf, dataQux, dataSomethingBoolean, dataHurky] = guardArray( + { attributes: div.attributes }, + { min: 6 } + ); locEqual(dataFoo, 2, 9, 2, 24, 'data-foo'); locEqual(dataDerp, 3, 6, 3, 23, 'data-derp'); @@ -314,7 +319,7 @@ test('element dynamic attribute', function () { let [img] = ast.body; if (assertNodeType(img, 'ElementNode')) { - let [src] = img.attributes; + let [src] = guardArray({ attributes: img.attributes }, { min: 1 }); locEqual(src, 1, 5, 1, 17); let { value } = src; locEqual(value, 1, 9, 1, 17); @@ -339,7 +344,10 @@ foo" let [, div] = ast.body; if (assertNodeType(div, 'ElementNode')) { - let [dataFoo, dataBar, dataDerp, dataQux] = div.attributes; + let [dataFoo, dataBar, dataDerp, dataQux] = guardArray( + { attributes: div.attributes }, + { min: 4 } + ); let dataFooValue = dataFoo.value; let dataBarValue = dataBar.value; let dataDerpValue = dataDerp.value; diff --git a/packages/@glimmer/syntax/test/package.json b/packages/@glimmer/syntax/test/package.json new file mode 100644 index 000000000..3d344e14c --- /dev/null +++ b/packages/@glimmer/syntax/test/package.json @@ -0,0 +1,9 @@ +{ + "private": true, + "name": "@glimmer-test/syntax", + "dependencies": { + "@glimmer/integration-tests": "workspace:^", + "@glimmer/interfaces": "workspace:^", + "@glimmer/util": "workspace:^" + } +} diff --git a/packages/@glimmer/syntax/test/parser-node-test.ts b/packages/@glimmer/syntax/test/parser-node-test.ts index 5fed26e71..139474ba0 100644 --- a/packages/@glimmer/syntax/test/parser-node-test.ts +++ b/packages/@glimmer/syntax/test/parser-node-test.ts @@ -1,8 +1,8 @@ -import { preprocess as parse, builders as b, ASTv1 } from '..'; import { Dict } from '@glimmer/interfaces'; -import { astEqual } from './support'; import { syntaxErrorFor } from '../../integration-tests'; +import { ASTv1, builders as b, preprocess as parse } from '..'; +import { astEqual } from './support'; const test = QUnit.test; @@ -62,10 +62,11 @@ function buildIntegrationPointTest(integrationPoint: string) { ); }; } -for (let i = 0, length = integrationPoints.length; i < length; i++) { + +for (const integrationPoint of integrationPoints) { test( - 'svg content with html content inline for ' + integrationPoints[i], - buildIntegrationPointTest(integrationPoints[i]) + 'svg content with html content inline for ' + integrationPoint, + buildIntegrationPointTest(integrationPoint) ); } @@ -887,11 +888,7 @@ export function normalizeHash( hash: Dict, loc?: ASTv1.SourceLocation ): ASTv1.Hash { - let pairs: ASTv1.HashPair[] = []; - - Object.keys(hash).forEach((key) => { - pairs.push(b.pair(key, hash[key])); - }); + let pairs = Object.entries(hash).map(([key, value]) => b.pair(key, value)); return b.hash(pairs, loc); } diff --git a/packages/@glimmer/syntax/test/plugin-node-test.ts b/packages/@glimmer/syntax/test/plugin-node-test.ts index bf5b93b06..8a9638d4e 100644 --- a/packages/@glimmer/syntax/test/plugin-node-test.ts +++ b/packages/@glimmer/syntax/test/plugin-node-test.ts @@ -1,6 +1,7 @@ -import { preprocess, Syntax, Walker, AST, ASTPluginEnvironment, ASTPluginBuilder } from '..'; import { expect } from '@glimmer/util'; +import { AST, ASTPluginBuilder, ASTPluginEnvironment, preprocess, Syntax, Walker } from '..'; + const { test } = QUnit; QUnit.module('[glimmer-syntax] Plugins - AST Transforms'); diff --git a/packages/@glimmer/syntax/test/support.ts b/packages/@glimmer/syntax/test/support.ts index 834d88d46..110e6f1a3 100644 --- a/packages/@glimmer/syntax/test/support.ts +++ b/packages/@glimmer/syntax/test/support.ts @@ -1,28 +1,42 @@ -import { preprocess as parse, AST, PreprocessOptions } from '..'; +import { entries } from '@glimmer/util'; + +import { AST, preprocess as parse, PreprocessOptions } from '..'; function normalizeNode(obj: AST.Node | Array): AST.Node | Array { + return normalizeValue(obj); +} + +function normalizeValue(obj: T): T { if (obj && typeof obj === 'object') { - let newObj: any; if (Array.isArray(obj)) { - newObj = obj.slice(); - for (let i = 0; i < obj.length; i++) { - newObj[i] = normalizeNode(obj[i]); - } + return obj.map(normalizeValue) as T; } else { - newObj = {}; - let keys = Object.keys(obj); - for (let i = 0; i < keys.length; i++) { - let key = keys[i]; - if (key === 'loc') continue; - newObj[key] = normalizeNode((obj as any)[key]); - } + return fromEntries( + entries(obj).flatMap(([key, value]) => + key === 'loc' ? [] : [[key, normalizeValue(value)]] + ) + ) as T; } - return newObj; } else { return obj; } } +// convert entries ([string, unknown][]) into a record +type FromEntries = { + [K in T[number] as K[0]]: Extract[1]; +}; + +function fromEntries(entries: T): FromEntries { + let out: any = {}; + + for (let [key, value] of entries) { + out[key as string] = value; + } + + return out as FromEntries; +} + export function astEqual( actual: any | null | undefined, expected: any | null | undefined, diff --git a/packages/@glimmer/syntax/test/traversal/manipulating-node-test.ts b/packages/@glimmer/syntax/test/traversal/manipulating-node-test.ts index 5199336cf..febc88580 100644 --- a/packages/@glimmer/syntax/test/traversal/manipulating-node-test.ts +++ b/packages/@glimmer/syntax/test/traversal/manipulating-node-test.ts @@ -1,12 +1,14 @@ -import { astEqual } from '../support'; +import { guardArray } from '@glimmer/integration-tests'; + import { - preprocess as parse, - traverse, - builders as b, AST, + builders as b, cannotRemoveNode, cannotReplaceNode, + preprocess as parse, + traverse, } from '../..'; +import { astEqual } from '../support'; QUnit.module('[glimmer-syntax] Traversal - manipulating'); @@ -14,7 +16,7 @@ QUnit.module('[glimmer-syntax] Traversal - manipulating'); QUnit.test(`[${eventName}] Replacing self in a key (returning null)`, (assert) => { let ast = parse(``); let el = ast.body[0] as AST.ElementNode; - let attr = el.attributes[0]; + let [attr] = guardArray({ attributes: el.attributes }, { min: 1 }); assert.throws(() => { traverse(ast, { @@ -33,7 +35,7 @@ QUnit.module('[glimmer-syntax] Traversal - manipulating'); QUnit.test(`[${eventName}] Replacing self in a key (returning an empty array)`, (assert) => { let ast = parse(``); let el = ast.body[0] as AST.ElementNode; - let attr = el.attributes[0]; + let [attr] = guardArray({ attributes: el.attributes }, { min: 1 }); assert.throws(() => { traverse(ast, { @@ -91,7 +93,7 @@ QUnit.module('[glimmer-syntax] Traversal - manipulating'); (assert) => { let ast = parse(``); let el = ast.body[0] as AST.ElementNode; - let attr = el.attributes[0]; + let [attr] = guardArray({ attributes: el.attributes }, { min: 1 }); assert.throws(() => { traverse(ast, { diff --git a/packages/@glimmer/syntax/test/traversal/visiting-keys-node-test.ts b/packages/@glimmer/syntax/test/traversal/visiting-keys-node-test.ts index e14e11cb4..040d37473 100644 --- a/packages/@glimmer/syntax/test/traversal/visiting-keys-node-test.ts +++ b/packages/@glimmer/syntax/test/traversal/visiting-keys-node-test.ts @@ -1,6 +1,6 @@ -import { preprocess as parse, traverse, AST } from '../..'; +import { AST, preprocess as parse, traverse } from '../..'; -function traversalEqual(node: AST.Node, expectedTraversal: Array<[string, AST.Node]>) { +function traversalEqual(node: AST.Node, expectedTraversal: Array<[string, AST.Node | undefined]>) { let actualTraversal: Array<[string, AST.BaseNode]> = []; traverse(node, { @@ -26,13 +26,13 @@ function traversalEqual(node: AST.Node, expectedTraversal: Array<[string, AST.No QUnit.assert.deepEqual( actualTraversal.map((a) => `${a[0]} ${a[1].type}`), - expectedTraversal.map((a) => `${a[0]} ${a[1].type}`) + expectedTraversal.map((a) => `${a[0]} ${a[1]?.type ?? 'undefined'}`) ); let nodesEqual = true; for (let i = 0; i < actualTraversal.length; i++) { - if (actualTraversal[i][1] !== expectedTraversal[i][1]) { + if (actualTraversal[i]?.[1] !== expectedTraversal[i]?.[1]) { nodesEqual = false; break; } @@ -66,14 +66,14 @@ QUnit.test('Blocks', function () { ['enter:pairs', block.hash], ['enter', block.hash.pairs[0]], ['enter:value', block.hash.pairs[0]], - ['enter', block.hash.pairs[0].value], - ['exit', block.hash.pairs[0].value], + ['enter', block.hash.pairs[0]?.value], + ['exit', block.hash.pairs[0]?.value], ['exit:value', block.hash.pairs[0]], ['exit', block.hash.pairs[0]], ['enter', block.hash.pairs[1]], ['enter:value', block.hash.pairs[1]], - ['enter', block.hash.pairs[1].value], - ['exit', block.hash.pairs[1].value], + ['enter', block.hash.pairs[1]?.value], + ['exit', block.hash.pairs[1]?.value], ['exit:value', block.hash.pairs[1]], ['exit', block.hash.pairs[1]], ['exit:pairs', block.hash], diff --git a/packages/@glimmer/syntax/test/traversal/visiting-node-test.ts b/packages/@glimmer/syntax/test/traversal/visiting-node-test.ts index ef16aadb9..eb9c92311 100644 --- a/packages/@glimmer/syntax/test/traversal/visiting-node-test.ts +++ b/packages/@glimmer/syntax/test/traversal/visiting-node-test.ts @@ -1,8 +1,11 @@ -import { preprocess as parse, traverse, AST, WalkerPath } from '../..'; +import { AST, preprocess as parse, traverse, WalkerPath } from '../..'; const { test } = QUnit; -function traversalEqual(node: AST.Node, expectedTraversal: Array<[string, AST.BaseNode]>) { +function traversalEqual( + node: AST.Node, + expectedTraversal: Array<[string, AST.BaseNode | undefined]> +) { let actualTraversal: Array<[string, AST.BaseNode]> = []; traverse(node, { @@ -18,13 +21,13 @@ function traversalEqual(node: AST.Node, expectedTraversal: Array<[string, AST.Ba QUnit.assert.deepEqual( actualTraversal.map((a) => `${a[0]} ${a[1].type}`), - expectedTraversal.map((a) => `${a[0]} ${a[1].type}`) + expectedTraversal.map((a) => `${a[0]} ${a[1]?.type}`) ); let nodesEqual = true; for (let i = 0; i < actualTraversal.length; i++) { - if (actualTraversal[i][1] !== expectedTraversal[i][1]) { + if (actualTraversal[i]?.[1] !== expectedTraversal[i]?.[1]) { nodesEqual = false; break; } @@ -40,34 +43,34 @@ test('Elements and attributes', function () { `
` ); let el = ast.body[0] as AST.ElementNode; - let concat = el.attributes[1].value as AST.ConcatStatement; - let concatMustache = concat.parts[1] as AST.MustacheStatement; - let attrMustache = el.attributes[2].value as AST.MustacheStatement; + let concat = el.attributes[1]?.value as AST.ConcatStatement | undefined; + let concatMustache = concat?.parts[1] as AST.MustacheStatement | undefined; + let attrMustache = el.attributes[2]?.value as AST.MustacheStatement | undefined; traversalEqual(ast, [ ['enter', ast], ['enter', el], ['enter', el.attributes[0]], - ['enter', el.attributes[0].value], - ['exit', el.attributes[0].value], + ['enter', el.attributes[0]?.value], + ['exit', el.attributes[0]?.value], ['exit', el.attributes[0]], ['enter', el.attributes[1]], ['enter', concat], - ['enter', concat.parts[0]], - ['exit', concat.parts[0]], + ['enter', concat?.parts[0]], + ['exit', concat?.parts[0]], ['enter', concatMustache], - ['enter', concatMustache.path], - ['exit', concatMustache.path], - ['enter', concatMustache.hash], - ['exit', concatMustache.hash], + ['enter', concatMustache?.path], + ['exit', concatMustache?.path], + ['enter', concatMustache?.hash], + ['exit', concatMustache?.hash], ['exit', concatMustache], ['exit', concat], ['exit', el.attributes[1]], ['enter', el.attributes[2]], ['enter', attrMustache], - ['enter', attrMustache.path], - ['exit', attrMustache.path], - ['enter', attrMustache.hash], - ['exit', attrMustache.hash], + ['enter', attrMustache?.path], + ['exit', attrMustache?.path], + ['enter', attrMustache?.hash], + ['exit', attrMustache?.hash], ['exit', attrMustache], ['exit', el.attributes[2]], ['enter', el.children[0]], @@ -86,28 +89,28 @@ test('Element modifiers', function () { ['enter', ast], ['enter', el], ['enter', el.modifiers[0]], - ['enter', el.modifiers[0].path], - ['exit', el.modifiers[0].path], - ['enter', el.modifiers[0].hash], - ['exit', el.modifiers[0].hash], + ['enter', el.modifiers[0]?.path], + ['exit', el.modifiers[0]?.path], + ['enter', el.modifiers[0]?.hash], + ['exit', el.modifiers[0]?.hash], ['exit', el.modifiers[0]], ['enter', el.modifiers[1]], - ['enter', el.modifiers[1].path], - ['exit', el.modifiers[1].path], - ['enter', el.modifiers[1].params[0]], - ['exit', el.modifiers[1].params[0]], - ['enter', el.modifiers[1].params[1]], - ['exit', el.modifiers[1].params[1]], - ['enter', el.modifiers[1].hash], - ['enter', el.modifiers[1].hash.pairs[0]], - ['enter', el.modifiers[1].hash.pairs[0].value], - ['exit', el.modifiers[1].hash.pairs[0].value], - ['exit', el.modifiers[1].hash.pairs[0]], - ['enter', el.modifiers[1].hash.pairs[1]], - ['enter', el.modifiers[1].hash.pairs[1].value], - ['exit', el.modifiers[1].hash.pairs[1].value], - ['exit', el.modifiers[1].hash.pairs[1]], - ['exit', el.modifiers[1].hash], + ['enter', el.modifiers[1]?.path], + ['exit', el.modifiers[1]?.path], + ['enter', el.modifiers[1]?.params[0]], + ['exit', el.modifiers[1]?.params[0]], + ['enter', el.modifiers[1]?.params[1]], + ['exit', el.modifiers[1]?.params[1]], + ['enter', el.modifiers[1]?.hash], + ['enter', el.modifiers[1]?.hash.pairs[0]], + ['enter', el.modifiers[1]?.hash.pairs[0]?.value], + ['exit', el.modifiers[1]?.hash.pairs[0]?.value], + ['exit', el.modifiers[1]?.hash.pairs[0]], + ['enter', el.modifiers[1]?.hash.pairs[1]], + ['enter', el.modifiers[1]?.hash.pairs[1]?.value], + ['exit', el.modifiers[1]?.hash.pairs[1]?.value], + ['exit', el.modifiers[1]?.hash.pairs[1]], + ['exit', el.modifiers[1]?.hash], ['exit', el.modifiers[1]], ['exit', el], ['exit', ast], @@ -142,12 +145,12 @@ test('Blocks', function () { ['exit', block2.params[1]], ['enter', block2.hash], ['enter', block2.hash.pairs[0]], - ['enter', block2.hash.pairs[0].value], - ['exit', block2.hash.pairs[0].value], + ['enter', block2.hash.pairs[0]?.value], + ['exit', block2.hash.pairs[0]?.value], ['exit', block2.hash.pairs[0]], ['enter', block2.hash.pairs[1]], - ['enter', block2.hash.pairs[1].value], - ['exit', block2.hash.pairs[1].value], + ['enter', block2.hash.pairs[1]?.value], + ['exit', block2.hash.pairs[1]?.value], ['exit', block2.hash.pairs[1]], ['exit', block2.hash], ['enter', block2.program], @@ -184,12 +187,12 @@ test('Mustaches', function () { ['exit', must2.params[1]], ['enter', must2.hash], ['enter', must2.hash.pairs[0]], - ['enter', must2.hash.pairs[0].value], - ['exit', must2.hash.pairs[0].value], + ['enter', must2.hash.pairs[0]?.value], + ['exit', must2.hash.pairs[0]?.value], ['exit', must2.hash.pairs[0]], ['enter', must2.hash.pairs[1]], - ['enter', must2.hash.pairs[1].value], - ['exit', must2.hash.pairs[1].value], + ['enter', must2.hash.pairs[1]?.value], + ['exit', must2.hash.pairs[1]?.value], ['exit', must2.hash.pairs[1]], ['exit', must2.hash], ['exit', must2], @@ -206,9 +209,9 @@ test('Nested helpers', function () { let must = ast.body[0] as AST.MustacheStatement; let sexp = must.params[0] as AST.SubExpression; - let nestedSexp1 = must.hash.pairs[0].value as AST.SubExpression; - let nestedSexp2 = must.hash.pairs[1].value as AST.SubExpression; - let deeplyNestedSexp = nestedSexp2.hash.pairs[0].value as AST.SubExpression; + let nestedSexp1 = must.hash.pairs[0]?.value as AST.SubExpression | undefined; + let nestedSexp2 = must.hash.pairs[1]?.value as AST.SubExpression | undefined; + let deeplyNestedSexp = nestedSexp2?.hash.pairs[0]?.value as AST.SubExpression | undefined; traversalEqual(ast, [ ['enter', ast], ['enter', must], @@ -223,42 +226,42 @@ test('Nested helpers', function () { ['exit', sexp.params[1]], ['enter', sexp.hash], ['enter', sexp.hash.pairs[0]], - ['enter', sexp.hash.pairs[0].value], - ['exit', sexp.hash.pairs[0].value], + ['enter', sexp.hash.pairs[0]?.value], + ['exit', sexp.hash.pairs[0]?.value], ['exit', sexp.hash.pairs[0]], ['enter', sexp.hash.pairs[1]], - ['enter', sexp.hash.pairs[1].value], - ['exit', sexp.hash.pairs[1].value], + ['enter', sexp.hash.pairs[1]?.value], + ['exit', sexp.hash.pairs[1]?.value], ['exit', sexp.hash.pairs[1]], ['exit', sexp.hash], ['exit', sexp], ['enter', must.hash], ['enter', must.hash.pairs[0]], ['enter', nestedSexp1], - ['enter', nestedSexp1.path], - ['exit', nestedSexp1.path], - ['enter', nestedSexp1.params[0]], - ['exit', nestedSexp1.params[0]], - ['enter', nestedSexp1.hash], - ['exit', nestedSexp1.hash], + ['enter', nestedSexp1?.path], + ['exit', nestedSexp1?.path], + ['enter', nestedSexp1?.params[0]], + ['exit', nestedSexp1?.params[0]], + ['enter', nestedSexp1?.hash], + ['exit', nestedSexp1?.hash], ['exit', nestedSexp1], ['exit', must.hash.pairs[0]], ['enter', must.hash.pairs[1]], ['enter', nestedSexp2], - ['enter', nestedSexp2.path], - ['exit', nestedSexp2.path], - ['enter', nestedSexp2.hash], - ['enter', nestedSexp2.hash.pairs[0]], + ['enter', nestedSexp2?.path], + ['exit', nestedSexp2?.path], + ['enter', nestedSexp2?.hash], + ['enter', nestedSexp2?.hash.pairs[0]], ['enter', deeplyNestedSexp], - ['enter', deeplyNestedSexp.path], - ['exit', deeplyNestedSexp.path], - ['enter', deeplyNestedSexp.params[0]], - ['exit', deeplyNestedSexp.params[0]], - ['enter', deeplyNestedSexp.hash], - ['exit', deeplyNestedSexp.hash], + ['enter', deeplyNestedSexp?.path], + ['exit', deeplyNestedSexp?.path], + ['enter', deeplyNestedSexp?.params[0]], + ['exit', deeplyNestedSexp?.params[0]], + ['enter', deeplyNestedSexp?.hash], + ['exit', deeplyNestedSexp?.hash], ['exit', deeplyNestedSexp], - ['exit', nestedSexp2.hash.pairs[0]], - ['exit', nestedSexp2.hash], + ['exit', nestedSexp2?.hash.pairs[0]], + ['exit', nestedSexp2?.hash], ['exit', nestedSexp2], ['exit', must.hash.pairs[1]], ['exit', must.hash], diff --git a/packages/@glimmer/util/index.ts b/packages/@glimmer/util/index.ts index 34f8814a6..5ab33e030 100644 --- a/packages/@glimmer/util/index.ts +++ b/packages/@glimmer/util/index.ts @@ -1,24 +1,29 @@ export * from './lib/array-utils'; export { default as assert, deprecate } from './lib/assert'; export { dict, isDict, isObject, StackImpl as Stack } from './lib/collections'; +export { beginTestSteps, endTestSteps, logStep, verifySteps } from './lib/debug-steps'; +export { default as debugToString } from './lib/debug-to-string'; export * from './lib/dom'; +export * from './lib/immediate'; +export { default as intern } from './lib/intern'; export { isSerializationFirstNode, SERIALIZATION_FIRST_NODE_STRING, } from './lib/is-serialization-first-node'; -export { assign, fillNulls, values } from './lib/object-utils'; +export { assign, entries, fillNulls, values } from './lib/object-utils'; export * from './lib/platform-utils'; +export * from './lib/present'; +export { + castToBrowser, + castToSimple, + checkNode, + isElement, + isSimpleElement, +} from './lib/simple-cast'; export * from './lib/string'; -export * from './lib/immediate'; export * from './lib/template'; -export { default as _WeakSet } from './lib/weak-set'; -export { castToSimple, castToBrowser, checkNode } from './lib/simple-cast'; -export * from './lib/present'; -export { default as intern } from './lib/intern'; - export { default as buildUntouchableThis } from './lib/untouchable-this'; -export { default as debugToString } from './lib/debug-to-string'; -export { beginTestSteps, endTestSteps, logStep, verifySteps } from './lib/debug-steps'; +export { default as _WeakSet } from './lib/weak-set'; export type FIXME = (T & S) | T; diff --git a/packages/@glimmer/util/lib/array-utils.ts b/packages/@glimmer/util/lib/array-utils.ts index bea1fed22..fa9eef68a 100644 --- a/packages/@glimmer/util/lib/array-utils.ts +++ b/packages/@glimmer/util/lib/array-utils.ts @@ -14,3 +14,16 @@ export const EMPTY_NUMBER_ARRAY = emptyArray(); export function isEmptyArray(input: unknown[] | readonly unknown[]): boolean { return input === EMPTY_ARRAY; } + +export function* reverse(input: T[]): IterableIterator { + for (let i = input.length - 1; i >= 0; i--) { + yield input[i]!; + } +} + +export function* enumerate(input: Iterable): IterableIterator<[number, T]> { + let i = 0; + for (const item of input) { + yield [i++, item]; + } +} diff --git a/packages/@glimmer/util/lib/collections.ts b/packages/@glimmer/util/lib/collections.ts index 5367aff89..68949b3fb 100644 --- a/packages/@glimmer/util/lib/collections.ts +++ b/packages/@glimmer/util/lib/collections.ts @@ -1,5 +1,8 @@ import { Dict, Option, Stack } from '@glimmer/interfaces'; +import { unwrap } from './platform-utils'; +import { getLast } from './present'; + export function dict(): Dict { return Object.create(null); } @@ -31,15 +34,14 @@ export class StackImpl implements Stack { pop(): Option { let item = this.stack.pop(); - let len = this.stack.length; - this.current = len === 0 ? null : this.stack[len - 1]; + this.current = getLast(this.stack) ?? null; return item === undefined ? null : item; } nth(from: number): Option { let len = this.stack.length; - return len < from ? null : this.stack[len - from]; + return len < from ? null : unwrap(this.stack[len - from]); } isEmpty(): boolean { diff --git a/packages/@glimmer/util/lib/debug-steps.ts b/packages/@glimmer/util/lib/debug-steps.ts index ef5b62825..f9b07dbef 100644 --- a/packages/@glimmer/util/lib/debug-steps.ts +++ b/packages/@glimmer/util/lib/debug-steps.ts @@ -1,4 +1,5 @@ import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; + import assert from './assert'; import { expect } from './platform-utils'; @@ -28,8 +29,10 @@ if (LOCAL_DEBUG) { logStep = (type: string, step: unknown) => { if (LOGGED_STEPS === null) return; - LOGGED_STEPS[type] = LOGGED_STEPS[type] || []; - LOGGED_STEPS[type].push(step); + let steps = LOGGED_STEPS[type]; + if (!steps) steps = LOGGED_STEPS[type] = []; + + steps.push(step); }; verifySteps = ( diff --git a/packages/@glimmer/util/lib/dom.ts b/packages/@glimmer/util/lib/dom.ts index 4bca146ac..ed41b3a66 100644 --- a/packages/@glimmer/util/lib/dom.ts +++ b/packages/@glimmer/util/lib/dom.ts @@ -1,5 +1,4 @@ -import { Option } from '@glimmer/interfaces'; -import { SimpleElement, SimpleNode } from '@glimmer/interfaces'; +import { Option, SimpleElement, SimpleNode } from '@glimmer/interfaces'; export function clearElement(parent: SimpleElement) { let current: Option = parent.firstChild; diff --git a/packages/@glimmer/util/lib/immediate.ts b/packages/@glimmer/util/lib/immediate.ts index 325ebde2c..e706d6291 100644 --- a/packages/@glimmer/util/lib/immediate.ts +++ b/packages/@glimmer/util/lib/immediate.ts @@ -1,4 +1,5 @@ import { LOCAL_DEBUG } from '@glimmer/local-debug-flags'; + import { debugAssert as assert } from './assert'; /* diff --git a/packages/@glimmer/util/lib/object-utils.ts b/packages/@glimmer/util/lib/object-utils.ts index a866c533c..3a1bc08b1 100644 --- a/packages/@glimmer/util/lib/object-utils.ts +++ b/packages/@glimmer/util/lib/object-utils.ts @@ -11,9 +11,11 @@ export function fillNulls(count: number): T[] { } export function values(obj: { [s: string]: T }): T[] { - const vals = []; - for (const key in obj) { - vals.push(obj[key]); - } - return vals; + return Object.values(obj); +} + +export type ObjectEntry = { [P in keyof D]: [P, D[P]] }[keyof D]; + +export function entries(dict: D): ObjectEntry[] { + return Object.entries(dict) as ObjectEntry[]; } diff --git a/packages/@glimmer/util/lib/platform-utils.ts b/packages/@glimmer/util/lib/platform-utils.ts index de93d33a7..45ee07fb9 100644 --- a/packages/@glimmer/util/lib/platform-utils.ts +++ b/packages/@glimmer/util/lib/platform-utils.ts @@ -1,4 +1,5 @@ -import { Maybe } from '@glimmer/interfaces'; +import { Maybe, Present } from '@glimmer/interfaces'; + import intern from './intern'; export type Factory = new (...args: unknown[]) => T; @@ -23,9 +24,9 @@ export function unwrap(val: Maybe): T { return val as T; } -export function expect(val: Maybe, message: string): T { +export function expect(val: T, message: string): Present { if (val === null || val === undefined) throw new Error(message); - return val as T; + return val as Present; } export function unreachable(message = 'unreachable'): Error { diff --git a/packages/@glimmer/util/lib/present.ts b/packages/@glimmer/util/lib/present.ts index e2dc4767c..fee0a3f7d 100644 --- a/packages/@glimmer/util/lib/present.ts +++ b/packages/@glimmer/util/lib/present.ts @@ -1,6 +1,16 @@ -import { Option, PresentArray } from '@glimmer/interfaces'; +import { Option, Present, PresentArray } from '@glimmer/interfaces'; -export function isPresent(list: readonly T[]): list is PresentArray { +export function isPresent(value: T): value is Present { + return value !== null && value !== undefined; +} + +export function assertPresent(value: T): asserts value is Present { + if (!isPresent(value)) { + throw new Error(`Expected present, got ${value}`); + } +} + +export function isPresentArray(list: readonly T[]): list is PresentArray { return list.length > 0; } @@ -9,38 +19,58 @@ export function ifPresent( ifPresent: (input: PresentArray) => U, otherwise: () => V ): U | V { - if (isPresent(list)) { + if (isPresentArray(list)) { return ifPresent(list); } else { return otherwise(); } } -export function toPresentOption(list: T[]): Option> { - if (isPresent(list)) { +export function arrayToOption(list: T[]): Option> { + if (isPresentArray(list)) { return list; } else { return null; } } -export function assertPresent( +export function assertPresentArray( list: T[], message = `unexpected empty list` ): asserts list is PresentArray { - if (!isPresent(list)) { + if (!isPresentArray(list)) { throw new Error(message); } } -export function mapPresent(list: PresentArray, callback: (input: T) => U): PresentArray; -export function mapPresent( +export function asPresentArray(list: T[], message = `unexpected empty list`): PresentArray { + assertPresentArray(list, message); + return list; +} + +export function getLast(list: PresentArray): T; +export function getLast(list: T[]): T | undefined; +export function getLast(list: T[]): T | undefined { + return list.length === 0 ? undefined : (list[list.length - 1] as T); +} + +export function getFirst(list: PresentArray): T; +export function getFirst(list: T[]): T | undefined; +export function getFirst(list: T[]): T | undefined { + return list.length === 0 ? undefined : (list[0] as T); +} + +export function mapPresentArray( + list: PresentArray, + mapper: (input: T) => U +): PresentArray; +export function mapPresentArray( list: PresentArray | null, - callback: (input: T) => U + mapper: (input: T) => U ): PresentArray | null; -export function mapPresent( +export function mapPresentArray( list: PresentArray | null, - callback: (input: T) => U + mapper: (input: T) => U ): PresentArray | null { if (list === null) { return null; @@ -48,7 +78,7 @@ export function mapPresent( let out: U[] = []; for (let item of list) { - out.push(callback(item)); + out.push(mapper(item)); } return out as PresentArray; diff --git a/packages/@glimmer/util/lib/simple-cast.ts b/packages/@glimmer/util/lib/simple-cast.ts index 24bbdc604..b5c48e7b7 100644 --- a/packages/@glimmer/util/lib/simple-cast.ts +++ b/packages/@glimmer/util/lib/simple-cast.ts @@ -1,5 +1,6 @@ +import { Maybe, NodeType, SimpleDocument, SimpleElement, SimpleNode } from '@glimmer/interfaces'; + import { unreachable } from './platform-utils'; -import { NodeType, SimpleDocument, SimpleElement, SimpleNode } from '@glimmer/interfaces'; interface GenericElementTags { HTML: HTMLElement; @@ -39,8 +40,8 @@ export function castToSimple( ) { if (isDocument(node)) { return node as SimpleDocument; - } else if (isElement(node)) { - return node as SimpleElement; + } else if (isSimpleElement(node)) { + return node; } else { return node as SimpleNode; } @@ -97,8 +98,12 @@ function isDocument(node: Node | SimpleNode | SimpleDocument): node is Document return node.nodeType === NodeType.DOCUMENT_NODE; } -function isElement(node: Node | SimpleNode | SimpleElement): node is Element | SimpleElement { - return node.nodeType === NodeType.ELEMENT_NODE; +export function isSimpleElement(node: Maybe): node is SimpleElement { + return node?.nodeType === NodeType.ELEMENT_NODE; +} + +export function isElement(node: Maybe): node is Element { + return node?.nodeType === NodeType.ELEMENT_NODE && node instanceof Element; } export function checkNode( diff --git a/packages/@glimmer/util/lib/string.ts b/packages/@glimmer/util/lib/string.ts index 646e94412..91ca64abd 100644 --- a/packages/@glimmer/util/lib/string.ts +++ b/packages/@glimmer/util/lib/string.ts @@ -1,3 +1,5 @@ +import { getFirst, getLast, isPresentArray } from './present'; + export function strip(strings: TemplateStringsArray, ...args: unknown[]) { let out = ''; for (let i = 0; i < strings.length; i++) { @@ -9,11 +11,11 @@ export function strip(strings: TemplateStringsArray, ...args: unknown[]) { let lines = out.split('\n'); - while (lines.length && lines[0].match(/^\s*$/)) { + while (isPresentArray(lines) && getFirst(lines).match(/^\s*$/)) { lines.shift(); } - while (lines.length && lines[lines.length - 1].match(/^\s*$/)) { + while (isPresentArray(lines) && getLast(lines).match(/^\s*$/)) { lines.pop(); } diff --git a/packages/@glimmer/util/lib/template.ts b/packages/@glimmer/util/lib/template.ts index 863d66ea9..0c8504a8a 100644 --- a/packages/@glimmer/util/lib/template.ts +++ b/packages/@glimmer/util/lib/template.ts @@ -1,4 +1,4 @@ -import { HandleResult, Template, TemplateOk, OkHandle, ErrHandle } from '@glimmer/interfaces'; +import { ErrHandle, HandleResult, OkHandle, Template, TemplateOk } from '@glimmer/interfaces'; export function unwrapHandle(handle: HandleResult): number { if (typeof handle === 'number') { diff --git a/packages/@glimmer/util/lib/untouchable-this.ts b/packages/@glimmer/util/lib/untouchable-this.ts index 5faa218a1..061696fc3 100644 --- a/packages/@glimmer/util/lib/untouchable-this.ts +++ b/packages/@glimmer/util/lib/untouchable-this.ts @@ -1,4 +1,5 @@ import { DEBUG } from '@glimmer/env'; + import { HAS_NATIVE_PROXY } from './platform-utils'; export default function buildUntouchableThis(source: string): null | object { diff --git a/packages/@glimmer/util/test/debug-to-string-test.ts b/packages/@glimmer/util/test/debug-to-string-test.ts index 6fe63af39..d8b723e3d 100644 --- a/packages/@glimmer/util/test/debug-to-string-test.ts +++ b/packages/@glimmer/util/test/debug-to-string-test.ts @@ -1,4 +1,5 @@ import { DEBUG } from '@glimmer/env'; + import { debugToString as maybeDebugToString } from '..'; // `window.ActiveXObject` is "falsey" in IE11 (but not `undefined` or `false`) // `"ActiveXObject" in window` returns `true` in all IE versions diff --git a/packages/@glimmer/util/test/immediate-test.ts b/packages/@glimmer/util/test/immediate-test.ts index 9f4fcf102..2a18ae7fb 100644 --- a/packages/@glimmer/util/test/immediate-test.ts +++ b/packages/@glimmer/util/test/immediate-test.ts @@ -1,4 +1,4 @@ -import { encodeImmediate, decodeImmediate, ImmediateConstants } from '..'; +import { decodeImmediate, encodeImmediate, ImmediateConstants } from '..'; const { module, test } = QUnit; diff --git a/packages/@glimmer/validator/index.ts b/packages/@glimmer/validator/index.ts index fe25f93b5..13afe2788 100644 --- a/packages/@glimmer/validator/index.ts +++ b/packages/@glimmer/validator/index.ts @@ -1,4 +1,4 @@ -import { symbolFor, getGlobal } from './lib/utils'; +import { getGlobal, symbolFor } from './lib/utils'; const GLIMMER_VALIDATOR_REGISTRATION = symbolFor('GLIMMER_VALIDATOR_REGISTRATION'); @@ -12,19 +12,41 @@ if (globalObj[GLIMMER_VALIDATOR_REGISTRATION] === true) { globalObj[GLIMMER_VALIDATOR_REGISTRATION] = true; -export { CombinatorTag, ConstantTag, DirtyableTag, Tag, UpdatableTag } from '@glimmer/interfaces'; - +export { + beginTrackingTransaction, + endTrackingTransaction, + logTrackingStack, + runInTrackingTransaction, + setTrackingTransactionEnv, +} from './lib/debug'; +export { dirtyTagFor, tagFor, TagMeta, tagMetaFor } from './lib/meta'; +export { trackedData } from './lib/tracked-data'; +export { + beginTrackFrame, + beginUntrackFrame, + Cache, + consumeTag, + createCache, + endTrackFrame, + endUntrackFrame, + getValue, + isConst, + isTracking, + resetTracking, + track, + untrack, +} from './lib/tracking'; export { ALLOW_CYCLES, bump, combine, COMPUTE, - CONSTANT_TAG, CONSTANT, + CONSTANT_TAG, createTag, createUpdatableTag, - CurrentTag, CURRENT_TAG, + CurrentTag, DIRTY_TAG as dirtyTag, INITIAL, isConstTag, @@ -32,35 +54,8 @@ export { UPDATE_TAG as updateTag, validateTag, valueForTag, - VolatileTag, - VOLATILE_TAG, VOLATILE, + VOLATILE_TAG, + VolatileTag, } from './lib/validators'; - -export { dirtyTagFor, tagFor, tagMetaFor, TagMeta } from './lib/meta'; - -export { - beginTrackFrame, - endTrackFrame, - beginUntrackFrame, - endUntrackFrame, - resetTracking, - consumeTag, - isTracking, - track, - untrack, - Cache, - createCache, - isConst, - getValue, -} from './lib/tracking'; - -export { trackedData } from './lib/tracked-data'; - -export { - logTrackingStack, - setTrackingTransactionEnv, - runInTrackingTransaction, - beginTrackingTransaction, - endTrackingTransaction, -} from './lib/debug'; +export { CombinatorTag, ConstantTag, DirtyableTag, Tag, UpdatableTag } from '@glimmer/interfaces'; diff --git a/packages/@glimmer/validator/lib/debug.ts b/packages/@glimmer/validator/lib/debug.ts index 55e977cb4..73574eea7 100644 --- a/packages/@glimmer/validator/lib/debug.ts +++ b/packages/@glimmer/validator/lib/debug.ts @@ -1,6 +1,7 @@ -import { Tag } from '@glimmer/interfaces'; import { DEBUG } from '@glimmer/env'; import { assert } from '@glimmer/global-context'; +import { Tag } from '@glimmer/interfaces'; +import { asPresentArray, getLast } from '@glimmer/util'; export let beginTrackingTransaction: | undefined @@ -171,7 +172,7 @@ if (DEBUG) { markTagAsConsumed = (_tag: Tag) => { if (!CONSUMED_TAGS || CONSUMED_TAGS.has(_tag)) return; - CONSUMED_TAGS.set(_tag, TRANSACTION_STACK[TRANSACTION_STACK.length - 1]); + CONSUMED_TAGS.set(_tag, getLast(asPresentArray(TRANSACTION_STACK))); // We need to mark the tag and all of its subtags as consumed, so we need to // cast it and access its internals. In the future this shouldn't be necessary, diff --git a/packages/@glimmer/validator/lib/meta.ts b/packages/@glimmer/validator/lib/meta.ts index 6ab010c48..76aab2a42 100644 --- a/packages/@glimmer/validator/lib/meta.ts +++ b/packages/@glimmer/validator/lib/meta.ts @@ -1,8 +1,9 @@ import { DEBUG } from '@glimmer/env'; -import { DIRTY_TAG, createUpdatableTag } from './validators'; +import { ConstantTag, UpdatableTag } from '@glimmer/interfaces'; + import { assertTagNotConsumed } from './debug'; import { Indexable, unwrap } from './utils'; -import { ConstantTag, UpdatableTag } from '@glimmer/interfaces'; +import { createUpdatableTag, DIRTY_TAG } from './validators'; function isObjectLike(u: T): u is Indexable & T { return (typeof u === 'object' && u !== null) || typeof u === 'function'; diff --git a/packages/@glimmer/validator/lib/tracked-data.ts b/packages/@glimmer/validator/lib/tracked-data.ts index f4ee85968..d70437278 100644 --- a/packages/@glimmer/validator/lib/tracked-data.ts +++ b/packages/@glimmer/validator/lib/tracked-data.ts @@ -1,4 +1,4 @@ -import { tagFor, dirtyTagFor } from './meta'; +import { dirtyTagFor, tagFor } from './meta'; import { consumeTag } from './tracking'; export type Getter = (self: T) => T[K] | undefined; diff --git a/packages/@glimmer/validator/lib/tracking.ts b/packages/@glimmer/validator/lib/tracking.ts index 0db4eeb4f..bff073e07 100644 --- a/packages/@glimmer/validator/lib/tracking.ts +++ b/packages/@glimmer/validator/lib/tracking.ts @@ -1,21 +1,21 @@ import { DEBUG } from '@glimmer/env'; -import { - CONSTANT_TAG, - validateTag, - Revision, - valueForTag, - isConstTag, - combine, -} from './validators'; +import { Tag } from '@glimmer/interfaces'; import { - markTagAsConsumed, beginTrackingTransaction, endTrackingTransaction, + markTagAsConsumed, resetTrackingTransaction, } from './debug'; import { symbol, unwrap } from './utils'; -import { Tag } from '@glimmer/interfaces'; +import { + combine, + CONSTANT_TAG, + isConstTag, + Revision, + validateTag, + valueForTag, +} from './validators'; /** * An object that that tracks @tracked properties that were consumed. @@ -241,13 +241,13 @@ function assertTag(tag: Tag | undefined, cache: InternalCache): asserts tag is T // refactors are merged, and we should generally be moving away from it. It may // be necessary in Ember for a while longer, but I think we'll be able to drop // it in favor of cache sooner rather than later. -export function track(callback: () => void, debugLabel?: string | false): Tag { +export function track(block: () => void, debugLabel?: string | false): Tag { beginTrackFrame(debugLabel); let tag; try { - callback(); + block(); } finally { tag = endTrackFrame(); } diff --git a/packages/@glimmer/validator/lib/validators.ts b/packages/@glimmer/validator/lib/validators.ts index 5333ed593..a6233be12 100644 --- a/packages/@glimmer/validator/lib/validators.ts +++ b/packages/@glimmer/validator/lib/validators.ts @@ -1,22 +1,23 @@ import { DEBUG } from '@glimmer/env'; +import { scheduleRevalidate } from '@glimmer/global-context'; import type { - MonomorphicTagId, COMBINATOR_TAG_ID as ICOMBINATOR_TAG_ID, CONSTANT_TAG_ID as ICONSTANT_TAG_ID, - DIRTYABLE_TAG_ID as IDIRTYABLE_TAG_ID, - UPDATABLE_TAG_ID as IUPDATABLE_TAG_ID, - VOLATILE_TAG_ID as IVOLATILE_TAG_ID, + ConstantTag, CURRENT_TAG_ID as ICURRENT_TAG_ID, - UpdatableTag, - TagTypeSymbol, + DIRTYABLE_TAG_ID as IDIRTYABLE_TAG_ID, DirtyableTag, - TagComputeSymbol, + MonomorphicTagId, Tag, - ConstantTag, + TagComputeSymbol, + TagTypeSymbol, + UPDATABLE_TAG_ID as IUPDATABLE_TAG_ID, + UpdatableTag, + VOLATILE_TAG_ID as IVOLATILE_TAG_ID, } from '@glimmer/interfaces'; -import { scheduleRevalidate } from '@glimmer/global-context'; -import { symbol, unwrap } from './utils'; + import { assertTagNotConsumed } from './debug'; +import { symbol, unwrap } from './utils'; ////////// @@ -97,7 +98,7 @@ class MonomorphicTagImpl { case 0: return CONSTANT_TAG; case 1: - return tags[0]; + return tags[0] as Tag; default: let tag: MonomorphicTagImpl = new MonomorphicTagImpl(COMBINATOR_TAG_ID); tag.subtag = tags; @@ -136,8 +137,8 @@ class MonomorphicTagImpl { if (subtag !== null) { if (Array.isArray(subtag)) { - for (let i = 0; i < subtag.length; i++) { - let value = subtag[i][COMPUTE](); + for (const tag of subtag) { + let value = tag[COMPUTE](); revision = Math.max(value, revision); } } else { diff --git a/packages/@glimmer/validator/package.json b/packages/@glimmer/validator/package.json index 846492fa2..e0e5a3680 100644 --- a/packages/@glimmer/validator/package.json +++ b/packages/@glimmer/validator/package.json @@ -11,6 +11,7 @@ "dependencies": { "@glimmer/env": "^0.1.7", "@glimmer/global-context": "workspace:^", - "@glimmer/interfaces": "workspace:^" + "@glimmer/interfaces": "workspace:^", + "@glimmer/util": "workspace:^" } } diff --git a/packages/@glimmer/validator/test/meta-test.ts b/packages/@glimmer/validator/test/meta-test.ts index 89bbff52b..39720b877 100644 --- a/packages/@glimmer/validator/test/meta-test.ts +++ b/packages/@glimmer/validator/test/meta-test.ts @@ -1,6 +1,5 @@ -import { module, test } from './-utils'; - import { dirtyTagFor, tagFor, validateTag, valueForTag } from '..'; +import { module, test } from './-utils'; module('@glimmer/validator: meta', () => { test('it creates a unique tag for a property on a given object', (assert) => { diff --git a/packages/@glimmer/validator/test/tracking-test.ts b/packages/@glimmer/validator/test/tracking-test.ts index 3004ac467..8368b5a11 100644 --- a/packages/@glimmer/validator/test/tracking-test.ts +++ b/packages/@glimmer/validator/test/tracking-test.ts @@ -1,13 +1,14 @@ -import { module, test } from './-utils'; - import { DEBUG } from '@glimmer/env'; import { + beginTrackFrame, consumeTag, + createCache, createTag, - beginTrackFrame, - endTrackFrame, dirtyTag, + endTrackFrame, + getValue, + isConst, isTracking, runInTrackingTransaction, track, @@ -15,10 +16,8 @@ import { untrack, validateTag, valueForTag, - createCache, - isConst, - getValue, } from '..'; +import { module, test } from './-utils'; module('@glimmer/validator: tracking', () => { module('track', () => { diff --git a/packages/@glimmer/validator/test/validators-test.ts b/packages/@glimmer/validator/test/validators-test.ts index d5b6ab846..48f9e8d54 100644 --- a/packages/@glimmer/validator/test/validators-test.ts +++ b/packages/@glimmer/validator/test/validators-test.ts @@ -1,22 +1,22 @@ -import { module, test } from './-utils'; import { DEBUG } from '@glimmer/env'; import { testOverrideGlobalContext } from '@glimmer/global-context'; import { UpdatableTag } from '@glimmer/interfaces'; import { ALLOW_CYCLES, - CONSTANT_TAG, - CURRENT_TAG, - VOLATILE_TAG, bump, combine, + CONSTANT_TAG, createTag, createUpdatableTag, + CURRENT_TAG, dirtyTag, updateTag, validateTag, valueForTag, + VOLATILE_TAG, } from '..'; +import { module, test } from './-utils'; function unwrap(value: T | null | undefined): T { if (value === null || value === undefined) { diff --git a/packages/@glimmer/vm/index.ts b/packages/@glimmer/vm/index.ts index c39d7483e..d1c74d9d2 100644 --- a/packages/@glimmer/vm/index.ts +++ b/packages/@glimmer/vm/index.ts @@ -1,18 +1,18 @@ export { isMachineOp, isOp } from './lib/opcodes'; export { - MachineRegister, - SyscallRegister, - SavedRegister, - TemporaryRegister, - Register, - isLowLevelRegister, - $pc, $fp, + $pc, $ra, - $sp, $s0, $s1, + $sp, $t0, $t1, $v0, + isLowLevelRegister, + MachineRegister, + Register, + SavedRegister, + SyscallRegister, + TemporaryRegister, } from './lib/registers'; diff --git a/packages/@glimmer/vm/lib/opcodes.ts b/packages/@glimmer/vm/lib/opcodes.ts index 9ecbb2f52..af3028878 100644 --- a/packages/@glimmer/vm/lib/opcodes.ts +++ b/packages/@glimmer/vm/lib/opcodes.ts @@ -1,6 +1,6 @@ /* This file is generated by build/debug.js */ -import { Op, MachineOp } from '@glimmer/interfaces'; +import { MachineOp, Op } from '@glimmer/interfaces'; export function isMachineOp(value: number): value is MachineOp { return value >= 0 && value <= 15; diff --git a/packages/@glimmer/vm/tsconfig.json b/packages/@glimmer/vm/tsconfig.json index a37bcb4f8..cf644ec2e 100644 --- a/packages/@glimmer/vm/tsconfig.json +++ b/packages/@glimmer/vm/tsconfig.json @@ -19,11 +19,13 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, + "useDefineForClassFields": true, + "exactOptionalPropertyTypes": true, "newLine": "LF", "noEmit": true, "skipLibCheck": true }, - "include": ["lib/**/*.ts", "index.ts"] + "include": ["lib/**/*.ts", "index.ts", "**/fixtures/**/*"] } diff --git a/packages/@glimmer/wire-format/index.ts b/packages/@glimmer/wire-format/index.ts index 5ebf8fbd2..745d86e6a 100644 --- a/packages/@glimmer/wire-format/index.ts +++ b/packages/@glimmer/wire-format/index.ts @@ -1,4 +1,4 @@ -import { Statements, Statement, SexpOpcodes, Expressions, Expression } from '@glimmer/interfaces'; +import { Expression, Expressions, SexpOpcodes, Statement, Statements } from '@glimmer/interfaces'; export function is(variant: number): (value: any) => value is T { return function (value: any): value is T { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d6a68ebb..3614cca23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,6 +147,9 @@ importers: eslint-plugin-simple-import-sort: specifier: ^10.0.0 version: 10.0.0(eslint@8.39.0) + eslint-plugin-unused-imports: + specifier: ^2.0.0 + version: 2.0.0(@typescript-eslint/eslint-plugin@5.59.2)(eslint@8.39.0) execa: specifier: ^7.1.1 version: 7.1.1 @@ -656,8 +659,20 @@ importers: specifier: workspace:^ version: link:../local-debug-flags '@types/qunit': - specifier: ^2.9.0 - version: 2.9.0 + specifier: ^2.19.5 + version: 2.19.5 + + packages/@glimmer/syntax/test: + dependencies: + '@glimmer/integration-tests': + specifier: workspace:^ + version: link:../../integration-tests + '@glimmer/interfaces': + specifier: workspace:^ + version: link:../../interfaces + '@glimmer/util': + specifier: workspace:^ + version: link:../../util packages/@glimmer/util: dependencies: @@ -686,6 +701,9 @@ importers: '@glimmer/interfaces': specifier: workspace:^ version: link:../interfaces + '@glimmer/util': + specifier: workspace:^ + version: link:../util packages/@glimmer/vm: dependencies: @@ -5856,6 +5874,7 @@ packages: /eslint-config-prettier@8.8.0(eslint@8.39.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: @@ -6022,6 +6041,26 @@ packages: eslint: 8.39.0 dev: true + /eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.59.2)(eslint@8.39.0): + resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.59.2(@typescript-eslint/parser@5.59.2)(eslint@8.39.0)(typescript@5.0.4) + eslint: 8.39.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -11000,6 +11039,7 @@ packages: /update-browserslist-db@1.0.11(browserslist@4.21.5): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 056fdda5e..ce1332b27 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,4 +2,5 @@ packages: - 'benchmark' - 'lib/local-linker' - 'packages/@glimmer/*' + - 'packages/@glimmer/*/test' - 'packages/build-utils/@glimmer/*' diff --git a/testem-browserstack.js b/testem-browserstack.js index f860ada31..a698ce01f 100644 --- a/testem-browserstack.js +++ b/testem-browserstack.js @@ -97,7 +97,7 @@ module.exports = { '--os', 'OS X', '--osv', - 'Mojave', + 'Monterey', '--b', 'safari', '--bv', @@ -115,7 +115,7 @@ module.exports = { '--os', 'OS X', '--osv', - 'High Sierra', + 'Big Sur', '--b', 'safari', '--bv', diff --git a/tsconfig.build.json b/tsconfig.build.json index 25535ac21..fd738a179 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -19,5 +19,6 @@ "server/**/*", "packages/build-utils/@glimmer/**/*", "./*.js" - ] + ], + "exclude": ["**/fixtures/**/*"] } diff --git a/tsconfig.json b/tsconfig.json index 1a2ed2f14..326530dc2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { // Compilation Configuration "target": "es2020", - "lib": ["ES2020", "DOM"], + "lib": ["ES2020", "ES2022.Error", "DOM"], "inlineSources": true, "inlineSourceMap": true, "declaration": true, @@ -22,10 +22,10 @@ "noUnusedParameters": true, "noImplicitReturns": true, "useDefineForClassFields": true, - // "exactOptionalPropertyTypes": true, - // "noImplicitOverride": true, - // "noPropertyAccessFromIndexSignature": true, - // "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, "newLine": "LF", "noEmit": true, @@ -33,5 +33,5 @@ "skipLibCheck": true }, "include": ["packages/**/*.ts", "packages/interfaces/**/*.d.ts"], - "exclude": ["dist", "ts-dist", "**/dist", "tmp", "node_modules", ".vscode"] + "exclude": ["dist", "ts-dist", "**/dist", "tmp", "node_modules", ".vscode", "**/fixtures/**/*"] }