Skip to content

Commit 1150480

Browse files
author
Mikhail Arkhipov
authored
#34, #110 - suppress Intellisense in strings and comments (#339)
* Basic tokenizer * Fixed property names * Tests, round I * Tests, round II * tokenizer test * Remove temorary change * Fix merge issue * Merge conflict * Merge conflict * Completion test * Fix last line * Fix javascript math * Make test await for results * Add license headers * Rename definitions to types * License headers
1 parent 7efb558 commit 1150480

17 files changed

+985
-1027
lines changed

package-lock.json

Lines changed: 100 additions & 1007 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,7 @@
15391539
"semver": "^5.4.1",
15401540
"tmp": "0.0.29",
15411541
"tree-kill": "^1.1.0",
1542+
"typescript-char": "^0.0.0",
15421543
"uint64be": "^1.0.1",
15431544
"untildify": "^3.0.2",
15441545
"vscode-debugadapter": "^1.0.1",

src/client/common/helpers.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const tmp = require('tmp');
22

33
export function isNotInstalledError(error: Error): boolean {
44
const isError = typeof (error) === 'object' && error !== null;
5+
// tslint:disable-next-line:no-any
56
const errorObj = <any>error;
67
if (!isError) {
78
return false;
@@ -11,20 +12,23 @@ export function isNotInstalledError(error: Error): boolean {
1112
}
1213

1314
export interface Deferred<T> {
14-
resolve(value?: T | PromiseLike<T>);
15-
reject(reason?: any);
1615
readonly promise: Promise<T>;
1716
readonly resolved: boolean;
1817
readonly rejected: boolean;
1918
readonly completed: boolean;
19+
resolve(value?: T | PromiseLike<T>);
20+
// tslint:disable-next-line:no-any
21+
reject(reason?: any);
2022
}
2123

2224
class DeferredImpl<T> implements Deferred<T> {
2325
private _resolve: (value?: T | PromiseLike<T>) => void;
26+
// tslint:disable-next-line:no-any
2427
private _reject: (reason?: any) => void;
2528
private _resolved: boolean = false;
2629
private _rejected: boolean = false;
2730
private _promise: Promise<T>;
31+
// tslint:disable-next-line:no-any
2832
constructor(private scope: any = null) {
2933
// tslint:disable-next-line:promise-must-complete
3034
this._promise = new Promise<T>((res, rej) => {
@@ -36,6 +40,7 @@ class DeferredImpl<T> implements Deferred<T> {
3640
this._resolve.apply(this.scope ? this.scope : this, arguments);
3741
this._resolved = true;
3842
}
43+
// tslint:disable-next-line:no-any
3944
reject(reason?: any) {
4045
this._reject.apply(this.scope ? this.scope : this, arguments);
4146
this._rejected = true;
@@ -53,12 +58,14 @@ class DeferredImpl<T> implements Deferred<T> {
5358
return this._rejected || this._resolved;
5459
}
5560
}
56-
export function createDeferred<T>(scope: any = null): Deferred<T> {
61+
// tslint:disable-next-line:no-any
62+
export function createDeferred<T>(scope: any = null): Deferred<T> {
5763
return new DeferredImpl<T>(scope);
5864
}
5965

6066
export function createTemporaryFile(extension: string, temporaryDirectory?: string): Promise<{ filePath: string, cleanupCallback: Function }> {
61-
let options: any = { postfix: extension };
67+
// tslint:disable-next-line:no-any
68+
const options: any = { postfix: extension };
6269
if (temporaryDirectory) {
6370
options.dir = temporaryDirectory;
6471
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
5+
// tslint:disable-next-line:import-name
6+
import Char from 'typescript-char';
7+
import { TextIterator } from './textIterator';
8+
import { ICharacterStream, ITextIterator } from './types';
9+
10+
export class CharacterStream implements ICharacterStream {
11+
private text: ITextIterator;
12+
private _position: number;
13+
private _currentChar: number;
14+
private _isEndOfStream: boolean;
15+
16+
constructor(text: string | ITextIterator) {
17+
this.text = typeof text === 'string' ? new TextIterator(text) : text;
18+
this._position = 0;
19+
this._currentChar = text.length > 0 ? text.charCodeAt(0) : 0;
20+
this._isEndOfStream = text.length === 0;
21+
}
22+
23+
public getText(): string {
24+
return this.text.getText();
25+
}
26+
27+
public get position(): number {
28+
return this._position;
29+
}
30+
31+
public set position(value: number) {
32+
this._position = value;
33+
this.checkBounds();
34+
}
35+
36+
public get currentChar(): number {
37+
return this._currentChar;
38+
}
39+
40+
public get nextChar(): number {
41+
return this.position + 1 < this.text.length ? this.text.charCodeAt(this.position + 1) : 0;
42+
}
43+
44+
public get prevChar(): number {
45+
return this.position - 1 >= 0 ? this.text.charCodeAt(this.position - 1) : 0;
46+
}
47+
48+
public isEndOfStream(): boolean {
49+
return this._isEndOfStream;
50+
}
51+
52+
public lookAhead(offset: number): number {
53+
const pos = this._position + offset;
54+
return pos < 0 || pos >= this.text.length ? 0 : this.text.charCodeAt(pos);
55+
}
56+
57+
public advance(offset: number) {
58+
this.position += offset;
59+
}
60+
61+
public moveNext(): boolean {
62+
if (this._position < this.text.length - 1) {
63+
// Most common case, no need to check bounds extensively
64+
this._position += 1;
65+
this._currentChar = this.text.charCodeAt(this._position);
66+
return true;
67+
}
68+
this.advance(1);
69+
return !this.isEndOfStream();
70+
}
71+
72+
public isAtWhiteSpace(): boolean {
73+
return this.currentChar <= Char.Space || this.currentChar === 0x200B; // Unicode whitespace
74+
}
75+
76+
public isAtLineBreak(): boolean {
77+
return this.currentChar === Char.CarriageReturn || this.currentChar === Char.LineFeed;
78+
}
79+
80+
public skipLineBreak(): void {
81+
if (this._currentChar === Char.CarriageReturn) {
82+
this.moveNext();
83+
if (this.currentChar === Char.LineFeed) {
84+
this.moveNext();
85+
}
86+
} else if (this._currentChar === Char.LineFeed) {
87+
this.moveNext();
88+
}
89+
}
90+
91+
public skipWhitespace(): void {
92+
while (!this.isEndOfStream() && this.isAtWhiteSpace()) {
93+
this.moveNext();
94+
}
95+
}
96+
97+
public skipToEol(): void {
98+
while (!this.isEndOfStream() && !this.isAtLineBreak()) {
99+
this.moveNext();
100+
}
101+
}
102+
103+
public skipToWhitespace(): void {
104+
while (!this.isEndOfStream() && !this.isAtWhiteSpace()) {
105+
this.moveNext();
106+
}
107+
}
108+
109+
public isAtString(): boolean {
110+
return this.currentChar === Char.SingleQuote || this.currentChar === Char.DoubleQuote;
111+
}
112+
113+
public charCodeAt(index: number): number {
114+
return this.text.charCodeAt(index);
115+
}
116+
117+
public get length(): number {
118+
return this.text.length;
119+
}
120+
121+
private checkBounds(): void {
122+
if (this._position < 0) {
123+
this._position = 0;
124+
}
125+
126+
this._isEndOfStream = this._position >= this.text.length;
127+
if (this._isEndOfStream) {
128+
this._position = this.text.length;
129+
}
130+
131+
this._currentChar = this._isEndOfStream ? 0 : this.text.charCodeAt(this._position);
132+
}
133+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
5+
import { Position, Range, TextDocument } from 'vscode';
6+
import { ITextIterator } from './types';
7+
8+
export class TextIterator implements ITextIterator {
9+
private text: string;
10+
11+
constructor(text: string) {
12+
this.text = text;
13+
}
14+
15+
public charCodeAt(index: number): number {
16+
if (index >= 0 && index < this.text.length) {
17+
return this.text.charCodeAt(index);
18+
}
19+
return 0;
20+
}
21+
22+
public get length(): number {
23+
return this.text.length;
24+
}
25+
26+
public getText(): string {
27+
return this.text;
28+
}
29+
}
30+
31+
export class DocumentTextIterator implements ITextIterator {
32+
public readonly length: number;
33+
34+
private document: TextDocument;
35+
36+
constructor(document: TextDocument) {
37+
this.document = document;
38+
39+
const lastIndex = this.document.lineCount - 1;
40+
const lastLine = this.document.lineAt(lastIndex);
41+
const end = new Position(lastIndex, lastLine.range.end.character);
42+
this.length = this.document.offsetAt(end);
43+
}
44+
45+
public charCodeAt(index: number): number {
46+
const position = this.document.positionAt(index);
47+
return this.document
48+
.getText(new Range(position, position.translate(0, 1)))
49+
.charCodeAt(position.character);
50+
}
51+
52+
public getText(): string {
53+
return this.document.getText();
54+
}
55+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
5+
import { ITextRange, ITextRangeCollection } from './types';
6+
7+
export class TextRangeCollection<T extends ITextRange> implements ITextRangeCollection<T> {
8+
private items: T[];
9+
10+
constructor(items: T[]) {
11+
this.items = items;
12+
}
13+
14+
public get start(): number {
15+
return this.items.length > 0 ? this.items[0].start : 0;
16+
}
17+
18+
public get end(): number {
19+
return this.items.length > 0 ? this.items[this.items.length - 1].end : 0;
20+
}
21+
22+
public get length(): number {
23+
return this.end - this.start;
24+
}
25+
26+
public get count(): number {
27+
return this.items.length;
28+
}
29+
30+
public contains(position: number) {
31+
return position >= this.start && position < this.end;
32+
}
33+
34+
public getItemAt(index: number): T {
35+
if (index < 0 || index >= this.items.length) {
36+
throw new Error('index is out of range');
37+
}
38+
return this.items[index] as T;
39+
}
40+
41+
public getItemAtPosition(position: number): number {
42+
if (this.count === 0) {
43+
return -1;
44+
}
45+
if (position < this.start) {
46+
return -1;
47+
}
48+
if (position >= this.end) {
49+
return -1;
50+
}
51+
52+
let min = 0;
53+
let max = this.count - 1;
54+
55+
while (min <= max) {
56+
const mid = Math.floor(min + (max - min) / 2);
57+
const item = this.items[mid];
58+
59+
if (item.start === position) {
60+
return mid;
61+
}
62+
63+
if (position < item.start) {
64+
max = mid - 1;
65+
} else {
66+
min = mid + 1;
67+
}
68+
}
69+
return -1;
70+
}
71+
72+
public getItemContaining(position: number): number {
73+
if (this.count === 0) {
74+
return -1;
75+
}
76+
if (position < this.start) {
77+
return -1;
78+
}
79+
if (position > this.end) {
80+
return -1;
81+
}
82+
83+
let min = 0;
84+
let max = this.count - 1;
85+
86+
while (min <= max) {
87+
const mid = Math.floor(min + (max - min) / 2);
88+
const item = this.items[mid];
89+
90+
if (item.contains(position)) {
91+
return mid;
92+
}
93+
if (mid < this.count - 1 && item.end <= position && position < this.items[mid + 1].start) {
94+
return -1;
95+
}
96+
97+
if (position < item.start) {
98+
max = mid - 1;
99+
} else {
100+
min = mid + 1;
101+
}
102+
}
103+
return -1;
104+
}
105+
}

0 commit comments

Comments
 (0)