Jelajahi Sumber

Merge branch 'main' into samstrohkorbatt/python-fstring

samstrohkorbatt 1 tahun lalu
induk
melakukan
7d97bc2392

+ 13 - 0
CHANGELOG.md

@@ -1,5 +1,18 @@
 # Monaco Editor Changelog
 
+## [0.48.0]
+
+### Additions
+
+- Various bug fixes
+- Minimap Section Headers (see config option `showRegionSectionHeaders`)
+- Diff Editor Gutter Menu (see config option `renderGutterMenu`)
+- `InlineCompletionsProvider.handlePartialAccept` has `PartialAcceptInfo`
+
+Contributions to `monaco-editor`:
+
+- [@jeremy-rifkin (Jeremy Rifkin)](https://github.com/jeremy-rifkin): Fix bug with highlighting of C++ raw string literals [PR #4436](https://github.com/microsoft/monaco-editor/pull/4436)
+
 ## [0.47.0]
 
 ### Additions

+ 9 - 9
package-lock.json

@@ -1,12 +1,12 @@
 {
 	"name": "monaco-editor",
-	"version": "0.47.0",
+	"version": "0.48.0",
 	"lockfileVersion": 2,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "monaco-editor",
-			"version": "0.47.0",
+			"version": "0.48.0",
 			"hasInstallScript": true,
 			"license": "MIT",
 			"devDependencies": {
@@ -25,7 +25,7 @@
 				"jsdom": "^19.0.0",
 				"jsonc-parser": "^3.0.0",
 				"mocha": "^9.2.0",
-				"monaco-editor-core": "0.48.0-dev-20240320",
+				"monaco-editor-core": "0.48.0-rc",
 				"parcel": "^2.7.0",
 				"pin-github-action": "^1.8.0",
 				"playwright": "^1.32.2",
@@ -5388,9 +5388,9 @@
 			"dev": true
 		},
 		"node_modules/monaco-editor-core": {
-			"version": "0.48.0-dev-20240320",
-			"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.48.0-dev-20240320.tgz",
-			"integrity": "sha512-fXS0Bt39Qv9C10Cuuf0ZvgcK8LhN+fP+27sDfjILEQCUVRa4pDAtvZOny2BiiPqsmOINch8UVNSZtH7+Af3ngQ==",
+			"version": "0.48.0-rc",
+			"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.48.0-rc.tgz",
+			"integrity": "sha512-e/k+px1voI36YTd/tae6s6GBqFSWybH0coMDCaHwDwYND85mcNzNw3UB6HIrU7NY2qPtLSTdbS3RFat8QUyrgw==",
 			"dev": true
 		},
 		"node_modules/mri": {
@@ -11144,9 +11144,9 @@
 			}
 		},
 		"monaco-editor-core": {
-			"version": "0.48.0-dev-20240320",
-			"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.48.0-dev-20240320.tgz",
-			"integrity": "sha512-fXS0Bt39Qv9C10Cuuf0ZvgcK8LhN+fP+27sDfjILEQCUVRa4pDAtvZOny2BiiPqsmOINch8UVNSZtH7+Af3ngQ==",
+			"version": "0.48.0-rc",
+			"resolved": "https://registry.npmjs.org/monaco-editor-core/-/monaco-editor-core-0.48.0-rc.tgz",
+			"integrity": "sha512-e/k+px1voI36YTd/tae6s6GBqFSWybH0coMDCaHwDwYND85mcNzNw3UB6HIrU7NY2qPtLSTdbS3RFat8QUyrgw==",
 			"dev": true
 		},
 		"mri": {

+ 3 - 3
package.json

@@ -1,7 +1,7 @@
 {
 	"name": "monaco-editor",
-	"version": "0.47.0",
-	"vscodeRef": "1e790d77f81672c49be070e04474901747115651",
+	"version": "0.48.0",
+	"vscodeRef": "e170252f762678dec6ca2cc69aba1570769a5d39",
 	"private": true,
 	"description": "A browser based code editor",
 	"homepage": "https://github.com/microsoft/monaco-editor",
@@ -52,7 +52,7 @@
 		"jsdom": "^19.0.0",
 		"jsonc-parser": "^3.0.0",
 		"mocha": "^9.2.0",
-		"monaco-editor-core": "0.48.0-dev-20240320",
+		"monaco-editor-core": "0.48.0-rc",
 		"parcel": "^2.7.0",
 		"pin-github-action": "^1.8.0",
 		"playwright": "^1.32.2",

+ 1 - 0
src/basic-languages/monaco.contribution.ts

@@ -79,6 +79,7 @@ import './systemverilog/systemverilog.contribution';
 import './tcl/tcl.contribution';
 import './twig/twig.contribution';
 import './typescript/typescript.contribution';
+import './typespec/typespec.contribution';
 import './vb/vb.contribution';
 import './wgsl/wgsl.contribution';
 import './xml/xml.contribution';

+ 24 - 0
src/basic-languages/typespec/typespec.contribution.ts

@@ -0,0 +1,24 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { registerLanguage } from '../_.contribution';
+
+declare var AMD: any;
+declare var require: any;
+
+registerLanguage({
+	id: 'typespec',
+	extensions: ['.tsp'],
+	aliases: ['TypeSpec'],
+	loader: () => {
+		if (AMD) {
+			return new Promise((resolve, reject) => {
+				require(['vs/basic-languages/typespec/typespec'], resolve, reject);
+			});
+		} else {
+			return import('./typespec');
+		}
+	}
+});

+ 500 - 0
src/basic-languages/typespec/typespec.test.ts

@@ -0,0 +1,500 @@
+/*---------------------------------------------------------------------------------------------
+ *  Copyright (c) Microsoft Corporation. All rights reserved.
+ *  Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { testTokenization } from '../test/testRunner';
+
+// Those test were auto generated from the test in the https://github.com/microsoft/typespec repo
+// to keep in sync you can follow the instruction in https://github.com/microsoft/typespec/blob/main/packages/monarch/README.md
+
+testTokenization('typespec', [
+	[
+		{
+			line: 'import "@typespec/http";',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 6,
+					type: ''
+				},
+				{
+					startIndex: 7,
+					type: 'string.tsp'
+				},
+				{
+					startIndex: 23,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'using TypeSpec.Http',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 14,
+					type: ''
+				},
+				{
+					startIndex: 15,
+					type: 'identifier.tsp'
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'namespace Foo {}',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 13,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'namespace Foo {',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 13,
+					type: ''
+				}
+			]
+		},
+		{
+			line: '    model Bar {}',
+			tokens: [
+				{
+					startIndex: 0,
+					type: ''
+				},
+				{
+					startIndex: 4,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 13,
+					type: ''
+				}
+			]
+		},
+		{
+			line: '  }',
+			tokens: [
+				{
+					startIndex: 0,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'model Foo {}',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'model Foo is Bar;',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 12,
+					type: ''
+				},
+				{
+					startIndex: 13,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 16,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'model Foo extends Bar;',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 17,
+					type: ''
+				},
+				{
+					startIndex: 18,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 21,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'interface Foo {}',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 10,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 13,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'union Foo {}',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'scalar foo extends string;',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 6,
+					type: ''
+				},
+				{
+					startIndex: 7,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 10,
+					type: ''
+				},
+				{
+					startIndex: 11,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 18,
+					type: ''
+				},
+				{
+					startIndex: 19,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 25,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'op test(): void;',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 2,
+					type: ''
+				},
+				{
+					startIndex: 3,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 7,
+					type: ''
+				},
+				{
+					startIndex: 11,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 15,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'enum Direction { up, down }',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 4,
+					type: ''
+				},
+				{
+					startIndex: 5,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 14,
+					type: ''
+				},
+				{
+					startIndex: 17,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 19,
+					type: ''
+				},
+				{
+					startIndex: 21,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 25,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'alias Foo = "a" | "b";',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 9,
+					type: ''
+				},
+				{
+					startIndex: 12,
+					type: 'string.tsp'
+				},
+				{
+					startIndex: 15,
+					type: ''
+				},
+				{
+					startIndex: 18,
+					type: 'string.tsp'
+				},
+				{
+					startIndex: 21,
+					type: ''
+				}
+			]
+		}
+	],
+	[
+		{
+			line: 'alias T =  """',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'keyword.tsp'
+				},
+				{
+					startIndex: 5,
+					type: ''
+				},
+				{
+					startIndex: 6,
+					type: 'identifier.tsp'
+				},
+				{
+					startIndex: 7,
+					type: ''
+				},
+				{
+					startIndex: 11,
+					type: 'string.tsp'
+				}
+			]
+		},
+		{
+			line: '  this',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'string.tsp'
+				}
+			]
+		},
+		{
+			line: '  is',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'string.tsp'
+				}
+			]
+		},
+		{
+			line: '  multiline',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'string.tsp'
+				}
+			]
+		},
+		{
+			line: '  """',
+			tokens: [
+				{
+					startIndex: 0,
+					type: 'string.tsp'
+				}
+			]
+		}
+	]
+]);

+ 130 - 0
src/basic-languages/typespec/typespec.ts

@@ -0,0 +1,130 @@
+import type { languages } from '../../fillers/monaco-editor-core';
+
+const bounded = (text: string) => `\\b${text}\\b`;
+const notBefore = (regex: string) => `(?!${regex})`;
+
+const identifierStart = '[_a-zA-Z]';
+const identifierContinue = '[_a-zA-Z0-9]';
+const identifier = bounded(`${identifierStart}${identifierContinue}*`);
+const directive = bounded(`[_a-zA-Z-0-9]+`);
+
+const keywords = [
+	'import',
+	'model',
+	'scalar',
+	'namespace',
+	'op',
+	'interface',
+	'union',
+	'using',
+	'is',
+	'extends',
+	'enum',
+	'alias',
+	'return',
+	'void',
+	'if',
+	'else',
+	'projection',
+	'dec',
+	'extern',
+	'fn'
+];
+const namedLiterals = ['true', 'false', 'null', 'unknown', 'never'];
+const nonCommentWs = `[ \\t\\r\\n]`;
+const numericLiteral = `[0-9]+`;
+
+export const conf: languages.LanguageConfiguration = {
+	comments: {
+		lineComment: '//',
+		blockComment: ['/*', '*/']
+	},
+	brackets: [
+		['{', '}'],
+		['[', ']'],
+		['(', ')']
+	],
+	autoClosingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' },
+		{ open: '/**', close: ' */', notIn: ['string'] }
+	],
+	surroundingPairs: [
+		{ open: '{', close: '}' },
+		{ open: '[', close: ']' },
+		{ open: '(', close: ')' },
+		{ open: '"', close: '"' }
+	],
+	indentationRules: {
+		decreaseIndentPattern: new RegExp('^((?!.*?/\\*).*\\*/)?\\s*[\\}\\]].*$'),
+		increaseIndentPattern: new RegExp(
+			'^((?!//).)*(\\{([^}"\'`/]*|(\\t|[ ])*//.*)|\\([^)"\'`/]*|\\[[^\\]"\'`/]*)$'
+		),
+		// e.g.  * ...| or */| or *-----*/|
+		unIndentedLinePattern: new RegExp(
+			'^(\\t|[ ])*[ ]\\*[^/]*\\*/\\s*$|^(\\t|[ ])*[ ]\\*/\\s*$|^(\\t|[ ])*[ ]\\*([ ]([^\\*]|\\*(?!/))*)?$'
+		)
+	}
+};
+
+export const language: languages.IMonarchLanguage = {
+	defaultToken: '',
+	tokenPostfix: '.tsp',
+	brackets: [
+		{ open: '{', close: '}', token: 'delimiter.curly' },
+		{ open: '[', close: ']', token: 'delimiter.square' },
+		{ open: '(', close: ')', token: 'delimiter.parenthesis' }
+	],
+	symbols: /[=:;<>]+/,
+	keywords,
+	namedLiterals,
+	escapes: `\\\\(u{[0-9A-Fa-f]+}|n|r|t|\\\\|"|\\\${)`,
+	tokenizer: {
+		root: [{ include: '@expression' }, { include: '@whitespace' }],
+		stringVerbatim: [
+			{ regex: `(|"|"")[^"]`, action: { token: 'string' } },
+			{ regex: `"""${notBefore(`"`)}`, action: { token: 'string', next: '@pop' } }
+		],
+		stringLiteral: [
+			{ regex: `\\\${`, action: { token: 'delimiter.bracket', next: '@bracketCounting' } },
+			{ regex: `[^\\\\"$]+`, action: { token: 'string' } },
+			{ regex: '@escapes', action: { token: 'string.escape' } },
+			{ regex: `\\\\.`, action: { token: 'string.escape.invalid' } },
+			{ regex: `"`, action: { token: 'string', next: '@pop' } }
+		],
+		bracketCounting: [
+			{ regex: `{`, action: { token: 'delimiter.bracket', next: '@bracketCounting' } },
+			{ regex: `}`, action: { token: 'delimiter.bracket', next: '@pop' } },
+			{ include: '@expression' }
+		],
+		comment: [
+			{ regex: `[^\\*]+`, action: { token: 'comment' } },
+			{ regex: `\\*\\/`, action: { token: 'comment', next: '@pop' } },
+			{ regex: `[\\/*]`, action: { token: 'comment' } }
+		],
+		whitespace: [
+			{ regex: nonCommentWs },
+			{ regex: `\\/\\*`, action: { token: 'comment', next: '@comment' } },
+			{ regex: `\\/\\/.*$`, action: { token: 'comment' } }
+		],
+		expression: [
+			{ regex: `"""`, action: { token: 'string', next: '@stringVerbatim' } },
+			{ regex: `"${notBefore(`""`)}`, action: { token: 'string', next: '@stringLiteral' } },
+			{ regex: numericLiteral, action: { token: 'number' } },
+			{
+				regex: identifier,
+				action: {
+					cases: {
+						'@keywords': { token: 'keyword' },
+						'@namedLiterals': { token: 'keyword' },
+						'@default': { token: 'identifier' }
+					}
+				}
+			},
+			{ regex: `@${identifier}`, action: { token: 'tag' } },
+			{ regex: `#${directive}`, action: { token: 'directive' } }
+		]
+	}
+};

+ 71 - 0
website/src/website/data/home-samples/sample.typespec.txt

@@ -0,0 +1,71 @@
+import "@typespec/rest";
+import "@typespec/openapi";
+import "./decorators.js";
+
+using TypeSpec.Http;
+
+@service({
+  title: "Pet Store Service",
+})
+/** This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the api key `special-key` to test the authorization filters. */
+namespace PetStore;
+
+// Model types
+model Pet {
+  name: string;
+  tag?: string;
+
+  @minValue(0)
+  @maxValue(20)
+  age: int32;
+}
+
+model Toy {
+  id: int64;
+  petId: int64;
+  name: string;
+}
+
+/** Error */
+@error
+model Error {
+  code: int32;
+  message: string;
+}
+
+/** Not modified */
+model NotModified<Body> {
+  @statusCode _: 304;
+  @body body: Body;
+}
+
+@friendlyName("{name}ListResults", Item)
+model ResponsePage<Item> {
+  items: Item[];
+  nextLink?: string;
+}
+
+model PetId {
+  @path petId: int32;
+}
+
+/** Manage your pets. */
+@route("/pets")
+namespace Pets {
+  /** Delete a pet. */
+  @delete
+  op delete(...PetId): OkResponse | Error;
+
+  @fancyDoc("List pets.")
+  op list(@query nextLink?: string): ResponsePage<Pet> | Error;
+
+  /** Returns a pet. Supports eTags. */
+  op read(...PetId): Pet | (NotModifiedResponse & Pet) | Error;
+
+  @post op create(@body pet: Pet): Pet | Error;
+}
+
+@route("/pets/{petId}/toys")
+namespace ListPetToysResponse {
+  op list(@path petId: string, @query nameFilter: string): ResponsePage<Toy> | Error;
+}