ECMAScript | Язык ECMAScript: Исходный Код (Source Code)

ECMAScript | Язык ECMAScript: Исходный Код (Source Code)

11.1 (Source Text)

11.2 (Types of Source Code)

 

11.1 Исходный Текст — Source Text

Синтаксис

SourceCharacter ::

любая кодовая точка Unicode

Код ECMAScript выражается с помощью Unicode. Исходный текст ECMAScript представляет собой последовательность кодовых точек. Все значения кодовых точек Unicode от U+0000 до U+10FFFF, включая суррогатные кодовые точки, могут встречаться в исходном тексте, если это разрешено грамматиками ECMAScript. Фактические кодировки, используемые для хранения и обмена исходного текста ECMAScript, не имеют отношения к этой спецификации. Независимо от внешней кодировки исходного текста, соответствующая реализация ECMAScript обрабатывает исходный текст, как если бы это была эквивалентная последовательность значений исходного символа SourceCharacter, причем каждый исходный символ SourceCharacter является кодовой точкой Unicode. Соответствующие реализации ECMAScript не обязаны выполнять какую-либо нормализацию исходного текста или вести себя так, как если бы они выполняли нормализацию исходного текста.

Компоненты последовательности комбинируемых символов рассматриваются как отдельные кодовые точки Unicode, даже если пользователь может рассматривать всю последовательность как один символ.

 

Примечание

В строковых литералах, литералах регулярных выражений, литералах шаблонов и идентификаторах любая кодовая точка Unicode также может быть выражена с помощью управляющих последовательностей Unicode, которые явно выражают числовое значение кодовой точки. Внутри комментария такая escape-последовательность фактически игнорируется как часть комментария.

ECMAScript отличается от языка программирования Java поведением управляющих последовательностей Unicode. В программе Java, если escape-последовательность Unicode \u000A, например, встречается в однострочном комментарии, она интерпретируется как признак конца строки (кодовая точка Unicode U+000A — LINE FEED (LF)) и, следовательно, следующий код точка не является частью комментария. Точно так же, если escape-последовательность Unicode \u000A встречается в строковом литерале в программе Java, она также интерпретируется как признак конца строки, что недопустимо в строковом литерале — нужно писать \n вместо \u000A, чтобы вызвать LINE FEED (LF), чтобы быть частью значения String строкового литерала. В программе ECMAScript escape-последовательность Unicode, встречающаяся в комментарии, никогда не интерпретируется и, следовательно, не может способствовать завершению комментария. Точно так же escape-последовательность Unicode, встречающаяся в строковом литерале в программе ECMAScript, всегда вносит свой вклад в литерал и никогда не интерпретируется как признак конца строки или как кодовая точка, которая может завершать строковый литерал.

 

11.1.1 Static Semantics: UTF16EncodeCodePoint ( cp )

11.1.2 Static Semantics: CodePointsToString ( text )

11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )

11.1.4 Static Semantics: CodePointAt ( string, position )

11.1.5 Static Semantics: StringToCodePoints ( string )

11.1.6 Static Semantics: ParseText ( sourceText, goalSymbol )

 

11.1.1 Static Semantics: UTF16EncodeCodePoint ( cp )

Абстрактная операция UTF16EncodeCodePoint принимает аргумент cp (кодовая точка Unicode). При вызове он выполняет следующие шаги:

1. Утверждено: 0 ≤ cp ≤ 0x10FFFF.
2. Если cp ≤ 0xFFFF, вернуть строковое значение String, состоящее из кодовой единицы, значение которой равно cp.
3. Пусть cu1 будет единицей кода, значение которой равно floor((cp - 0x10000) / 0x400) + 0xD800.
4. Пусть cu2 будет единицей кода, значение которой равно ((cp - 0x10000) по модулю 0x400) + 0xDC00.
5. Вернуть конкатенацию строк cu1 и cu2.

 

11.1.2 Static Semantics: CodePointsToString ( text )

Абстрактная операция CodePointsToString принимает аргумент text (последовательность кодовых точек Unicode). Он преобразует текст в строковое значение, как описано в разделе 6.1.4. При вызове он выполняет следующие шаги:

1. Пусть результатом result будет пустая строка.
2. Для каждой кодовой точки cp из text выполните
   а. Задайте для результата result конкатенацию строк результата result и ! UTF16EncodeCodePoint(cp).
3. Вернуть результат result.

 

11.1.3 Static Semantics: UTF16SurrogatePairToCodePoint ( lead, trail )

Абстрактная операция UTF16SurrogatePairToCodePoint принимает аргументы lead (единица кода) и trail (единица кода). Две кодовые единицы, которые образуют суррогатную пару UTF-16, преобразуются в кодовую точку. При вызове она выполняет следующие шаги:

