Skip to content

Commit

Permalink
feat: error on unexpected custom directive on <slot>
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleSound committed Apr 21, 2024
1 parent 831b818 commit f183394
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ export function render(_ctx) {
}"
`;
exports[`compiler: transform <slot> outlets > error on unexpected custom directive on <slot> 1`] = `
"import { createSlot as _createSlot } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createSlot("default", null)
return n0
}"
`;
exports[`compiler: transform <slot> outlets > named slot outlet with fallback 1`] = `
"import { createSlot as _createSlot, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NodeTypes } from '@vue/compiler-core'
import { ErrorCodes, NodeTypes } from '@vue/compiler-core'
import {
IRNodeTypes,
transformChildren,
Expand Down Expand Up @@ -208,5 +208,26 @@ describe('compiler: transform <slot> outlets', () => {
])
})

test.todo('error on unexpected custom directive on <slot>')
test('error on unexpected custom directive on <slot>', () => {
const onError = vi.fn()
const source = `<slot v-foo />`
const index = source.indexOf('v-foo')
const { code } = compileWithSlotsOutlet(source, { onError })
expect(code).toMatchSnapshot()
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
loc: {
start: {
offset: index,
line: 1,
column: index + 1,
},
end: {
offset: index + 5,
line: 1,
column: index + 6,
},
},
})
})
})
29 changes: 24 additions & 5 deletions packages/compiler-vapor/src/transforms/transformSlotOutlet.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {
type AttributeNode,
type DirectiveNode,
type ElementNode,
ElementTypes,
ErrorCodes,
NodeTypes,
type SimpleExpressionNode,
createCompilerError,
createSimpleExpression,
isStaticArgOf,
isStaticExp,
Expand All @@ -16,7 +20,7 @@ import {
type IRProps,
type VaporDirectiveNode,
} from '../ir'
import { camelize, extend } from '@vue/shared'
import { camelize, extend, isBuiltInDirective } from '@vue/shared'
import { genDefaultDynamic } from './utils'
import { buildProps } from './transformElement'

Expand All @@ -33,7 +37,8 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
)

let name: SimpleExpressionNode | undefined
const nonNameProps = []
const nonNameProps: (AttributeNode | DirectiveNode)[] = []
const customDirectives: DirectiveNode[] = []
for (const p of props) {
if (p.type === NodeTypes.ATTRIBUTE) {
if (p.value) {
Expand All @@ -58,13 +63,27 @@ export const transformSlotOutlet: NodeTransform = (node, context) => {
name.ast = null
}
} else {
if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
p.arg.content = camelize(p.arg.content)
if (!isBuiltInDirective(p.name)) {
customDirectives.push(p)
} else {
if (p.name === 'bind' && p.arg && isStaticExp(p.arg)) {
p.arg.content = camelize(p.arg.content)
}
nonNameProps.push(p)
}
nonNameProps.push(p)
}
}
}

if (customDirectives.length) {
context.options.onError(
createCompilerError(
ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET,
customDirectives[0].loc,
),
)
}

name ||= createSimpleExpression('default', true)
let irProps: IRProps[] = []
if (nonNameProps.length > 0) {
Expand Down

0 comments on commit f183394

Please sign in to comment.