2019-09-27 23:42:02 +08:00
|
|
|
import { isString } from '@vue/shared'
|
|
|
|
|
2019-09-17 23:07:46 +08:00
|
|
|
// Vue template is a platform-agnostic superset of HTML (syntax only).
|
|
|
|
// More namespaces like SVG and MathML are declared by platform specific
|
|
|
|
// compilers.
|
|
|
|
export type Namespace = number
|
|
|
|
|
|
|
|
export const enum Namespaces {
|
|
|
|
HTML
|
|
|
|
}
|
|
|
|
|
2019-09-17 02:43:29 +08:00
|
|
|
export const enum NodeTypes {
|
2019-09-18 07:08:47 +08:00
|
|
|
ROOT,
|
|
|
|
ELEMENT,
|
2019-09-17 02:43:29 +08:00
|
|
|
TEXT,
|
|
|
|
COMMENT,
|
2019-09-27 23:42:02 +08:00
|
|
|
SIMPLE_EXPRESSION,
|
|
|
|
INTERPOLATION,
|
2019-09-18 07:08:47 +08:00
|
|
|
ATTRIBUTE,
|
2019-09-17 02:43:29 +08:00
|
|
|
DIRECTIVE,
|
2019-09-22 03:47:26 +08:00
|
|
|
// containers
|
2019-09-23 14:52:54 +08:00
|
|
|
COMPOUND_EXPRESSION,
|
2019-09-18 07:08:47 +08:00
|
|
|
IF,
|
|
|
|
IF_BRANCH,
|
2019-09-22 03:47:26 +08:00
|
|
|
FOR,
|
|
|
|
// codegen
|
2019-09-23 04:50:57 +08:00
|
|
|
JS_CALL_EXPRESSION,
|
|
|
|
JS_OBJECT_EXPRESSION,
|
|
|
|
JS_PROPERTY,
|
2019-09-28 10:25:32 +08:00
|
|
|
JS_ARRAY_EXPRESSION,
|
|
|
|
JS_SLOT_FUNCTION
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export const enum ElementTypes {
|
|
|
|
ELEMENT,
|
|
|
|
COMPONENT,
|
2019-09-18 07:08:47 +08:00
|
|
|
SLOT,
|
|
|
|
TEMPLATE
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface Node {
|
|
|
|
type: NodeTypes
|
|
|
|
loc: SourceLocation
|
|
|
|
}
|
|
|
|
|
2019-09-22 03:47:26 +08:00
|
|
|
// The node's range. The `start` is inclusive and `end` is exclusive.
|
|
|
|
// [start, end)
|
|
|
|
export interface SourceLocation {
|
|
|
|
start: Position
|
|
|
|
end: Position
|
|
|
|
source: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface Position {
|
|
|
|
offset: number // from start of file
|
|
|
|
line: number
|
|
|
|
column: number
|
|
|
|
}
|
|
|
|
|
2019-09-18 07:08:47 +08:00
|
|
|
export type ParentNode = RootNode | ElementNode | IfBranchNode | ForNode
|
2019-09-22 03:47:26 +08:00
|
|
|
|
2019-09-27 23:42:02 +08:00
|
|
|
export type ExpressionNode = SimpleExpressionNode | CompoundExpressionNode
|
|
|
|
|
2019-09-18 07:08:47 +08:00
|
|
|
export type ChildNode =
|
|
|
|
| ElementNode
|
2019-09-27 23:42:02 +08:00
|
|
|
| InterpolationNode
|
2019-10-01 02:51:55 +08:00
|
|
|
| CompoundExpressionNode
|
2019-09-18 07:08:47 +08:00
|
|
|
| TextNode
|
|
|
|
| CommentNode
|
|
|
|
| IfNode
|
|
|
|
| ForNode
|
|
|
|
|
2019-09-17 02:43:29 +08:00
|
|
|
export interface RootNode extends Node {
|
|
|
|
type: NodeTypes.ROOT
|
2019-09-18 07:08:47 +08:00
|
|
|
children: ChildNode[]
|
2019-09-23 11:07:36 +08:00
|
|
|
imports: string[]
|
|
|
|
statements: string[]
|
2019-09-26 02:13:33 +08:00
|
|
|
hoists: JSChildNode[]
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface ElementNode extends Node {
|
|
|
|
type: NodeTypes.ELEMENT
|
2019-09-17 23:07:46 +08:00
|
|
|
ns: Namespace
|
2019-09-17 02:43:29 +08:00
|
|
|
tag: string
|
|
|
|
tagType: ElementTypes
|
|
|
|
isSelfClosing: boolean
|
2019-09-22 05:42:12 +08:00
|
|
|
props: Array<AttributeNode | DirectiveNode>
|
2019-09-18 07:08:47 +08:00
|
|
|
children: ChildNode[]
|
2019-09-22 03:47:26 +08:00
|
|
|
codegenNode: CallExpression | undefined
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface TextNode extends Node {
|
|
|
|
type: NodeTypes.TEXT
|
|
|
|
content: string
|
|
|
|
isEmpty: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface CommentNode extends Node {
|
|
|
|
type: NodeTypes.COMMENT
|
|
|
|
content: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface AttributeNode extends Node {
|
|
|
|
type: NodeTypes.ATTRIBUTE
|
|
|
|
name: string
|
|
|
|
value: TextNode | undefined
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface DirectiveNode extends Node {
|
|
|
|
type: NodeTypes.DIRECTIVE
|
|
|
|
name: string
|
|
|
|
exp: ExpressionNode | undefined
|
|
|
|
arg: ExpressionNode | undefined
|
|
|
|
modifiers: string[]
|
|
|
|
}
|
|
|
|
|
2019-09-27 23:42:02 +08:00
|
|
|
export interface SimpleExpressionNode extends Node {
|
|
|
|
type: NodeTypes.SIMPLE_EXPRESSION
|
2019-09-17 02:43:29 +08:00
|
|
|
content: string
|
|
|
|
isStatic: boolean
|
2019-09-28 12:19:24 +08:00
|
|
|
// an expression parsed as the params of a function will track
|
|
|
|
// the identifiers declared inside the function body.
|
|
|
|
identifiers?: string[]
|
2019-09-27 23:42:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface InterpolationNode extends Node {
|
|
|
|
type: NodeTypes.INTERPOLATION
|
|
|
|
content: ExpressionNode
|
|
|
|
}
|
|
|
|
|
|
|
|
// always dynamic
|
|
|
|
export interface CompoundExpressionNode extends Node {
|
|
|
|
type: NodeTypes.COMPOUND_EXPRESSION
|
2019-10-01 02:51:55 +08:00
|
|
|
children: (SimpleExpressionNode | InterpolationNode | TextNode | string)[]
|
2019-09-28 12:19:24 +08:00
|
|
|
// an expression parsed as the params of a function will track
|
|
|
|
// the identifiers declared inside the function body.
|
|
|
|
identifiers?: string[]
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
2019-09-18 07:08:47 +08:00
|
|
|
export interface IfNode extends Node {
|
|
|
|
type: NodeTypes.IF
|
|
|
|
branches: IfBranchNode[]
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface IfBranchNode extends Node {
|
|
|
|
type: NodeTypes.IF_BRANCH
|
|
|
|
condition: ExpressionNode | undefined // else
|
|
|
|
children: ChildNode[]
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface ForNode extends Node {
|
|
|
|
type: NodeTypes.FOR
|
|
|
|
source: ExpressionNode
|
2019-09-29 04:02:08 +08:00
|
|
|
valueAlias: ExpressionNode | undefined
|
|
|
|
keyAlias: ExpressionNode | undefined
|
|
|
|
objectIndexAlias: ExpressionNode | undefined
|
2019-09-18 07:08:47 +08:00
|
|
|
children: ChildNode[]
|
|
|
|
}
|
|
|
|
|
2019-09-23 04:50:57 +08:00
|
|
|
// We also include a number of JavaScript AST nodes for code generation.
|
|
|
|
// The AST is an intentioanlly minimal subset just to meet the exact needs of
|
2019-09-22 03:47:26 +08:00
|
|
|
// Vue render function generation.
|
2019-09-23 04:50:57 +08:00
|
|
|
export type JSChildNode =
|
2019-09-22 03:47:26 +08:00
|
|
|
| CallExpression
|
|
|
|
| ObjectExpression
|
|
|
|
| ArrayExpression
|
|
|
|
| ExpressionNode
|
2019-09-28 10:25:32 +08:00
|
|
|
| SlotFunctionExpression
|
2019-09-22 03:47:26 +08:00
|
|
|
|
|
|
|
export interface CallExpression extends Node {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_CALL_EXPRESSION
|
2019-10-01 09:17:12 +08:00
|
|
|
callee: string
|
2019-09-28 08:29:20 +08:00
|
|
|
arguments: (string | JSChildNode | ChildNode[])[]
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
|
|
|
|
2019-09-22 03:47:26 +08:00
|
|
|
export interface ObjectExpression extends Node {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_OBJECT_EXPRESSION
|
2019-09-22 03:47:26 +08:00
|
|
|
properties: Array<Property>
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface Property extends Node {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_PROPERTY
|
2019-09-22 03:47:26 +08:00
|
|
|
key: ExpressionNode
|
2019-09-26 00:39:46 +08:00
|
|
|
value: JSChildNode
|
2019-09-22 03:47:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface ArrayExpression extends Node {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_ARRAY_EXPRESSION
|
|
|
|
elements: Array<string | JSChildNode>
|
2019-09-17 02:43:29 +08:00
|
|
|
}
|
2019-09-22 05:42:12 +08:00
|
|
|
|
2019-09-28 10:25:32 +08:00
|
|
|
export interface SlotFunctionExpression extends Node {
|
|
|
|
type: NodeTypes.JS_SLOT_FUNCTION
|
|
|
|
params: ExpressionNode | undefined
|
|
|
|
returns: ChildNode[]
|
|
|
|
}
|
|
|
|
|
2019-09-22 05:42:12 +08:00
|
|
|
export function createArrayExpression(
|
|
|
|
elements: ArrayExpression['elements'],
|
|
|
|
loc: SourceLocation
|
|
|
|
): ArrayExpression {
|
|
|
|
return {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_ARRAY_EXPRESSION,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc,
|
|
|
|
elements
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createObjectExpression(
|
|
|
|
properties: Property[],
|
|
|
|
loc: SourceLocation
|
|
|
|
): ObjectExpression {
|
|
|
|
return {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_OBJECT_EXPRESSION,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc,
|
|
|
|
properties
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createObjectProperty(
|
|
|
|
key: ExpressionNode,
|
2019-09-27 23:42:02 +08:00
|
|
|
value: JSChildNode,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc: SourceLocation
|
|
|
|
): Property {
|
|
|
|
return {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_PROPERTY,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc,
|
|
|
|
key,
|
|
|
|
value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-27 23:42:02 +08:00
|
|
|
export function createSimpleExpression(
|
2019-09-22 05:42:12 +08:00
|
|
|
content: string,
|
|
|
|
isStatic: boolean,
|
2019-09-27 23:42:02 +08:00
|
|
|
loc: SourceLocation
|
|
|
|
): SimpleExpressionNode {
|
2019-09-22 05:42:12 +08:00
|
|
|
return {
|
2019-09-27 23:42:02 +08:00
|
|
|
type: NodeTypes.SIMPLE_EXPRESSION,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc,
|
|
|
|
content,
|
2019-09-27 23:42:02 +08:00
|
|
|
isStatic
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createInterpolation(
|
|
|
|
content: string | CompoundExpressionNode,
|
|
|
|
loc: SourceLocation
|
|
|
|
): InterpolationNode {
|
|
|
|
return {
|
|
|
|
type: NodeTypes.INTERPOLATION,
|
|
|
|
loc,
|
|
|
|
content: isString(content)
|
|
|
|
? createSimpleExpression(content, false, loc)
|
|
|
|
: content
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createCompoundExpression(
|
|
|
|
children: CompoundExpressionNode['children'],
|
|
|
|
loc: SourceLocation
|
|
|
|
): CompoundExpressionNode {
|
|
|
|
return {
|
|
|
|
type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
|
loc,
|
|
|
|
children
|
2019-09-22 05:42:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createCallExpression(
|
2019-10-01 09:17:12 +08:00
|
|
|
callee: string,
|
2019-09-22 05:42:12 +08:00
|
|
|
args: CallExpression['arguments'],
|
|
|
|
loc: SourceLocation
|
|
|
|
): CallExpression {
|
|
|
|
return {
|
2019-09-23 04:50:57 +08:00
|
|
|
type: NodeTypes.JS_CALL_EXPRESSION,
|
2019-09-22 05:42:12 +08:00
|
|
|
loc,
|
|
|
|
callee,
|
|
|
|
arguments: args
|
|
|
|
}
|
|
|
|
}
|
2019-09-28 10:25:32 +08:00
|
|
|
|
|
|
|
export function createFunctionExpression(
|
|
|
|
params: ExpressionNode | undefined,
|
|
|
|
returns: ChildNode[],
|
|
|
|
loc: SourceLocation
|
|
|
|
): SlotFunctionExpression {
|
|
|
|
return {
|
|
|
|
type: NodeTypes.JS_SLOT_FUNCTION,
|
|
|
|
params,
|
|
|
|
returns,
|
|
|
|
loc
|
|
|
|
}
|
|
|
|
}
|