chore: Merge branch 'main' into minor

This commit is contained in:
Evan You 2023-12-24 22:50:06 +08:00
commit 5ec937723a
10 changed files with 305 additions and 245 deletions

View File

@ -63,7 +63,7 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before
You will need [Node.js](https://nodejs.org) **version 18.12+**, and [PNPM](https://pnpm.io) **version 8+**. You will need [Node.js](https://nodejs.org) **version 18.12+**, and [PNPM](https://pnpm.io) **version 8+**.
We also recommend installing [ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier. We also recommend installing [@antfu/ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier.
After cloning the repo, run: After cloning the repo, run:
@ -90,7 +90,7 @@ The project uses [simple-git-hooks](https://github.com/toplenboren/simple-git-ho
## Scripts ## Scripts
**The examples below will be using the `nr` command from the [ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`. **The examples below will be using the `nr` command from the [@antfu/ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`.
The `run-s` and `run-p` commands found in some scripts are from [npm-run-all](https://github.com/mysticatea/npm-run-all) for orchestrating multiple scripts. `run-s` means "run in sequence" while `run-p` means "run in parallel". The `run-s` and `run-p` commands found in some scripts are from [npm-run-all](https://github.com/mysticatea/npm-run-all) for orchestrating multiple scripts. `run-s` means "run in sequence" while `run-p` means "run in parallel".

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"version": "3.4.0-beta.4", "version": "3.4.0-beta.4",
"packageManager": "pnpm@8.12.0", "packageManager": "pnpm@8.12.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "node scripts/dev.js", "dev": "node scripts/dev.js",
@ -59,8 +59,8 @@
"node": ">=18.12.0" "node": ">=18.12.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/parser": "^7.23.5", "@babel/parser": "^7.23.6",
"@babel/types": "^7.23.5", "@babel/types": "^7.23.6",
"@codspeed/vitest-plugin": "^2.3.1", "@codspeed/vitest-plugin": "^2.3.1",
"@rollup/plugin-alias": "^5.0.1", "@rollup/plugin-alias": "^5.0.1",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.7",
@ -70,16 +70,16 @@
"@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-terser": "^0.4.4",
"@types/hash-sum": "^1.0.2", "@types/hash-sum": "^1.0.2",
"@types/minimist": "^1.2.5", "@types/minimist": "^1.2.5",
"@types/node": "^20.10.4", "@types/node": "^20.10.5",
"@types/semver": "^7.5.5", "@types/semver": "^7.5.5",
"@typescript-eslint/parser": "^6.13.2", "@typescript-eslint/parser": "^6.15.0",
"@vitest/coverage-istanbul": "^1.0.4", "@vitest/coverage-istanbul": "^1.1.0",
"@vue/consolidate": "0.17.3", "@vue/consolidate": "0.17.3",
"conventional-changelog-cli": "^4.1.0", "conventional-changelog-cli": "^4.1.0",
"enquirer": "^2.4.1", "enquirer": "^2.4.1",
"esbuild": "^0.19.5", "esbuild": "^0.19.5",
"esbuild-plugin-polyfill-node": "^0.3.0", "esbuild-plugin-polyfill-node": "^0.3.0",
"eslint": "^8.55.0", "eslint": "^8.56.0",
"eslint-define-config": "^1.24.1", "eslint-define-config": "^1.24.1",
"eslint-plugin-jest": "^27.6.0", "eslint-plugin-jest": "^27.6.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
@ -89,14 +89,14 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"magic-string": "^0.30.5", "magic-string": "^0.30.5",
"markdown-table": "^3.0.3", "markdown-table": "^3.0.3",
"marked": "^11.0.1", "marked": "^11.1.0",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
"prettier": "^3.1.1", "prettier": "^3.1.1",
"pretty-bytes": "^6.1.1", "pretty-bytes": "^6.1.1",
"pug": "^3.0.2", "pug": "^3.0.2",
"puppeteer": "~21.6.0", "puppeteer": "~21.6.1",
"rimraf": "^5.0.5", "rimraf": "^5.0.5",
"rollup": "^4.1.4", "rollup": "^4.1.4",
"rollup-plugin-dts": "^6.1.0", "rollup-plugin-dts": "^6.1.0",
@ -108,9 +108,9 @@
"terser": "^5.22.0", "terser": "^5.22.0",
"todomvc-app-css": "^2.4.3", "todomvc-app-css": "^2.4.3",
"tslib": "^2.6.2", "tslib": "^2.6.2",
"tsx": "^4.6.2", "tsx": "^4.7.0",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.0.5", "vite": "^5.0.5",
"vitest": "^1.0.4" "vitest": "^1.1.0"
} }
} }

View File

@ -32,13 +32,13 @@
}, },
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme", "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme",
"dependencies": { "dependencies": {
"@babel/parser": "^7.23.5", "@babel/parser": "^7.23.6",
"@vue/shared": "workspace:*", "@vue/shared": "workspace:*",
"entities": "^4.5.0", "entities": "^4.5.0",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.0.2" "source-map-js": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/types": "^7.23.5" "@babel/types": "^7.23.6"
} }
} }

