graphql 16.0.1 → 16.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +4 -4
  2. package/error/GraphQLError.js +4 -1
  3. package/error/GraphQLError.mjs +4 -1
  4. package/error/locatedError.js +2 -8
  5. package/error/locatedError.mjs +2 -6
  6. package/execution/execute.js +16 -5
  7. package/execution/execute.mjs +16 -5
  8. package/execution/mapAsyncIterator.js +3 -1
  9. package/execution/mapAsyncIterator.mjs +3 -1
  10. package/execution/subscribe.js +8 -0
  11. package/execution/subscribe.mjs +7 -0
  12. package/execution/values.js +3 -2
  13. package/execution/values.mjs +3 -2
  14. package/graphql.js +8 -0
  15. package/graphql.mjs +7 -0
  16. package/index.d.ts +3 -0
  17. package/index.js +12 -0
  18. package/index.mjs +3 -0
  19. package/jsutils/devAssert.js +1 -1
  20. package/jsutils/devAssert.mjs +1 -1
  21. package/jsutils/instanceOf.js +3 -1
  22. package/jsutils/instanceOf.mjs +3 -1
  23. package/jsutils/invariant.js +1 -1
  24. package/jsutils/invariant.mjs +1 -1
  25. package/jsutils/mapValue.js +2 -2
  26. package/jsutils/mapValue.mjs +2 -2
  27. package/jsutils/toError.d.ts +4 -0
  28. package/jsutils/toError.js +25 -0
  29. package/jsutils/toError.mjs +18 -0
  30. package/language/blockString.d.ts +7 -3
  31. package/language/blockString.js +121 -64
  32. package/language/blockString.mjs +111 -62
  33. package/language/characterClasses.d.ts +9 -0
  34. package/language/characterClasses.js +13 -0
  35. package/language/characterClasses.mjs +12 -0
  36. package/language/lexer.js +21 -13
  37. package/language/lexer.mjs +22 -14
  38. package/language/parser.js +3 -2
  39. package/language/parser.mjs +3 -2
  40. package/language/printer.js +3 -1
  41. package/language/printer.mjs +3 -1
  42. package/language/visitor.js +2 -1
  43. package/language/visitor.mjs +2 -1
  44. package/package.json +4 -1
  45. package/type/directives.d.ts +1 -1
  46. package/type/directives.js +3 -3
  47. package/type/directives.mjs +3 -3
  48. package/type/index.d.ts +3 -0
  49. package/type/index.js +12 -0
  50. package/type/index.mjs +3 -0
  51. package/type/introspection.js +8 -4
  52. package/type/introspection.mjs +8 -4
  53. package/type/scalars.d.ts +10 -0
  54. package/type/scalars.js +18 -10
  55. package/type/scalars.mjs +16 -11
  56. package/type/schema.d.ts +1 -1
  57. package/type/schema.js +5 -3
  58. package/type/schema.mjs +4 -3
  59. package/type/validate.js +35 -26
  60. package/type/validate.mjs +35 -26
  61. package/utilities/TypeInfo.js +4 -0
  62. package/utilities/TypeInfo.mjs +4 -0
  63. package/utilities/assertValidName.js +3 -2
  64. package/utilities/assertValidName.mjs +3 -2
  65. package/utilities/astFromValue.js +4 -2
  66. package/utilities/astFromValue.mjs +4 -2
  67. package/utilities/buildClientSchema.js +2 -0
  68. package/utilities/buildClientSchema.mjs +2 -0
  69. package/utilities/coerceInputValue.js +4 -2
  70. package/utilities/coerceInputValue.mjs +4 -2
  71. package/utilities/extendSchema.js +40 -32
  72. package/utilities/extendSchema.mjs +40 -29
  73. package/utilities/findBreakingChanges.js +4 -2
  74. package/utilities/findBreakingChanges.mjs +4 -2
  75. package/utilities/lexicographicSortSchema.js +6 -5
  76. package/utilities/lexicographicSortSchema.mjs +6 -5
  77. package/utilities/printSchema.js +9 -7
  78. package/utilities/printSchema.mjs +10 -5
  79. package/utilities/separateOperations.js +2 -0
  80. package/utilities/separateOperations.mjs +2 -0
  81. package/utilities/stripIgnoredCharacters.js +3 -19
  82. package/utilities/stripIgnoredCharacters.mjs +4 -23
  83. package/utilities/typeFromAST.js +13 -24
  84. package/utilities/typeFromAST.mjs +12 -17
  85. package/utilities/valueFromAST.js +4 -2
  86. package/utilities/valueFromAST.mjs +4 -2
  87. package/utilities/valueFromASTUntyped.js +1 -11
  88. package/utilities/valueFromASTUntyped.mjs +1 -5
  89. package/validation/rules/KnownArgumentNamesRule.js +3 -1
  90. package/validation/rules/KnownArgumentNamesRule.mjs +3 -1
  91. package/validation/rules/KnownDirectivesRule.js +11 -7
  92. package/validation/rules/KnownDirectivesRule.mjs +7 -3
  93. package/validation/rules/OverlappingFieldsCanBeMergedRule.js +4 -3
  94. package/validation/rules/OverlappingFieldsCanBeMergedRule.mjs +4 -3
  95. package/validation/rules/PossibleTypeExtensionsRule.js +14 -8
  96. package/validation/rules/PossibleTypeExtensionsRule.mjs +10 -4
  97. package/validation/rules/ProvidedRequiredArgumentsRule.js +8 -3
  98. package/validation/rules/ProvidedRequiredArgumentsRule.mjs +8 -3
  99. package/validation/rules/UniqueArgumentDefinitionNamesRule.js +9 -3
  100. package/validation/rules/UniqueArgumentDefinitionNamesRule.mjs +9 -3
  101. package/validation/rules/UniqueArgumentNamesRule.js +3 -1
  102. package/validation/rules/UniqueArgumentNamesRule.mjs +3 -1
  103. package/validation/rules/UniqueEnumValueNamesRule.js +3 -1
  104. package/validation/rules/UniqueEnumValueNamesRule.mjs +3 -1
  105. package/validation/rules/UniqueFieldDefinitionNamesRule.js +3 -1
  106. package/validation/rules/UniqueFieldDefinitionNamesRule.mjs +3 -1
  107. package/validation/rules/UniqueOperationTypesRule.js +3 -1
  108. package/validation/rules/UniqueOperationTypesRule.mjs +3 -1
  109. package/validation/rules/UniqueVariableNamesRule.js +3 -1
  110. package/validation/rules/UniqueVariableNamesRule.mjs +3 -1
  111. package/version.js +3 -3
  112. package/version.mjs +3 -3