1. Утверждение: lead - это ведущий суррогат, а trail - конечный суррогат.
2. Пусть cp будет (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000.
3. Верните кодовую точку cp.

 

11.1.4 Static Semantics: CodePointAt ( string, position )

Абстрактная операция CodePointAt принимает аргумент строки string (String) и позицию position (неотрицательное целое число). Она интерпретирует строку string как последовательность кодовых точек в кодировке UTF-16, как описано в разделе 6.1.4, и считывает из неё одну кодовую точку, начиная с кодовой единицы с индексом позиции position. При вызове она выполняет следующие шаги:

1. Пусть размер size будет длиной строки string.
2. Утверждено: position ≥ 0 и position < size.
3. Пусть first будет единицей кода в индексе позиции position в строке string.
4. Пусть cp будет кодовой точкой, числовое значение которой совпадает с first.
5. Если first не является ведущим суррогатом или последним суррогатом, то
   а. Вернуть запись Record {[[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false}.
6. Если first является конечный суррогат или position + 1 = size, то
   а. Вернуть запись Record {[[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true}.
7. Пусть second будет единицей кода с индексом position + 1 в строке string.
8. Если second не является последним суррогатом, тогда
   а. Вернуть запись Record {[[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true}.
9. Установите cp на ! UTF16SurrogatePairToCodePoint(first, second).
10. Верните запись Record {[[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false}.

 

11.1.5 Static Semantics: StringToCodePoints ( string )

Абстрактная операция StringToCodePoints принимает аргумент строки string (String). Она возвращает последовательность кодовых точек Unicode, которая является результатом интерпретации строки string как текста Unicode в кодировке UTF-16, как описано в разделе 6.1.4. При вызове он выполняет следующие шаги:

1. Пусть codePoints будет новым пустым списком List.
2. Пусть размер size будет длиной строки string.
3. Пусть позиция position равна 0.
4. Повторите, пока position < size (позиция < размер),
   а. Пусть cp будет ! CodePointAt(string, position).
   b. Добавьте cp.[[CodePoint]] в codePoints.
   c. Установить position на position + cp.[[CodeUnitCount]].
5. Вернуть codePoints.

 

11.1.6 Static Semantics: ParseText ( sourceText, goalSymbol )

Абстрактная операция ParseText принимает аргументы sourceText (последовательность кодовых точек Unicode) и goalSymbol (нетерминал в одной из грамматик ECMAScript). При вызове она выполняет следующие шаги:

1. Попытайтесь проанализировать sourceText, используя goalSymbol в качестве символа цели, и проанализируйте результат синтаксического анализа на предмет любых ранних ошибок. Анализ и раннее обнаружение ошибок могут чередоваться в зависимости от определённой реализации.

2. Если синтаксический анализ прошел успешно и ранних ошибок не было обнаружено, верните Узел Синтаксического Анализа (экземпляр goalSymbol) в корне дерева синтаксического анализа, полученного в результате синтаксического анализа.

3. В противном случае верните Список из одного или нескольких объектов SyntaxError, представляющих ошибки синтаксического анализа и / или ранние ошибки. Если присутствует более одной ошибки синтаксического анализа или ранней ошибки, количество и порядок объектов ошибок в списке определяется реализацией, но должен присутствовать по крайней мере один.

Примечание 1

Рассмотрим текст, который имеет раннюю ошибку в определенном месте, а также синтаксическую ошибку в более позднем месте. Реализация, которая выполняет проход синтаксического анализа, за которым следует проход ранних ошибок, может сообщать о синтаксической ошибке и не переходить к проходу ранних ошибок. Реализация, которая чередует эти два действия, может сообщить о ранней ошибке и не продолжить поиск синтаксической ошибки. Третья реализация может сообщать обе ошибки. Все эти поведения соответствуют друг другу.

Примечание 2

Также пункт 17.

 

 

11.2 Типы исходного кода — Types of Source Code

Есть четыре типа кода ECMAScript:

  1. Global code
  2. Eval code
  3. Function code
  4. Module code

 

Global code

Глобальный код (Global code) — это исходный текст, который рассматривается как сценарий ECMAScript. Глобальный код конкретного скрипта не включает в себя исходный текст, который анализируется как часть FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, AsyncGeneratorExpression, MethodDefinition, ArrowFrunction, AsyncArrowFunction, ClassDeclaration или ClassExpression.

Eval code

Оценочный код (Eval code) — это исходный текст, передаваемый встроенной функции eval. Точнее, если параметром встроенной функции eval является строка, она рассматривается как скрипт Script языка ECMAScript. Оценочный код для конкретного вызова eval — это часть глобального кода этого скрипта Script.

Function code

Код функции (Function code) — это исходный текст, который анализируется для предоставления значения внутренних слотов [[ECMAScriptCode]] и [[FormalParameters]] (раздел 10.2) объекта функции ECMAScript. Код функции конкретной функции ECMAScript не включает какой-либо исходный текст, который анализируется как код функции вложенного FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, AsyncGeneratorExpression, MethodDefinition, ArrowFrunction, AsyncArrowFunction, ClassDeclaration или ClassExpression.

Кроме того, если исходный текст, упомянутый выше, анализируется как:

тогда исходный текст, соответствующий BindingIdentifier (если есть) этого объявления или выражения, также включается в код функции соответствующей функции.

Module code

Код модуля (Module code) — это исходный текст, то есть код, предоставленный как ModuleBody. Это код, который непосредственно оценивается при инициализации модуля. Код модуля конкретного модуля не включает исходный текст, который анализируется как часть вложенного FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, AsyncGeneratorExpression, MethodDefinition, ArrowFunction, AsyncArrowFunction, ClassDeclaration или ClassExpression.

Примечание 1

Код функции обычно предоставляется в виде тел Определений Функций (15.2), Определений Стрелочных Функций (15.3), Определений Методов (15.4), Определений Функций Генератора (15.5), Определений Асинхронных Функций (15.8), Определений Функций Асинхронных Генераторов (15.6), и Асинхронные Стрелочные Функции (15.9). Код функции также является производным от аргументов конструктора функции (20.2.1.1), конструктора GeneratorFunction (27.3.1.1) и конструктора AsyncFunction (27.7.1.1).

Примечание 2

Практический эффект от включения идентификатора привязки BindingIdentifier в код функции заключается в том, что ранние ошибки для кода строгого режима применяются к BindingIdentifier, который является именем функции, тело которой содержит директиву «use strict», даже если окружающий код не является кодом строгого режима.

 

11.2.1 Прологи директив и директива Use Strict

Пролог директивы (Directive Prologue) — это самая длинная последовательность выражений ExpressionStatements, встречающихся в качестве начальных StatementListItems или ModuleItems для FunctionBody, ScriptBody или ModuleBody, и где каждый ExpressionStatement в последовательности полностью состоит из токена StringLiteral, за которым следует точка с запятой. Точка с запятой может отображаться явно или может быть вставлена с помощью автоматической вставки точки с запятой (12.9). Пролог директивы может быть пустой последовательностью.

Директива Use Strict — это выражение ExpressionStatement в Прологе Директивы, StringLiteral которого является одной из точных последовательностей кодовых точек "use strict" или 'use strict'. Директива Use Strict не может содержать EscapeSequence или LineContinuation.

Примечание

ExpressionStatements пролога директивы обычно оцениваются во время оценки содержащей продукции. Реализации могут определять конкретные значения реализации для ExpressionStatements, которые не являются директивой Use Strict и которые встречаются в Прологе Директивы. Если соответствующий механизм уведомления существует, реализация должна выдать предупреждение, если она встречает в Прологе Директивы выражение ExpressionStatement, которое не является директивой строгого использования и не имеет значения, определенного реализацией.

 

 

11.2.2 Код СтрогогоРежима

Синтаксическая единица ECMAScript может обрабатываться с использованием как неограниченного, так и строгого синтаксиса и семантики режима (4.3.2). Код интерпретируется как код строгого режима в следующих ситуациях:

  1. Глобальный код является кодом строгого режима, если он начинается с пролога директивы, который содержит директиву строгого использования.
  2. Код модуля — это всегда код строгого режима.
  3. Все части ClassDeclaration или ClassExpression являются кодом строгого режима.
  4. Код оценки — это код строгого режима, если он начинается с пролога директивы, который содержит директиву Use Strict, или если вызов eval является прямым eval, который содержится в коде строгого режима.
  5. Код функции является кодом в строгом режиме, если связанный FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, AsyncFunctionDeclaration, AsyncFunctionExpression, AsyncGeneratorDeclaration, AsyncGeneratorExpressionMethodDefinition, ArrowFunction или AsyncArrowFunction содержится в коде строгого режима или значение этой функции, если значение этого кода функции [[ECMAScriptCode]] внутренний слот начинается с Пролога Директивы, который содержит директиву строгого использования.
  6. Код функции, который предоставляется в качестве аргументов встроенным конструкторам Function, Generator, AsyncFunction и AsyncGenerator, является кодом в строгом режиме, если последний аргумент является String, который при обработке является FunctionBody, который начинается с Пролога Директивы, содержащего Use Strict Директиву.

Код ECMAScript, который не является кодом строгого режима, называется нестрогим кодом.

 

11.2.3 Функции, не относящиеся к ECMAScript

Реализация ECMAScript может поддерживать оценку функций экзотических объектов, оценочное поведение которых выражается в некоторой определяемой хостом форме исполняемого кода, отличной от кода ECMAScript. Является ли объект функции функцией кода ECMAScript или функцией не-ECMAScript, семантически не наблюдается с точки зрения функции кода ECMAScript, которая вызывает или вызывается такой функцией, отличной от ECMAScript.

 

Информационные ссылки

Стандарт ECMAScript — Раздел «11 ECMAScript Language: Source Code» — https://tc39.es/ecma262/#sec-ecmascript-language-source-code