@typespec/prettier-plugin-typespec 0.57.0-dev.1 → 0.58.0-dev.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.
package/dist/index.js CHANGED
@@ -302,6 +302,7 @@ const diagnostics = {
302
302
  default: "Invalid identifier.",
303
303
  tag: "Invalid tag name. Use backticks around code if this was not meant to be a tag.",
304
304
  param: "Invalid parameter name.",
305
+ prop: "Invalid property name.",
305
306
  templateParam: "Invalid template parameter name.",
306
307
  },
307
308
  },
@@ -1168,51 +1169,52 @@ var SyntaxKind;
1168
1169
  SyntaxKind[SyntaxKind["Doc"] = 52] = "Doc";
1169
1170
  SyntaxKind[SyntaxKind["DocText"] = 53] = "DocText";
1170
1171
  SyntaxKind[SyntaxKind["DocParamTag"] = 54] = "DocParamTag";
1171
- SyntaxKind[SyntaxKind["DocReturnsTag"] = 55] = "DocReturnsTag";
1172
- SyntaxKind[SyntaxKind["DocErrorsTag"] = 56] = "DocErrorsTag";
1173
- SyntaxKind[SyntaxKind["DocTemplateTag"] = 57] = "DocTemplateTag";
1174
- SyntaxKind[SyntaxKind["DocUnknownTag"] = 58] = "DocUnknownTag";
1175
- SyntaxKind[SyntaxKind["Projection"] = 59] = "Projection";
1176
- SyntaxKind[SyntaxKind["ProjectionParameterDeclaration"] = 60] = "ProjectionParameterDeclaration";
1177
- SyntaxKind[SyntaxKind["ProjectionModelSelector"] = 61] = "ProjectionModelSelector";
1178
- SyntaxKind[SyntaxKind["ProjectionModelPropertySelector"] = 62] = "ProjectionModelPropertySelector";
1179
- SyntaxKind[SyntaxKind["ProjectionScalarSelector"] = 63] = "ProjectionScalarSelector";
1180
- SyntaxKind[SyntaxKind["ProjectionOperationSelector"] = 64] = "ProjectionOperationSelector";
1181
- SyntaxKind[SyntaxKind["ProjectionUnionSelector"] = 65] = "ProjectionUnionSelector";
1182
- SyntaxKind[SyntaxKind["ProjectionUnionVariantSelector"] = 66] = "ProjectionUnionVariantSelector";
1183
- SyntaxKind[SyntaxKind["ProjectionInterfaceSelector"] = 67] = "ProjectionInterfaceSelector";
1184
- SyntaxKind[SyntaxKind["ProjectionEnumSelector"] = 68] = "ProjectionEnumSelector";
1185
- SyntaxKind[SyntaxKind["ProjectionEnumMemberSelector"] = 69] = "ProjectionEnumMemberSelector";
1186
- SyntaxKind[SyntaxKind["ProjectionExpressionStatement"] = 70] = "ProjectionExpressionStatement";
1187
- SyntaxKind[SyntaxKind["ProjectionIfExpression"] = 71] = "ProjectionIfExpression";
1188
- SyntaxKind[SyntaxKind["ProjectionBlockExpression"] = 72] = "ProjectionBlockExpression";
1189
- SyntaxKind[SyntaxKind["ProjectionMemberExpression"] = 73] = "ProjectionMemberExpression";
1190
- SyntaxKind[SyntaxKind["ProjectionLogicalExpression"] = 74] = "ProjectionLogicalExpression";
1191
- SyntaxKind[SyntaxKind["ProjectionEqualityExpression"] = 75] = "ProjectionEqualityExpression";
1192
- SyntaxKind[SyntaxKind["ProjectionUnaryExpression"] = 76] = "ProjectionUnaryExpression";
1193
- SyntaxKind[SyntaxKind["ProjectionRelationalExpression"] = 77] = "ProjectionRelationalExpression";
1194
- SyntaxKind[SyntaxKind["ProjectionArithmeticExpression"] = 78] = "ProjectionArithmeticExpression";
1195
- SyntaxKind[SyntaxKind["ProjectionCallExpression"] = 79] = "ProjectionCallExpression";
1196
- SyntaxKind[SyntaxKind["ProjectionLambdaExpression"] = 80] = "ProjectionLambdaExpression";
1197
- SyntaxKind[SyntaxKind["ProjectionLambdaParameterDeclaration"] = 81] = "ProjectionLambdaParameterDeclaration";
1198
- SyntaxKind[SyntaxKind["ProjectionModelExpression"] = 82] = "ProjectionModelExpression";
1199
- SyntaxKind[SyntaxKind["ProjectionModelProperty"] = 83] = "ProjectionModelProperty";
1200
- SyntaxKind[SyntaxKind["ProjectionModelSpreadProperty"] = 84] = "ProjectionModelSpreadProperty";
1201
- SyntaxKind[SyntaxKind["ProjectionSpreadProperty"] = 85] = "ProjectionSpreadProperty";
1202
- SyntaxKind[SyntaxKind["ProjectionTupleExpression"] = 86] = "ProjectionTupleExpression";
1203
- SyntaxKind[SyntaxKind["ProjectionStatement"] = 87] = "ProjectionStatement";
1204
- SyntaxKind[SyntaxKind["ProjectionDecoratorReferenceExpression"] = 88] = "ProjectionDecoratorReferenceExpression";
1205
- SyntaxKind[SyntaxKind["Return"] = 89] = "Return";
1206
- SyntaxKind[SyntaxKind["JsNamespaceDeclaration"] = 90] = "JsNamespaceDeclaration";
1207
- SyntaxKind[SyntaxKind["TemplateArgument"] = 91] = "TemplateArgument";
1208
- SyntaxKind[SyntaxKind["TypeOfExpression"] = 92] = "TypeOfExpression";
1209
- SyntaxKind[SyntaxKind["ObjectLiteral"] = 93] = "ObjectLiteral";
1210
- SyntaxKind[SyntaxKind["ObjectLiteralProperty"] = 94] = "ObjectLiteralProperty";
1211
- SyntaxKind[SyntaxKind["ObjectLiteralSpreadProperty"] = 95] = "ObjectLiteralSpreadProperty";
1212
- SyntaxKind[SyntaxKind["ArrayLiteral"] = 96] = "ArrayLiteral";
1213
- SyntaxKind[SyntaxKind["ConstStatement"] = 97] = "ConstStatement";
1214
- SyntaxKind[SyntaxKind["CallExpression"] = 98] = "CallExpression";
1215
- SyntaxKind[SyntaxKind["ScalarConstructor"] = 99] = "ScalarConstructor";
1172
+ SyntaxKind[SyntaxKind["DocPropTag"] = 55] = "DocPropTag";
1173
+ SyntaxKind[SyntaxKind["DocReturnsTag"] = 56] = "DocReturnsTag";
1174
+ SyntaxKind[SyntaxKind["DocErrorsTag"] = 57] = "DocErrorsTag";
1175
+ SyntaxKind[SyntaxKind["DocTemplateTag"] = 58] = "DocTemplateTag";
1176
+ SyntaxKind[SyntaxKind["DocUnknownTag"] = 59] = "DocUnknownTag";
1177
+ SyntaxKind[SyntaxKind["Projection"] = 60] = "Projection";
1178
+ SyntaxKind[SyntaxKind["ProjectionParameterDeclaration"] = 61] = "ProjectionParameterDeclaration";
1179
+ SyntaxKind[SyntaxKind["ProjectionModelSelector"] = 62] = "ProjectionModelSelector";
1180
+ SyntaxKind[SyntaxKind["ProjectionModelPropertySelector"] = 63] = "ProjectionModelPropertySelector";
1181
+ SyntaxKind[SyntaxKind["ProjectionScalarSelector"] = 64] = "ProjectionScalarSelector";
1182
+ SyntaxKind[SyntaxKind["ProjectionOperationSelector"] = 65] = "ProjectionOperationSelector";
1183
+ SyntaxKind[SyntaxKind["ProjectionUnionSelector"] = 66] = "ProjectionUnionSelector";
1184
+ SyntaxKind[SyntaxKind["ProjectionUnionVariantSelector"] = 67] = "ProjectionUnionVariantSelector";
1185
+ SyntaxKind[SyntaxKind["ProjectionInterfaceSelector"] = 68] = "ProjectionInterfaceSelector";
1186
+ SyntaxKind[SyntaxKind["ProjectionEnumSelector"] = 69] = "ProjectionEnumSelector";
1187
+ SyntaxKind[SyntaxKind["ProjectionEnumMemberSelector"] = 70] = "ProjectionEnumMemberSelector";
1188
+ SyntaxKind[SyntaxKind["ProjectionExpressionStatement"] = 71] = "ProjectionExpressionStatement";
1189
+ SyntaxKind[SyntaxKind["ProjectionIfExpression"] = 72] = "ProjectionIfExpression";
1190
+ SyntaxKind[SyntaxKind["ProjectionBlockExpression"] = 73] = "ProjectionBlockExpression";
1191
+ SyntaxKind[SyntaxKind["ProjectionMemberExpression"] = 74] = "ProjectionMemberExpression";
1192
+ SyntaxKind[SyntaxKind["ProjectionLogicalExpression"] = 75] = "ProjectionLogicalExpression";
1193
+ SyntaxKind[SyntaxKind["ProjectionEqualityExpression"] = 76] = "ProjectionEqualityExpression";
1194
+ SyntaxKind[SyntaxKind["ProjectionUnaryExpression"] = 77] = "ProjectionUnaryExpression";
1195
+ SyntaxKind[SyntaxKind["ProjectionRelationalExpression"] = 78] = "ProjectionRelationalExpression";
1196
+ SyntaxKind[SyntaxKind["ProjectionArithmeticExpression"] = 79] = "ProjectionArithmeticExpression";
1197
+ SyntaxKind[SyntaxKind["ProjectionCallExpression"] = 80] = "ProjectionCallExpression";
1198
+ SyntaxKind[SyntaxKind["ProjectionLambdaExpression"] = 81] = "ProjectionLambdaExpression";
1199
+ SyntaxKind[SyntaxKind["ProjectionLambdaParameterDeclaration"] = 82] = "ProjectionLambdaParameterDeclaration";
1200
+ SyntaxKind[SyntaxKind["ProjectionModelExpression"] = 83] = "ProjectionModelExpression";
1201
+ SyntaxKind[SyntaxKind["ProjectionModelProperty"] = 84] = "ProjectionModelProperty";
1202
+ SyntaxKind[SyntaxKind["ProjectionModelSpreadProperty"] = 85] = "ProjectionModelSpreadProperty";
1203
+ SyntaxKind[SyntaxKind["ProjectionSpreadProperty"] = 86] = "ProjectionSpreadProperty";
1204
+ SyntaxKind[SyntaxKind["ProjectionTupleExpression"] = 87] = "ProjectionTupleExpression";
1205
+ SyntaxKind[SyntaxKind["ProjectionStatement"] = 88] = "ProjectionStatement";
1206
+ SyntaxKind[SyntaxKind["ProjectionDecoratorReferenceExpression"] = 89] = "ProjectionDecoratorReferenceExpression";
1207
+ SyntaxKind[SyntaxKind["Return"] = 90] = "Return";
1208
+ SyntaxKind[SyntaxKind["JsNamespaceDeclaration"] = 91] = "JsNamespaceDeclaration";
1209
+ SyntaxKind[SyntaxKind["TemplateArgument"] = 92] = "TemplateArgument";
1210
+ SyntaxKind[SyntaxKind["TypeOfExpression"] = 93] = "TypeOfExpression";
1211
+ SyntaxKind[SyntaxKind["ObjectLiteral"] = 94] = "ObjectLiteral";
1212
+ SyntaxKind[SyntaxKind["ObjectLiteralProperty"] = 95] = "ObjectLiteralProperty";
1213
+ SyntaxKind[SyntaxKind["ObjectLiteralSpreadProperty"] = 96] = "ObjectLiteralSpreadProperty";
1214
+ SyntaxKind[SyntaxKind["ArrayLiteral"] = 97] = "ArrayLiteral";
1215
+ SyntaxKind[SyntaxKind["ConstStatement"] = 98] = "ConstStatement";
1216
+ SyntaxKind[SyntaxKind["CallExpression"] = 99] = "CallExpression";
1217
+ SyntaxKind[SyntaxKind["ScalarConstructor"] = 100] = "ScalarConstructor";
1216
1218
  })(SyntaxKind || (SyntaxKind = {}));
