Skip to content

Commit b70e8a2

Browse files
author
Mikhail Arkhipov
authored
* Fix pylint search * Handle quote escapes in strings * Escapes in strings * CR feedback * Missing pip * Test * Tests * Tests * Mac python path * Tests * Tests * Test * "Go To Python object" doesn't work * Proper detection and type population in virtual env * Test fixes * Simplify venv check * Remove duplicates * Test * Discover pylintrc better + tests * Undo change * CR feedback * Set interprereter before checking install * Fix typo and path compare on Windows * Rename method * #815 - 'F' in flake8 means warning * 730 - same folder temp * Properly resolve ~ * Test * Test * Fix dot spacing * Remove banner * Delete banner code
1 parent a5fd614 commit b70e8a2

File tree

9 files changed

+100
-74
lines changed

9 files changed

+100
-74
lines changed

src/client/banner.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/client/common/installer/pythonInstallation.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@ export class PythonInstaller {
3535
return true;
3636
}
3737

38-
await this.shell.showErrorMessage('Python is not installed. Please download and install Python before using the extension.');
39-
this.shell.openUrl('https://www.python.org/downloads');
38+
const download = 'Download';
39+
if (await this.shell.showErrorMessage('Python is not installed. Please download and install Python before using the extension.', download) === download) {
40+
this.shell.openUrl('https://www.python.org/downloads');
41+
}
4042
return false;
4143
}
4244
}

src/client/extension.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ if ((Reflect as any).metadata === undefined) {
88
import { Container } from 'inversify';
99
import * as vscode from 'vscode';
1010
import { Disposable, Memento, OutputChannel, window } from 'vscode';
11-
import { BannerService } from './banner';
1211
import { PythonSettings } from './common/configSettings';
1312
import * as settings from './common/configSettings';
1413
import { STANDARD_OUTPUT_CHANNEL } from './common/constants';
@@ -183,9 +182,6 @@ export async function activate(context: vscode.ExtensionContext) {
183182
});
184183
activationDeferred.resolve();
185184

186-
// tslint:disable-next-line:no-unused-expression
187-
new BannerService(persistentStateFactory);
188-
189185
const deprecationMgr = new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtension);
190186
deprecationMgr.initialize();
191187
context.subscriptions.push(new FeatureDeprecationManager(persistentStateFactory, !!jupyterExtension));

