From fa8c650ef4c3cd24819129e78821a981c4e22794 Mon Sep 17 00:00:00 2001 From: David Wilson Date: Sun, 8 Nov 2015 11:02:38 -0800 Subject: [PATCH] Update codebase to comply with VSC 0.10.0 APIs This change updates the current codebase to comply with the current state of the VS Code 0.10.0 APIs. It also includes some improvements to the package.json manifest to make things display well on the Visual Studio Gallery. --- .gitignore | 3 +- .vscodeignore | 5 +- README.md | 53 +- docs/development.md | 30 + images/PowerShell_icon.png | Bin 0 -> 10518 bytes package.json | 59 +- src/features/bufferSyncSupport.ts | 28 +- src/features/commentsSupport.ts | 19 - src/features/configuration.ts | 10 +- src/features/declarationSupport.ts | 60 +- src/features/navigateTypesSupport.ts | 39 +- src/features/occurrencesSupport.ts | 23 +- src/features/parameterHintsSupport.ts | 39 +- src/features/referenceSupport.ts | 24 +- src/features/suggestSupport.ts | 184 ++-- src/powershellDef.ts | 120 --- src/powershellMain.ts | 122 ++- src/powershellServiceClient.ts | 129 +-- typings/vscode-typings.d.ts | 5 +- typings/vscode.d.ts | 1309 ------------------------- 20 files changed, 417 insertions(+), 1844 deletions(-) create mode 100644 docs/development.md create mode 100644 images/PowerShell_icon.png delete mode 100644 src/features/commentsSupport.ts delete mode 100644 src/powershellDef.ts delete mode 100644 typings/vscode.d.ts diff --git a/.gitignore b/.gitignore index 04a5b2ee9a..c006f31f5e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bin/ out/ node_modules/ vscode-powershell.zip -vscps-preview.zip \ No newline at end of file +vscps-preview.zip +*.vsix \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index 57ebba3e2a..d9c90f4234 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,9 +1,10 @@ .vscode/** typings/** -node_modules/vscode/** -node_modules/vscode-languageworker/** +node_modules/** **/*.ts .gitignore tsconfig.json +build/** bin/EditorServices.log +bin/DebugService.log bin/*.vshost.* \ No newline at end of file diff --git a/README.md b/README.md index e3f90430a8..478c840c7e 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,36 @@ # Windows PowerShell for Visual Studio Code -Windows PowerShell language support for Visual Studio Code. +This extension provides Windows PowerShell language support for Visual Studio Code. More details forthcoming. -## Building the code +## Features -First, install the package dependencies: +- IntelliSense for cmdlets and more +- Rule-based analysis provided by [Windows PowerShell Script Analyzer](http://github.com/PowerShell/PSScriptAnalyzer) +- Go to Definition for cmdlets and variables +- Find References of cmdlets and variables +- Local script debugging! -``` -npm install -``` - -The next two steps are required if you have Node.js 5 installed due to some change in npm: - -``` -cd node_modules\vscode -npm install -``` - -Now you can compile the code: - -``` -npm run compile -``` - -After the initial compile, the source files will be watched and recompiled -when changes are saved. +## Example Scripts -## Running the compiled code +There are some example scripts in the extension's `examples` folder that you can +use to discover PowerShell editing and debugging functionality. Please +check out the included [README.md](examples/README.md) file to learn more about +how to use them. -From a PowerShell or cmd.exe prompt, run the following command: +This folder can be found at the following path: ``` -code --extensionDevelopmentPath="c:\path\to\vscode-powershell" . +c:\Users\\.vscode\extensions\daviwil.PowerShell\examples ``` - -If you allow the compiler to continue watching for file changes, you can use -the `Reload Window` command found in the command palette `(Ctrl+Shift+P)` -so that the new source files are loaded. -## Example Scripts +## Contributing to the Code -There are some example scripts in the `examples` folder that you can -use to discover PowerShell editing and debugging functionality. Please -check out the [README.md](examples/README.md) file to learn more about -how to use them. +Check out the [development documentation](docs/development.md) for more details +on how to contribute to this extension! ## License -This project is [licensed under the MIT License](LICENSE). Please see the +This extension is [licensed under the MIT License](LICENSE). Please see the [third-party notices](Third Party Notices.txt) file for details on the third-party binaries that we include with releases of this project. diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 0000000000..15be7089ca --- /dev/null +++ b/docs/development.md @@ -0,0 +1,30 @@ +# Working with the PowerShell extension code + +## Building the code + +First, install the package dependencies: + +``` +npm install +``` + +Now you can compile the code: + +``` +npm run compile +``` + +After the initial compile, the source files will be watched and recompiled +when changes are saved. + +## Running the compiled code + +From a PowerShell or cmd.exe prompt, run the following command: + +``` +code --extensionDevelopmentPath="c:\path\to\vscode-powershell" . +``` + +If you allow the compiler to continue watching for file changes, you can use +the `Reload Window` command found in the command palette `(Ctrl+Shift+P)` +so that the new source files are loaded. diff --git a/images/PowerShell_icon.png b/images/PowerShell_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b20df69b8c537099b394491bd5ee2dfd46e8a91f GIT binary patch literal 10518 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 Y0BG*hNy~MV9smFU07*qoM6N<$f+(' - }; - -} - -export = CommentsSupport; \ No newline at end of file diff --git a/src/features/configuration.ts b/src/features/configuration.ts index 8b03e797af..24b3e0ff81 100644 --- a/src/features/configuration.ts +++ b/src/features/configuration.ts @@ -17,7 +17,11 @@ export var defaultConfiguration: IConfiguration = { enableLogging: false } -export function load(myPluginId: string): Thenable { - let configuration = vscode.extensions.getConfigurationMemento(myPluginId); - return configuration.getValues(defaultConfiguration); +export function load(myPluginId: string): IConfiguration { + let configuration = vscode.workspace.getConfiguration(myPluginId); + return { + editorServicesHostPath: configuration.get("editorServicesHostPath", "../bin/Microsoft.PowerShell.EditorServices.Host.exe"), + waitForDebugger: configuration.get("waitForDebugger", false), + enableLogging: configuration.get("enableLogging", false) + } } diff --git a/src/features/declarationSupport.ts b/src/features/declarationSupport.ts index 226147d33c..b9da6948fb 100644 --- a/src/features/declarationSupport.ts +++ b/src/features/declarationSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class DeclarationSupport implements vscode.Modes.IDeclarationSupport { +class DeclarationSupport implements vscode.DefinitionProvider { private client: PowershellService.IPowershellServiceClient; @@ -18,47 +18,41 @@ class DeclarationSupport implements vscode.Modes.IDeclarationSupport { this.client = client; } - public findDeclaration(document: vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideDefinition(document: vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { var args:Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve(null); + return Promise.resolve(null); } return this.client.execute('definition', args).then((response) => { var locations:Proto.FileSpan[] = response.body; if (!locations || locations.length === 0) { + vscode.window.showWarningMessage("The selected symbol's definition could not be found."); return null; } - var location = locations[0]; - var resource = this.client.asUrl(location.file); - // if (resource === null) { - // return null; - // } - // - // return locations.map(location => { - // var resource = this.client.asUrl(location.file); - // if (resource === null) { - // return null; - // } else { - // return { - // resource: resource, - // range: new vscode.Range(location.start.line, location.start.offset, location.end.line, location.end.offset) - // } - // } - // }); - if (resource === null) { - return null; - } else { - return { - resource: resource, - range: new vscode.Range(location.start.line, location.start.offset, location.end.line, location.end.offset) - }; - } + + return locations.map(location => { + var resource = this.client.asUrl(location.file); + if (resource === null) { + return null; + } else { + // TODO: Strangely, this doesn't work if I return the Location directly, + // only works if I assign to a variable first. Not sure what is going on yet. + var loc = + new vscode.Location( + resource, + new vscode.Range( + location.start.line - 1, + location.start.offset - 1, + location.end.line - 1, + location.end.offset - 1 + )); + return loc; + } + }); }, () => { return null; }); diff --git a/src/features/navigateTypesSupport.ts b/src/features/navigateTypesSupport.ts index c21b3ce71a..80e43fec06 100644 --- a/src/features/navigateTypesSupport.ts +++ b/src/features/navigateTypesSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { +class NavigateTypeSupport implements vscode.WorkspaceSymbolProvider { private client: PowershellService.IPowershellServiceClient; private modeId: string @@ -18,20 +18,20 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { this.modeId = modeId; } - public getNavigateToItems(search:string, token:vscode.CancellationToken): Promise { + public provideWorkspaceSymbols(search:string, token:vscode.CancellationToken): Promise { // Get all PowerShell files in the workspace let uri: vscode.Uri; - let documents = vscode.workspace.getTextDocuments(); + let documents = vscode.workspace.textDocuments; for (let document of documents) { - if (document.getLanguageId() === this.modeId) { - uri = document.getUri(); + if (document.languageId === this.modeId) { + uri = document.uri; break; } } if (!uri) { - return Promise.resolve([]); + return Promise.resolve([]); } var args:Proto.NavtoRequestArgs = { @@ -39,20 +39,19 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { searchValue: search }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } - return this.client.execute('navto', args, token).then((response):vscode.Modes.ITypeBearing[] => { + return this.client.execute('navto', args, token).then((response):vscode.SymbolInformation[] => { var data = response.body; if (data) { return data.map((item) => { - return { - containerName: item.containerName, - name: item.name, - parameters: (item.kind === 'method' || item.kind === 'function') ? '()' : '', - type: item.kind, - range: new vscode.Range(item.start.line, item.start.offset, item.end.line, item.end.offset), - resourceUri: this.client.asUrl(item.file) - }; + let range = new vscode.Range(item.start.line - 1, item.start.offset - 1, item.end.line - 1, item.end.offset - 1); + let label = item.name; + if (item.kind === 'method' || item.kind === 'function') { + label += '()'; + } + return new vscode.SymbolInformation(label, _kindMapping[item.kind], range, + this.client.asUrl(item.file), item.containerName); }); } else { return []; @@ -64,4 +63,12 @@ class NavigateTypeSupport implements vscode.Modes.INavigateTypesSupport { } } +var _kindMapping: { [kind: string]: vscode.SymbolKind } = Object.create(null); +_kindMapping['method'] = vscode.SymbolKind.Method; +_kindMapping['enum'] = vscode.SymbolKind.Enum; +_kindMapping['function'] = vscode.SymbolKind.Function; +_kindMapping['class'] = vscode.SymbolKind.Class; +_kindMapping['interface'] = vscode.SymbolKind.Interface; +_kindMapping['var'] = vscode.SymbolKind.Variable; + export = NavigateTypeSupport; \ No newline at end of file diff --git a/src/features/occurrencesSupport.ts b/src/features/occurrencesSupport.ts index 7f4d7acc2b..a881b4d293 100644 --- a/src/features/occurrencesSupport.ts +++ b/src/features/occurrencesSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class OccurrencesSupport implements vscode.Modes.IOccurrencesSupport { +class OccurrencesSupport implements vscode.DocumentHighlightProvider { private client: PowershellService.IPowershellServiceClient; @@ -16,25 +16,22 @@ class OccurrencesSupport implements vscode.Modes.IOccurrencesSupport { this.client = client; } - public findOccurrences(resource:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideDocumentHighlights(resource:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { var args:Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(resource.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(resource.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } - return this.client.execute('occurrences', args, token).then((response):vscode.Modes.IOccurrence[] => { + return this.client.execute('occurrences', args, token).then((response):vscode.DocumentHighlight[] => { var data = response.body; if (data) { return data.map((item) => { - return { - kind: item.isWriteAccess ? 'write' : null, - range: new vscode.Range(item.start.line, item.start.offset, item.end.line, item.end.offset) - }; + return new vscode.DocumentHighlight( + new vscode.Range(item.start.line - 1, item.start.offset - 1, item.end.line - 1, item.end.offset - 1), + item.isWriteAccess ? vscode.DocumentHighlightKind.Write : vscode.DocumentHighlightKind.Read); }); } }, (err) => { diff --git a/src/features/parameterHintsSupport.ts b/src/features/parameterHintsSupport.ts index 9d3de384a5..37cdc227d8 100644 --- a/src/features/parameterHintsSupport.ts +++ b/src/features/parameterHintsSupport.ts @@ -9,7 +9,7 @@ import Proto = require('../protocol'); import PowershellService = require('../powershellService'); import Previewer = require('./previewer'); -class ParameterHintsSupport implements vscode.Modes.IParameterHintsSupport { +class ParameterHintsSupport implements vscode.SignatureHelpProvider { public triggerCharacters:string[] = ['(', ',','"','-']; public excludeTokens:string[] = ['string']; @@ -20,41 +20,32 @@ class ParameterHintsSupport implements vscode.Modes.IParameterHintsSupport { this.client = client; } - public getParameterHints(document:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken): Promise { + public provideSignatureHelp(document:vscode.TextDocument, position:vscode.Position, token: vscode.CancellationToken):Promise { var args:Proto.SignatureHelpRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve(null); + return Promise.resolve(null); } return this.client.execute('signatureHelp', args).then((response) => { var info = response.body; if (!info) { return null; } - var result = { - currentSignature: 0, - currentParameter: 0, - signatures: [] - }; + + var result = new vscode.SignatureHelp(); + result.activeSignature = info.selectedItemIndex; + result.activeParameter = info.argumentIndex; + info.items.forEach(item => { - var signature = { - label: info.commandName += ' ', - documentation: null, - parameters: [] - }; + var signature = new vscode.SignatureInformation(''); + signature.label += info.commandName + ' '; var paramlabel = item.signatureText; - var parameter = { - label: paramlabel, - documentation: null, - signatureLabelOffset: signature.label.length, - signatureLabelEnd: signature.label.length + paramlabel.length - }; + var parameter = new vscode.ParameterInformation(item.signatureText, ''); + signature.label += paramlabel; signature.parameters.push(parameter); diff --git a/src/features/referenceSupport.ts b/src/features/referenceSupport.ts index ba25d4bbef..09de1b2071 100644 --- a/src/features/referenceSupport.ts +++ b/src/features/referenceSupport.ts @@ -8,7 +8,7 @@ import vscode = require('vscode'); import Proto = require('../protocol'); import PowershellService = require('../powershellService'); -class ReferenceSupport implements vscode.Modes.IReferenceSupport { +class ReferenceSupport implements vscode.ReferenceProvider { private client: PowershellService.IPowershellServiceClient; @@ -18,27 +18,25 @@ class ReferenceSupport implements vscode.Modes.IReferenceSupport { this.client = client; } - public findReferences(document: vscode.TextDocument, position: vscode.Position, includeDeclaration:boolean, token: vscode.CancellationToken): Promise { + public provideReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Promise { var args: Proto.FileLocationRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + file: this.client.asAbsolutePath(document.uri), + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } return this.client.execute('references', args, token).then((msg) => { - var result: vscode.Modes.IReference[] = []; + var result: vscode.Location[] = []; var refs = msg.body.refs; for (var i = 0; i < refs.length; i++) { var ref = refs[i]; var url = this.client.asUrl(ref.file); - result.push({ - resource: url, - range: new vscode.Range(ref.start.line, ref.start.offset, ref.end.line, ref.end.offset) - }); + result.push( + new vscode.Location( + url, + new vscode.Range(ref.start.line - 1, ref.start.offset - 1, ref.end.line - 1, ref.end.offset - 1))); } return result; }, () => { diff --git a/src/features/suggestSupport.ts b/src/features/suggestSupport.ts index 4fdd747831..39f9b05a1f 100644 --- a/src/features/suggestSupport.ts +++ b/src/features/suggestSupport.ts @@ -9,38 +9,72 @@ import vscode = require('vscode'); import Previewer = require('./previewer'); import Proto = require('../protocol'); import PConst = require('../protocol.const'); -import Configuration = require('./configuration'); import PowershellService = require('../powershellService'); -class SuggestSupport implements vscode.Modes.ISuggestSupport { +class PowerShellCompletionItem extends vscode.CompletionItem { + + document: vscode.TextDocument; + position: vscode.Position; + + constructor(entry: Proto.CompletionEntry) { + super(entry.name); + this.sortText = entry.sortText; + this.kind = PowerShellCompletionItem.convertKind(entry.kind); + } + + private static convertKind(kind: string): vscode.CompletionItemKind { + switch (kind) { + case PConst.Kind.primitiveType: + case PConst.Kind.keyword: + return vscode.CompletionItemKind.Keyword; + case PConst.Kind.variable: + case PConst.Kind.localVariable: + return vscode.CompletionItemKind.Variable; + case PConst.Kind.memberVariable: + case PConst.Kind.memberGetAccessor: + case PConst.Kind.memberSetAccessor: + return vscode.CompletionItemKind.Field; + case PConst.Kind.function: + case PConst.Kind.memberFunction: + case PConst.Kind.constructSignature: + case PConst.Kind.callSignature: + case PConst.Kind.indexSignature: + return vscode.CompletionItemKind.Function; + case PConst.Kind.enum: + return vscode.CompletionItemKind.Enum; + case PConst.Kind.module: + return vscode.CompletionItemKind.Module; + case PConst.Kind.class: + return vscode.CompletionItemKind.Class; + case PConst.Kind.interface: + return vscode.CompletionItemKind.Interface; + } + + return vscode.CompletionItemKind.Property; + } +} + +class SuggestSupport implements vscode.CompletionItemProvider { public triggerCharacters = ['.','$','-']; public excludeTokens = ['string', 'comment', 'numeric']; public sortBy = [{ type: 'reference', partSeparator: '/' }]; private client: PowershellService.IPowershellServiceClient; - private config:Configuration.IConfiguration; constructor(client: PowershellService.IPowershellServiceClient) { this.client = client; - this.config = Configuration.defaultConfiguration; - } - - public setConfiguration(config: Configuration.IConfiguration): void { - this.config = config; } - public suggest(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { - var filepath = this.client.asAbsolutePath(document.getUri()); + public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { + var filepath = this.client.asAbsolutePath(document.uri); var args: Proto.CompletionsRequestArgs = { file: filepath, - //line: position.line + 1, - //offset: position.character + 1 - line: position.line, - offset: position.character + line: position.line + 1, + offset: position.character + 1 }; if (!args.file) { - return Promise.resolve([]); + return Promise.resolve([]); } // Need to capture the word at position before we send the request. @@ -62,100 +96,68 @@ class SuggestSupport implements vscode.Modes.ISuggestSupport { // }); // isMemberCompletion = value === '.'; // } - - var suggests:vscode.Modes.ISuggestion[] = []; + + var completionItems: vscode.CompletionItem[] = []; var body = msg.body; - // sort by CompletionEntry#sortText - // TODO: Uncomment this? - //msg.body.sort(SuggestSupport.bySortText); - for (var i = 0; i < body.length; i++) { var element = body[i]; - suggests.push({ - label: element.name, - codeSnippet: element.name, - type: this.monacoTypeFromEntryKind(element.kind) - }); + var item = new PowerShellCompletionItem(element); + item.document = document; + item.position = position; + + completionItems.push(item); } - var currentWord = ''; - if (wordRange) { - currentWord = document.getTextInRange(new vscode.Range(wordRange.start, position)); - } - return [{ - currentWord: currentWord, - suggestions: suggests - }]; + + return completionItems; + }, (err:Proto.CompletionsResponse) => { return []; }); } + + public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): any | Thenable { + if (item instanceof PowerShellCompletionItem) { + + var args: Proto.CompletionDetailsRequestArgs = { + file: this.client.asAbsolutePath(item.document.uri), + line: item.position.line + 1, + offset: item.position.character + 1, + entryNames: [item.label] + }; + return this.client.execute('completionEntryDetails', args, token).then((response) => { + var details = response.body; + if (details && details.length > 0) { + var detail = details[0]; + item.documentation = Previewer.plain(detail.documentation); + item.detail = Previewer.plain(detail.displayParts); + } - public getSuggestionDetails(document:vscode.TextDocument, position:vscode.Position, suggestion:vscode.Modes.ISuggestion, token: vscode.CancellationToken): Promise { - if(suggestion.type === 'snippet') { - return Promise.resolve(suggestion); - } - - var args: Proto.CompletionDetailsRequestArgs = { - file: this.client.asAbsolutePath(document.getUri()), - //line: position.line + 1, - //offset: position.character + 1, - line: position.line, - offset: position.character, - entryNames: [ - suggestion.label - ] - }; - return this.client.execute('completionEntryDetails', args).then((response) => { - var details = response.body; - if (details && details.length > 0) { - var detail = details[0]; - suggestion.documentationLabel = Previewer.plain(detail.documentation); - suggestion.typeLabel = Previewer.plain(detail.displayParts); - } + if (item.kind === vscode.CompletionItemKind.Function) { + var codeSnippet = detail.name, + suggestionArgumentNames: string[]; - if (this.monacoTypeFromEntryKind(detail.kind) === 'function') { - var codeSnippet = detail.name, - suggestionArgumentNames: string[]; + // suggestionArgumentNames = detail.displayParts + // .filter(part => part.kind === 'parameterName') + // .map(part => `{{${part.text}}}`); - suggestionArgumentNames = detail.displayParts - .filter(part => part.kind === 'parameterName') - .map(part => `{{${part.text}}}`); + if (suggestionArgumentNames.length > 0) { + codeSnippet += '(' + suggestionArgumentNames.join(', ') + '){{}}'; + } else { + codeSnippet += '()'; + } - if (suggestionArgumentNames.length > 0) { - codeSnippet += '(' + suggestionArgumentNames.join(', ') + '){{}}'; - } else { - codeSnippet += '()'; + item.insertText = codeSnippet; } - suggestion.codeSnippet = codeSnippet; - } - return suggestion; - }, (err:Proto.CompletionDetailsResponse) => { - return suggestion; - }); - } - private monacoTypeFromEntryKind(kind:string):string { - switch(kind) { - case PConst.Kind.primitiveType: - case PConst.Kind.keyword: - return 'keyword'; + return item; - case PConst.Kind.variable: - case PConst.Kind.localVariable: - case PConst.Kind.memberVariable: - case PConst.Kind.memberGetAccessor: - case PConst.Kind.memberSetAccessor: - return 'field'; + }, (err:Proto.CompletionDetailsResponse) => { + return item; + }); - case PConst.Kind.function: - case PConst.Kind.memberFunction: - case PConst.Kind.constructSignature: - case PConst.Kind.callSignature: - return 'function'; } - return kind; - } + } private static bySortText(a: Proto.CompletionEntry, b: Proto.CompletionEntry): number { return a.sortText.localeCompare(b.sortText); diff --git a/src/powershellDef.ts b/src/powershellDef.ts deleted file mode 100644 index 8e0498bcc2..0000000000 --- a/src/powershellDef.ts +++ /dev/null @@ -1,120 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - -'use strict'; - -import vscode = require('vscode'); - -export var language = { - displayName: 'PowerShell', - name: 'ps1', - defaultToken: '', - ignoreCase: true, - - lineComment: '#', - blockCommentStart: '<#', - blockCommentEnd: '#>', - - // the default separators except `$-` - wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, - - brackets: [ - { token: 'delimiter.curly', open: '{', close: '}' }, - { token: 'delimiter.square', open: '[', close: ']' }, - { token: 'delimiter.parenthesis', open: '(', close: ')' }], - - enhancedBrackets: [ - { tokenType:'string', openTrigger: '"', open: /@"$/, closeComplete: '"@' }, - { tokenType:'string', openTrigger: '\'', open: /@'$/, closeComplete: '\'@' }, - { tokenType:'string', openTrigger: '"', open: /"$/, closeComplete: '"' }, - { tokenType: 'string', openTrigger: '\'', open: /'$/, closeComplete: '\'' } - ], - - autoClosingPairs: [['{', '}'], ['[', ']'], ['(', ')']], // Defined explicitly, to suppress the - // default auto-closing of ' and " which is - // override above by enhancedBrackets - - keywords: [ - 'begin', 'break', 'catch', 'class', 'continue', 'data', - 'define', 'do', 'dynamicparam', 'else', 'elseif', 'end', - 'exit', 'filter', 'finally', 'for', 'foreach', 'from', - 'function', 'if', 'in', 'param', 'process', 'return', - 'switch', 'throw', 'trap', 'try', 'until', 'using', - 'var', 'while', 'workflow', 'parallel', 'sequence', 'inlinescript', 'configuration' - ], - - helpKeywords: /SYNOPSIS|DESCRIPTION|PARAMETER|EXAMPLE|INPUTS|OUTPUTS|NOTES|LINK|COMPONENT|ROLE|FUNCTIONALITY|FORWARDHELPTARGETNAME|FORWARDHELPCATEGORY|REMOTEHELPRUNSPACE|EXTERNALHELP/, - - // we include these common regular expressions - symbols: /[=>/, 'comment', '@pop'], - [/(\.)(@helpKeywords)(?!\w)/, { token: 'comment.keyword.$2' } ], - [/[\.#]/, 'comment' ] - ], - }, -}; \ No newline at end of file diff --git a/src/powershellMain.ts b/src/powershellMain.ts index bd734b421f..d5b9b89393 100644 --- a/src/powershellMain.ts +++ b/src/powershellMain.ts @@ -7,9 +7,7 @@ import vscode = require('vscode'); import PowershellService = require('./powershellService'); -import PowerShellDef = require("./powerShellDef"); //import ExtraInfoSupport = require('./features/extraInfoSupport'); -import CommentsSupport = require('./features/commentsSupport'); import OccurrencesSupport = require('./features/occurrencesSupport'); import ParameterHintsSupport = require('./features/parameterHintsSupport'); import BufferSyncSupport = require('./features/bufferSyncSupport'); @@ -26,51 +24,61 @@ export function activate(subscriptions: vscode.Disposable[]): void { var MODE_ID = 'PowerShell'; var clientHost = new PowershellServiceClientHost(); var client = clientHost.serviceClient; - - subscriptions.push( - vscode.Modes.registerMonarchDefinition('PowerShell', PowerShellDef.language)); - - vscode.Modes.TokenTypeClassificationSupport.register(MODE_ID, { - wordDefinition: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g - }); - vscode.Modes.ElectricCharacterSupport.register(MODE_ID, { + + vscode.languages.setLanguageConfiguration(MODE_ID, + { + wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\'\"\,\.\<\>\/\?\s]+)/g, + + indentationRules: { + // ^(.*\*/)?\s*\}.*$ + decreaseIndentPattern: /^(.*\*\/)?\s*\}.*$/, + // ^.*\{[^}"']*$ + increaseIndentPattern: /^.*\{[^}"']*$/ + }, + + comments: { + lineComment: '#', + blockComment: ['<#', '#>'] + }, + brackets: [ - { tokenType:'delimiter.curly.ts', open: '{', close: '}', isElectric: true }, - { tokenType:'delimiter.square.ts', open: '[', close: ']', isElectric: true }, - { tokenType:'delimiter.paren.ts', open: '(', close: ')', isElectric: true } + ['{', '}'], + ['[', ']'], + ['(', ')'], ], - docComment: { scope:'comment.documentation', open:'/**', lineStart:' * ', close:' */' } - }); - vscode.Modes.CharacterPairSupport.register(MODE_ID, { - autoClosingPairs: [ - { open: '{', close: '}' }, - { open: '[', close: ']' }, - { open: '(', close: ')' }, - { open: '"', close: '"', notIn: ['string'] }, - { open: '\'', close: '\'', notIn: ['string', 'comment'] } - ] + + __electricCharacterSupport: { + brackets: [ + { tokenType:'delimiter.curly.ts', open: '{', close: '}', isElectric: true }, + { tokenType:'delimiter.square.ts', open: '[', close: ']', isElectric: true }, + { tokenType:'delimiter.paren.ts', open: '(', close: ')', isElectric: true } + ], + docComment: { scope:'comment.documentation', open:'/**', lineStart:' * ', close:' */' } + }, + + __characterPairSupport: { + autoClosingPairs: [ + { open: '{', close: '}' }, + { open: '[', close: ']' }, + { open: '(', close: ')' }, + { open: '"', close: '"', notIn: ['string'] }, + { open: '\'', close: '\'', notIn: ['string', 'comment'] } + ] + } + }); - + //vscode.languages.registerHoverProvider(MODE_ID, new ExtraInfoSupport(client)); - vscode.Modes.CommentsSupport.register(MODE_ID, new CommentsSupport()); - //vscode.languages.registerDefinitionProvider(MODE_ID, new DeclarationSupport(client)); - //vscode.languages.registerDocumentHighlightProvider(MODE_ID, new OccurrencesSupport(client)); - vscode.Modes.DeclarationSupport.register(MODE_ID, new DeclarationSupport(client)); - vscode.Modes.OccurrencesSupport.register(MODE_ID, new OccurrencesSupport(client)); - vscode.Modes.ParameterHintsSupport.register(MODE_ID, new ParameterHintsSupport(client)); - //vscode.languages.registerReferenceProvider(MODE_ID, new ReferenceSupport(client)); + vscode.languages.registerDefinitionProvider(MODE_ID, new DeclarationSupport(client)); + vscode.languages.registerDocumentHighlightProvider(MODE_ID, new OccurrencesSupport(client)); + vscode.languages.registerSignatureHelpProvider(MODE_ID, new ParameterHintsSupport(client)); + vscode.languages.registerReferenceProvider(MODE_ID, new ReferenceSupport(client)); //vscode.languages.registerWorkspaceSymbolProvider(new NavigateTypeSupport(client, MODE_ID)); - vscode.Modes.ReferenceSupport.register(MODE_ID, new ReferenceSupport(client)); - vscode.Modes.NavigateTypesSupport.register(MODE_ID, new NavigateTypeSupport(client, MODE_ID)); clientHost.addBufferSyncSupport(new BufferSyncSupport(client, MODE_ID)); var suggestSupport = new SuggestSupport(client); - vscode.Modes.SuggestSupport.register(MODE_ID, suggestSupport); - - Configuration.load(MODE_ID).then((config) => { - suggestSupport.setConfiguration(config); - }); + vscode.languages.registerCompletionItemProvider(MODE_ID, suggestSupport, '.'); } class PowershellServiceClientHost implements PowershellService.IPowershellServiceClientHost { @@ -78,7 +86,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic private client: PowershellServiceClient; private syntaxDiagnostics: {[key:string]:vscode.Diagnostic[];}; - private currentDiagnostics: { [key: string]: vscode.Disposable }; + private currentDiagnostics: vscode.DiagnosticCollection; private bufferSyncSupports: BufferSyncSupport[]; constructor() { @@ -99,7 +107,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic this.client = new PowershellServiceClient(this); this.syntaxDiagnostics = Object.create(null); - this.currentDiagnostics = Object.create(null); + this.currentDiagnostics = vscode.languages.createDiagnosticCollection('PowerShell'); } public addBufferSyncSupport(support: BufferSyncSupport): void { @@ -117,7 +125,7 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic /* internal */ syntaxDiagnosticsReceived(event:Proto.DiagnosticEvent):void { var body = event.body; if (body.diagnostics) { - var markers = this.createMarkerDatas(body.file, body.diagnostics); + var markers = this.createMarkerDatas(body.diagnostics); this.syntaxDiagnostics[body.file] = markers; } } @@ -125,45 +133,25 @@ class PowershellServiceClientHost implements PowershellService.IPowershellServic /* internal */ semanticDiagnosticsReceived(event:Proto.DiagnosticEvent):void { var body = event.body; if (body.diagnostics) { - var diagnostics = this.createMarkerDatas(body.file, body.diagnostics); + var diagnostics = this.createMarkerDatas(body.diagnostics); var syntaxMarkers = this.syntaxDiagnostics[body.file]; if (syntaxMarkers) { delete this.syntaxDiagnostics[body.file]; diagnostics = syntaxMarkers.concat(diagnostics); } - this.currentDiagnostics[body.file] && this.currentDiagnostics[body.file].dispose(); - this.currentDiagnostics[body.file] = vscode.languages.addDiagnostics(diagnostics); + + this.currentDiagnostics.set(vscode.Uri.file(body.file), diagnostics); } } - private createMarkerDatas(fileName: string, diagnostics: Proto.Diagnostic[]): vscode.Diagnostic[] { + private createMarkerDatas(diagnostics: Proto.Diagnostic[]): vscode.Diagnostic[] { let result: vscode.Diagnostic[] = []; for (let diagnostic of diagnostics) { - let uri = vscode.Uri.file(fileName); let {start, end, text} = diagnostic; - //let range = new vscode.Range(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1); - let range = new vscode.Range(start.line, start.offset, end.line, end.offset); - let location = new vscode.Location(uri, range); + let range = new vscode.Range(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1); - result.push(new vscode.Diagnostic(diagnostic.severity, location, text, 'powershell')); + result.push(new vscode.Diagnostic(range, text)); } return result; } - - // private createMarkerDatas(diagnostics:Proto.Diagnostic[]):vscode.Services.IMarkerData[] { - // var markers: vscode.Services.IMarkerData[] = []; - // for (var i = 0; i < diagnostics.length; i++) { - // var diagnostic = diagnostics[i]; - // var marker:vscode.Services.IMarkerData = { - // severity: diagnostic.severity, - // message: diagnostic.text, - // startLineNumber: diagnostic.start.line, - // startColumn: diagnostic.start.offset, - // endLineNumber: diagnostic.end.line, - // endColumn : diagnostic.end.offset - // }; - // markers.push(marker); - // } - // return markers; - // } } diff --git a/src/powershellServiceClient.ts b/src/powershellServiceClient.ts index 9e564d60be..a270cc3c23 100644 --- a/src/powershellServiceClient.ts +++ b/src/powershellServiceClient.ts @@ -88,73 +88,74 @@ class PowershellServiceClient implements PowershellService.IPowershellServiceCli private startService(): void { this.servicePromise = new Promise((resolve, reject) => { - configuration.load('PowerShell').then(config => { - //vscode.extensions.getConfigurationMemento('PowerShell').getValue('editorServicesHostPath').then(editorServicesHostPath => { - var editorServicesHostPath = config.editorServicesHostPath; - - PowershellServiceClient.Trace = true; //config.enableLogging; - console.log("-- PowerShell logging enabled? " + PowershellServiceClient.Trace); + var config = configuration.load('PowerShell'); + var editorServicesHostPath = config.editorServicesHostPath; + + PowershellServiceClient.Trace = config.enableLogging; + console.log("POWERSHELL> Logging enabled: " + PowershellServiceClient.Trace); + + if (config.editorServicesHostPath) + { + this.log("Found Editor Services path from config: " + editorServicesHostPath); + + // Make the path absolute if it's not + editorServicesHostPath = + path.resolve( + __dirname, + config.editorServicesHostPath); + + this.log(" Resolved path to: " + editorServicesHostPath); + } + else + { + // Use the default path in the plugin's 'bin' folder + editorServicesHostPath = + path.join( + __dirname, + '..', + 'bin', + 'Microsoft.PowerShell.EditorServices.Host.exe'); + + this.log("Using default Editor Services path: " + editorServicesHostPath); + } + + var childProcess:cp.ChildProcess = null; + try { + var args: string[]; - if (config.editorServicesHostPath) + if (config.waitForDebugger) { - // Make the path absolute if it's not - editorServicesHostPath = - path.resolve( - config.editorServicesHostPath); - - this.log("Found Editor Services path from config: " + editorServicesHostPath); + args = ['/waitForDebugger']; + this.log("Language service will wait for debugger after launching."); } - else - { - // Use the default path in the plugin's 'bin' folder - editorServicesHostPath = - path.join( - __dirname, - '..', - 'bin', - 'Microsoft.PowerShell.EditorServices.Host.exe'); - - this.log("Using default Editor Services path: " + editorServicesHostPath); - } - - var childProcess:cp.ChildProcess = null; - try { - var args: string[]; - - if (config.waitForDebugger) - { - args = ['/waitForDebugger']; - this.log("Language service will wait for debugger after launching."); - } - - if (isWin) { - childProcess = cp.spawn(editorServicesHostPath, args); - - } /*else if (isDarwin) { - childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/osx/node'), args); - } else if (isLinux && arch === 'x64') { - childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/linux/x64/node'), args); - }*/ - - childProcess.on('error', (err:Error) => { - this.lastError = err; - this.serviceExited(); - }); - childProcess.on('exit', (err:Error) => { - this.serviceExited(); - }); - this.reader = new WireProtocol.Reader(childProcess.stdout, (msg) => { - this.dispatchMessage(msg); - }); - - this.log("Finished spawning language service."); - - resolve(childProcess); - } catch (error) { - this.log("Failed to launch the language service! -> " + error); - reject(error); - } - }); + + if (isWin) { + childProcess = cp.spawn(editorServicesHostPath, args); + + } /*else if (isDarwin) { + childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/osx/node'), args); + } else if (isLinux && arch === 'x64') { + childProcess = cp.spawn(path.join(vscode.Paths.getAppRoot(), 'tools/bin/linux/x64/node'), args); + }*/ + + childProcess.on('error', (err:Error) => { + this.lastError = err; + this.serviceExited(); + }); + childProcess.on('exit', (err:Error) => { + this.serviceExited(); + }); + this.reader = new WireProtocol.Reader(childProcess.stdout, (msg) => { + this.dispatchMessage(msg); + }); + + this.log("Finished spawning language service."); + + resolve(childProcess); + } catch (error) { + this.log("Failed to launch the language service! -> " + error); + reject(error); + } }); } diff --git a/typings/vscode-typings.d.ts b/typings/vscode-typings.d.ts index 379fb23d39..ae9f2e5cad 100644 --- a/typings/vscode-typings.d.ts +++ b/typings/vscode-typings.d.ts @@ -1,7 +1,4 @@ -// TODO: Re-enable this once we're building against the shipped 0.10.0 typings -/* */ - -// TODO: Remove these once we move back to the packaged typings +/// /// /// /// diff --git a/typings/vscode.d.ts b/typings/vscode.d.ts deleted file mode 100644 index a845e5bfa3..0000000000 --- a/typings/vscode.d.ts +++ /dev/null @@ -1,1309 +0,0 @@ -/*--------------------------------------------------------- - * Copyright (C) Microsoft Corporation. All rights reserved. - *--------------------------------------------------------*/ - - -declare module 'vscode' { - - // TODO@api - // Naming: Command, Action, ... - - /** - * The command callback. - */ - export interface CommandCallback { - - /** - * - */ - (...args:any[]):T | Thenable; - } - - /** - * Namespace for commanding - */ - export namespace commands { - - /** - * Registers a command that can be invoked via a keyboard shortcut, - * an menu item, an action, or directly. - * - * @param command - The unique identifier of this command - * @param callback - The command callback - * @param thisArgs - (optional) The this context used when invoking {{callback}} - * @return Disposable which unregisters this command on disposal - */ - export function registerCommand(command: string, callback: CommandCallback, thisArg?: any): Disposable; - - /** - * Register a text editor command that will make edits. - * It can be invoked via a keyboard shortcut, a menu item, an action, or directly. - * - * @param command - The unique identifier of this command - * @param callback - The command callback. The {{textEditor}} and {{edit}} passed in are available only for the duration of the callback. - * @param thisArgs - (optional) The `this` context used when invoking {{callback}} - * @return Disposable which unregisters this command on disposal - */ - export function registerTextEditorCommand(command: string, callback: (textEditor:TextEditor, edit:TextEditorEdit) => void, thisArg?: any): Disposable; - - /** - * Executes a command - * - * @param command - Identifier of the command to execute - * @param ...rest - Parameter passed to the command function - * @return - */ - export function executeCommand(command: string, ...rest: any[]): Thenable; - } - - export interface TextEditorOptions { - tabSize: number; - insertSpaces: boolean; - } - - export class TextDocument { - - constructor(uri: Uri, lines: string[], eol: string, languageId: string, versionId: number, isDirty:boolean); - - /** - * Get the associated URI for this document. Most documents have the file:// scheme, indicating that they represent files on disk. - * However, some documents may have other schemes indicating that they are not available on disk. - */ - getUri(): Uri; - - /** - * Returns the file system path of the file associated with this document. Shorthand - * notation for ```TextDocument.getUri().fsPath``` - */ - getPath(): string; - - /** - * Is this document representing an untitled file. - */ - isUntitled(): boolean; - - isDirty(): boolean; - - save(): Thenable; - - /** - * The language identifier associated with this document. - */ - getLanguageId(): string; - - /** - * The version number of this document (it will strictly increase after each change). - */ - getVersionId(): number; - - /** - * Get the entire text in this document. - */ - getText(): string; - - /** - * Get the text in a specific range in this document. - */ - getTextInRange(range: Range): string; - - /** - * Get the text on a specific line in this document. - */ - getTextOnLine(line:number): string; - - /** - * Ensure a range sticks to the text. - */ - validateRange(range:Range): Range; - - /** - * Ensure a position sticks to the text. - */ - validatePosition(position:Position): Position; - - /** - * Get the number of lines in this document. - */ - getLineCount(): number; - - /** - * Get the maximum column for line {{line}}. - */ - getLineMaxColumn(line:number): number; - - /** - * Get the word under a certain position. May return null if position is at whitespace, on empty line, etc. - */ - getWordRangeAtPosition(position:Position): Range; - } - - export class Position { - - line: number; - - character: number; - - constructor(line: number, character: number); - - isBefore(other: Position): boolean; - - isBeforeOrEqual(other: Position): boolean; - } - - export class Range { - - start: Position; - - end: Position; - - constructor(start: Position, end: Position); - constructor(startLine: number, startColumn: number, endLine:number, endColumn:number); - - contains(positionOrRange: Position | Range): boolean; - - /** - * @return `true` iff `start` and `end` are equal - */ - isEmpty(): boolean; - - /** - * @return `true` iff start and end are on the same line - */ - isOneLine(): boolean; - } - - export class Selection extends Range { - - anchor: Position; - - active: Position; - - constructor(anchor: Position, active: Position); - constructor(anchorLine: number, anchorColumn: number, activeLine:number, activeColumn:number); - - isReversed(): boolean; - } - - export class TextEditor { - - constructor(document: TextDocument, selections: Selection[], options: TextEditorOptions); - - dispose(); - - /** - * Get the document associated with this text editor. The document will be the same for the entire lifetime of this text editor. - */ - getTextDocument(): TextDocument; - - /** - * Get the primary selection on this text editor. In case the text editor has multiple selections, the first one will be returned. - */ - getSelection(): Selection; - - /** - * Set the selection on this text editor. - */ - setSelection(value: Position | Range | Selection): Thenable; - - /** - * Get the selections in this text editor. - */ - getSelections(): Selection[]; - - /** - * Set the selections in this text editor. - */ - setSelections(value: Selection[]): Thenable; - - /** - * Get text editor options. - */ - getOptions(): TextEditorOptions; - - /** - * Change text editor options. - */ - setOptions(options: TextEditorOptions): Thenable; - - /** - * Perform an edit on the document associated with this text editor. - * The passed in {{editBuilder}} is available only for the duration of the callback. - */ - edit(callback:(editBuilder:TextEditorEdit)=>void): Thenable; - - } - - /** - * A complex edit that will be applied on a TextEditor. - * This holds a description of the edits and if the edits are valid (i.e. no overlapping regions, etc.) they can be applied on a Document associated with a TextEditor. - */ - export interface TextEditorEdit { - /** - * Replace a certain text region with a new value. - */ - replace(location: Position | Range | Selection, value: string): void; - - /** - * Insert text at a location - */ - insert(location: Position, value: string): void; - - /** - * Delete a certain text region. - */ - delete(location: Range | Selection): void; - - } - - /** - * A universal resource identifier representing either a file on disk on - * or another resource, e.g untitled. - */ - class Uri { - - constructor(); - static parse(path: string): Uri; - static file(path: string): Uri; - static create(path: string): Uri; - - /** - * scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'. - * The part before the first colon. - */ - scheme: string; - - - /** - * authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'. - * The part between the first double slashes and the next slash. - */ - authority: string; - - - /** - * path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'. - */ - path: string; - - /** - * query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'. - */ - query: string; - - /** - * fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'. - */ - fragment: string; - - /** - * Retuns a string representing the corresponding file system path of this URI. - * Will handle UNC paths and normalize windows drive letters to lower-case. Also - * uses the platform specific path separator. Will *not* validate the path for - * invalid characters and semantics. Will *not* look at the scheme of this URI. - */ - fsPath: string; - - /** - * Returns a canonical representation of this URI. The representation and normalization - * of a URI depends on the scheme. - */ - toString(): string; - - toJSON(): any; - } - - interface CancellationToken { - isCancellationRequested: boolean; - onCancellationRequested: Event; - } - - class CancellationTokenSource { - - token: CancellationToken; - - cancel(): void; - - dispose(): void; - } - - /** - * Represents a type which can release resources, such - * as event listening or a timer. - */ - class Disposable { - - /** - * Combine many disposables into one. - * - * @return Returns a new disposable which, upon dispose, will - * dispose all provided disposables - */ - static of(...disposables: Disposable[]): Disposable; - - /** - * Combine many disposable-likes into one. Use this method - * when having objects with a dispose function which are not - * instances of Disposable. - * - * @return Returns a new disposable which, upon dispose, will - * dispose all provides disposable-likes. - */ - static from(...disposableLikes: { dispose: () => any }[]): Disposable; - - /** - * Creates a new Disposable calling the provided function - * on dispose - * @param callOnDispose Function that disposes something - */ - constructor(callOnDispose: Function); - - /** - * Dispose this object. - */ - dispose(): any; - } - - /** - * Represents a typed event. - */ - interface Event { - - /** - * - * @param listener The listener function will be call when the event happens. - * @param thisArgs The 'this' which will be used when calling the event listener. - * @param disposables An array to which a {{IDisposable}} will be added. The - * @return - */ - (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; - } - - /** - * A file system watcher notifies about changes to files and folders - * on disk. To get an instanceof of a {{FileSystemWatcher}} use - * {{workspace.createFileSystemWatcher}}. - */ - export interface FileSystemWatcher extends Disposable { - - /** - * Happens on file/folder creation. - */ - onDidCreate: Event; - - /** - * Happens on file/folder change. - */ - onDidChange: Event; - - /** - * Happens on file/folder deletion. - */ - onDidDelete: Event; - } - - /** - * - */ - export interface QuickPickOptions { - /** - * an optional flag to include the description when filtering the picks - */ - matchOnDescription?: boolean; - - /** - * an optional string to show as place holder in the input box to guide the user what she picks on - */ - placeHolder?: string; - } - - /** - * - */ - export interface QuickPickItem { - label: string; - description: string; - } - - /** - * - */ - export interface InputBoxOptions { - /** - * The text to display underneath the input box. - */ - prompt?: string; - - /** - * an optional string to show as place holder in the input box to guide the user what to type - */ - placeHolder?: string; - } - - /** - * - */ - interface LanguageFilter { - language?: string; - scheme?: string; - pattern?: string; - } - - /** - * - */ - type LanguageSelector = string|LanguageFilter|(string|LanguageFilter)[]; - - - /** - * - */ - interface ReadOnlyMemento { - - /** - * @param key The name of a property to read. - * @param defaultValue The default value in case the denoted property doesn't exists. - * @return - */ - getValue(key: string, defaultValue?: T): Thenable; - - /** - * - */ - getValues(defaultValue?: T): Thenable; - } - - /** - * - */ - interface Memento extends ReadOnlyMemento { - setValue(key: string, value: any): Thenable; - } - - /** - * Represents the severity of diagnostics. - */ - export enum DiagnosticSeverity { - Warning = 1, - Error = 2 - } - - /** - * Represents a location inside a resource, such as a line - * inside a text file. - */ - export class Location { - constructor(uri: Uri, range: Selection | Range | Position); - uri: Uri; - range: Range; - } - - /** - * Represents a diagnostic, such as a compiler error or warning, along with the location - * in which they occurred. - */ - export class Diagnostic { - - constructor(severity: DiagnosticSeverity, location: Location, message: string, source?:string); - - severity: DiagnosticSeverity; - - location: Location; - - message: string; - - source: string; - } - - // TODO@api, TODO@Joh,Ben - // output channels need to be known upfront (contributes in package.json) - export interface OutputChannel extends Disposable { - append(value: string): void; - appendLine(value: string): void; - clear(): void; - reveal(): void; - } - - export interface ExecutionOptions { - cwd?: string; - env?: { [name: string]: any }; - } - - export interface TextEditorSelectionChangeEvent { - textEditor: TextEditor; - selections: Selection[]; - } - - export interface TextEditorOptionsChangeEvent { - textEditor: TextEditor; - options: TextEditorOptions; - } - - export interface ITelemetryInfo { - sessionId: string; - machineId: string; - instanceId: string; - } - - export namespace window { - - export function getActiveTextEditor(): TextEditor; - - export const onDidChangeActiveTextEditor: Event; - - export const onDidChangeTextEditorSelection: Event; - - export const onDidChangeTextEditorOptions: Event; - - export function showInformationMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function showWarningMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function showErrorMessage(message: string, ...commands: { title: string; command: string | CommandCallback; }[]): Thenable; - - export function setStatusBarMessage(message: string, hideAfterSeconds?: number): Disposable; - - export function showQuickPick(items: string[], options?: QuickPickOptions): Thenable; - - export function showQuickPick(items: T[], options?: QuickPickOptions): Thenable; - - /** - * Opens an input box to ask the user for input. - */ - export function showInputBox(options?: InputBoxOptions): Thenable; - - export function getOutputChannel(name: string): OutputChannel; - - /** - * ✂ - don't use. Will be cut soone! - TODO@api move into a node_module - */ - export function runInTerminal(command: string, args: string[], options?: ExecutionOptions): Thenable; - } - - /** - * An event describing a change in the text of a model. - */ - export interface TextDocumentContentChangeEvent { - /** - * The range that got replaced. - */ - range: Range; - /** - * The length of the range that got replaced. - */ - rangeLength: number; - /** - * The new text for the range. - */ - text: string; - } - - export interface TextDocumentChangeEvent { - document: TextDocument; - contentChanges: TextDocumentContentChangeEvent[]; - } - - // TODO@api in the future there might be multiple opened folder in VSCode - // so that we shouldn't make broken assumptions here - export namespace workspace { - - /** - * Creates a file system watcher. A glob pattern that filters the - * file events must be provided. Optionally, flags to ignore certain - * kind of events can be provided. - * - * @param globPattern - A glob pattern that is applied to the names of created, changed, and deleted files. - * @param ignoreCreateEvents - Ignore when files have been created. - * @param ignoreChangeEvents - Ignore when files have been changed. - * @param ignoreDeleteEvents - Ignore when files have been deleted. - */ - export function createFileSystemWatcher(globPattern: string, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher; - - // TODO@api - justify this being here - export function getPath(): string; - - export function getRelativePath(pathOrUri: string|Uri): string; - - // TODO@api - justify this being here - export function findFiles(include: string, exclude: string, maxResults?:number): Thenable; - - /** - * save all dirty files - */ - export function saveAll(includeUntitled?: boolean): Thenable; - - export function getTextDocuments(): TextDocument[]; - export function getTextDocument(resource: Uri): TextDocument; - export const onDidOpenTextDocument: Event; - export const onDidCloseTextDocument: Event; - export const onDidChangeTextDocument: Event; - export const onDidSaveTextDocument: Event; - } - - export namespace languages { - - /** - * Add diagnostics, such as compiler errors or warnings. They will be represented as - * squiggles in text editors and in a list of diagnostics. - * To remove the diagnostics again, dispose the `Disposable` which is returned - * from this function call. - * - * @param diagnostics Array of diagnostics - * @return A disposable the removes the diagnostics again. - */ - export function addDiagnostics(diagnostics: Diagnostic[]): Disposable; - - /** - * - */ - export function addInformationLanguageStatus(language: LanguageSelector|Uri|Uri[], message: string | { octicon: string; message: string;}, command: string | CommandCallback): Disposable; - - /** - * - */ - export function addWarningLanguageStatus(language: LanguageSelector | Uri | Uri[], message: string | { octicon: string; message: string; }, command: string | CommandCallback): Disposable; - - /** - * - */ - export function addErrorLanguageStatus(language: LanguageSelector | Uri | Uri[], message: string | { octicon: string; message: string; }, command: string | CommandCallback): Disposable; - } - - export namespace extensions { - - export function getStateMemento(extensionId: string, global?: boolean): Memento; - - export function getConfigurationMemento(extensionId: string): ReadOnlyMemento; - - export function getExtension(extensionId: string): any; - - export function getTelemetryInfo(): Thenable; - } - - export interface IHTMLContentElement { - formattedText?:string; - text?: string; - className?: string; - style?: string; - customStyle?: any; - tagName?: string; - children?: IHTMLContentElement[]; - isText?: boolean; - } - - // --- Begin Monaco.Modes - module Modes { - interface ILanguage { - // required - name: string; // unique name to identify the language - tokenizer: Object; // map from string to ILanguageRule[] - - // optional - displayName?: string; // nice display name - ignoreCase?: boolean; // is the language case insensitive? - lineComment?: string; // used to insert/delete line comments in the editor - blockCommentStart?: string; // used to insert/delete block comments in the editor - blockCommentEnd?: string; - defaultToken?: string; // if no match in the tokenizer assign this token class (default 'source') - brackets?: ILanguageBracket[]; // for example [['{','}','delimiter.curly']] - - // advanced - start?: string; // start symbol in the tokenizer (by default the first entry is used) - tokenPostfix?: string; // attach this to every token class (by default '.' + name) - autoClosingPairs?: string[][]; // for example [['"','"']] - wordDefinition?: RegExp; // word definition regular expression - outdentTriggers?: string; // characters that could potentially cause outdentation - enhancedBrackets?: Modes.IRegexBracketPair[];// Advanced auto completion, auto indenting, and bracket matching - } - - /** - * This interface can be shortened as an array, ie. ['{','}','delimiter.curly'] - */ - interface ILanguageBracket { - open: string; // open bracket - close: string; // closeing bracket - token: string; // token class - } - - interface ILanguageAutoComplete { - triggers: string; // characters that trigger auto completion rules - match: string|RegExp; // autocomplete if this matches - complete: string; // complete with this string - } - - interface ILanguageAutoIndent { - match: string|RegExp; // auto indent if this matches on enter - matchAfter: string|RegExp; // and auto-outdent if this matches on the next line - } - - /** - * Standard brackets used for auto indentation - */ - export interface IBracketPair { - tokenType:string; - open:string; - close:string; - isElectric:boolean; - } - - /** - * Regular expression based brackets. These are always electric. - */ - export interface IRegexBracketPair { - openTrigger?: string; // The character that will trigger the evaluation of 'open'. - open: RegExp; // The definition of when an opening brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character). - closeComplete?: string; // How to complete a matching open brace. Matches from 'open' will be expanded, e.g. '' - matchCase?: boolean; // If set to true, the case of the string captured in 'open' will be detected an applied also to 'closeComplete'. - // This is useful for cases like BEGIN/END or begin/end where the opening and closing phrases are unrelated. - // For identical phrases, use the $1 replacement syntax above directly in closeComplete, as it will - // include the proper casing from the captured string in 'open'. - // Upper/Lower/Camel cases are detected. Camel case dection uses only the first two characters and assumes - // that 'closeComplete' contains wors separated by spaces (e.g. 'End Loop') - - closeTrigger?: string; // The character that will trigger the evaluation of 'close'. - close?: RegExp; // The definition of when a closing brace is detected. This regex is matched against the entire line upto, and including the last typed character (the trigger character). - tokenType?: string; // The type of the token. Matches from 'open' or 'close' will be expanded, e.g. 'keyword.$1'. - // Only used to auto-(un)indent a closing bracket. - } - - /** - * Definition of documentation comments (e.g. Javadoc/JSdoc) - */ - export interface IDocComment { - scope: string; // What tokens should be used to detect a doc comment (e.g. 'comment.documentation'). - open: string; // The string that starts a doc comment (e.g. '/**') - lineStart: string; // The string that appears at the start of each line, except the first and last (e.g. ' * '). - close?: string; // The string that appears on the last line and closes the doc comment (e.g. ' */'). - } - - // --- Begin InplaceReplaceSupport - /** - * Interface used to navigate with a value-set. - */ - interface IInplaceReplaceSupport { - sets: string[][]; - } - var InplaceReplaceSupport: { - register(modeId: string, inplaceReplaceSupport: Modes.IInplaceReplaceSupport): Disposable; - }; - // --- End InplaceReplaceSupport - - - // --- Begin TokenizationSupport - enum Bracket { - None = 0, - Open = 1, - Close = -1 - } - // --- End TokenizationSupport - - // --- Begin IDeclarationSupport - export interface IDeclarationSupport { - tokens?: string[]; - findDeclaration(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var DeclarationSupport: { - register(modeId: string, declarationSupport: IDeclarationSupport): Disposable; - }; - // --- End IDeclarationSupport - - // --- Begin ICodeLensSupport - export interface ICodeLensSupport { - findCodeLensSymbols(document: TextDocument, token: CancellationToken): Thenable; - findCodeLensReferences(document: TextDocument, requests: ICodeLensSymbolRequest[], token: CancellationToken): Thenable; - } - export interface ICodeLensSymbolRequest { - position: Position; - languageModeStateId?: number; - } - export interface ICodeLensSymbol { - range: Range; - } - export interface ICodeLensReferences { - references: IReference[][]; - languageModeStateId?: number; - } - var CodeLensSupport: { - register(modeId: string, codeLensSupport: ICodeLensSupport): Disposable; - }; - // --- End ICodeLensSupport - - // --- Begin IOccurrencesSupport - export interface IOccurrence { - kind?:string; - range:Range; - } - export interface IOccurrencesSupport { - findOccurrences(resource: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var OccurrencesSupport: { - register(modeId: string, occurrencesSupport:IOccurrencesSupport): Disposable; - }; - // --- End IOccurrencesSupport - - // --- Begin IOutlineSupport - export interface IOutlineEntry { - label: string; - type: string; - icon?: string; // icon class or null to use the default images based on the type - range: Range; - children?: IOutlineEntry[]; - } - export interface IOutlineSupport { - getOutline(document: TextDocument, token: CancellationToken): Thenable; - outlineGroupLabel?: { [name: string]: string; }; - } - var OutlineSupport: { - register(modeId: string, outlineSupport:IOutlineSupport): Disposable; - }; - // --- End IOutlineSupport - - // --- Begin IOutlineSupport - export interface IQuickFix { - label: string; - id: any; - score: number; - documentation?: string; - } - - export interface IQuickFixResult { - edits: IResourceEdit[]; - } - - export interface IQuickFixSupport { - getQuickFixes(resource: TextDocument, marker: Range, token: CancellationToken): Thenable; - runQuickFixAction(resource: TextDocument, range: Range, id: any, token: CancellationToken): Thenable; - } - var QuickFixSupport: { - register(modeId: string, quickFixSupport:IQuickFixSupport): Disposable - }; - // --- End IOutlineSupport - - // --- Begin IReferenceSupport - export interface IReferenceSupport { - tokens?: string[]; - - /** - * @returns a list of reference of the symbol at the position in the - * given resource. - */ - findReferences(document: TextDocument, position: Position, includeDeclaration: boolean, token: CancellationToken): Thenable; - } - var ReferenceSupport: { - register(modeId: string, quickFixSupport:IReferenceSupport): Disposable; - }; - // --- End IReferenceSupport - - // --- Begin IParameterHintsSupport - export interface IParameter { - label:string; - documentation?:string; - signatureLabelOffset?:number; - signatureLabelEnd?:number; - } - - export interface ISignature { - label:string; - documentation?:string; - parameters:IParameter[]; - } - - export interface IParameterHints { - currentSignature:number; - currentParameter:number; - signatures:ISignature[]; - } - - export interface IParameterHintsSupport { - /** - * On which characters presses should parameter hints be potentially shown. - */ - triggerCharacters: string[]; - - /** - * A list of token types that prevent the parameter hints from being shown (e.g. comment, string) - */ - excludeTokens: string[]; - /** - * @returns the parameter hints for the specified position in the file. - */ - getParameterHints(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var ParameterHintsSupport: { - register(modeId: string, parameterHintsSupport:IParameterHintsSupport): Disposable; - }; - // --- End IParameterHintsSupport - - // --- Begin IExtraInfoSupport - export interface IComputeExtraInfoResult { - range: Range; - value?: string; - htmlContent?: IHTMLContentElement[]; - className?: string; - } - export interface IExtraInfoSupport { - computeInfo(document: TextDocument, position: Position, token: CancellationToken): Thenable; - } - var ExtraInfoSupport: { - register(modeId: string, extraInfoSupport:IExtraInfoSupport): Disposable; - }; - // --- End IExtraInfoSupport - - // --- Begin IRenameSupport - export interface IRenameResult { - currentName: string; - edits: IResourceEdit[]; - rejectReason?: string; - } - export interface IRenameSupport { - filter?: string[]; - rename(document: TextDocument, position: Position, newName: string, token: CancellationToken): Thenable; - } - var RenameSupport: { - register(modeId: string, renameSupport:IRenameSupport): Disposable; - }; - // --- End IRenameSupport - - // --- Begin IFormattingSupport - /** - * Interface used to format a model - */ - export interface IFormattingOptions { - tabSize:number; - insertSpaces:boolean; - } - /** - * A single edit operation, that acts as a simple replace. - * i.e. Replace text at `range` with `text` in model. - */ - export interface ISingleEditOperation { - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: Range; - /** - * The text to replace with. This can be null to emulate a simple delete. - */ - text: string; - } - /** - * Supports to format source code. There are three levels - * on which formatting can be offered: - * (1) format a document - * (2) format a selectin - * (3) format on keystroke - */ - export interface IFormattingSupport { - formatDocument: (document: TextDocument, options: IFormattingOptions, token: CancellationToken) => Thenable; - formatRange?: (document: TextDocument, range: Range, options: IFormattingOptions, token: CancellationToken) => Thenable; - autoFormatTriggerCharacters?: string[]; - formatAfterKeystroke?: (document: TextDocument, position: Position, ch: string, options: IFormattingOptions, token: CancellationToken) => Thenable; - } - var FormattingSupport: { - register(modeId: string, formattingSupport:IFormattingSupport): Disposable; - }; - // --- End IRenameSupport - - // --- Begin ISuggestSupport - export interface ISortingTypeAndSeparator { - type: string; - partSeparator?: string; - } - export interface IHighlight { - start:number; - end:number; - } - export interface ISuggestion { - label: string; - codeSnippet: string; - type: string; - highlights?: IHighlight[]; - typeLabel?: string; - documentationLabel?: string; - } - export interface ISuggestions { - currentWord:string; - suggestions:ISuggestion[]; - incomplete?: boolean; - overwriteBefore?: number; - overwriteAfter?: number; - } - export interface ISuggestSupport { - triggerCharacters: string[]; - excludeTokens: string[]; - - sortBy?: ISortingTypeAndSeparator[]; - - suggest: (document: TextDocument, position: Position, token: CancellationToken) => Thenable; - getSuggestionDetails? : (document: TextDocument, position: Position, suggestion:ISuggestion, token: CancellationToken) => Thenable; - } - var SuggestSupport: { - register(modeId:string, suggestSupport:ISuggestSupport): Disposable; - }; - // --- End ISuggestSupport - - // --- Start INavigateTypesSupport - - export interface ITypeBearing { - containerName: string; - name: string; - parameters: string; - type: string; - range: Range; - resourceUri: Uri; - } - - export interface INavigateTypesSupport { - getNavigateToItems:(search: string, token: CancellationToken) => Thenable; - } - var NavigateTypesSupport: { - register(modeId:string, navigateTypeSupport:INavigateTypesSupport): Disposable; - }; - - // --- End INavigateTypesSupport - - // --- Begin ICommentsSupport - export interface ICommentsSupport { - commentsConfiguration: ICommentsConfiguration; - } - export interface ICommentsConfiguration { - lineCommentTokens?:string[]; - blockCommentStartToken?:string; - blockCommentEndToken?:string; - } - var CommentsSupport: { - register(modeId:string, commentsSupport:ICommentsSupport): Disposable; - }; - // --- End ICommentsSupport - - // --- Begin ITokenTypeClassificationSupport - export interface ITokenTypeClassificationSupport { - wordDefinition?: RegExp; - } - var TokenTypeClassificationSupport: { - register(modeId:string, tokenTypeClassificationSupport:ITokenTypeClassificationSupport): Disposable; - }; - // --- End ITokenTypeClassificationSupport - - // --- Begin IElectricCharacterSupport - export interface IElectricCharacterSupport { - brackets: IBracketPair[]; - regexBrackets?: IRegexBracketPair[]; - docComment?: IDocComment; - caseInsensitive?: boolean; - embeddedElectricCharacters?: string[]; - } - var ElectricCharacterSupport: { - register(modeId:string, electricCharacterSupport:IElectricCharacterSupport): Disposable; - }; - // --- End IElectricCharacterSupport - - // --- Begin ICharacterPairSupport - export interface ICharacterPairSupport { - autoClosingPairs: IAutoClosingPairConditional[]; - surroundingPairs?: IAutoClosingPair[]; - } - /** - * Interface used to support insertion of matching characters like brackets and qoutes. - */ - export interface IAutoClosingPair { - open:string; - close:string; - } - export interface IAutoClosingPairConditional extends IAutoClosingPair { - notIn?: string[]; - } - var CharacterPairSupport: { - register(modeId:string, characterPairSupport:ICharacterPairSupport): Disposable; - }; - // --- End ICharacterPairSupport - - // --- Begin IOnEnterSupport - export interface IBracketPair2 { - open: string; - close: string; - } - export interface IIndentationRules { - decreaseIndentPattern: RegExp; - increaseIndentPattern: RegExp; - indentNextLinePattern?: RegExp; - unIndentedLinePattern?: RegExp; - } - export enum IndentAction { - None, - Indent, - IndentOutdent, - Outdent - } - export interface IEnterAction { - indentAction:IndentAction; - appendText?:string; - removeText?:number; - } - export interface IOnEnterRegExpRules { - beforeText: RegExp; - afterText?: RegExp; - action: IEnterAction; - } - export interface IOnEnterSupportOptions { - brackets?: IBracketPair2[]; - indentationRules?: IIndentationRules; - regExpRules?: IOnEnterRegExpRules[]; - } - var OnEnterSupport: { - register(modeId:string, opts:IOnEnterSupportOptions): Disposable; - }; - // --- End IOnEnterSupport - - export interface IResourceEdit { - resource: Uri; - range?: Range; - newText: string; - } - - export interface IReference { - resource: Uri; - range: Range; - } - - interface IMode { - getId(): string; - } - - export interface IWorker { - disposable: Disposable; - load(): Thenable; - } - - function registerMonarchDefinition(modeId: string, language: Modes.ILanguage): Disposable; - function loadInBackgroundWorker(scriptSrc: string): IWorker; - - } - - -} - -declare module 'vscode-testing' { - import vscode = require('vscode'); - export interface IRelaxedToken { - startIndex: number; - type: string; - bracket?: vscode.Modes.Bracket; - } - export interface ITestItem { - line: string; - tokens: IRelaxedToken[]; - } - export function testTokenization(name:string, language: vscode.Modes.ILanguage, tests:ITestItem[][]): void; - export interface IOnEnterAsserter { - nothing(oneLineAboveText:string, beforeText:string, afterText:string): void; - indents(oneLineAboveText:string, beforeText:string, afterText:string): void; - outdents(oneLineAboveText:string, beforeText:string, afterText:string): void; - indentsOutdents(oneLineAboveText:string, beforeText:string, afterText:string): void; - } - export function testOnEnter(name:string, language: vscode.Modes.ILanguage, callback:(assertOnEnter:IOnEnterAsserter) => void): void; -} - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise libary is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommand the use of native promises which are available in VS Code. - */ -interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; -} - -// ---- ES6 promise ------------------------------------------------------ - -/** - * Represents the completion of an asynchronous operation - */ -interface Promise extends Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Promise; - then(onfulfilled?: (value: T) => TResult | Thenable, onrejected?: (reason: any) => void): Promise; - - /** - * Attaches a callback for only the rejection of the Promise. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of the callback. - */ - catch(onrejected?: (reason: any) => T | Thenable): Promise; - - // [Symbol.toStringTag]: string; -} - -interface PromiseConstructor { - // /** - // * A reference to the prototype. - // */ - // prototype: Promise; - - /** - * Creates a new Promise. - * @param executor A callback used to initialize the promise. This callback is passed two arguments: - * a resolve callback used resolve the promise with a value or the result of another promise, - * and a reject callback used to reject the promise with a provided reason or error. - */ - new (executor: (resolve: (value?: T | Thenable) => void, reject: (reason?: any) => void) => void): Promise; - - /** - * Creates a Promise that is resolved with an array of results when all of the provided Promises - * resolve, or rejected when any Promise is rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - all(values: Array>): Promise; - - /** - * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved - * or rejected. - * @param values An array of Promises. - * @returns A new Promise. - */ - race(values: Array>): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new rejected promise for the provided reason. - * @param reason The reason the promise was rejected. - * @returns A new rejected Promise. - */ - reject(reason: any): Promise; - - /** - * Creates a new resolved promise for the provided value. - * @param value A promise. - * @returns A promise whose internal state matches the provided promise. - */ - resolve(value: T | Thenable): Promise; - - /** - * Creates a new resolved promise . - * @returns A resolved promise. - */ - resolve(): Promise; - - // [Symbol.species]: Function; -} - -declare var Promise: PromiseConstructor;