Skip to content

Commit 334bca8

Browse files
committed
feat(workspace): Compatible with the workspace utils class of Vscode
1 parent 990ab74 commit 334bca8

File tree

8 files changed

+867
-0
lines changed

8 files changed

+867
-0
lines changed

src/edit/location.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/* ---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import { Location as ILocation } from 'vscode-languageserver-protocol'
6+
import { URI } from 'vscode-uri'
7+
import { Position } from './position'
8+
import { Range } from './range'
9+
10+
export class Location implements ILocation {
11+
public static isLocation(thing: any): thing is ILocation {
12+
if (thing instanceof Location) {
13+
return true
14+
}
15+
if (!thing) {
16+
return false
17+
}
18+
return Range.isRange((thing as Location).range)
19+
&& URI.isUri((thing as Location).uri)
20+
}
21+
22+
/**
23+
* Creates a Location literal.
24+
*
25+
* @param uri The location's uri.
26+
* @param range The location's range.
27+
* @deprecated use `new Location(uri, range)` instead.
28+
*/
29+
public static create(uri: string, range: Range): Location {
30+
return new Location(uri, range)
31+
}
32+
/**
33+
* Checks whether the given literal conforms to the [Location](#Location) interface.
34+
*
35+
* @deprecated Use the `Location.isLocation` instead.
36+
*/
37+
public static is(value: any): value is ILocation {
38+
return ILocation.is(value)
39+
}
40+
41+
public uri: string
42+
public range!: Range
43+
44+
constructor(uri: string, rangeOrPosition: Range | Position) {
45+
this.uri = uri
46+
47+
if (!rangeOrPosition) {
48+
// that's OK
49+
} else if (Range.isRange(rangeOrPosition)) {
50+
this.range = Range.of(rangeOrPosition)
51+
} else if (Position.isPosition(rangeOrPosition)) {
52+
this.range = new Range(rangeOrPosition, rangeOrPosition)
53+
} else {
54+
throw new Error('Illegal argument')
55+
}
56+
}
57+
58+
public toJSON(): any {
59+
return {
60+
uri: this.uri,
61+
range: this.range
62+
}
63+
}
64+
}

src/edit/position.ts

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/* ---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
import { Position as IPosition } from 'vscode-languageserver-protocol'
6+
import { illegalArgument } from '../util/errors'
7+
8+
export { IPosition }
9+
10+
export class Position implements IPosition {
11+
public static Min(...positions: Position[]): Position {
12+
if (positions.length === 0) {
13+
throw new TypeError()
14+
}
15+
let result = positions[0]
16+
for (let i = 1; i < positions.length; i++) {
17+
const p = positions[i]
18+
if (p.isBefore(result!)) {
19+
result = p
20+
}
21+
}
22+
return result
23+
}
24+
25+
public static Max(...positions: Position[]): Position {
26+
if (positions.length === 0) {
27+
throw new TypeError()
28+
}
29+
let result = positions[0]
30+
for (let i = 1; i < positions.length; i++) {
31+
const p = positions[i]
32+
if (p.isAfter(result!)) {
33+
result = p
34+
}
35+
}
36+
return result
37+
}
38+
39+
public static isPosition(other: any): other is Position {
40+
if (!other) {
41+
return false
42+
}
43+
if (other instanceof Position) {
44+
return true
45+
}
46+
let { line, character } = other as Position
47+
if (typeof line === 'number' && typeof character === 'number') {
48+
return true
49+
}
50+
return false
51+
}
52+
53+
public static of(obj: IPosition): Position {
54+
if (obj instanceof Position) {
55+
return obj
56+
} else if (this.isPosition(obj)) {
57+
return new Position(obj.line, obj.character)
58+
}
59+
throw new Error('Invalid argument, is NOT a position-like object')
60+
}
61+
62+
private _line: number
63+
private _character: number
64+
65+
public get line(): number {
66+
return this._line
67+
}
68+
69+
public get character(): number {
70+
return this._character
71+
}
72+
73+
constructor(line: number, character: number) {
74+
if (line < 0) {
75+
throw illegalArgument('line must be non-negative')
76+
}
77+
if (character < 0) {
78+
throw illegalArgument('character must be non-negative')
79+
}
80+
this._line = line
81+
this._character = character
82+
}
83+
84+
public isBefore(other: Position): boolean {
85+
if (this._line < other._line) {
86+
return true
87+
}
88+
if (other._line < this._line) {
89+
return false
90+
}
91+
return this._character < other._character
92+
}
93+
94+
public isBeforeOrEqual(other: Position): boolean {
95+
if (this._line < other._line) {
96+
return true
97+
}
98+
if (other._line < this._line) {
99+
return false
100+
}
101+
return this._character <= other._character
102+
}
103+
104+
public isAfter(other: Position): boolean {
105+
return !this.isBeforeOrEqual(other)
106+
}
107+
108+
public isAfterOrEqual(other: Position): boolean {
109+
return !this.isBefore(other)
110+
}
111+
112+
public isEqual(other: Position): boolean {
113+
return this._line === other._line && this._character === other._character
114+
}
115+
116+
public compareTo(other: Position): number {
117+
if (this._line < other._line) {
118+
return -1
119+
} else if (this._line > other.line) {
120+
return 1
121+
} else {
122+
// equal line
123+
if (this._character < other._character) {
124+
return -1
125+
} else if (this._character > other._character) {
126+
return 1
127+
} else {
128+
// equal line and character
129+
return 0
130+
}
131+
}
132+
}
133+
134+
public translate(change: { lineDelta?: number; characterDelta?: number }): Position
135+
public translate(lineDelta?: number, characterDelta?: number): Position
136+
public translate(lineDeltaOrChange: number | undefined | { lineDelta?: number; characterDelta?: number }, characterDelta = 0): Position {
137+
138+
if (lineDeltaOrChange === null || characterDelta === null) {
139+
throw illegalArgument()
140+
}
141+
142+
let lineDelta: number
143+
if (typeof lineDeltaOrChange === 'undefined') {
144+
lineDelta = 0
145+
} else if (typeof lineDeltaOrChange === 'number') {
146+
lineDelta = lineDeltaOrChange
147+
} else {
148+
lineDelta = typeof lineDeltaOrChange.lineDelta === 'number' ? lineDeltaOrChange.lineDelta : 0
149+
characterDelta = typeof lineDeltaOrChange.characterDelta === 'number' ? lineDeltaOrChange.characterDelta : 0
150+
}
151+
152+
if (lineDelta === 0 && characterDelta === 0) {
153+
return this
154+
}
155+
return new Position(this.line + lineDelta, this.character + characterDelta)
156+
}
157+
158+
public with(change: { line?: number; character?: number }): Position
159+
public with(line?: number, character?: number): Position
160+
public with(lineOrChange: number | undefined | { line?: number; character?: number }, character: number = this.character): Position {
161+
if (lineOrChange === null || character === null) {
162+
throw illegalArgument()
163+
}
164+
165+
let line: number
166+
if (typeof lineOrChange === 'undefined') {
167+
line = this.line
168+
169+
} else if (typeof lineOrChange === 'number') {
170+
line = lineOrChange
171+
172+
} else {
173+
line = typeof lineOrChange.line === 'number' ? lineOrChange.line : this.line
174+
character = typeof lineOrChange.character === 'number' ? lineOrChange.character : this.character
175+
}
176+
177+
if (line === this.line && character === this.character) {
178+
return this
179+
}
180+
return new Position(line, character)
181+
}
182+
183+
public toJSON(): any {
184+
return { line: this.line, character: this.character }
185+
}
186+
}

0 commit comments

Comments
 (0)