Skip to content

Commit

Permalink
Expose language metadata as const (#1111)
Browse files Browse the repository at this point in the history
Exposing the LanguageMetadata as const with satisfies allows the values of
its members like `languageId` or `fileExtensions` to be exposed statically.
This allows for patterns like
```
type MyFileExtensions = typeof MyFancyDSLLanguageMetaData.fileExtensions
```
Where then MyFileExtensions is not typed to a generic `string[]`
but to `['.myDsl']` which makes it easier to avoid mistakes.

Unfortunately this is a breaking change because it requires the fileExtensions
on the LanguageMetaData to be readonly to work.
  • Loading branch information
coolya authored Jul 12, 2023
1 parent 1584fac commit 1749111
Show file tree
Hide file tree
Showing 10 changed files with 20 additions and 20 deletions.
2 changes: 1 addition & 1 deletion examples/arithmetics/src/cli/cli-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import path from 'path';
import chalk from 'chalk';
import { URI } from 'vscode-uri';

export async function extractDocument<T extends AstNode>(fileName: string, extensions: string[], services: LangiumServices): Promise<LangiumDocument<T>> {
export async function extractDocument<T extends AstNode>(fileName: string, extensions: readonly string[], services: LangiumServices): Promise<LangiumDocument<T>> {
if (!extensions.includes(path.extname(fileName))) {
console.error(chalk.yellow(`Please, choose a file with one of these extensions: ${extensions}.`));
process.exit(1);
Expand Down
4 changes: 2 additions & 2 deletions examples/arithmetics/src/language-server/generated/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import type { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumS
import { ArithmeticsAstReflection } from './ast';
import { ArithmeticsGrammar } from './grammar';

export const ArithmeticsLanguageMetaData: LanguageMetaData = {
export const ArithmeticsLanguageMetaData = {
languageId: 'arithmetics',
fileExtensions: ['.calc'],
caseInsensitive: true
};
} as const satisfies LanguageMetaData;

export const ArithmeticsGeneratedSharedModule: Module<LangiumSharedServices, LangiumGeneratedSharedServices> = {
AstReflection: () => new ArithmeticsAstReflection()
Expand Down
4 changes: 2 additions & 2 deletions examples/domainmodel/src/cli/cli-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import path from 'path';
import chalk from 'chalk';
import { URI } from 'vscode-uri';

export async function extractDocument<T extends AstNode>(fileName: string, extensions: string[], services: LangiumServices): Promise<LangiumDocument<T>> {
export async function extractDocument<T extends AstNode>(fileName: string, extensions: readonly string[], services: LangiumServices): Promise<LangiumDocument<T>> {
if (!extensions.includes(path.extname(fileName))) {
console.error(chalk.yellow(`Please, choose a file with one of these extensions: ${extensions}.`));
process.exit(1);
Expand Down Expand Up @@ -39,7 +39,7 @@ export async function extractDocument<T extends AstNode>(fileName: string, exten
return document as LangiumDocument<T>;
}

export async function extractAstNode<T extends AstNode>(fileName: string, extensions: string[], services: LangiumServices): Promise<T> {
export async function extractAstNode<T extends AstNode>(fileName: string, extensions: readonly string[], services: LangiumServices): Promise<T> {
return (await extractDocument(fileName, extensions, services)).parseResult.value as T;
}

Expand Down
4 changes: 2 additions & 2 deletions examples/domainmodel/src/language-server/generated/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import type { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumS
import { DomainModelAstReflection } from './ast';
import { DomainModelGrammar } from './grammar';

export const DomainModelLanguageMetaData: LanguageMetaData = {
export const DomainModelLanguageMetaData = {
languageId: 'domain-model',
fileExtensions: ['.dmodel'],
caseInsensitive: false
};
} as const satisfies LanguageMetaData;

export const parserConfig: IParserConfig = {
recoveryEnabled: true,
Expand Down
8 changes: 4 additions & 4 deletions examples/requirements/src/language-server/generated/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import type { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumS
import { RequirementsAndTestsAstReflection } from './ast';
import { RequirementsGrammar, TestsGrammar } from './grammar';

export const RequirementsLanguageMetaData: LanguageMetaData = {
export const RequirementsLanguageMetaData = {
languageId: 'requirements-lang',
fileExtensions: ['.req'],
caseInsensitive: false
};
} as const satisfies LanguageMetaData;

export const TestsLanguageMetaData: LanguageMetaData = {
export const TestsLanguageMetaData = {
languageId: 'tests-lang',
fileExtensions: ['.tst'],
caseInsensitive: false
};
} as const satisfies LanguageMetaData;

export const RequirementsAndTestsGeneratedSharedModule: Module<LangiumSharedServices, LangiumGeneratedSharedServices> = {
AstReflection: () => new RequirementsAndTestsAstReflection()
Expand Down
4 changes: 2 additions & 2 deletions examples/statemachine/src/cli/cli-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import chalk from 'chalk';
import type { AstNode, LangiumDocument, LangiumServices } from 'langium';
import { URI } from 'vscode-uri';

export async function extractDocument(fileName: string, extensions: string[], services: LangiumServices): Promise<LangiumDocument> {
export async function extractDocument(fileName: string, extensions: readonly string[], services: LangiumServices): Promise<LangiumDocument> {
if (!extensions.includes(path.extname(fileName))) {
console.error(chalk.yellow(`Please, choose a file with one of these extensions: ${extensions}.`));
process.exit(1);
Expand Down Expand Up @@ -38,7 +38,7 @@ export async function extractDocument(fileName: string, extensions: string[], se
return document;
}

export async function extractAstNode<T extends AstNode>(fileName: string, extensions: string[], services: LangiumServices): Promise<T> {
export async function extractAstNode<T extends AstNode>(fileName: string, extensions: readonly string[], services: LangiumServices): Promise<T> {
return (await extractDocument(fileName, extensions, services)).parseResult?.value as T;
}

Expand Down
4 changes: 2 additions & 2 deletions examples/statemachine/src/language-server/generated/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import type { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumS
import { StatemachineAstReflection } from './ast';
import { StatemachineGrammar } from './grammar';

export const StatemachineLanguageMetaData: LanguageMetaData = {
export const StatemachineLanguageMetaData = {
languageId: 'statemachine',
fileExtensions: ['.statemachine'],
caseInsensitive: false
};
} as const satisfies LanguageMetaData;

export const StatemachineGeneratedSharedModule: Module<LangiumSharedServices, LangiumGeneratedSharedServices> = {
AstReflection: () => new StatemachineAstReflection()
Expand Down
4 changes: 2 additions & 2 deletions packages/langium-cli/src/generator/module-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ export function generateModule(grammars: Grammar[], config: LangiumConfig, gramm
for (const grammar of grammars) {
if (grammar.name) {
const config = grammarConfigMap.get(grammar)!;
node.append('export const ', grammar.name, 'LanguageMetaData: LanguageMetaData = {', NL);
node.append('export const ', grammar.name, 'LanguageMetaData = {', NL);
node.indent(metaData => {
metaData.append(`languageId: '${config.id}',`, NL);
metaData.append(`fileExtensions: [${config.fileExtensions && config.fileExtensions.map(e => appendQuotesAndDot(e)).join(', ')}],`, NL);
metaData.append(`caseInsensitive: ${Boolean(config.caseInsensitive)}`, NL);
});
node.append('};', NL, NL);
node.append('} as const satisfies LanguageMetaData;', NL, NL);
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/langium/src/grammar/generated/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import type { IParserConfig } from '../../parser/parser-config';
import { LangiumGrammarAstReflection } from './ast';
import { LangiumGrammarGrammar } from './grammar';

export const LangiumGrammarLanguageMetaData: LanguageMetaData = {
export const LangiumGrammarLanguageMetaData = {
languageId: 'langium',
fileExtensions: ['.langium'],
caseInsensitive: false
};
} as const satisfies LanguageMetaData;

export const LangiumGrammarParserConfig: IParserConfig = {
maxLookahead: 3,
Expand Down
2 changes: 1 addition & 1 deletion packages/langium/src/grammar/language-meta-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

export interface LanguageMetaData {
languageId: string;
fileExtensions: string[];
fileExtensions: readonly string[];
caseInsensitive: boolean;
}

0 comments on commit 1749111

Please sign in to comment.