@@ -3,10 +3,12 @@
3
3
  Object.defineProperty(exports, '__esModule', {
4
4
  value: true,
5
5
  });
6
- exports.dedentBlockStringValue = dedentBlockStringValue;
7
- exports.getBlockStringIndentation = getBlockStringIndentation;
6
+ exports.dedentBlockStringLines = dedentBlockStringLines;
7
+ exports.isPrintableAsBlockString = isPrintableAsBlockString;
8
8
  exports.printBlockString = printBlockString;
9
9
 
10
+ var _characterClasses = require('./characterClasses.js');
11
+
10
12
  /**
11
13
  * Produces the value of a block string from its parsed raw value, similar to
12
14
  * CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc.
@@ -15,94 +17,128 @@ exports.printBlockString = printBlockString;
15
17
  *
16
18
  * @internal
17
19
  */
18
- function dedentBlockStringValue(rawString) {
19
- // Expand a block string's raw value into independent lines.
20
- const lines = rawString.split(/\r\n|[\n\r]/g); // Remove common indentation from all lines but first.
20
+ function dedentBlockStringLines(lines) {
21
+ var _firstNonEmptyLine2;
21
22
 
22
- const commonIndent = getBlockStringIndentation(rawString);
23
+ let commonIndent = Number.MAX_SAFE_INTEGER;
24
+ let firstNonEmptyLine = null;
25
+ let lastNonEmptyLine = -1;
23
26
 
24
- if (commonIndent !== 0) {
25
- for (let i = 1; i < lines.length; i++) {
26
- lines[i] = lines[i].slice(commonIndent);
27
- }
28
- } // Remove leading and trailing blank lines.
27
+ for (let i = 0; i < lines.length; ++i) {
28
+ var _firstNonEmptyLine;
29
29
 
30
- let startLine = 0;
30
+ const line = lines[i];
31
+ const indent = leadingWhitespace(line);
31
32
 
32
- while (startLine < lines.length && isBlank(lines[startLine])) {
33
- ++startLine;
34
- }
33
+ if (indent === line.length) {
34
+ continue; // skip empty lines
35
+ }
35
36
 
36
- let endLine = lines.length;
37
+ firstNonEmptyLine =
38
+ (_firstNonEmptyLine = firstNonEmptyLine) !== null &&
39
+ _firstNonEmptyLine !== void 0
40
+ ? _firstNonEmptyLine
41
+ : i;
42
+ lastNonEmptyLine = i;
37
43
 
38
- while (endLine > startLine && isBlank(lines[endLine - 1])) {
39
- --endLine;
40
- } // Return a string of the lines joined with U+000A.
44
+ if (i !== 0 && indent < commonIndent) {
45
+ commonIndent = indent;
46
+ }
47
+ }
41
48
 
42
- return lines.slice(startLine, endLine).join('\n');
49
+ return lines // Remove common indentation from all lines but first.
50
+ .map((line, i) => (i === 0 ? line : line.slice(commonIndent))) // Remove leading and trailing blank lines.
51
+ .slice(
52
+ (_firstNonEmptyLine2 = firstNonEmptyLine) !== null &&
53
+ _firstNonEmptyLine2 !== void 0
54
+ ? _firstNonEmptyLine2
55
+ : 0,
56
+ lastNonEmptyLine + 1,
57
+ );
43
58
  }
44
59
 
45
- function isBlank(str) {
46
- for (const char of str) {
47
- if (char !== ' ' && char !== '\t') {
48
- return false;
49
- }
60
+ function leadingWhitespace(str) {
61
+ let i = 0;
62
+
63
+ while (
64
+ i < str.length &&
65
+ (0, _characterClasses.isWhiteSpace)(str.charCodeAt(i))
66
+ ) {
67
+ ++i;
50
68
  }
51
69
 
52
- return true;
70
+ return i;
53
71
  }
54
72
  /**
55
73
  * @internal
56
74
  */
57
75
 
58
- function getBlockStringIndentation(value) {
59
- var _commonIndent;
76
+ function isPrintableAsBlockString(value) {
77
+ if (value === '') {
78
+ return true; // empty string is printable
79
+ }
60
80
 
61
- let isFirstLine = true;
62
81
  let isEmptyLine = true;
63
- let indent = 0;
64
- let commonIndent = null;
82
+ let hasIndent = false;
83
+ let hasCommonIndent = true;
84
+ let seenNonEmptyLine = false;
65
85
 
66
86
  for (let i = 0; i < value.length; ++i) {
67
- switch (value.charCodeAt(i)) {
68
- case 13:
87
+ switch (value.codePointAt(i)) {
88
+ case 0x0000:
89
+ case 0x0001:
90
+ case 0x0002:
91
+ case 0x0003:
92
+ case 0x0004:
93
+ case 0x0005:
94
+ case 0x0006:
95
+ case 0x0007:
96
+ case 0x0008:
97
+ case 0x000b:
98
+ case 0x000c:
99
+ case 0x000e:
100
+ case 0x000f:
101
+ return false;
102
+ // Has non-printable characters
103
+
104
+ case 0x000d:
69
105
  // \r
70
- if (value.charCodeAt(i + 1) === 10) {
71
- ++i; // skip \r\n as one symbol
72
- }
73
-
74
- // falls through
106
+ return false;
107
+ // Has \r or \r\n which will be replaced as \n
75
108
 
76
109
  case 10:
77
110
  // \n
78
- isFirstLine = false;
111
+ if (isEmptyLine && !seenNonEmptyLine) {
112
+ return false; // Has leading new line
113
+ }
114
+
115
+ seenNonEmptyLine = true;
79
116
  isEmptyLine = true;
80
- indent = 0;
117
+ hasIndent = false;
81
118
  break;
82
119
 
83
120
  case 9: // \t
84
121
 
85
122
  case 32:
86
123
  // <space>
87
- ++indent;
124
+ hasIndent || (hasIndent = isEmptyLine);
88
125
  break;
89
126
 
90
127
  default:
91
- if (
92
- isEmptyLine &&
93
- !isFirstLine &&
94
- (commonIndent === null || indent < commonIndent)
95
- ) {
96
- commonIndent = indent;
97
- }
98
-
128
+ hasCommonIndent && (hasCommonIndent = hasIndent);
99
129
  isEmptyLine = false;
100
130
  }
101
131
  }
102
132
 
103
- return (_commonIndent = commonIndent) !== null && _commonIndent !== void 0
104
- ? _commonIndent
105
- : 0;
133
+ if (isEmptyLine) {
134
+ return false; // Has trailing empty lines
135
+ }
136
+
137
+ if (hasCommonIndent && seenNonEmptyLine) {
138
+ return false; // Has internal indent
139
+ }
140
+
141
+ return true;
106
142
  }
107
143
  /**
108
144
  * Print a block string in the indented block form by adding a leading and
@@ -112,27 +148,48 @@ function getBlockStringIndentation(value) {
112
148
  * @internal
113
149
  */
114
150
 
115
- function printBlockString(value, preferMultipleLines = false) {
116
- const isSingleLine = !value.includes('\n');
117
- const hasLeadingSpace = value.startsWith(' ') || value.startsWith('\t');
118
- const hasTrailingQuote = value.endsWith('"');
151
+ function printBlockString(value, options) {
152
+ const escapedValue = value.replace(/"""/g, '\\"""'); // Expand a block string's raw value into independent lines.
153
+
154
+ const lines = escapedValue.split(/\r\n|[\n\r]/g);
155
+ const isSingleLine = lines.length === 1; // If common indentation is found we can fix some of those cases by adding leading new line
156
+
157
+ const forceLeadingNewLine =
158
+ lines.length > 1 &&
159
+ lines
160
+ .slice(1)
161
+ .every(
162
+ (line) =>
163
+ line.length === 0 ||
164
+ (0, _characterClasses.isWhiteSpace)(line.charCodeAt(0)),
165
+ ); // Trailing triple quotes just looks confusing but doesn't force trailing new line
166
+
167
+ const hasTrailingTripleQuotes = escapedValue.endsWith('\\"""'); // Trailing quote (single or double) or slash forces trailing new line
168
+
169
+ const hasTrailingQuote = value.endsWith('"') && !hasTrailingTripleQuotes;
119
170
  const hasTrailingSlash = value.endsWith('\\');
171
+ const forceTrailingNewline = hasTrailingQuote || hasTrailingSlash;
120
172
  const printAsMultipleLines =
121
- !isSingleLine ||
122
- hasTrailingQuote ||
123
- hasTrailingSlash ||
124
- preferMultipleLines;
173
+ !(options !== null && options !== void 0 && options.minimize) && // add leading and trailing new lines only if it improves readability
174
+ (!isSingleLine ||
175
+ value.length > 70 ||
176
+ forceTrailingNewline ||
177
+ forceLeadingNewLine ||
178
+ hasTrailingTripleQuotes);
125
179
  let result = ''; // Format a multi-line block quote to account for leading space.
126
180
 
127
- if (printAsMultipleLines && !(isSingleLine && hasLeadingSpace)) {
181
+ const skipLeadingNewLine =
182
+ isSingleLine && (0, _characterClasses.isWhiteSpace)(value.charCodeAt(0));
183
+
184
+ if ((printAsMultipleLines && !skipLeadingNewLine) || forceLeadingNewLine) {
128
185
  result += '\n';
129
186
  }
130
187
 
131
- result += value;
188
+ result += escapedValue;
132
189
 
133
- if (printAsMultipleLines) {
190
+ if (printAsMultipleLines || forceTrailingNewline) {
134
191
  result += '\n';
135
192
  }
136
193
 
137
- return '"""' + result.replace(/"""/g, '\\"""') + '"""';
194
+ return '"""' + result + '"""';
138
195
  }
@@ -1,3 +1,4 @@
1
+ import { isWhiteSpace } from './characterClasses.mjs';
1
2
  /**
2
3
  * Produces the value of a block string from its parsed raw value, similar to
3
4
  * CoffeeScript's block string, Python's docstring trim or Ruby's strip_heredoc.
@@ -6,94 +7,126 @@
6
7
  *
7
8
  * @internal
8
9
  */
9
- export function dedentBlockStringValue(rawString) {
10
- // Expand a block string's raw value into independent lines.
11
- const lines = rawString.split(/\r\n|[\n\r]/g); // Remove common indentation from all lines but first.
12
10
 
13
- const commonIndent = getBlockStringIndentation(rawString);
11
+ export function dedentBlockStringLines(lines) {
12
+ var _firstNonEmptyLine2;
14
13
 
15
- if (commonIndent !== 0) {
16
- for (let i = 1; i < lines.length; i++) {
17
- lines[i] = lines[i].slice(commonIndent);
18
- }
19
- } // Remove leading and trailing blank lines.
14
+ let commonIndent = Number.MAX_SAFE_INTEGER;
15
+ let firstNonEmptyLine = null;
16
+ let lastNonEmptyLine = -1;
20
17
 
21
- let startLine = 0;
18
+ for (let i = 0; i < lines.length; ++i) {
19
+ var _firstNonEmptyLine;
22
20
 
23
- while (startLine < lines.length && isBlank(lines[startLine])) {
24
- ++startLine;
25
- }
21
+ const line = lines[i];
22
+ const indent = leadingWhitespace(line);
26
23
 
27
- let endLine = lines.length;
24
+ if (indent === line.length) {
25
+ continue; // skip empty lines
26
+ }
28
27
 
29
- while (endLine > startLine && isBlank(lines[endLine - 1])) {
30
- --endLine;
31
- } // Return a string of the lines joined with U+000A.
28
+ firstNonEmptyLine =
29
+ (_firstNonEmptyLine = firstNonEmptyLine) !== null &&
30
+ _firstNonEmptyLine !== void 0
31
+ ? _firstNonEmptyLine
32
+ : i;
33
+ lastNonEmptyLine = i;
32
34
 
33
- return lines.slice(startLine, endLine).join('\n');
35
+ if (i !== 0 && indent < commonIndent) {
36
+ commonIndent = indent;
37
+ }
38
+ }
39
+
40
+ return lines // Remove common indentation from all lines but first.
41
+ .map((line, i) => (i === 0 ? line : line.slice(commonIndent))) // Remove leading and trailing blank lines.
42
+ .slice(
43
+ (_firstNonEmptyLine2 = firstNonEmptyLine) !== null &&
44
+ _firstNonEmptyLine2 !== void 0
45
+ ? _firstNonEmptyLine2
46
+ : 0,
47
+ lastNonEmptyLine + 1,
48
+ );
34
49
  }
35
50
 
36
- function isBlank(str) {
37
- for (const char of str) {
38
- if (char !== ' ' && char !== '\t') {
39
- return false;
40
- }
51
+ function leadingWhitespace(str) {
52
+ let i = 0;
53
+
54
+ while (i < str.length && isWhiteSpace(str.charCodeAt(i))) {
55
+ ++i;
41
56
  }
42
57
 
43
- return true;
58
+ return i;
44
59
  }
45
60
  /**
46
61
  * @internal
47
62
  */
48
63
 
49
- export function getBlockStringIndentation(value) {
50
- var _commonIndent;
64
+ export function isPrintableAsBlockString(value) {
65
+ if (value === '') {
66
+ return true; // empty string is printable
67
+ }
51
68
 
52
- let isFirstLine = true;
53
69
  let isEmptyLine = true;
54
- let indent = 0;
55
- let commonIndent = null;
70
+ let hasIndent = false;
71
+ let hasCommonIndent = true;
72
+ let seenNonEmptyLine = false;
56
73
 
57
74
  for (let i = 0; i < value.length; ++i) {
58
- switch (value.charCodeAt(i)) {
59
- case 13:
75
+ switch (value.codePointAt(i)) {
76
+ case 0x0000:
77
+ case 0x0001:
78
+ case 0x0002:
79
+ case 0x0003:
80
+ case 0x0004:
81
+ case 0x0005:
82
+ case 0x0006:
83
+ case 0x0007:
84
+ case 0x0008:
85
+ case 0x000b:
86
+ case 0x000c:
87
+ case 0x000e:
88
+ case 0x000f:
89
+ return false;
90
+ // Has non-printable characters
91
+
92
+ case 0x000d:
60
93
  // \r
61
- if (value.charCodeAt(i + 1) === 10) {
62
- ++i; // skip \r\n as one symbol
63
- }
64
-
65
- // falls through
94
+ return false;
95
+ // Has \r or \r\n which will be replaced as \n
66
96
 
67
97
  case 10:
68
98
  // \n
69
- isFirstLine = false;
99
+ if (isEmptyLine && !seenNonEmptyLine) {
100
+ return false; // Has leading new line
101
+ }
102
+
103
+ seenNonEmptyLine = true;
70
104
  isEmptyLine = true;
71
- indent = 0;
105
+ hasIndent = false;
72
106
  break;
73
107
 
74
108
  case 9: // \t
75
109
 
76
110
  case 32:
77
111
  // <space>
78
- ++indent;
112
+ hasIndent || (hasIndent = isEmptyLine);
79
113
  break;
80
114
 
81
115
  default:
82
- if (
83
- isEmptyLine &&
84
- !isFirstLine &&
85
- (commonIndent === null || indent < commonIndent)
86
- ) {
87
- commonIndent = indent;
88
- }
89
-
116
+ hasCommonIndent && (hasCommonIndent = hasIndent);
90
117
  isEmptyLine = false;
91
118
  }
92
119
  }
93
120
 
94
- return (_commonIndent = commonIndent) !== null && _commonIndent !== void 0
95
- ? _commonIndent
96
- : 0;
121
+ if (isEmptyLine) {
122
+ return false; // Has trailing empty lines
123
+ }
124
+
125
+ if (hasCommonIndent && seenNonEmptyLine) {
126
+ return false; // Has internal indent
127
+ }
128
+
129
+ return true;
97
130
  }
98
131
  /**
99
132
  * Print a block string in the indented block form by adding a leading and
@@ -103,27 +136,43 @@ export function getBlockStringIndentation(value) {
103
136
  * @internal
104
137
  */
105
138
 
106
- export function printBlockString(value, preferMultipleLines = false) {
107
- const isSingleLine = !value.includes('\n');
108
- const hasLeadingSpace = value.startsWith(' ') || value.startsWith('\t');
109
- const hasTrailingQuote = value.endsWith('"');
139
+ export function printBlockString(value, options) {
140
+ const escapedValue = value.replace(/"""/g, '\\"""'); // Expand a block string's raw value into independent lines.
141
+
142
+ const lines = escapedValue.split(/\r\n|[\n\r]/g);
143
+ const isSingleLine = lines.length === 1; // If common indentation is found we can fix some of those cases by adding leading new line
144
+
145
+ const forceLeadingNewLine =
146
+ lines.length > 1 &&
147
+ lines
148
+ .slice(1)
149
+ .every((line) => line.length === 0 || isWhiteSpace(line.charCodeAt(0))); // Trailing triple quotes just looks confusing but doesn't force trailing new line
150
+
151
+ const hasTrailingTripleQuotes = escapedValue.endsWith('\\"""'); // Trailing quote (single or double) or slash forces trailing new line
152
+
153
+ const hasTrailingQuote = value.endsWith('"') && !hasTrailingTripleQuotes;
110
154
  const hasTrailingSlash = value.endsWith('\\');
155
+ const forceTrailingNewline = hasTrailingQuote || hasTrailingSlash;
111
156
  const printAsMultipleLines =
112
- !isSingleLine ||
113
- hasTrailingQuote ||
114
- hasTrailingSlash ||
115
- preferMultipleLines;
157
+ !(options !== null && options !== void 0 && options.minimize) && // add leading and trailing new lines only if it improves readability
158
+ (!isSingleLine ||
159
+ value.length > 70 ||
160
+ forceTrailingNewline ||
161
+ forceLeadingNewLine ||
162
+ hasTrailingTripleQuotes);
116
163
  let result = ''; // Format a multi-line block quote to account for leading space.
117
164
 
118
- if (printAsMultipleLines && !(isSingleLine && hasLeadingSpace)) {
165
+ const skipLeadingNewLine = isSingleLine && isWhiteSpace(value.charCodeAt(0));
166
+
167
+ if ((printAsMultipleLines && !skipLeadingNewLine) || forceLeadingNewLine) {
119
168
  result += '\n';
120
169
  }
121
170
 
122
- result += value;
171
+ result += escapedValue;
123
172
 
124
- if (printAsMultipleLines) {
173
+ if (printAsMultipleLines || forceTrailingNewline) {
125
174
  result += '\n';
126
175
  }
127
176
 
128
- return '"""' + result.replace(/"""/g, '\\"""') + '"""';
177
+ return '"""' + result + '"""';
129
178
  }
@@ -1,3 +1,12 @@
1
+ /**
2
+ * ```
3
+ * WhiteSpace ::
4
+ * - "Horizontal Tab (U+0009)"
5
+ * - "Space (U+0020)"
6
+ * ```
7
+ * @internal
8
+ */
9
+ export declare function isWhiteSpace(code: number): boolean;
1
10
  /**
2
11
  * ```
3
12
  * Digit :: one of
@@ -7,7 +7,19 @@ exports.isDigit = isDigit;
7
7
  exports.isLetter = isLetter;
8
8
  exports.isNameContinue = isNameContinue;
9
9
  exports.isNameStart = isNameStart;
10
+ exports.isWhiteSpace = isWhiteSpace;
10
11
 
12
+ /**
13
+ * ```
14
+ * WhiteSpace ::
15
+ * - "Horizontal Tab (U+0009)"
16
+ * - "Space (U+0020)"
17
+ * ```
18
+ * @internal
19
+ */
20
+ function isWhiteSpace(code) {
21
+ return code === 0x0009 || code === 0x0020;
22
+ }
11
23
  /**
12
24
  * ```
13
25
  * Digit :: one of
@@ -15,6 +27,7 @@ exports.isNameStart = isNameStart;
15
27
  * ```
16
28
  * @internal
17
29
  */
30
+
18
31
  function isDigit(code) {
19
32
  return code >= 0x0030 && code <= 0x0039;
20
33
  }
@@ -1,3 +1,14 @@
1
+ /**
2
+ * ```
3
+ * WhiteSpace ::
4
+ * - "Horizontal Tab (U+0009)"
5
+ * - "Space (U+0020)"
6
+ * ```
7
+ * @internal
8
+ */
9
+ export function isWhiteSpace(code) {
10
+ return code === 0x0009 || code === 0x0020;
11
+ }
1
12
  /**
2
13
  * ```
3
14
  * Digit :: one of
@@ -5,6 +16,7 @@
5
16
  * ```
6
17
  * @internal
7
18
  */
19
+
8
20
  export function isDigit(code) {
9
21
  return code >= 0x0030 && code <= 0x0039;
10
22
  }
package/language/lexer.js CHANGED
@@ -893,11 +893,11 @@ function readEscapedCharacter(lexer, position) {
893
893
  function readBlockString(lexer, start) {
894
894
  const body = lexer.source.body;
895
895
  const bodyLength = body.length;
896
- const startLine = lexer.line;
897
- const startColumn = 1 + start - lexer.lineStart;
896
+ let lineStart = lexer.lineStart;
898
897
  let position = start + 3;
899
898
  let chunkStart = position;
900
- let rawValue = '';
899
+ let currentLine = '';
900
+ const blockLines = [];
901
901
 
902
902
  while (position < bodyLength) {
903
903
  const code = body.charCodeAt(position); // Closing Triple-Quote (""")
@@ -907,15 +907,18 @@ function readBlockString(lexer, start) {
907
907
  body.charCodeAt(position + 1) === 0x0022 &&
908
908
  body.charCodeAt(position + 2) === 0x0022
909
909
  ) {
910
- rawValue += body.slice(chunkStart, position);
911
- return new _ast.Token(
910
+ currentLine += body.slice(chunkStart, position);
911
+ blockLines.push(currentLine);
912
+ const token = createToken(
913
+ lexer,
912
914
  _tokenKind.TokenKind.BLOCK_STRING,
913
915
  start,
914
- position + 3,
915
- startLine,
916
- startColumn,
917
- (0, _blockString.dedentBlockStringValue)(rawValue),
916
+ position + 3, // Return a string of the lines joined with U+000A.
917
+ (0, _blockString.dedentBlockStringLines)(blockLines).join('\n'),
918
918
  );
919
+ lexer.line += blockLines.length - 1;
920
+ lexer.lineStart = lineStart;
921
+ return token;
919
922
  } // Escaped Triple-Quote (\""")
920
923
 
921
924
  if (
@@ -924,21 +927,26 @@ function readBlockString(lexer, start) {
924
927
  body.charCodeAt(position + 2) === 0x0022 &&
925
928
  body.charCodeAt(position + 3) === 0x0022
926
929
  ) {
927
- rawValue += body.slice(chunkStart, position) + '"""';
930
+ currentLine += body.slice(chunkStart, position);
931
+ chunkStart = position + 1; // skip only slash
932
+
928
933
  position += 4;
929
- chunkStart = position;
930
934
  continue;
931
935
  } // LineTerminator
932
936
 
933
937
  if (code === 0x000a || code === 0x000d) {
938
+ currentLine += body.slice(chunkStart, position);
939
+ blockLines.push(currentLine);
940
+
934
941
  if (code === 0x000d && body.charCodeAt(position + 1) === 0x000a) {
935
942
  position += 2;
936
943
  } else {
937
944
  ++position;
938
945
  }
939
946
 
940
- ++lexer.line;
941
- lexer.lineStart = position;
947
+ currentLine = '';
948
+ chunkStart = position;
949
+ lineStart = position;
942
950
  continue;
943
951
  } // SourceCharacter
944
952