makeMap,
babelParserDefaultPlugins,
hasOwn,
- isString
+ isString,
+ isReferencedIdentifier,
+ isInDestructureAssignment,
+ isStaticProperty,
+ isStaticPropertyKey,
+ isFunctionType
} from '@vue/shared'
import { createCompilerError, ErrorCodes } from '../errors'
import {
Node,
- Function,
Identifier,
- ObjectProperty,
AssignmentExpression,
UpdateExpression
} from '@babel/types'
ids.push(node)
}
}
- } else if (isFunction(node)) {
+ } else if (isFunctionType(node)) {
// walk function expressions and add its arguments to known identifiers
// so that we don't prefix them
node.params.forEach(p =>
return ret
}
-const isFunction = (node: Node): node is Function => {
- return /Function(?:Expression|Declaration)$|Method$/.test(node.type)
-}
-
-const isStaticProperty = (node: Node): node is ObjectProperty =>
- node &&
- (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
- !node.computed
-
-const isStaticPropertyKey = (node: Node, parent: Node) =>
- isStaticProperty(parent) && parent.key === node
-
function shouldPrefix(id: Identifier, parent: Node, parentStack: Node[]) {
- // declaration id
- if (
- (parent.type === 'VariableDeclarator' ||
- parent.type === 'ClassDeclaration') &&
- parent.id === id
- ) {
- return false
- }
-
- if (isFunction(parent)) {
- // function decalration/expression id
- if ((parent as any).id === id) {
- return false
- }
- // params list
- if (parent.params.includes(id)) {
- return false
- }
- }
-
- // property key
- // this also covers object destructure pattern
- if (isStaticPropertyKey(id, parent)) {
- return false
- }
-
- // non-assignment array destructure pattern
- if (
- parent.type === 'ArrayPattern' &&
- !isInDestructureAssignment(parent, parentStack)
- ) {
- return false
- }
-
- // member expression property
- if (
- (parent.type === 'MemberExpression' ||
- parent.type === 'OptionalMemberExpression') &&
- parent.property === id &&
- !parent.computed
- ) {
- return false
- }
-
- // is a special keyword but parsed as identifier
- if (id.name === 'arguments') {
- return false
- }
-
// skip whitelisted globals
if (isGloballyWhitelisted(id.name)) {
return false
}
-
// special case for webpack compilation
if (id.name === 'require') {
return false
}
-
- return true
-}
-
-function isInDestructureAssignment(parent: Node, parentStack: Node[]): boolean {
- if (
- parent &&
- (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')
- ) {
- let i = parentStack.length
- while (i--) {
- const p = parentStack[i]
- if (p.type === 'AssignmentExpression') {
- return true
- } else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
- break
- }
- }
- }
- return false
+ return isReferencedIdentifier(id, parent, parentStack)
}
function stringifyExpression(exp: ExpressionNode | string): string {
camelize,
capitalize,
generateCodeFrame,
+ isFunctionType,
+ isReferencedIdentifier,
+ isStaticProperty,
+ isStaticPropertyKey,
makeMap
} from '@vue/shared'
import {
ArrayPattern,
Identifier,
ExportSpecifier,
- Function as FunctionNode,
TSType,
TSTypeLiteral,
TSFunctionType,
) {
;(walk as any)(node, {
enter(child: Node, parent: Node) {
- if (isFunction(child)) {
+ if (isFunctionType(child)) {
this.skip()
}
if (child.type === 'AwaitExpression') {
if (node.type === 'Identifier') {
if (
!knownIds[node.name] &&
- isRefIdentifier(node, parent!, parentStack)
+ isReferencedIdentifier(node, parent!, parentStack)
) {
onIdentifier(node, parent!, parentStack)
}
- } else if (isFunction(node)) {
+ } else if (isFunctionType(node)) {
// #3445
// should not rewrite local variables sharing a name with a top-level ref
if (node.body.type === 'BlockStatement') {
})
}
-function isRefIdentifier(
- id: Identifier,
- parent: Node | null,
- parentStack: Node[]
-) {
- if (!parent) {
- return true
- }
-
- // declaration id
- if (
- (parent.type === 'VariableDeclarator' ||
- parent.type === 'ClassDeclaration') &&
- parent.id === id
- ) {
- return false
- }
-
- if (isFunction(parent)) {
- // function decalration/expression id
- if ((parent as any).id === id) {
- return false
- }
- // params list
- if (parent.params.includes(id)) {
- return false
- }
- }
-
- // property key
- // this also covers object destructure pattern
- if (isStaticPropertyKey(id, parent)) {
- return false
- }
-
- // non-assignment array destructure pattern
- if (
- parent.type === 'ArrayPattern' &&
- !isInDestructureAssignment(parent, parentStack)
- ) {
- return false
- }
-
- // member expression property
- if (
- (parent.type === 'MemberExpression' ||
- parent.type === 'OptionalMemberExpression') &&
- parent.property === id &&
- !parent.computed
- ) {
- return false
- }
-
- // is a special keyword but parsed as identifier
- if (id.name === 'arguments') {
- return false
- }
-
- return true
-}
-
-const isStaticProperty = (node: Node): node is ObjectProperty =>
- node &&
- (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
- !node.computed
-
-const isStaticPropertyKey = (node: Node, parent: Node) =>
- isStaticProperty(parent) && parent.key === node
-
-function isFunction(node: Node): node is FunctionNode {
- return /Function(?:Expression|Declaration)$|Method$/.test(node.type)
-}
-
function isCallOf(
node: Node | null | undefined,
test: string | ((id: string) => boolean)
WritableComputedRef
} from '@vue/reactivity'
-export function $ref<T>(arg: T | Ref<T>): UnwrapRef<T>
+declare const RefMarker: unique symbol
+type RefValue<T> = T & { [RefMarker]?: any }
+
+export function $ref<T>(arg?: T | Ref<T>): RefValue<UnwrapRef<T>>
export function $ref() {}
-export function $shallowRef<T>(arg: T): T {
- return arg
-}
+export function $shallowRef<T>(arg?: T): RefValue<T>
+export function $shallowRef() {}
declare const ComputedRefMarker: unique symbol
-type ComputedValue<T> = T & { [ComputedRefMarker]?: any }
+type ComputedRefValue<T> = T & { [ComputedRefMarker]?: any }
declare const WritableComputedRefMarker: unique symbol
-type WritableComputedValue<T> = T & { [WritableComputedRefMarker]?: any }
+type WritableComputedRefValue<T> = T & { [WritableComputedRefMarker]?: any }
export function $computed<T>(
getter: () => T,
debuggerOptions?: DebuggerOptions
-): ComputedValue<T>
+): ComputedRefValue<T>
export function $computed<T>(
options: WritableComputedOptions<T>,
debuggerOptions?: DebuggerOptions
-): WritableComputedValue<T>
+): WritableComputedRefValue<T>
export function $computed() {}
export function $fromRefs<T>(source: T): ShallowUnwrapRef<T>
return null as any
}
-export function $raw<T>(value: ComputedValue<T>): ComputedRef<T>
-export function $raw<T>(value: WritableComputedValue<T>): WritableComputedRef<T>
-export function $raw<T>(value: T): Ref<T>
+export function $raw<T extends ComputedRefValue<any>>(
+ value: T
+): T extends ComputedRefValue<infer V> ? ComputedRef<V> : never
+export function $raw<T>(
+ value: WritableComputedRefValue<T>
+): WritableComputedRef<T>
+export function $raw<T>(value: RefValue<T>): Ref<T>
export function $raw() {
return null as any
}
--- /dev/null
+import {
+ Identifier,
+ Node,
+ isReferenced,
+ Function,
+ ObjectProperty
+} from '@babel/types'
+
+export function isReferencedIdentifier(
+ id: Identifier,
+ parent: Node | null,
+ parentStack: Node[]
+) {
+ if (!parent) {
+ return true
+ }
+
+ // is a special keyword but parsed as identifier
+ if (id.name === 'arguments') {
+ return false
+ }
+
+ if (isReferenced(id, parent)) {
+ return true
+ }
+
+ // babel's isReferenced check returns false for ids being assigned to, so we
+ // need to cover those cases here
+ switch (parent.type) {
+ case 'AssignmentExpression':
+ case 'AssignmentPattern':
+ return true
+ case 'ObjectPattern':
+ case 'ArrayPattern':
+ return isInDestructureAssignment(parent, parentStack)
+ }
+
+ return false
+}
+
+export function isInDestructureAssignment(
+ parent: Node,
+ parentStack: Node[]
+): boolean {
+ if (
+ parent &&
+ (parent.type === 'ObjectProperty' || parent.type === 'ArrayPattern')
+ ) {
+ let i = parentStack.length
+ while (i--) {
+ const p = parentStack[i]
+ if (p.type === 'AssignmentExpression') {
+ return true
+ } else if (p.type !== 'ObjectProperty' && !p.type.endsWith('Pattern')) {
+ break
+ }
+ }
+ }
+ return false
+}
+
+export const isFunctionType = (node: Node): node is Function => {
+ return /Function(?:Expression|Declaration)$|Method$/.test(node.type)
+}
+
+export const isStaticProperty = (node: Node): node is ObjectProperty =>
+ node &&
+ (node.type === 'ObjectProperty' || node.type === 'ObjectMethod') &&
+ !node.computed
+
+export const isStaticPropertyKey = (node: Node, parent: Node) =>
+ isStaticProperty(parent) && parent.key === node
export * from './escapeHtml'
export * from './looseEqual'
export * from './toDisplayString'
+export * from './astUtils'
/**
* List of @babel/parser plugins that are used for template expression