-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(diagnostics): code action & diagnostic warning to convert 'one-w…
…ay' to 'to-view' (#66) * feat(diagnostics): introduce one-way warning and refactor server diagnostics * refactor(code-action): refactor to server code actions
- Loading branch information
Erik Lieben
authored
Dec 31, 2017
1 parent
06815bd
commit 2eb4ee1
Showing
19 changed files
with
641 additions
and
1,552 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,59 @@ | ||
import * as path from 'path'; | ||
import { ExtensionContext, OutputChannel, window, languages, SnippetString } from 'vscode'; | ||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; | ||
import AureliaCliCommands from './aureliaCLICommands'; | ||
import htmlInvalidCasingActionProvider from './htmlInvalidCasingCodeActionProvider'; | ||
import { RelatedFiles } from './relatedFiles'; | ||
|
||
let outputChannel: OutputChannel; | ||
|
||
export function activate(context: ExtensionContext) { | ||
|
||
// Create default output channel | ||
outputChannel = window.createOutputChannel('aurelia'); | ||
context.subscriptions.push(outputChannel); | ||
|
||
// Register CLI commands | ||
context.subscriptions.push(AureliaCliCommands.registerCommands(outputChannel)); | ||
context.subscriptions.push(new RelatedFiles()); | ||
|
||
// Register code fix | ||
const invalidCasingAction = new htmlInvalidCasingActionProvider(); | ||
invalidCasingAction.activate(context.subscriptions); | ||
languages.registerCodeActionsProvider('html', invalidCasingAction); | ||
|
||
// Register Aurelia language server | ||
const serverModule = context.asAbsolutePath(path.join('dist', 'src', 'server', 'main.js')); | ||
const debugOptions = { execArgv: ['--nolazy', '--debug=6100'] }; | ||
const serverOptions: ServerOptions = { | ||
debug: { module: serverModule, options: debugOptions, transport: TransportKind.ipc }, | ||
run: { module: serverModule, transport: TransportKind.ipc }, | ||
}; | ||
|
||
const clientOptions: LanguageClientOptions = { | ||
diagnosticCollectionName: 'Aurelia', | ||
documentSelector: ['html'], | ||
initializationOptions: {}, | ||
synchronize: { | ||
configurationSection: ['aurelia'], | ||
}, | ||
}; | ||
|
||
const client = new LanguageClient('html', 'Aurelia', serverOptions, clientOptions); | ||
const disposable = client.start(); | ||
context.subscriptions.push(disposable); | ||
} | ||
import * as path from 'path'; | ||
import { ExtensionContext, OutputChannel, window, languages, SnippetString, commands, TextEdit } from 'vscode'; | ||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient'; | ||
import AureliaCliCommands from './aureliaCLICommands'; | ||
import { RelatedFiles } from './relatedFiles'; | ||
|
||
let outputChannel: OutputChannel; | ||
|
||
export function activate(context: ExtensionContext) { | ||
|
||
// Create default output channel | ||
outputChannel = window.createOutputChannel('aurelia'); | ||
context.subscriptions.push(outputChannel); | ||
|
||
// Register CLI commands | ||
context.subscriptions.push(AureliaCliCommands.registerCommands(outputChannel)); | ||
context.subscriptions.push(new RelatedFiles()); | ||
|
||
// Register Code Actions | ||
const edit = (uri: string, documentVersion: number, edits: TextEdit[]) => | ||
{ | ||
let textEditor = window.activeTextEditor; | ||
if (textEditor && textEditor.document.uri.toString() === uri) { | ||
textEditor.edit(mutator => { | ||
for(let edit of edits) { | ||
mutator.replace(client.protocol2CodeConverter.asRange(edit.range), edit.newText); | ||
} | ||
}).then((success) => { | ||
window.activeTextEditor.document.save(); | ||
if (!success) { | ||
window.showErrorMessage('Failed to apply Aurelia code fixes to the document. Please consider opening an issue with steps to reproduce.'); | ||
} | ||
}); | ||
} | ||
}; | ||
context.subscriptions.push(commands.registerCommand('aurelia-attribute-invalid-case', edit)); | ||
context.subscriptions.push(commands.registerCommand('aurelia-binding-one-way-deprecated', edit)); | ||
|
||
// Register Aurelia language server | ||
const serverModule = context.asAbsolutePath(path.join('dist', 'src', 'server', 'main.js')); | ||
const debugOptions = { execArgv: ['--nolazy', '--debug=6100'] }; | ||
const serverOptions: ServerOptions = { | ||
debug: { module: serverModule, options: debugOptions, transport: TransportKind.ipc }, | ||
run: { module: serverModule, transport: TransportKind.ipc }, | ||
}; | ||
|
||
const clientOptions: LanguageClientOptions = { | ||
diagnosticCollectionName: 'Aurelia', | ||
documentSelector: ['html'], | ||
initializationOptions: {}, | ||
synchronize: { | ||
configurationSection: ['aurelia'], | ||
}, | ||
}; | ||
|
||
const client = new LanguageClient('html', 'Aurelia', serverOptions, clientOptions); | ||
const disposable = client.start(); | ||
context.subscriptions.push(disposable); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Diagnostic, TextEdit, Command, TextDocument } from "vscode-languageserver-types"; | ||
import { DocumentParser } from "../DocumentParser"; | ||
import { attributeInvalidCaseFix } from "../Common/AttributeInvalidCaseFix"; | ||
|
||
export class HtmlInvalidCaseCodeAction { | ||
public name = 'aurelia-attribute-invalid-case'; | ||
|
||
public async commands(diagnostic: Diagnostic, document: TextDocument): Promise<Command> { | ||
const text = document.getText(); | ||
const start = document.offsetAt(diagnostic.range.start); | ||
const end = document.offsetAt(diagnostic.range.end); | ||
const parser = new DocumentParser(); | ||
const element = await parser.getElementAtPosition(text, start, end); | ||
|
||
const original = text.substring(start, end); | ||
let fixed = original; | ||
if (element) { | ||
fixed = attributeInvalidCaseFix(fixed, element.name); | ||
} | ||
|
||
return Command.create( | ||
`Rename ${original} to ${fixed}`, | ||
'aurelia-attribute-invalid-case', | ||
document.uri, | ||
document.version, | ||
[ | ||
TextEdit.replace(diagnostic.range, fixed) | ||
]); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
src/server/CodeActions/OneWayBindingDeprecatedCodeAction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { Diagnostic, TextEdit, Command, TextDocument } from "vscode-languageserver-types"; | ||
|
||
export class OneWayBindingDeprecatedCodeAction { | ||
public name = 'aurelia-binding-one-way-deprecated'; | ||
|
||
public async commands(diagnostic: Diagnostic, document: TextDocument): Promise<Command> { | ||
|
||
return Command.create( | ||
`Change 'one-way' binding behaviour to 'to-view'`, | ||
'aurelia-binding-one-way-deprecated', | ||
document.uri, | ||
document.version, | ||
[ | ||
TextEdit.replace(diagnostic.range, 'to-view') | ||
]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { AttributeMap } from 'aurelia-templating-binding'; | ||
import {AttributeDefinition, TagDefinition } from './../../server/DocumentParser'; | ||
|
||
export function attributeInvalidCaseFix(name: string, elementName: string) { | ||
|
||
// TODO: find a way to detect if this element is a svg element | ||
const attributeMap = new AttributeMap({ | ||
isStandardSvgAttribute: () => false | ||
}); | ||
|
||
let fixed; | ||
const auElement = attributeMap.elements[elementName]; | ||
|
||
// only replace dashes in non data-* and aria-* attributes | ||
let lookupProperty = name.toLowerCase(); | ||
if (/^(?!(data|aria)-).*$/g.test(lookupProperty)) { | ||
lookupProperty = lookupProperty.replace('-',''); | ||
} | ||
|
||
if (auElement && lookupProperty in auElement) { | ||
fixed = auElement[lookupProperty]; | ||
} | ||
else if (lookupProperty in attributeMap.allElements) { | ||
fixed = attributeMap.allElements[lookupProperty]; | ||
} | ||
else { | ||
fixed = name.split(/(?=[A-Z])/).map(s => s.toLowerCase()).join('-'); | ||
} | ||
|
||
return fixed; | ||
} |
Oops, something went wrong.