@typespec/compiler
Version:
TypeSpec Compiler Preview
844 lines • 24.1 kB
JavaScript
// TextMate-based syntax highlighting is implemented in this file.
// typespec.tmLanguage is generated by running this script.
import { mkdir, writeFile } from "fs/promises";
import { resolve } from "path";
import * as tm from "tmlanguage-generator";
const meta = tm.meta;
const identifierStart = "[_$[:alpha:]]";
// cspell:disable-next-line
const identifierContinue = "[_$[:alnum:]]";
const beforeIdentifier = `(?=(${identifierStart}|\`))`;
const escapedIdentifier = "`(?:[^`\\\\]|\\\\.)*`";
const simpleIdentifier = `\\b${identifierStart}${identifierContinue}*\\b`;
const identifier = `${simpleIdentifier}|${escapedIdentifier}`;
const qualifiedIdentifier = `\\b${identifierStart}(?:${identifierContinue}|\\.${identifierStart})*\\b`;
const stringPattern = '\\"(?:[^\\"\\\\]|\\\\.)*\\"';
const modifierKeyword = `\\b(?:extern)\\b`;
const statementKeyword = `\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b`;
const universalEnd = `(?=,|;|@|\\)|\\}|${modifierKeyword}|${statementKeyword})`;
const universalEndExceptComma = `(?=;|@|\\)|\\}|${modifierKeyword}|${statementKeyword})`;
/**
* Universal end with extra end char: `=`
*/
const expressionEnd = `(?=,|;|@|\\)|\\}|=|${statementKeyword})`;
const hexNumber = "\\b(?<!\\$)0(?:x|X)[0-9a-fA-F][0-9a-fA-F_]*(n)?\\b(?!\\$)";
const binaryNumber = "\\b(?<!\\$)0(?:b|B)[01][01_]*(n)?\\b(?!\\$)";
const decimalNumber = "(?<!\\$)(?:" +
"(?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*(n)?\\b)|" + // 1.1E+3
"(?:\\b[0-9][0-9_]*(\\.)[eE][+-]?[0-9][0-9_]*(n)?\\b)|" + // 1.E+3
"(?:\\B(\\.)[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*(n)?\\b)|" + // .1E+3
"(?:\\b[0-9][0-9_]*[eE][+-]?[0-9][0-9_]*(n)?\\b)|" + // 1E+3
"(?:\\b[0-9][0-9_]*(\\.)[0-9][0-9_]*(n)?\\b)|" + // 1.1
"(?:\\b[0-9][0-9_]*(\\.)(n)?\\B)|" + // 1.
"(?:\\B(\\.)[0-9][0-9_]*(n)?\\b)|" + // .1
"(?:\\b[0-9][0-9_]*(n)?\\b(?!\\.))" + // 1
")(?!\\$)";
const anyNumber = `(?:${hexNumber}|${binaryNumber}|${decimalNumber})`;
const expression = {
key: "expression",
patterns: [
/* placeholder filled later due to cycle*/
],
};
const statement = {
key: "statement",
patterns: [
/*placeholder filled later due to cycle*/
],
};
const booleanLiteral = {
key: "boolean-literal",
scope: "constant.language.tsp",
match: `\\b(true|false)\\b`,
};
const escapeChar = {
key: "escape-character",
scope: "constant.character.escape.tsp",
match: "\\\\.",
};
const templateExpression = {
key: "template-expression",
scope: meta,
begin: "\\$\\{",
beginCaptures: {
"0": { scope: "punctuation.definition.template-expression.begin.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.definition.template-expression.end.tsp" },
},
patterns: [expression],
};
const stringLiteral = {
key: "string-literal",
scope: "string.quoted.double.tsp",
begin: '"',
end: '"|$',
patterns: [templateExpression, escapeChar],
};
const tripleQuotedStringLiteral = {
key: "triple-quoted-string-literal",
scope: "string.quoted.triple.tsp",
begin: '"""',
end: '"""',
patterns: [templateExpression, escapeChar],
};
const punctuationComma = {
key: "punctuation-comma",
scope: "punctuation.comma.tsp",
match: ",",
};
const punctuationAccessor = {
key: "punctuation-accessor",
scope: "punctuation.accessor.tsp",
match: "\\.",
};
const punctuationSemicolon = {
key: "punctuation-semicolon",
scope: "punctuation.terminator.statement.tsp",
match: ";",
};
const operatorAssignment = {
key: "operator-assignment",
scope: "keyword.operator.assignment.tsp",
match: "=",
};
const numericLiteral = {
key: "numeric-literal",
scope: "constant.numeric.tsp",
match: anyNumber,
};
const lineComment = {
key: "line-comment",
scope: "comment.line.double-slash.tsp",
match: "//.*$",
};
const blockComment = {
key: "block-comment",
scope: "comment.block.tsp",
begin: "/\\*",
end: "\\*/",
};
const docCommentParam = {
key: "doc-comment-param",
scope: "comment.block.tsp",
match: `(?x)((@)(?:param|template|prop))\\s+(${identifier})\\b`,
captures: {
"1": { scope: "keyword.tag.tspdoc" },
"2": { scope: "keyword.tag.tspdoc" },
"3": { scope: "variable.name.tsp" },
},
};
const docCommentReturn = {
key: "doc-comment-return-tag",
scope: "comment.block.tsp",
match: `(?x)((@)(?:returns))\\b`,
captures: {
"1": { scope: "keyword.tag.tspdoc" },
"2": { scope: "keyword.tag.tspdoc" },
},
};
const docCommentUnknownTag = {
key: "doc-comment-unknown-tag",
scope: "comment.block.tsp",
match: `(?x)((@)(?:${identifier}))\\b`,
captures: {
"1": { scope: "entity.name.tag.tsp" },
"2": { scope: "entity.name.tag.tsp" },
},
};
const docCommentBlock = {
key: "doc-comment-block",
patterns: [docCommentParam, docCommentReturn, docCommentUnknownTag],
};
const docComment = {
key: "doc-comment",
scope: "comment.block.tsp",
begin: "/\\*\\*",
beginCaptures: {
"0": { scope: "comment.block.tsp" },
},
end: "\\*/",
endCaptures: {
"0": { scope: "comment.block.tsp" },
},
patterns: [docCommentBlock],
};
// Tokens that match standing alone in any context: literals and comments
const token = {
key: "token",
patterns: [
docComment,
lineComment,
blockComment,
// `"""` must come before `"` or first two quotes of `"""` will match as
// empty string
tripleQuotedStringLiteral,
stringLiteral,
booleanLiteral,
numericLiteral,
],
};
const parenthesizedExpression = {
key: "parenthesized-expression",
scope: meta,
begin: "\\(",
beginCaptures: {
"0": { scope: "punctuation.parenthesis.open.tsp" },
},
end: "\\)",
endCaptures: {
"0": { scope: "punctuation.parenthesis.close.tsp" },
},
patterns: [expression, punctuationComma],
};
const callExpression = {
key: "callExpression",
scope: meta,
begin: `(${qualifiedIdentifier})\\s*(\\()`,
beginCaptures: {
"1": { scope: "entity.name.function.tsp" },
"2": { scope: "punctuation.parenthesis.open.tsp" },
},
end: "\\)",
endCaptures: {
"0": { scope: "punctuation.parenthesis.close.tsp" },
},
patterns: [token, expression, punctuationComma],
};
const decorator = {
key: "decorator",
scope: meta,
begin: `((@)${qualifiedIdentifier})`,
beginCaptures: {
"1": { scope: "entity.name.tag.tsp" },
"2": { scope: "entity.name.tag.tsp" },
},
end: `${beforeIdentifier}|${universalEnd}`,
patterns: [token, parenthesizedExpression],
};
const augmentDecoratorStatement = {
key: "augment-decorator-statement",
scope: meta,
begin: `((@@)${qualifiedIdentifier})`,
beginCaptures: {
"1": { scope: "entity.name.tag.tsp" },
"2": { scope: "entity.name.tag.tsp" },
},
end: `${beforeIdentifier}|${universalEnd}`,
patterns: [token, parenthesizedExpression],
};
const identifierExpression = {
key: "identifier-expression",
scope: "entity.name.type.tsp",
match: identifier,
};
const valueOfExpression = {
key: "valueof",
scope: meta,
begin: `\\b(valueof)`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `(?=>)|${universalEnd}`,
patterns: [expression],
};
const typeOfExpression = {
key: "typeof",
scope: meta,
begin: `\\b(typeof)`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `(?=>)|${universalEnd}`,
patterns: [expression],
};
const typeArgument = {
key: "type-argument",
scope: meta,
begin: `(?:(${identifier})\\s*(=))`,
beginCaptures: {
"1": { scope: "entity.name.type.tsp" },
"2": { scope: "keyword.operator.assignment.tsp" },
},
end: `(?=>)|${universalEnd}`,
endCaptures: {
"0": { scope: "keyword.operator.assignment.tsp" },
},
patterns: [token, expression, punctuationComma],
};
const typeArguments = {
key: "type-arguments",
scope: meta,
begin: "<",
beginCaptures: {
"0": { scope: "punctuation.definition.typeparameters.begin.tsp" },
},
end: ">",
endCaptures: {
"0": { scope: "punctuation.definition.typeparameters.end.tsp" },
},
patterns: [typeArgument, expression, punctuationComma],
};
const typeParameterConstraint = {
key: "type-parameter-constraint",
scope: meta,
begin: `extends`,
beginCaptures: {
"0": { scope: "keyword.other.tsp" },
},
end: `(?=>)|${universalEnd}`,
patterns: [expression],
};
const typeParameterDefault = {
key: "type-parameter-default",
scope: meta,
begin: `=`,
beginCaptures: {
"0": { scope: "keyword.operator.assignment.tsp" },
},
end: `(?=>)|${universalEnd}`,
patterns: [expression],
};
const typeParameter = {
key: "type-parameter",
scope: meta,
begin: `(${identifier})`,
beginCaptures: {
"1": { scope: "entity.name.type.tsp" },
},
end: `(?=>)|${universalEnd}`,
patterns: [token, typeParameterConstraint, typeParameterDefault],
};
const typeParameters = {
key: "type-parameters",
scope: meta,
begin: "<",
beginCaptures: {
"0": { scope: "punctuation.definition.typeparameters.begin.tsp" },
},
end: ">",
endCaptures: {
"0": { scope: "punctuation.definition.typeparameters.end.tsp" },
},
patterns: [typeParameter, punctuationComma],
};
const tupleLiteral = {
key: "tuple-literal",
scope: meta,
begin: "#\\[",
beginCaptures: {
"0": { scope: "punctuation.hashsquarebracket.open.tsp" },
},
end: "\\]",
endCaptures: {
"0": { scope: "punctuation.squarebracket.close.tsp" },
},
patterns: [expression, punctuationComma],
};
const tupleExpression = {
key: "tuple-expression",
scope: meta,
begin: "\\[",
beginCaptures: {
"0": { scope: "punctuation.squarebracket.open.tsp" },
},
end: "\\]",
endCaptures: {
"0": { scope: "punctuation.squarebracket.close.tsp" },
},
patterns: [expression],
};
const typeAnnotation = {
key: "type-annotation",
scope: meta,
begin: "\\s*(\\??)\\s*(:)",
beginCaptures: {
"1": { scope: "keyword.operator.optional.tsp" },
"2": { scope: "keyword.operator.type.annotation.tsp" },
},
end: expressionEnd,
patterns: [expression],
};
const modelProperty = {
key: "model-property",
scope: meta,
begin: `(?:(${identifier})|(${stringPattern}))`,
beginCaptures: {
"1": { scope: "variable.name.tsp" },
"2": { scope: "string.quoted.double.tsp" },
},
end: universalEnd,
patterns: [token, typeAnnotation, operatorAssignment, expression],
};
const spreadExpression = {
key: "spread-operator",
scope: meta,
begin: "\\.\\.\\.",
beginCaptures: {
"0": { scope: "keyword.operator.spread.tsp" },
},
end: universalEnd,
patterns: [expression],
};
const directive = {
key: "directive",
scope: meta,
begin: `\\s*(#${simpleIdentifier})`,
beginCaptures: {
"1": { scope: "keyword.directive.name.tsp" },
},
end: `$|${universalEnd}`,
patterns: [stringLiteral, identifierExpression],
};
const modelExpression = {
key: "model-expression",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [
// modelProperty must come before token or quoted property name will be
// considered an arbitrarily positioned string literal and not match as part
// of modelProperty begin.
modelProperty,
token,
directive,
decorator,
spreadExpression,
punctuationSemicolon,
],
};
const objectLiteralProperty = {
key: "object-literal-property",
scope: meta,
begin: `(?:(${identifier})\\s*(:))`,
beginCaptures: {
"1": { scope: "variable.name.tsp" },
"2": { scope: "keyword.operator.type.annotation.tsp" },
},
end: universalEnd,
patterns: [token, expression],
};
const objectLiteral = {
key: "object-literal",
scope: meta,
begin: "#\\{",
beginCaptures: {
"0": { scope: "punctuation.hashcurlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [token, objectLiteralProperty, directive, spreadExpression, punctuationComma],
};
const modelHeritage = {
key: "model-heritage",
scope: meta,
begin: "\\b(extends|is)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `((?=\\{)|${universalEndExceptComma})`,
patterns: [expression, punctuationComma],
};
const modelStatement = {
key: "model-statement",
scope: meta,
begin: "\\b(model)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `(?<=\\})|${universalEnd}`,
patterns: [
token,
typeParameters,
modelHeritage, // before expression or `extends` or `is` will look like type name
expression, // enough to match name, type parameters, and body.
],
};
const operationParameters = {
key: "operation-parameters",
scope: meta,
begin: "\\(",
beginCaptures: {
"0": { scope: "punctuation.parenthesis.open.tsp" },
},
end: "\\)",
endCaptures: {
"0": { scope: "punctuation.parenthesis.close.tsp" },
},
patterns: [token, decorator, modelProperty, spreadExpression, punctuationComma],
};
const scalarExtends = {
key: "scalar-extends",
scope: meta,
begin: "\\b(extends)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: universalEndExceptComma,
patterns: [expression, punctuationComma],
};
const scalarConstructor = {
key: "scalar-constructor",
scope: meta,
begin: `\\b(init)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.function.tsp" },
},
end: universalEnd,
patterns: [token, operationParameters],
};
const scalarBody = {
key: "scalar-body",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [token, directive, scalarConstructor, punctuationSemicolon],
};
const scalarStatement = {
key: "scalar-statement",
scope: meta,
begin: `\\b(scalar)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.type.tsp" },
},
end: `(?<=\\})|${universalEnd}`,
patterns: [
token,
typeParameters,
scalarExtends, // before expression or `extends` will look like type name
scalarBody,
],
};
const enumMember = {
key: "enum-member",
scope: meta,
begin: `(?:(${identifier})\\s*(:?))`,
beginCaptures: {
"1": { scope: "variable.name.tsp" },
"2": { scope: "keyword.operator.type.annotation.tsp" },
},
end: universalEnd,
patterns: [token, typeAnnotation],
};
const enumBody = {
key: "enum-body",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [enumMember, token, directive, decorator, punctuationComma],
};
const enumStatement = {
key: "enum-statement",
scope: meta,
begin: `\\b(enum)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.type.tsp" },
},
end: `(?<=\\})|${universalEnd}`,
patterns: [token, enumBody],
};
const namedUnionVariant = {
key: "union-variant",
scope: meta,
begin: `(?:(${identifier})\\s*(:))`,
beginCaptures: {
"1": { scope: "variable.name.tsp" },
"2": { scope: "keyword.operator.type.annotation.tsp" },
},
end: universalEnd,
patterns: [token, expression],
};
const unionBody = {
key: "union-body",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [namedUnionVariant, token, directive, decorator, expression, punctuationComma],
};
const unionStatement = {
key: "union-statement",
scope: meta,
begin: `\\b(union)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.type.tsp" },
},
end: `(?<=\\})|${universalEnd}`,
patterns: [token, unionBody],
};
const aliasAssignment = {
key: "alias-id",
scope: meta,
begin: `(=)\\s*`,
beginCaptures: {
"1": { scope: "keyword.operator.assignment.tsp" },
},
end: universalEnd,
patterns: [expression],
};
const aliasStatement = {
key: "alias-statement",
scope: meta,
begin: `\\b(alias)\\b\\s+(${identifier})\\s*`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.type.tsp" },
},
end: universalEnd,
patterns: [aliasAssignment, typeParameters],
};
const constStatement = {
key: "const-statement",
scope: meta,
begin: `\\b(const)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "variable.name.tsp" },
},
end: universalEnd,
patterns: [typeAnnotation, operatorAssignment, expression],
};
const namespaceName = {
key: "namespace-name",
scope: meta,
begin: beforeIdentifier,
end: `((?=\\{)|${universalEnd})`,
patterns: [identifierExpression, punctuationAccessor],
};
const namespaceBody = {
key: "namespace-body",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [statement],
};
const namespaceStatement = {
key: "namespace-statement",
scope: meta,
begin: "\\b(namespace)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `((?<=\\})|${universalEnd})`,
patterns: [token, namespaceName, namespaceBody],
};
const operationHeritage = {
key: "operation-heritage",
scope: meta,
begin: "\\b(is)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: universalEnd,
patterns: [expression],
};
const operationSignature = {
key: "operation-signature",
patterns: [
typeParameters,
operationHeritage,
operationParameters,
typeAnnotation, // return type
],
};
const operationStatement = {
key: "operation-statement",
scope: meta,
begin: `\\b(op)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.function.tsp" },
},
end: universalEnd,
patterns: [token, operationSignature],
};
const interfaceMember = {
key: "interface-member",
scope: meta,
begin: `(?:\\b(op)\\b\\s+)?(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "entity.name.function.tsp" },
},
end: universalEnd,
patterns: [token, operationSignature],
};
const interfaceHeritage = {
key: "interface-heritage",
scope: meta,
begin: "\\b(extends)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `((?=\\{)|${universalEndExceptComma})`,
patterns: [expression, punctuationComma],
};
const interfaceBody = {
key: "interface-body",
scope: meta,
begin: "\\{",
beginCaptures: {
"0": { scope: "punctuation.curlybrace.open.tsp" },
},
end: "\\}",
endCaptures: {
"0": { scope: "punctuation.curlybrace.close.tsp" },
},
patterns: [token, directive, decorator, interfaceMember, punctuationSemicolon],
};
const interfaceStatement = {
key: "interface-statement",
scope: meta,
begin: "\\b(interface)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: `(?<=\\})|${universalEnd}`,
patterns: [
token,
typeParameters,
interfaceHeritage, // before expression or extends will look like type name
interfaceBody, // before expression or { will match model expression
expression, // enough to match name and type parameters
],
};
const importStatement = {
key: "import-statement",
scope: meta,
begin: "\\b(import)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: universalEnd,
patterns: [token],
};
const usingStatement = {
key: "using-statement",
scope: meta,
begin: "\\b(using)\\b",
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
},
end: universalEnd,
patterns: [token, identifierExpression, punctuationAccessor],
};
const decoratorDeclarationStatement = {
key: "decorator-declaration-statement",
scope: meta,
begin: `(?:(extern)\\s+)?\\b(dec)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "keyword.other.tsp" },
"3": { scope: "entity.name.function.tsp" },
},
end: universalEnd,
patterns: [token, operationParameters],
};
const functionDeclarationStatement = {
key: "function-declaration-statement",
scope: meta,
begin: `(?:(extern)\\s+)?\\b(fn)\\b\\s+(${identifier})`,
beginCaptures: {
"1": { scope: "keyword.other.tsp" },
"2": { scope: "keyword.other.tsp" },
"3": { scope: "entity.name.function.tsp" },
},
end: universalEnd,
patterns: [token, operationParameters, typeAnnotation],
};
// NOTE: We don't actually classify all the different expression types and their
// punctuation yet. For now, at least, we only deal with the ones that would
// break coloring due to breaking out of context inappropriately with parens/
// braces/brackets that weren't handled with appropriate precedence. The other
// expressions color acceptably as unclassified punctuation around those we do
// handle here.
expression.patterns = [
token,
directive,
parenthesizedExpression,
valueOfExpression,
typeOfExpression,
typeArguments,
objectLiteral,
tupleLiteral,
tupleExpression,
modelExpression,
callExpression,
identifierExpression,
];
statement.patterns = [
token,
directive,
augmentDecoratorStatement,
decorator,
modelStatement,
scalarStatement,
unionStatement,
interfaceStatement,
enumStatement,
aliasStatement,
constStatement,
namespaceStatement,
operationStatement,
importStatement,
usingStatement,
decoratorDeclarationStatement,
functionDeclarationStatement,
punctuationSemicolon,
];
const grammar = {
$schema: tm.schema,
name: "TypeSpec",
scopeName: "source.tsp",
fileTypes: ["tsp"],
patterns: [statement],
};
export async function main() {
const plist = await tm.emitPList(grammar, {
errorSourceFilePath: resolve("./src/tmlanguage.ts"),
});
const json = await tm.emitJSON(grammar, {
errorSourceFilePath: resolve("./src/tmlanguage.ts"),
});
await mkdir("./dist", { recursive: true });
await writeFile("./dist/typespec.tmLanguage", plist);
await mkdir("../../grammars", { recursive: true });
await writeFile("../../grammars/typespec.json", json);
}
//# sourceMappingURL=tmlanguage.js.map