Skip to content

Commit 2d4fd87

Browse files
dannymcgeeayazhafiz
authored andcommitted
refactor: build template.json grammar from typescript source files (#581)
* Added ts-node dev dependency * Added tsconfig, types and build script * Added source files for Template grammar * npm script for building grammars * Built template.json from source * Formatting * Added final newline to build script * Fixed incorrect type * Removed unnecessary type literal abstractions * Refactored to function declarations * Refactored and added comments for clarity * Removed ts-node dev dependency * Bugfix: index.ts not resolved as expected when using WSL * Integrated syntax compilation into build script * Formatting * Consolidated Template grammar files
1 parent 3a630f2 commit 2d4fd87

File tree

11 files changed

+233
-204
lines changed

11 files changed

+233
-204
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ dist/
1212
.vscode/settings.json
1313
.vimrc
1414
.nvimrc
15+
syntaxes/out
1516
syntaxes/test/*.js
1617
syntaxes/test/*.map

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,16 @@
9696
"compile:test": "tsc -b server/src/tests",
9797
"compile:integration": "tsc -b integration",
9898
"compile:syntaxes-test": "tsc -b syntaxes/test",
99+
"compile:syntaxes": "tsc -b syntaxes",
100+
"build:syntaxes": "yarn compile:syntaxes && node syntaxes/out/build.js",
99101
"format": "scripts/format.sh",
100102
"watch": "tsc -b -w",
101103
"postinstall": "vscode-install && cd client && yarn && cd ../server && yarn && cd ..",
102104
"package": "rm -rf dist && node scripts/package.js",
103105
"test": "yarn compile:test && jasmine server/out/tests/*_spec.js",
104106
"test:lsp": "yarn compile:integration && jasmine integration/out/lsp/*_spec.js",
105107
"test:e2e": "yarn compile:integration && ./scripts/e2e.sh",
106-
"test:syntaxes": "yarn compile:syntaxes-test && jasmine syntaxes/test/driver.js"
108+
"test:syntaxes": "yarn compile:syntaxes-test && yarn build:syntaxes && jasmine syntaxes/test/driver.js"
107109
},
108110
"dependencies": {
109111
"typescript": "~3.7.4"

scripts/build.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ set -ex -o pipefail
55
# Clean up from last build
66
rm -rf client/out
77
rm -rf server/out
8+
rm -rf syntaxes/out
89
rm -rf dist
910
rm -rf **/*.tsbuildinfo
1011

@@ -17,9 +18,13 @@ cp package.json yarn.lock angular.png CHANGELOG.md README.md dist
1718
cp client/package.json client/yarn.lock dist/client
1819
# Copy files to server directory
1920
cp server/package.json server/yarn.lock server/README.md dist/server
20-
# Copy files to syntaxes directory
21+
# Build and copy files to syntaxes directory
22+
node syntaxes/out/build.js
2123
mkdir dist/syntaxes
24+
cp syntaxes/out/*.json dist/syntaxes
25+
# TODO: Remove the next two lines once all syntaxes have been refactored to TypeScript
2226
cp syntaxes/*.json dist/syntaxes
27+
rm dist/syntaxes/tsconfig.json
2328

2429
pushd dist
2530
yarn install --production --ignore-scripts

scripts/cleanup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ set -ex -o pipefail
55
# Clean up from last build
66
rm -rf client/out
77
rm -rf server/out
8+
rm -rf syntaxes/out

syntaxes/src/build.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import * as fs from 'fs';
10+
11+
import {GrammarDefinition, JsonObject} from './types';
12+
import {template} from './template/grammar';
13+
14+
// Recursively transforms a TypeScript grammar definition into an object which can be processed by
15+
// JSON.stringify to generate a valid TextMate JSON grammar definition
16+
function processGrammar(grammar: GrammarDefinition): JsonObject {
17+
const processedGrammar: JsonObject = {};
18+
for (const [key, value] of Object.entries(grammar)) {
19+
if (typeof value === 'string') {
20+
processedGrammar[key] = value;
21+
} else if (value instanceof RegExp) {
22+
// Escape backslashes/quote marks and trim the demarcating `/` characters from a regex literal
23+
processedGrammar[key] = value.toString().replace(/^\/|\/$/g, '');
24+
} else if (value instanceof Array) {
25+
processedGrammar[key] = value.map(processGrammar);
26+
} else {
27+
processedGrammar[key] = processGrammar(value);
28+
}
29+
}
30+
return processedGrammar;
31+
}
32+
33+
// Build a TextMate grammar JSON file from a source TypeScript object
34+
function build(grammar: GrammarDefinition, filename: string): void {
35+
const processedGrammar: JsonObject = processGrammar(grammar);
36+
const grammarContent: string = JSON.stringify(processedGrammar, null, ' ') + '\n';
37+
38+
fs.writeFile(`syntaxes/out/${filename}.json`, grammarContent, (error) => {
39+
if (error) throw error;
40+
});
41+
}
42+
43+
build(template, 'template');

syntaxes/src/template/grammar.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {GrammarDefinition} from '../types';
10+
11+
export const template: GrammarDefinition = {
12+
scopeName: 'template.ng',
13+
injectionSelector: 'L:text.html -comment',
14+
patterns: [
15+
{include: '#interpolation'},
16+
{include: '#propertyBinding'},
17+
{include: '#eventBinding'},
18+
{include: '#twoWayBinding'},
19+
{include: '#templateBinding'},
20+
],
21+
repository: {
22+
23+
interpolation: {
24+
begin: /{{/,
25+
beginCaptures: {
26+
0: {name: 'punctuation.definition.block.ts'},
27+
},
28+
end: /}}/,
29+
endCaptures: {
30+
0: {name: 'punctuation.definition.block.ts'},
31+
},
32+
contentName: 'source.js',
33+
patterns: [
34+
{include: 'source.js'},
35+
],
36+
},
37+
38+
propertyBinding: {
39+
begin: /(\[\s*@?[-_a-zA-Z0-9.$]*\s*])(=)(["'])/,
40+
beginCaptures: {
41+
1: {
42+
name: 'entity.other.attribute-name.html entity.other.ng-binding-name.property.html',
43+
patterns: [
44+
{include: '#bindingKey'},
45+
],
46+
},
47+
2: {name: 'punctuation.separator.key-value.html'},
48+
3: {name: 'string.quoted.html punctuation.definition.string.begin.html'},
49+
},
50+
end: /\3/,
51+
endCaptures: {
52+
0: {name: 'string.quoted.html punctuation.definition.string.end.html'},
53+
},
54+
name: 'meta.ng-binding.property.html',
55+
contentName: 'source.js',
56+
patterns: [
57+
{include: 'source.js'},
58+
],
59+
},
60+
61+
eventBinding: {
62+
begin: /(\(\s*@?[-_a-zA-Z0-9.$]*\s*\))(=)(["'])/,
63+
beginCaptures: {
64+
1: {
65+
name: 'entity.other.attribute-name.html entity.other.ng-binding-name.event.html',
66+
patterns: [
67+
{include: '#bindingKey'},
68+
],
69+
},
70+
2: {name: 'punctuation.separator.key-value.html'},
71+
3: {name: 'string.quoted.html punctuation.definition.string.begin.html'},
72+
},
73+
end: /\3/,
74+
endCaptures: {
75+
0: {name: 'string.quoted.html punctuation.definition.string.end.html'},
76+
},
77+
name: 'meta.ng-binding.event.html',
78+
contentName: 'source.js',
79+
patterns: [
80+
{include: 'source.js'},
81+
],
82+
},
83+
84+
twoWayBinding: {
85+
begin: /(\[\s*\(\s*@?[-_a-zA-Z0-9.$]*\s*\)\s*\])(=)(["'])/,
86+
beginCaptures: {
87+
1: {
88+
name: 'entity.other.attribute-name.html entity.other.ng-binding-name.two-way.html',
89+
patterns: [
90+
{include: '#bindingKey'},
91+
],
92+
},
93+
2: {name: 'punctuation.separator.key-value.html'},
94+
3: {name: 'string.quoted.html punctuation.definition.string.begin.html'},
95+
},
96+
end: /\3/,
97+
endCaptures: {
98+
0: {name: 'string.quoted.html punctuation.definition.string.end.html'},
99+
},
100+
name: 'meta.ng-binding.two-way.html',
101+
contentName: 'source.js',
102+
patterns: [
103+
{include: 'source.js'},
104+
],
105+
},
106+
107+
templateBinding: {
108+
begin: /(\*[-_a-zA-Z0-9.$]*)(=)(["'])/,
109+
beginCaptures: {
110+
1: {
111+
name: 'entity.other.attribute-name.html entity.other.ng-binding-name.template.html',
112+
patterns: [
113+
{include: '#bindingKey'},
114+
],
115+
},
116+
2: {name: 'punctuation.separator.key-value.html'},
117+
3: {name: 'string.quoted.html punctuation.definition.string.begin.html'},
118+
},
119+
end: /\3/,
120+
endCaptures: {
121+
0: {name: 'string.quoted.html punctuation.definition.string.end.html'},
122+
},
123+
name: 'meta.ng-binding.template.html',
124+
contentName: 'source.js',
125+
patterns: [
126+
{include: 'source.js'},
127+
],
128+
},
129+
130+
bindingKey: {
131+
patterns: [
132+
{
133+
match: /([\[\(]{1,2})(?:\s*)(@?[-_a-zA-Z0-9.$]*)(?:\s*)([\]\)]{1,2})/,
134+
captures: {
135+
1: {name: 'punctuation.definition.ng-binding-name.begin.html'},
136+
2: {
137+
patterns: [
138+
{
139+
match: /\./,
140+
name: 'punctuation.accessor.html',
141+
},
142+
],
143+
},
144+
3: {name: 'punctuation.definition.ng-binding-name.end.html'},
145+
},
146+
},
147+
],
148+
},
149+
},
150+
};

syntaxes/src/types.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
export interface GrammarDefinition {
10+
[key: string]: string|RegExp|GrammarDefinition|GrammarDefinition[];
11+
}
12+
13+
export interface JsonObject {
14+
[key: string]: string|JsonObject|JsonObject[];
15+
}

0 commit comments

Comments
 (0)