1217
1219
  var IdentifierKind;
1218
1220
  (function (IdentifierKind) {
@@ -2474,6 +2476,8 @@ function createScanner(source, diagnosticHandler) {
2474
2476
  return getStringTokenValue(token, tokenFlags);
2475
2477
  case Token.Identifier:
2476
2478
  return getIdentifierTokenValue();
2479
+ case Token.DocText:
2480
+ return getDocTextValue();
2477
2481
  default:
2478
2482
  return getTokenText();
2479
2483
  }
@@ -2639,6 +2643,9 @@ function createScanner(source, diagnosticHandler) {
2639
2643
  // fallthrough
2640
2644
  case 10 /* CharCode.LineFeed */:
2641
2645
  return next(Token.NewLine);
2646
+ case 92 /* CharCode.Backslash */:
2647
+ tokenFlags |= TokenFlags.Escaped;
2648
+ return position === endPosition - 1 ? next(Token.DocText) : next(Token.DocText, 2);
2642
2649
  case 32 /* CharCode.Space */:
2643
2650
  case 9 /* CharCode.Tab */:
2644
2651
  case 11 /* CharCode.VerticalTab */:
@@ -2933,6 +2940,39 @@ function createScanner(source, diagnosticHandler) {
2933
2940
  }
2934
2941
  return text;
2935
2942
  }
2943
+ function getDocTextValue() {
2944
+ if (tokenFlags & TokenFlags.Escaped) {
2945
+ let start = tokenPosition;
2946
+ const end = position;
2947
+ let result = "";
2948
+ let pos = start;
2949
+ while (pos < end) {
2950
+ const ch = input.charCodeAt(pos);
2951
+ if (ch !== 92 /* CharCode.Backslash */) {
2952
+ pos++;
2953
+ continue;
2954
+ }
2955
+ if (pos === end - 1) {
2956
+ break;
2957
+ }
2958
+ result += input.substring(start, pos);
2959
+ switch (input.charCodeAt(pos + 1)) {
2960
+ case 64 /* CharCode.At */:
2961
+ result += "@";
2962
+ break;
2963
+ default:
2964
+ result += input.substring(pos, pos + 2);
2965
+ }
2966
+ pos += 2;
2967
+ start = pos;
2968
+ }
2969
+ result += input.substring(start, end);
2970
+ return result;
2971
+ }
2972
+ else {
2973
+ return input.substring(tokenPosition, position);
2974
+ }
2975
+ }
2936
2976
  function findTripleQuotedStringIndent(start, end) {
2937
2977
  end = end - 3; // Remove the """
2938
2978
  // remove whitespace before closing delimiter and record it as required
@@ -3102,6 +3142,8 @@ function createScanner(source, diagnosticHandler) {
3102
3142
  return "\\";
3103
3143
  case 36 /* CharCode.$ */:
3104
3144
  return "$";
3145
+ case 64 /* CharCode.At */:
3146
+ return "@";
3105
3147
  case 96 /* CharCode.Backtick */:
3106
3148
  return "`";
3107
3149
  default:
@@ -3707,8 +3749,8 @@ function createParser(code, options = {}) {
3707
3749
  function parseInterfaceStatement(pos, decorators) {
3708
3750
  parseExpected(Token.InterfaceKeyword);
3709
3751
  const id = parseIdentifier();
3710
- const templateParameters = parseTemplateParameterList();
3711
- let extendList = [];
3752
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
3753
+ let extendList = createEmptyList();
3712
3754
  if (token() === Token.ExtendsKeyword) {
3713
3755
  nextToken();
3714
3756
  extendList = parseList(ListKind.Heritage, parseReferenceExpression);
@@ -3717,21 +3759,23 @@ function createParser(code, options = {}) {
3717
3759
  error({ code: "token-expected", format: { token: "'extends' or '{'" } });
3718
3760
  nextToken();
3719
3761
  }
3720
- const operations = parseList(ListKind.InterfaceMembers, (pos, decorators) => parseOperationStatement(pos, decorators, true));
3762
+ const { items: operations, range: bodyRange } = parseList(ListKind.InterfaceMembers, (pos, decorators) => parseOperationStatement(pos, decorators, true));
3721
3763
  return {
3722
3764
  kind: SyntaxKind.InterfaceStatement,
3723
3765
  id,
3724
3766
  templateParameters,
3767
+ templateParametersRange,
3725
3768
  operations,
3726
- extends: extendList,
3769
+ bodyRange,
3770
+ extends: extendList.items,
3727
3771
  decorators,
3728
3772
  ...finishNode(pos),
3729
3773
  };
3730
3774
  }
3731
3775
  function parseTemplateParameterList() {
3732
- const list = parseOptionalList(ListKind.TemplateParameters, parseTemplateParameter);
3776
+ const detail = parseOptionalList(ListKind.TemplateParameters, parseTemplateParameter);
3733
3777
  let setDefault = false;
3734
- for (const item of list) {
3778
+ for (const item of detail.items) {
3735
3779
  if (!item.default && setDefault) {
3736
3780
  error({ code: "default-required", target: item });
3737
3781
  continue;
@@ -3740,17 +3784,18 @@ function createParser(code, options = {}) {
3740
3784
  setDefault = true;
3741
3785
  }
3742
3786
  }
3743
- return list;
3787
+ return detail;
3744
3788
  }
3745
3789
  function parseUnionStatement(pos, decorators) {
3746
3790
  parseExpected(Token.UnionKeyword);
3747
3791
  const id = parseIdentifier();
3748
- const templateParameters = parseTemplateParameterList();
3749
- const options = parseList(ListKind.UnionVariants, parseUnionVariant);
3792
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
3793
+ const { items: options } = parseList(ListKind.UnionVariants, parseUnionVariant);
3750
3794
  return {
3751
3795
  kind: SyntaxKind.UnionStatement,
3752
3796
  id,
3753
3797
  templateParameters,
3798
+ templateParametersRange,
3754
3799
  decorators,
3755
3800
  options,
3756
3801
  ...finishNode(pos),
@@ -3816,7 +3861,7 @@ function createParser(code, options = {}) {
3816
3861
  parseExpected(Token.OpKeyword);
3817
3862
  }
3818
3863
  const id = parseIdentifier();
3819
- const templateParameters = parseTemplateParameterList();
3864
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
3820
3865
  // Make sure the next token is one that is expected
3821
3866
  const token = expectTokenIsOneOf(Token.OpenParen, Token.IsKeyword);
3822
3867
  // Check if we're parsing a declaration or reuse of another operation
@@ -3850,6 +3895,7 @@ function createParser(code, options = {}) {
3850
3895
  kind: SyntaxKind.OperationStatement,
3851
3896
  id,
3852
3897
  templateParameters,
3898
+ templateParametersRange,
3853
3899
  signature,
3854
3900
  decorators,
3855
3901
  ...finishNode(pos),
@@ -3857,10 +3903,11 @@ function createParser(code, options = {}) {
3857
3903
  }
3858
3904
  function parseOperationParameters() {
3859
3905
  const pos = tokenPos();
3860
- const properties = parseList(ListKind.OperationParameters, parseModelPropertyOrSpread);
3906
+ const { items: properties, range: bodyRange } = parseList(ListKind.OperationParameters, parseModelPropertyOrSpread);
3861
3907
  const parameters = {
3862
3908
  kind: SyntaxKind.ModelExpression,
3863
3909
  properties,
3910
+ bodyRange,
3864
3911
  ...finishNode(pos),
3865
3912
  };
3866
3913
  return parameters;
@@ -3868,22 +3915,22 @@ function createParser(code, options = {}) {
3868
3915
  function parseModelStatement(pos, decorators) {
3869
3916
  parseExpected(Token.ModelKeyword);
3870
3917
  const id = parseIdentifier();
3871
- const templateParameters = parseTemplateParameterList();
3918
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
3872
3919
  expectTokenIsOneOf(Token.OpenBrace, Token.Equals, Token.ExtendsKeyword, Token.IsKeyword);
3873
3920
  const optionalExtends = parseOptionalModelExtends();
3874
3921
  const optionalIs = optionalExtends ? undefined : parseOptionalModelIs();
3875
- let properties = [];
3922
+ let propDetail = createEmptyList();
3876
3923
  if (optionalIs) {
3877
3924
  const tok = expectTokenIsOneOf(Token.Semicolon, Token.OpenBrace);
3878
3925
  if (tok === Token.Semicolon) {
3879
3926
  nextToken();
3880
3927
  }
3881
3928
  else {
3882
- properties = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
3929
+ propDetail = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
3883
3930
  }
3884
3931
  }
3885
3932
  else {
3886
- properties = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
3933
+ propDetail = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
3887
3934
  }
3888
3935
  return {
3889
3936
  kind: SyntaxKind.ModelStatement,
@@ -3891,8 +3938,10 @@ function createParser(code, options = {}) {
3891
3938
  extends: optionalExtends,
3892
3939
  is: optionalIs,
3893
3940
  templateParameters,
3941
+ templateParametersRange,
3894
3942
  decorators,
3895
- properties,
3943
+ properties: propDetail.items,
3944
+ bodyRange: propDetail.range,
3896
3945
  ...finishNode(pos),
3897
3946
  };
3898
3947
  }
@@ -4024,15 +4073,17 @@ function createParser(code, options = {}) {
4024
4073
  function parseScalarStatement(pos, decorators) {
4025
4074
  parseExpected(Token.ScalarKeyword);
4026
4075
  const id = parseIdentifier();
4027
- const templateParameters = parseTemplateParameterList();
4076
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
4028
4077
  const optionalExtends = parseOptionalScalarExtends();
4029
- const members = parseScalarMembers();
4078
+ const { items: members, range: bodyRange } = parseScalarMembers();
4030
4079
  return {
4031
4080
  kind: SyntaxKind.ScalarStatement,
4032
4081
  id,
4033
4082
  templateParameters,
4083
+ templateParametersRange,
4034
4084
  extends: optionalExtends,
4035
4085
  members,
4086
+ bodyRange,
4036
4087
  decorators,
4037
4088
  ...finishNode(pos),
4038
4089
  };
@@ -4046,7 +4097,7 @@ function createParser(code, options = {}) {
4046
4097
  function parseScalarMembers() {
4047
4098
  if (token() === Token.Semicolon) {
4048
4099
  nextToken();
4049
- return [];
4100
+ return createEmptyList();
4050
4101
  }
4051
4102
  else {
4052
4103
  return parseList(ListKind.ScalarMembers, parseScalarMember);
@@ -4056,7 +4107,7 @@ function createParser(code, options = {}) {
4056
4107
  reportInvalidDecorators(decorators, "scalar member");
4057
4108
  parseExpected(Token.InitKeyword);
4058
4109
  const id = parseIdentifier();
4059
- const parameters = parseFunctionParameters();
4110
+ const { items: parameters } = parseFunctionParameters();
4060
4111
  return {
4061
4112
  kind: SyntaxKind.ScalarConstructor,
4062
4113
  id,
@@ -4067,7 +4118,7 @@ function createParser(code, options = {}) {
4067
4118
  function parseEnumStatement(pos, decorators) {
4068
4119
  parseExpected(Token.EnumKeyword);
4069
4120
  const id = parseIdentifier();
4070
- const members = parseList(ListKind.EnumMembers, parseEnumMemberOrSpread);
4121
+ const { items: members } = parseList(ListKind.EnumMembers, parseEnumMemberOrSpread);
4071
4122
  return {
4072
4123
  kind: SyntaxKind.EnumStatement,
4073
4124
  id,
@@ -4121,7 +4172,7 @@ function createParser(code, options = {}) {
4121
4172
  function parseAliasStatement(pos) {
4122
4173
  parseExpected(Token.AliasKeyword);
4123
4174
  const id = parseIdentifier();
4124
- const templateParameters = parseTemplateParameterList();
4175
+ const { items: templateParameters, range: templateParametersRange } = parseTemplateParameterList();
4125
4176
  parseExpected(Token.Equals);
4126
4177
  const value = parseExpression();
4127
4178
  parseExpected(Token.Semicolon);
@@ -4129,6 +4180,7 @@ function createParser(code, options = {}) {
4129
4180
  kind: SyntaxKind.AliasStatement,
4130
4181
  id,
4131
4182
  templateParameters,
4183
+ templateParametersRange,
4132
4184
  value,
4133
4185
  ...finishNode(pos),
4134
4186
  };
@@ -4268,17 +4320,18 @@ function createParser(code, options = {}) {
4268
4320
  const pos = tokenPos();
4269
4321
  const target = parseIdentifierOrMemberExpression(message);
4270
4322
  if (token() === Token.OpenParen) {
4323
+ const { items: args } = parseList(ListKind.FunctionArguments, parseExpression);
4271
4324
  return {
4272
4325
  kind: SyntaxKind.CallExpression,
4273
4326
  target,
4274
- arguments: parseList(ListKind.FunctionArguments, parseExpression),
4327
+ arguments: args,
4275
4328
  ...finishNode(pos),
4276
4329
  };
4277
4330
  }
4278
4331
  return parseReferenceExpressionInternal(target, pos);
4279
4332
  }
4280
4333
  function parseReferenceExpressionInternal(target, pos) {
4281
- const args = parseOptionalList(ListKind.TemplateArguments, parseTemplateArgument);
4334
+ const { items: args } = parseOptionalList(ListKind.TemplateArguments, parseTemplateArgument);
4282
4335
  return {
4283
4336
  kind: SyntaxKind.TypeReference,
4284
4337
  target,
@@ -4329,29 +4382,31 @@ function createParser(code, options = {}) {
4329
4382
  // `@<missing identifier>` applied to `model Foo`, and not as `@model`
4330
4383
  // applied to invalid statement `Foo`.
4331
4384
  const target = parseIdentifierOrMemberExpression(undefined, false);
4332
- const args = parseOptionalList(ListKind.DecoratorArguments, parseExpression);
4385
+ const { items: args } = parseOptionalList(ListKind.DecoratorArguments, parseExpression);
4333
4386
  if (args.length === 0) {
4334
4387
  error({ code: "augment-decorator-target" });
4388
+ const emptyList = createEmptyList();
4335
4389
  return {
4336
4390
  kind: SyntaxKind.AugmentDecoratorStatement,
4337
4391
  target,
4338
4392
  targetType: {
4339
4393
  kind: SyntaxKind.TypeReference,
4340
4394
  target: createMissingIdentifier(),
4341
- arguments: [],
4395
+ arguments: emptyList.items,
4342
4396
  ...finishNode(pos),
4343
4397
  },
4344
- arguments: [],
4398
+ arguments: args,
4345
4399
  ...finishNode(pos),
4346
4400
  };
4347
4401
  }
4348
4402
  let [targetEntity, ...decoratorArgs] = args;
4349
4403
  if (targetEntity.kind !== SyntaxKind.TypeReference) {
4350
4404
  error({ code: "augment-decorator-target", target: targetEntity });
4405
+ const emptyList = createEmptyList();
4351
4406
  targetEntity = {
4352
4407
  kind: SyntaxKind.TypeReference,
4353
4408
  target: createMissingIdentifier(),
4354
- arguments: [],
4409
+ arguments: emptyList.items,
4355
4410
  ...finishNode(pos),
4356
4411
  };
4357
4412
  }
@@ -4383,7 +4438,7 @@ function createParser(code, options = {}) {
4383
4438
  // `@<missing identifier>` applied to `model Foo`, and not as `@model`
4384
4439
  // applied to invalid statement `Foo`.
4385
4440
  const target = parseIdentifierOrMemberExpression(undefined, false);
4386
- const args = parseOptionalList(ListKind.DecoratorArguments, parseExpression);
4441
+ const { items: args } = parseOptionalList(ListKind.DecoratorArguments, parseExpression);
4387
4442
  return {
4388
4443
  kind: SyntaxKind.DecoratorExpression,
4389
4444
  arguments: args,
@@ -4567,7 +4622,7 @@ function createParser(code, options = {}) {
4567
4622
  }
4568
4623
  function parseTupleExpression() {
4569
4624
  const pos = tokenPos();
4570
- const values = parseList(ListKind.Tuple, parseExpression);
4625
+ const { items: values } = parseList(ListKind.Tuple, parseExpression);
4571
4626
  return {
4572
4627
  kind: SyntaxKind.TupleExpression,
4573
4628
  values,
@@ -4576,25 +4631,27 @@ function createParser(code, options = {}) {
4576
4631
  }
4577
4632
  function parseModelExpression() {
4578
4633
  const pos = tokenPos();
4579
- const properties = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
4634
+ const { items: properties, range: bodyRange } = parseList(ListKind.ModelProperties, parseModelPropertyOrSpread);
4580
4635
  return {
4581
4636
  kind: SyntaxKind.ModelExpression,
4582
4637
  properties,
4638
+ bodyRange,
4583
4639
  ...finishNode(pos),
4584
4640
  };
4585
4641
  }
4586
4642
  function parseObjectLiteral() {
4587
4643
  const pos = tokenPos();
4588
- const properties = parseList(ListKind.ObjectLiteralProperties, parseObjectLiteralPropertyOrSpread);
4644
+ const { items: properties, range: bodyRange } = parseList(ListKind.ObjectLiteralProperties, parseObjectLiteralPropertyOrSpread);
4589
4645
  return {
4590
4646
  kind: SyntaxKind.ObjectLiteral,
4591
4647
  properties,
4648
+ bodyRange,
4592
4649
  ...finishNode(pos),
4593
4650
  };
4594
4651
  }
4595
4652
  function parseArrayLiteral() {
4596
4653
  const pos = tokenPos();
4597
- const values = parseList(ListKind.ArrayLiteral, parseExpression);
4654
+ const { items: values } = parseList(ListKind.ArrayLiteral, parseExpression);
4598
4655
  return {
4599
4656
  kind: SyntaxKind.ArrayLiteral,
4600
4657
  values,
@@ -4767,7 +4824,8 @@ function createParser(code, options = {}) {
4767
4824
  const modifierFlags = modifiersToFlags(modifiers);
4768
4825
  parseExpected(Token.DecKeyword);
4769
4826
  const id = parseIdentifier();
4770
- let [target, ...parameters] = parseFunctionParameters();
4827
+ const allParamListDetail = parseFunctionParameters();
4828
+ let [target, ...parameters] = allParamListDetail.items;
4771
4829
  if (target === undefined) {
4772
4830
  error({ code: "decorator-decl-target", target: { pos, end: previousTokenEnd } });
4773
4831
  target = {
@@ -4797,7 +4855,7 @@ function createParser(code, options = {}) {
4797
4855
  const modifierFlags = modifiersToFlags(modifiers);
4798
4856
  parseExpected(Token.FnKeyword);
4799
4857
  const id = parseIdentifier();
4800
- const parameters = parseFunctionParameters();
4858
+ const { items: parameters } = parseFunctionParameters();
4801
4859
  let returnType;
4802
4860
  if (parseOptional(Token.Colon)) {
4803
4861
  returnType = parseExpression();
@@ -4816,7 +4874,7 @@ function createParser(code, options = {}) {
4816
4874
  function parseFunctionParameters() {
4817
4875
  const parameters = parseList(ListKind.FunctionParameters, parseFunctionParameter);
4818
4876
  let foundOptional = false;
4819
- for (const [index, item] of parameters.entries()) {
4877
+ for (const [index, item] of parameters.items.entries()) {
4820
4878
  if (!item.optional && foundOptional) {
4821
4879
  error({ code: "required-parameter-first", target: item });
4822
4880
  continue;
@@ -4827,7 +4885,7 @@ function createParser(code, options = {}) {
4827
4885
  if (item.rest && item.optional) {
4828
4886
  error({ code: "rest-parameter-required", target: item });
4829
4887
  }
4830
- if (item.rest && index !== parameters.length - 1) {
4888
+ if (item.rest && index !== parameters.items.length - 1) {
4831
4889
  error({ code: "rest-parameter-last", target: item });
4832
4890
  }
4833
4891
  }
@@ -4919,7 +4977,7 @@ function createParser(code, options = {}) {
4919
4977
  }
4920
4978
  let parameters;
4921
4979
  if (token() === Token.OpenParen) {
4922
- parameters = parseList(ListKind.ProjectionParameter, parseProjectionParameter);
4980
+ parameters = parseList(ListKind.ProjectionParameter, parseProjectionParameter).items;
4923
4981
  }
4924
4982
  else {
4925
4983
  parameters = [];
@@ -5141,7 +5199,7 @@ function createParser(code, options = {}) {
5141
5199
  kind: SyntaxKind.ProjectionCallExpression,
5142
5200
  callKind: "method",
5143
5201
  target: expr,
5144
- arguments: parseList(ListKind.CallArguments, parseProjectionExpression),
5202
+ arguments: parseList(ListKind.CallArguments, parseProjectionExpression).items,
5145
5203
  ...finishNode(pos),
5146
5204
  };
5147
5205
  }
@@ -5224,7 +5282,7 @@ function createParser(code, options = {}) {
5224
5282
  }
5225
5283
  function parseProjectionLambdaOrParenthesizedExpression() {
5226
5284
  const pos = tokenPos();
5227
- const exprs = parseList(ListKind.ProjectionExpression, parseProjectionExpression);
5285
+ const exprs = parseList(ListKind.ProjectionExpression, parseProjectionExpression).items;
5228
5286
  if (token() === Token.EqualsGreaterThan) {
5229
5287
  // unpack the exprs (which should be just identifiers) into a param list
5230
5288
  const params = [];
@@ -5275,7 +5333,7 @@ function createParser(code, options = {}) {
5275
5333
  }
5276
5334
  function parseProjectionModelExpression() {
5277
5335
  const pos = tokenPos();
5278
- const properties = parseList(ListKind.ModelProperties, parseProjectionModelPropertyOrSpread);
5336
+ const { items: properties } = parseList(ListKind.ModelProperties, parseProjectionModelPropertyOrSpread);
5279
5337
  return {
5280
5338
  kind: SyntaxKind.ProjectionModelExpression,
5281
5339
  properties,
@@ -5349,7 +5407,7 @@ function createParser(code, options = {}) {
5349
5407
  }
5350
5408
  function parseProjectionTupleExpression() {
5351
5409
  const pos = tokenPos();
5352
- const values = parseList(ListKind.Tuple, parseProjectionExpression);
5410
+ const { items: values } = parseList(ListKind.Tuple, parseProjectionExpression);
5353
5411
  return {
5354
5412
  kind: SyntaxKind.ProjectionTupleExpression,
5355
5413
  values,
@@ -5533,6 +5591,12 @@ function createParser(code, options = {}) {
5533
5591
  }
5534
5592
  nextToken();
5535
5593
  break;
5594
+ case Token.DocText:
5595
+ parts.push(source.substring(start, tokenPos()));
5596
+ parts.push(tokenValue());
5597
+ nextToken();
5598
+ start = tokenPos();
5599
+ break;
5536
5600
  default:
5537
5601
  nextToken();
5538
5602
  break;
@@ -5562,6 +5626,8 @@ function createParser(code, options = {}) {
5562
5626
  return parseDocParamLikeTag(pos, tagName, SyntaxKind.DocParamTag, "param");
5563
5627
  case "template":
5564
5628
  return parseDocParamLikeTag(pos, tagName, SyntaxKind.DocTemplateTag, "templateParam");
5629
+ case "prop":
5630
+ return parseDocPropTag(pos, tagName);
5565
5631
  case "return":
5566
5632
  case "returns":
5567
5633
  return parseDocSimpleTag(pos, tagName, SyntaxKind.DocReturnsTag);
@@ -5576,9 +5642,7 @@ function createParser(code, options = {}) {
5576
5642
  * For example, `@param` and `@template`.
5577
5643
  */
5578
5644
  function parseDocParamLikeTag(pos, tagName, kind, messageId) {
5579
- const name = parseDocIdentifier(messageId);
5580
- parseOptionalHyphenDocParamLikeTag();
5581
- const content = parseDocContent();
5645
+ const { name, content } = parseDocParamLikeTagInternal(messageId);
5582
5646
  return {
5583
5647
  kind,
5584
5648
  tagName,
@@ -5587,6 +5651,22 @@ function createParser(code, options = {}) {
5587
5651
  ...finishNode(pos),
5588
5652
  };
5589
5653
  }
5654
+ function parseDocPropTag(pos, tagName) {
5655
+ const { name, content } = parseDocParamLikeTagInternal("prop");
5656
+ return {
5657
+ kind: SyntaxKind.DocPropTag,
5658
+ tagName,
5659
+ propName: name,
5660
+ content,
5661
+ ...finishNode(pos),
5662
+ };
5663
+ }
5664
+ function parseDocParamLikeTagInternal(messageId) {
5665
+ const name = parseDocIdentifier(messageId);
5666
+ parseOptionalHyphenDocParamLikeTag();
5667
+ const content = parseDocContent();
5668
+ return { name, content };
5669
+ }
5590
5670
  /**
5591
5671
  * Handles the optional hyphen in param-like documentation comment tags.
5592
5672
  *
@@ -5711,10 +5791,11 @@ function createParser(code, options = {}) {
5711
5791
  }
5712
5792
  function createMissingTypeReference() {
5713
5793
  const pos = tokenPos();
5794
+ const { items: args } = createEmptyList();
5714
5795
  return {
5715
5796
  kind: SyntaxKind.TypeReference,
5716
5797
  target: createMissingIdentifier(),
5717
- arguments: [],
5798
+ arguments: args,
5718
5799
  ...finishNode(pos),
5719
5800
  };
5720
5801
  }
@@ -5727,6 +5808,12 @@ function createParser(code, options = {}) {
5727
5808
  function withSymbol(obj) {
5728
5809
  return obj;
5729
5810
  }
5811
+ function createEmptyList(range = { pos: -1, end: -1 }) {
5812
+ return {
5813
+ items: [],
5814
+ range,
5815
+ };
5816
+ }
5730
5817
  /**
5731
5818
  * Parse a delimited list of elements, including the surrounding open and
5732
5819
  * close punctuation
@@ -5743,13 +5830,17 @@ function createParser(code, options = {}) {
5743
5830
  * do not go through here.
5744
5831
  */
5745
5832
  function parseList(kind, parseItem) {
5833
+ const r = createEmptyList();
5746
5834
  if (kind.open !== Token.None) {
5747
- parseExpected(kind.open);
5835
+ const t = tokenPos();
5836
+ if (parseExpected(kind.open)) {
5837
+ mutate(r.range).pos = t;
5838
+ }
5748
5839
  }
5749
5840
  if (kind.allowEmpty && parseOptional(kind.close)) {
5750
- return [];
5841
+ mutate(r.range).end = previousTokenEnd;
5842
+ return r;
5751
5843
  }
5752
- const items = [];
5753
5844
  while (true) {
5754
5845
  const startingPos = tokenPos();
5755
5846
  const { pos, docs, directives, decorators } = parseAnnotations({
@@ -5764,7 +5855,9 @@ function createParser(code, options = {}) {
5764
5855
  // of file. Note, however, that we must parse a missing element if
5765
5856
  // there were directives or decorators as we cannot drop those from
5766
5857
  // the tree.
5767
- parseExpected(kind.close);
5858
+ if (parseExpected(kind.close)) {
5859
+ mutate(r.range).end = previousTokenEnd;
5860
+ }
5768
5861
  break;
5769
5862
  }
5770
5863
  let item;
@@ -5776,12 +5869,13 @@ function createParser(code, options = {}) {
5776
5869
  mutate(item).docs = docs;
5777
5870
  mutate(item).directives = directives;
5778
5871
  }
5779
- items.push(item);
5872
+ r.items.push(item);
5780
5873
  const delimiter = token();
5781
5874
  const delimiterPos = tokenPos();
5782
5875
  if (parseOptionalDelimiter(kind)) {
5783
5876
  // Delimiter found: check if it's trailing.
5784
5877
  if (parseOptional(kind.close)) {
5878
+ mutate(r.range).end = previousTokenEnd;
5785
5879
  if (!kind.trailingDelimiterIsValid) {
5786
5880
  error({
5787
5881
  code: "trailing-token",
@@ -5805,6 +5899,7 @@ function createParser(code, options = {}) {
5805
5899
  break;
5806
5900
  }
5807
5901
  else if (parseOptional(kind.close)) {
5902
+ mutate(r.range).end = previousTokenEnd;
5808
5903
  // If a list *is* surrounded by punctuation, then the list ends when we
5809
5904
  // reach the close token.
5810
5905
  break;
@@ -5815,7 +5910,9 @@ function createParser(code, options = {}) {
5815
5910
  // assumption that the closing delimiter is missing. This check is
5816
5911
  // duplicated from above to preempt the parseExpected(delimeter)
5817
5912
  // below.
5818
- parseExpected(kind.close);
5913
+ if (parseExpected(kind.close)) {
5914
+ mutate(r.range).end = previousTokenEnd;
5915
+ }
5819
5916
  break;
5820
5917
  }
5821
5918
  else {
@@ -5834,21 +5931,23 @@ function createParser(code, options = {}) {
5834
5931
  //
5835
5932
  // Simple repro: `model M { ]` would loop forever without this check.
5836
5933
  //
5837
- parseExpected(kind.close);
5934
+ if (parseExpected(kind.close)) {
5935
+ mutate(r.range).end = previousTokenEnd;
5936
+ }
5838
5937
  nextToken();
5839
5938
  // remove the item that was entirely inserted by error recovery.
5840
- items.pop();
5939
+ r.items.pop();
5841
5940
  break;
5842
5941
  }
5843
5942
  }
5844
- return items;
5943
+ return r;
5845
5944
  }
5846
5945
  /**
5847
5946
  * Parse a delimited list with surrounding open and close punctuation if the
5848
5947
  * open token is present. Otherwise, return an empty list.
5849
5948
  */
5850
5949
  function parseOptionalList(kind, parseItem) {
5851
- return token() === kind.open ? parseList(kind, parseItem) : [];
5950
+ return token() === kind.open ? parseList(kind, parseItem) : createEmptyList();
5852
5951
  }
5853
5952
  function parseOptionalDelimiter(kind) {
5854
5953
  if (parseOptional(kind.delimiter)) {
@@ -6195,6 +6294,8 @@ function visitChildren(node, cb) {
6195
6294
  case SyntaxKind.DocParamTag:
6196
6295
  case SyntaxKind.DocTemplateTag:
6197
6296
  return (visitNode(cb, node.tagName) || visitNode(cb, node.paramName) || visitEach(cb, node.content));
6297
+ case SyntaxKind.DocPropTag:
6298
+ return (visitNode(cb, node.tagName) || visitNode(cb, node.propName) || visitEach(cb, node.content));
6198
6299
  case SyntaxKind.DocReturnsTag:
6199
6300
  case SyntaxKind.DocErrorsTag:
6200
6301
  case SyntaxKind.DocUnknownTag:
@@ -6448,7 +6549,7 @@ function group$1(contents, opts = {}) {
6448
6549
  function dedentToRoot(contents) {
6449
6550
  return align$1(Number.NEGATIVE_INFINITY, contents);
6450
6551
  }
6451
- function markAsRoot(contents) {
6552
+ function markAsRoot$1(contents) {
6452
6553
  return align$1({ type: "root" }, contents);
6453
6554
  }
6454
6555
  function dedent(contents) {
@@ -6491,7 +6592,7 @@ var literallineWithoutBreakParent = {
6491
6592
  var line$1 = { type: DOC_TYPE_LINE };
6492
6593
  var softline$1 = { type: DOC_TYPE_LINE, soft: true };
6493
6594
  var hardline$1 = [hardlineWithoutBreakParent, breakParent$1];
6494
- var literalline = [literallineWithoutBreakParent, breakParent$1];
6595
+ var literalline$1 = [literallineWithoutBreakParent, breakParent$1];
6495
6596
  var cursor = { type: DOC_TYPE_CURSOR };
6496
6597
  function join$1(separator, docs) {
6497
6598
  const parts = [];
@@ -6902,7 +7003,7 @@ function cleanDocFn(doc) {
6902
7003
  function cleanDoc(doc) {
6903
7004
  return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
6904
7005
  }
6905
- function replaceEndOfLine(doc, replacement = literalline) {
7006
+ function replaceEndOfLine(doc, replacement = literalline$1) {
6906
7007
  return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join$1(replacement, currentDoc.split("\n")) : currentDoc);
6907
7008
  }
6908
7009
  function canBreakFn(doc) {
@@ -7483,7 +7584,7 @@ var builders = {
7483
7584
  line: line$1,
7484
7585
  softline: softline$1,
7485
7586
  hardline: hardline$1,
7486
- literalline,
7587
+ literalline: literalline$1,
7487
7588
  group: group$1,
7488
7589
  conditionalGroup,
7489
7590
  fill,
@@ -7497,7 +7598,7 @@ var builders = {
7497
7598
  indentIfBreak,
7498
7599
  align: align$1,
7499
7600
  addAlignmentToDoc,
7500
- markAsRoot,
7601
+ markAsRoot: markAsRoot$1,
7501
7602
  dedentToRoot,
7502
7603
  dedent,
7503
7604
  hardlineWithoutBreakParent,
@@ -7721,7 +7822,7 @@ function needsParens(path, options) {
7721
7822
  }
7722
7823
  }
7723
7824
 
7724
- const { align, breakParent, group, hardline, ifBreak, indent, join, line, softline } = builders;
7825
+ const { align, breakParent, group, hardline, ifBreak, indent, join, line, softline, literalline, markAsRoot, } = builders;
7725
7826
  const { isNextLineEmpty } = util;
7726
7827
  /**
7727
7828
  * If the decorators for that node should try to be kept inline.
@@ -7916,6 +8017,7 @@ path, options, print) {
7916
8017
  return printDoc(path, options);
7917
8018
  case SyntaxKind.DocText:
7918
8019
  case SyntaxKind.DocParamTag:
8020
+ case SyntaxKind.DocPropTag:
7919
8021
  case SyntaxKind.DocTemplateTag:
7920
8022
  case SyntaxKind.DocReturnsTag:
7921
8023
  case SyntaxKind.DocErrorsTag:
@@ -8126,7 +8228,8 @@ function printCallOrDecoratorArgs(path, options, print) {
8126
8228
  // })
8127
8229
  const shouldHug = node.arguments.length === 1 &&
8128
8230
  (node.arguments[0].kind === SyntaxKind.ModelExpression ||
8129
- node.arguments[0].kind === SyntaxKind.StringLiteral);
8231
+ node.arguments[0].kind === SyntaxKind.StringLiteral ||
8232
+ node.arguments[0].kind === SyntaxKind.StringTemplateExpression);
8130
8233
  if (shouldHug) {
8131
8234
  return [
8132
8235
  "(",
@@ -8740,7 +8843,22 @@ function printModifiers(path, options, print) {
8740
8843
  }
8741
8844
  function printStringLiteral(path, options) {
8742
8845
  const node = path.node;
8743
- return getRawText(node, options);
8846
+ const multiline = isMultiline(node, options);
8847
+ const raw = getRawText(node, options);
8848
+ if (multiline) {
8849
+ const lines = splitLines(raw.slice(3));
8850
+ const whitespaceIndent = lines[lines.length - 1].length - 3;
8851
+ const newLines = trimMultilineString(lines, whitespaceIndent);
8852
+ return [`"""`, indent(markAsRoot(newLines))];
8853
+ }
8854
+ else {
8855
+ return raw;
8856
+ }
8857
+ }
8858
+ function isMultiline(node, options) {
8859
+ return (options.originalText[node.pos] &&
8860
+ options.originalText[node.pos + 1] === `"` &&
8861
+ options.originalText[node.pos + 2] === `"`);
8744
8862
  }
8745
8863
  function printNumberLiteral(path, options) {
8746
8864
  const node = path.node;
@@ -8878,14 +8996,76 @@ function printReturnExpression(path, options, print) {
8878
8996
  }
8879
8997
  function printStringTemplateExpression(path, options, print) {
8880
8998
  const node = path.node;
8881
- const content = [
8882
- getRawText(node.head, options),
8883
- path.map((span) => {
8884
- const expression = span.call(print, "expression");
8885
- return [expression, getRawText(span.node.literal, options)];
8886
- }, "spans"),
8887
- ];
8888
- return content;
8999
+ const multiline = isMultiline(node, options);
9000
+ const rawHead = getRawText(node.head, options);
9001
+ if (multiline) {
9002
+ const lastSpan = node.spans[node.spans.length - 1];
9003
+ const lastLines = splitLines(getRawText(lastSpan.literal, options));
9004
+ const whitespaceIndent = lastLines[lastLines.length - 1].length - 3;
9005
+ const content = [
9006
+ trimMultilineString(splitLines(rawHead.slice(3)), whitespaceIndent),
9007
+ path.map((span) => {
9008
+ const expression = span.call(print, "expression");
9009
+ const spanRawText = getRawText(span.node.literal, options);
9010
+ const spanLines = splitLines(spanRawText);
9011
+ return [
9012
+ expression,
9013
+ spanLines[0],
9014
+ literalline,
9015
+ trimMultilineString(spanLines.slice(1), whitespaceIndent),
9016
+ ];
9017
+ }, "spans"),
9018
+ ];
9019
+ return [`"""`, indent(markAsRoot([content]))];
9020
+ }
9021
+ else {
9022
+ const content = [
9023
+ rawHead,
9024
+ path.map((span) => {
9025
+ const expression = span.call(print, "expression");
9026
+ return [expression, getRawText(span.node.literal, options)];
9027
+ }, "spans"),
9028
+ ];
9029
+ return content;
9030
+ }
9031
+ }
9032
+ function splitLines(text) {
9033
+ const lines = [];
9034
+ let start = 0;
9035
+ let pos = 0;
9036
+ while (pos < text.length) {
9037
+ const ch = text.charCodeAt(pos);
9038
+ switch (ch) {
9039
+ case 13 /* CharCode.CarriageReturn */:
9040
+ if (text.charCodeAt(pos + 1) === 10 /* CharCode.LineFeed */) {
9041
+ lines.push(text.slice(start, pos));
9042
+ start = pos;
9043
+ pos++;
9044
+ }
9045
+ else {
9046
+ lines.push(text.slice(start, pos));
9047
+ start = pos;
9048
+ }
9049
+ break;
9050
+ case 10 /* CharCode.LineFeed */:
9051
+ lines.push(text.slice(start, pos));
9052
+ start = pos;
9053
+ break;
9054
+ }
9055
+ pos++;
9056
+ }
9057
+ lines.push(text.slice(start));
9058
+ return lines;
9059
+ }
9060
+ function trimMultilineString(lines, whitespaceIndent) {
9061
+ const newLines = [];
9062
+ for (let i = 0; i < lines.length; i++) {
9063
+ newLines.push(lines[i].slice(whitespaceIndent));
9064
+ if (i < lines.length - 1) {
9065
+ newLines.push(literalline);
9066
+ }
9067
+ }
9068
+ return newLines;
8889
9069
  }
8890
9070
  function printItemList(path, options, print, key) {
8891
9071
  return join(", ", path.map(print, key));