How Declarations are Collected for Instantiation?

Published on

To process the declaration instantiation, the engine needs things like VarDeclaredNames, LexicallyDeclaredNames, VarScopedDeclarations, and LexicallyScopedDeclarations in a piece of code.

In this article, we will see how this information is collected from the code according to the specification.

Declaration

What is declaration? The declaration is one kind of ECMAScript statement. Here’s all kinds of declarations listed in the specification:

14 ECMAScript Language: Statements and Declarations
Syntax
Declaration[Yield, Await] :
HoistableDeclaration[?Yield, ?Await, ~Default]
ClassDeclaration[?Yield, ?Await, ~Default]
LexicalDeclaration[+In, ?Yield, ?Await]
HoistableDeclaration[Yield, Await, Default] :
FunctionDeclaration[?Yield, ?Await, ?Default]
GeneratorDeclaration[?Yield, ?Await, ?Default]
AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]

Global

The information needed in GlobalDeclarationInstantiation(scriptBody, globalEnv):

How are VarScopedDeclarations collected from scriptBody?

In short, it collects top-level HoistableDeclarations (function), top-level VariableStatements (var), and block-nested VariableStatements.

Static Semantics: VarScopedDeclarations
ScriptBody : StatementList
1. Return TopLevelVarScopedDeclarations of StatementList.
Static Semantics: TopLevelVarScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be TopLevelVarScopedDeclarations of StatementList.
2. Let declarations2 be TopLevelVarScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Statement
1. If Statement is Statement : LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
2. Return VarScopedDeclarations of Statement.
StatementListItem : Declaration
1. If Declaration is Declaration : HoistableDeclaration , then
a. Let declaration be DeclarationPart of HoistableDeclaration.
b. Return « declaration ».
2. Return a new empty List.
// implicit definition of chain productions
Static Semantics: VarScopedDeclarations
Statement : BlockStatement
1. Return VarScopedDeclarations of BlockStatement.
BlockStatement : Block
1. Return VarScopedDeclarations of Block.
Block : { StatementList }
1. Return VarScopedDeclarations of StatementList.

About “implicit definition of chain productions,” see: What is the implicit definition of “chain productions”?

Static Semantics: VarScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be VarScopedDeclarations of StatementList.
2. Let declarations2 be VarScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Declaration
1. Return a new empty List.
VariableDeclarationList : VariableDeclaration
1. Return « VariableDeclaration ».

How are VarDeclaredNames collected from scriptBody?

Same as VarScopedDeclarations.

How are LexicallyScopedDeclarations collected from scriptBody?

In short, it collects top-level ClassDeclarations (class) and LexicalDeclarations (let and const).

Static Semantics: LexicallyScopedDeclarations
ScriptBody : StatementList
1. Return TopLevelLexicallyScopedDeclarations of StatementList.
Static Semantics: TopLevelLexicallyScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be TopLevelLexicallyScopedDeclarations of StatementList.
2. Let declarations2 be TopLevelLexicallyScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Statement
1. Return a new empty List.
StatementListItem : Declaration
1. If Declaration is Declaration : HoistableDeclaration , then
a. Return a new empty List.
2. Return « Declaration ».
14 ECMAScript Language: Statements and Declarations
Syntax
Declaration[Yield, Await] :
HoistableDeclaration[?Yield, ?Await, ~Default]
ClassDeclaration[?Yield, ?Await, ~Default]
LexicalDeclaration[+In, ?Yield, ?Await]
HoistableDeclaration[Yield, Await, Default] :
FunctionDeclaration[?Yield, ?Await, ?Default]
GeneratorDeclaration[?Yield, ?Await, ?Default]
AsyncFunctionDeclaration[?Yield, ?Await, ?Default]
AsyncGeneratorDeclaration[?Yield, ?Await, ?Default]

How are LexicallyDeclaredNames collected from scriptBody?

Same as LexicallyScopedDeclarations.

Function

The information needed in FunctionDeclarationInstantiation(functionObject, argumentsList)

How are VarScopedDeclarations collected from functionObject.[[ECMAScriptCode]]?

In short, it collects top-level HoistableDeclarations (function), top-level VariableStatements (var), and block-nested VariableStatements.

Static Semantics: VarScopedDeclarations
FunctionStatementList : [empty]
1. Return a new empty List.
FunctionStatementList : StatementList
1. Return the TopLevelVarScopedDeclarations of StatementList.
Static Semantics: TopLevelVarScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be TopLevelVarScopedDeclarations of StatementList.
2. Let declarations2 be TopLevelVarScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Statement
1. If Statement is Statement : LabelledStatement , return TopLevelVarScopedDeclarations of Statement.
2. Return VarScopedDeclarations of Statement.
StatementListItem : Declaration
1. If Declaration is Declaration : HoistableDeclaration , then
a. Let declaration be DeclarationPart of HoistableDeclaration.
b. Return « declaration ».
2. Return a new empty List.
// implicit definition of chain productions
Static Semantics: VarScopedDeclarations
Statement : BlockStatement
1. Return VarScopedDeclarations of BlockStatement.
BlockStatement : Block
1. Return VarScopedDeclarations of Block.
Block : { StatementList }
1. Return VarScopedDeclarations of StatementList.

About “implicit definition of chain productions,” see: What is the implicit definition of “chain productions”?

Static Semantics: VarScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be VarScopedDeclarations of StatementList.
2. Let declarations2 be VarScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Declaration
1. Return a new empty List.
VariableDeclarationList : VariableDeclaration
1. Return « VariableDeclaration ».

How are VarDeclaredNames collected?

Same as VarScopedDeclarations.

How are LexicallyScopedDeclarations collected from functionObject.[[ECMAScriptCode]]?

In short, it collects top-level ClassDeclarations (class) and LexicalDeclarations (let and const).

Static Semantics: LexicallyScopedDeclarations
ScriptBody : StatementList
1. Return TopLevelLexicallyScopedDeclarations of StatementList.
Static Semantics: TopLevelLexicallyScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be TopLevelLexicallyScopedDeclarations of StatementList.
2. Let declarations2 be TopLevelLexicallyScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Statement
1. Return a new empty List.
StatementListItem : Declaration
1. If Declaration is Declaration : HoistableDeclaration , then
a. Return a new empty List.
2. Return « Declaration ».

How are LexicallyDeclaredNames collected?

Same as LexicallyScopedDeclarations.

Block

The information needed in BlockDeclarationInstantiation(StatementList, blockEnv)

How are LexicallyScopedDeclarations collected from StatementList?

Static Semantics: LexicallyScopedDeclarations
StatementList : StatementList StatementListItem
1. Let declarations1 be LexicallyScopedDeclarations of StatementList.
2. Let declarations2 be LexicallyScopedDeclarations of StatementListItem.
3. Return the list-concatenation of declarations1 and declarations2.
StatementListItem : Statement
1. If Statement is Statement : LabelledStatement , return LexicallyScopedDeclarations of LabelledStatement.
2. Return a new empty List.

Since the LexicallyScopedDeclarations return empty list for the most of the statements except declarations and labelled statements, it means that collect the declarations from the current level are collected, while the declarations in nested blocks or functions are not.