src/client/formatters/lineFormatter.ts

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export class LineFormatter {
4848
break;
4949

5050
case TokenType.Identifier:
51-
if (!prev || (!this.isOpenBraceType(prev.type) && prev.type !== TokenType.Colon)) {
51+
if (prev && !this.isOpenBraceType(prev.type) && prev.type !== TokenType.Colon && prev.type !== TokenType.Operator) {
5252
this.builder.softAppendSpace();
5353
}
5454
this.builder.append(this.text.substring(t.start, t.end));
@@ -81,24 +81,44 @@ export class LineFormatter {
8181

8282
private handleOperator(index: number): void {
8383
const t = this.tokens.getItemAt(index);
84-
if (index >= 2 && t.length === 1 && this.text.charCodeAt(t.start) === Char.Equal) {
85-
if (this.braceCounter.isOpened(TokenType.OpenBrace)) {
86-
// Check if this is = in function arguments. If so, do not
87-
// add spaces around it.
88-
const prev = this.tokens.getItemAt(index - 1);
89-
const prevPrev = this.tokens.getItemAt(index - 2);
90-
if (prev.type === TokenType.Identifier &&
91-
(prevPrev.type === TokenType.Comma || prevPrev.type === TokenType.OpenBrace)) {
92-
this.builder.append('=');
84+
if (t.length === 1) {
85+
const opCode = this.text.charCodeAt(t.start);
86+
switch (opCode) {
87+
case Char.Equal:
88+
if (index >= 2 && this.handleEqual(t, index)) {
89+
return;
90+
}
91+
break;
92+
case Char.Period:
93+
this.builder.append('.');
94+
return;
95+
case Char.At:
96+
this.builder.append('@');
9397
return;
94-
}
98+
default:
99+
break;
95100
}
96101
}
97102
this.builder.softAppendSpace();
98103
this.builder.append(this.text.substring(t.start, t.end));
99104
this.builder.softAppendSpace();
100105
}
101106

107+
private handleEqual(t: IToken, index: number): boolean {
108+
if (this.braceCounter.isOpened(TokenType.OpenBrace)) {
109+
// Check if this is = in function arguments. If so, do not
110+
// add spaces around it.
111+
const prev = this.tokens.getItemAt(index - 1);
112+
const prevPrev = this.tokens.getItemAt(index - 2);
113+
if (prev.type === TokenType.Identifier &&
114+
(prevPrev.type === TokenType.Comma || prevPrev.type === TokenType.OpenBrace)) {
115+
this.builder.append('=');
116+
return true;
117+
}
118+
}
119+
return false;
120+
}
121+
102122
private handleOther(t: IToken): void {
103123
if (this.isBraceType(t.type)) {
104124
this.braceCounter.countBrace(t);

src/client/language/tokenizer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ export class Tokenizer implements ITokenizer {
127127
case Char.Colon:
128128
this.tokens.push(new Token(TokenType.Colon, this.cs.position, 1));
129129
break;
130-
case Char.Period:
131130
case Char.At:
132-
this.tokens.push(new Token(TokenType.Unknown, this.cs.position, 1));
131+
case Char.Period:
132+
this.tokens.push(new Token(TokenType.Operator, this.cs.position, 1));
133133
break;
134134
default:
135135
if (this.isPossibleNumber()) {

src/test/format/extension.onEnterFormat.test.ts

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,47 +12,64 @@ const unformattedFile = path.join(formatFilesPath, 'fileToFormatOnEnter.py');
1212

1313
suite('Formatting - OnEnter provider', () => {
1414
let document: vscode.TextDocument;
15+
let editor: vscode.TextEditor;
1516

1617
suiteSetup(initialize);
1718
setup(async () => {
1819
document = await vscode.workspace.openTextDocument(unformattedFile);
19-
await vscode.window.showTextDocument(document);
20+
editor = await vscode.window.showTextDocument(document);
2021
});
2122
suiteTeardown(closeActiveWindows);
2223
teardown(closeActiveWindows);
2324

24-
test('Regular string', async () => {
25-
const edits = await formatAtPosition(1, 0);
26-
assert.notEqual(edits!.length, 0, 'Line was not formatted');
25+
test('Simple statement', async () => {
26+
const text = await formatAtPosition(1, 0);
27+
assert.equal(text, 'x = 1', 'Line was not formatted');
2728
});
2829

2930
test('No formatting inside strings', async () => {
30-
const edits = await formatAtPosition(2, 0);
31-
assert.equal(edits!.length, 0, 'Text inside string was formatted');
31+
let text = await formatAtPosition(2, 0);
32+
assert.equal(text, '"""x=1', 'Text inside string was formatted');
33+
text = await formatAtPosition(3, 0);
34+
assert.equal(text, '"""', 'Text inside string was formatted');
3235
});
3336

3437
test('Whitespace before comment', async () => {
35-
const edits = await formatAtPosition(4, 0);
36-
assert.equal(edits!.length, 0, 'Whitespace before comment was formatted');
38+
const text = await formatAtPosition(4, 0);
39+
assert.equal(text, ' # comment', 'Whitespace before comment was not preserved');
3740
});
3841

3942
test('No formatting of comment', async () => {
40-
const edits = await formatAtPosition(5, 0);
41-
assert.equal(edits!.length, 0, 'Text inside comment was formatted');
43+
const text = await formatAtPosition(5, 0);
44+
assert.equal(text, '# x=1', 'Text inside comment was formatted');
4245
});
4346

4447
test('Formatting line ending in comment', async () => {
45-
const edits = await formatAtPosition(6, 0);
46-
assert.notEqual(edits!.length, 0, 'Line ending in comment was not formatted');
48+
const text = await formatAtPosition(6, 0);
49+
assert.equal(text, 'x + 1 # ', 'Line ending in comment was not formatted');
50+
});
51+
52+
test('Formatting line with @', async () => {
53+
const text = await formatAtPosition(7, 0);
54+
assert.equal(text, '@x', 'Line with @ was reformatted');
55+
});
56+
57+
test('Formatting line with @', async () => {
58+
const text = await formatAtPosition(8, 0);
59+
assert.equal(text, 'x.y', 'Line ending with period was reformatted');
4760
});
4861

4962
test('Formatting line ending in string', async () => {
50-
const edits = await formatAtPosition(7, 0);
51-
assert.notEqual(edits!.length, 0, 'Line ending in multilint string was not formatted');
63+
const text = await formatAtPosition(9, 0);
64+
assert.equal(text, 'x + """', 'Line ending in multiline string was not formatted');
5265
});
5366

54-
async function formatAtPosition(line: number, character: number): Promise<vscode.TextEdit[] | undefined> {
55-
return await vscode.commands.executeCommand<vscode.TextEdit[]>('vscode.executeFormatOnTypeProvider',
67+
async function formatAtPosition(line: number, character: number): Promise<string> {
68+
const edits = await vscode.commands.executeCommand<vscode.TextEdit[]>('vscode.executeFormatOnTypeProvider',
5669
document.uri, new vscode.Position(line, character), '\n', { insertSpaces: true, tabSize: 2 });
70+
if (edits) {
71+
await editor.edit(builder => edits.forEach(e => builder.replace(e.range, e.newText)));
72+
}
73+
return document.lineAt(line - 1).text;
5774
}
5875
});

src/test/install/pythonInstallation.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ suite('Installation', () => {
8181
let openUrlCalled = false;
8282
let url;
8383

84-
c.appShell.setup(x => x.showErrorMessage(TypeMoq.It.isAnyString())).callback(() => showErrorMessageCalled = true);
84+
const download = 'Download';
85+
c.appShell
86+
.setup(x => x.showErrorMessage(TypeMoq.It.isAnyString(), download))
87+
.callback(() => showErrorMessageCalled = true)
88+
.returns(() => Promise.resolve(download));
8589
c.appShell.setup(x => x.openUrl(TypeMoq.It.isAnyString())).callback((s: string) => {
8690
openUrlCalled = true;
8791
url = s;
@@ -93,6 +97,17 @@ suite('Installation', () => {
9397
assert.equal(showErrorMessageCalled, true, 'Error message not shown');
9498
assert.equal(openUrlCalled, true, 'Python download page not opened');
9599
assert.equal(url, 'https://www.python.org/downloads', 'Python download page is incorrect');
100+
101+
showErrorMessageCalled = false;
102+
openUrlCalled = false;
103+
c.appShell
104+
.setup(x => x.showErrorMessage(TypeMoq.It.isAnyString(), download))
105+
.callback(() => showErrorMessageCalled = true)
106+
.returns(() => Promise.resolve(''));
107+
108+
await c.pythonInstaller.checkPythonInstallation(c.settings.object);
109+
assert.equal(showErrorMessageCalled, true, 'Error message not shown');
110+
assert.equal(openUrlCalled, false, 'Python download page was opened');
96111
});
97112

98113
test('Mac: Default Python warning', async () => {

src/test/language/tokenizer.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,23 @@ suite('Language.Tokenizer', () => {
9191
assert.equal(tokens.getItemAt(i).type, TokenType.Comment);
9292
}
9393
});
94-
test('Period/At to unknown token', async () => {
94+
test('Period to operator token', async () => {
9595
const t = new Tokenizer();
96-
const tokens = t.tokenize('.@x');
96+
const tokens = t.tokenize('x.y');
9797
assert.equal(tokens.count, 3);
9898

99-
assert.equal(tokens.getItemAt(0).type, TokenType.Unknown);
100-
assert.equal(tokens.getItemAt(1).type, TokenType.Unknown);
99+
assert.equal(tokens.getItemAt(0).type, TokenType.Identifier);
100+
assert.equal(tokens.getItemAt(1).type, TokenType.Operator);
101101
assert.equal(tokens.getItemAt(2).type, TokenType.Identifier);
102102
});
103+
test('@ to operator token', async () => {
104+
const t = new Tokenizer();
105+
const tokens = t.tokenize('@x');
106+
assert.equal(tokens.count, 2);
107+
108+
assert.equal(tokens.getItemAt(0).type, TokenType.Operator);
109+
assert.equal(tokens.getItemAt(1).type, TokenType.Identifier);
110+
});
103111
test('Unknown token', async () => {
104112
const t = new Tokenizer();
105113
const tokens = t.tokenize('~$');

src/test/pythonFiles/formatting/fileToFormatOnEnter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@
44
# comment
55
# x=1
66
x+1 #
7+
@x
8+
x.y
79
x+"""

0 commit comments

Comments
 (0)