View File

@ -939,6 +939,34 @@ describe('resolveType', () => {
manufacturer: ['Object'] manufacturer: ['Object']
}) })
}) })
// #9871
test('shared generics with different args', () => {
const files = {
'/foo.ts': `export interface Foo<T> { value: T }`
}
const { props } = resolve(
`import type { Foo } from './foo'
defineProps<Foo<string>>()`,
files,
undefined,
`/One.vue`
)
expect(props).toStrictEqual({
value: ['String']
})
const { props: props2 } = resolve(
`import type { Foo } from './foo'
defineProps<Foo<number>>()`,
files,
undefined,
`/Two.vue`,
false /* do not invalidate cache */
)
expect(props2).toStrictEqual({
value: ['Number']
})
})
}) })
describe('errors', () => { describe('errors', () => {
@ -1012,7 +1040,8 @@ function resolve(
code: string, code: string,
files: Record<string, string> = {}, files: Record<string, string> = {},
options?: Partial<SFCScriptCompileOptions>, options?: Partial<SFCScriptCompileOptions>,
sourceFileName: string = '/Test.vue' sourceFileName: string = '/Test.vue',
invalidateCache = true
) { ) {
const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, { const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, {
filename: sourceFileName filename: sourceFileName
@ -1030,8 +1059,10 @@ function resolve(
...options ...options
}) })
for (const file in files) { if (invalidateCache) {
invalidateTypeCache(file) for (const file in files) {
invalidateTypeCache(file)
}
} }
// ctx.userImports is collected when calling compileScript(), but we are // ctx.userImports is collected when calling compileScript(), but we are

View File

@ -32,7 +32,7 @@
}, },
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme", "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme",
"dependencies": { "dependencies": {
"@babel/parser": "^7.23.5", "@babel/parser": "^7.23.6",
"@vue/compiler-core": "workspace:*", "@vue/compiler-core": "workspace:*",
"@vue/compiler-dom": "workspace:*", "@vue/compiler-dom": "workspace:*",
"@vue/compiler-ssr": "workspace:*", "@vue/compiler-ssr": "workspace:*",
@ -43,7 +43,7 @@
"source-map-js": "^1.0.2" "source-map-js": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/types": "^7.23.5", "@babel/types": "^7.23.6",
"@vue/consolidate": "^0.17.3", "@vue/consolidate": "^0.17.3",
"hash-sum": "^2.0.0", "hash-sum": "^2.0.0",
"lru-cache": "^10.1.0", "lru-cache": "^10.1.0",

View File

@ -115,7 +115,7 @@ export class TypeScope {
public types: Record<string, ScopeTypeNode> = Object.create(null), public types: Record<string, ScopeTypeNode> = Object.create(null),
public declares: Record<string, ScopeTypeNode> = Object.create(null) public declares: Record<string, ScopeTypeNode> = Object.create(null)
) {} ) {}
isGenericScope = false
resolvedImportSources: Record<string, string> = Object.create(null) resolvedImportSources: Record<string, string> = Object.create(null)
exportedTypes: Record<string, ScopeTypeNode> = Object.create(null) exportedTypes: Record<string, ScopeTypeNode> = Object.create(null)
exportedDeclares: Record<string, ScopeTypeNode> = Object.create(null) exportedDeclares: Record<string, ScopeTypeNode> = Object.create(null)
@ -146,15 +146,17 @@ export function resolveTypeElements(
scope?: TypeScope, scope?: TypeScope,
typeParameters?: Record<string, Node> typeParameters?: Record<string, Node>
): ResolvedElements { ): ResolvedElements {
if (node._resolvedElements) { const canCache = !typeParameters
if (canCache && node._resolvedElements) {
return node._resolvedElements return node._resolvedElements
} }
return (node._resolvedElements = innerResolveTypeElements( const resolved = innerResolveTypeElements(
ctx, ctx,
node, node,
node._ownerScope || scope || ctxToScope(ctx), node._ownerScope || scope || ctxToScope(ctx),
typeParameters typeParameters
)) )
return canCache ? (node._resolvedElements = resolved) : resolved
} }
function innerResolveTypeElements( function innerResolveTypeElements(
@ -215,17 +217,18 @@ function innerResolveTypeElements(
} }
const resolved = resolveTypeReference(ctx, node, scope) const resolved = resolveTypeReference(ctx, node, scope)
if (resolved) { if (resolved) {
const typeParams: Record<string, Node> = Object.create(null) let typeParams: Record<string, Node> | undefined
if ( if (
(resolved.type === 'TSTypeAliasDeclaration' || (resolved.type === 'TSTypeAliasDeclaration' ||
resolved.type === 'TSInterfaceDeclaration') && resolved.type === 'TSInterfaceDeclaration') &&
resolved.typeParameters && resolved.typeParameters &&
node.typeParameters node.typeParameters
) { ) {
typeParams = Object.create(null)
resolved.typeParameters.params.forEach((p, i) => { resolved.typeParameters.params.forEach((p, i) => {
let param = typeParameters && typeParameters[p.name] let param = typeParameters && typeParameters[p.name]
if (!param) param = node.typeParameters!.params[i] if (!param) param = node.typeParameters!.params[i]
typeParams[p.name] = param typeParams![p.name] = param
}) })
} }
return resolveTypeElements( return resolveTypeElements(
@ -322,6 +325,7 @@ function typeElementsToMap(
// capture generic parameters on node's scope // capture generic parameters on node's scope
if (typeParameters) { if (typeParameters) {
scope = createChildScope(scope) scope = createChildScope(scope)
scope.isGenericScope = true
Object.assign(scope.types, typeParameters) Object.assign(scope.types, typeParameters)
} }
;(e as MaybeWithScope)._ownerScope = scope ;(e as MaybeWithScope)._ownerScope = scope
@ -694,16 +698,18 @@ function resolveTypeReference(
name?: string, name?: string,
onlyExported = false onlyExported = false
): ScopeTypeNode | undefined { ): ScopeTypeNode | undefined {
if (node._resolvedReference) { const canCache = !scope?.isGenericScope
if (canCache && node._resolvedReference) {
return node._resolvedReference return node._resolvedReference
} }
return (node._resolvedReference = innerResolveTypeReference( const resolved = innerResolveTypeReference(
ctx, ctx,
scope || ctxToScope(ctx), scope || ctxToScope(ctx),
name || getReferenceName(node), name || getReferenceName(node),
node, node,
onlyExported onlyExported
)) )
return canCache ? (node._resolvedReference = resolved) : resolved
} }
function innerResolveTypeReference( function innerResolveTypeReference(

View File

@ -1,8 +1,8 @@
import { type SpyInstance } from 'vitest' import { type MockInstance } from 'vitest'
import { render, h } from '@vue/runtime-dom' import { render, h } from '@vue/runtime-dom'
describe('customized built-in elements support', () => { describe('customized built-in elements support', () => {
let createElement: SpyInstance let createElement: MockInstance
afterEach(() => { afterEach(() => {
createElement.mockRestore() createElement.mockRestore()
}) })

View File

@ -38,7 +38,7 @@
}, },
"homepage": "https://github.com/vuejs/core/tree/main/packages/vue-compat#readme", "homepage": "https://github.com/vuejs/core/tree/main/packages/vue-compat#readme",
"dependencies": { "dependencies": {
"@babel/parser": "^7.23.5", "@babel/parser": "^7.23.6",
"estree-walker": "^2.0.2", "estree-walker": "^2.0.2",
"source-map-js": "^1.0.2" "source-map-js": "^1.0.2"
}, },

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
import { type SpyInstance } from 'vitest' import { type MockInstance } from 'vitest'
vi.stubGlobal('MathMLElement', class MathMLElement {}) vi.stubGlobal('MathMLElement', class MathMLElement {})
@ -67,7 +67,7 @@ expect.extend({
} }
}) })
let warn: SpyInstance let warn: MockInstance
const asserted: Set<string> = new Set() const asserted: Set<string> = new Set()
beforeEach(() => { beforeEach(() => {