Skip to content

Commit 002b757

Browse files
committed
some fixes
1 parent 7f71dfe commit 002b757

File tree

3 files changed

+87
-76
lines changed

3 files changed

+87
-76
lines changed

Diff for: providers/ObjectScriptDefinitionProvider.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,21 @@ export class ObjectScriptDefinitionProvider implements vscode.DefinitionProvider
1818
return fromClassRef;
1919
}
2020

21-
let selfRef = document.getWordRangeAtPosition(position, /\.\.%?[a-zA-Z][a-zA-Z0-9]+(?:\.[a-zA-Z][a-zA-Z0-9]+)*/);
21+
let selfRef = document.getWordRangeAtPosition(position, /\.\.#?%?[a-zA-Z][a-zA-Z0-9]+(?:\.[a-zA-Z][a-zA-Z0-9]+)*/);
2222
if (selfRef) {
2323
let selfEntity = document.getText(selfRef).substr(2);
24+
let range = new vscode.Range(position.line, selfRef.start.character + 2, position.line, selfRef.end.character);
2425
let classDefinition = new ClassDefinition(file.name);
25-
return classDefinition.getPosition(selfEntity, document);
26+
return classDefinition.getMemberLocations(selfEntity).then(
27+
(locations): vscode.DefinitionLink[] =>
28+
locations.map(
29+
(location): vscode.DefinitionLink => ({
30+
originSelectionRange: range,
31+
targetUri: location.uri,
32+
targetRange: location.range
33+
})
34+
)
35+
);
2636
}
2737

2838
let macroRange = document.getWordRangeAtPosition(position);
@@ -117,7 +127,7 @@ export class ObjectScriptDefinitionProvider implements vscode.DefinitionProvider
117127
];
118128
} else {
119129
let classDefinition = new ClassDefinition(className);
120-
return classDefinition.getPosition(entity);
130+
return classDefinition.getMemberLocations(entity);
121131
}
122132
}
123133

Diff for: providers/WorkspaceSymbolProvider.ts

+43-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as vscode from 'vscode';
22
import { AtelierAPI } from '../api';
3-
import { DocumentContentProvider } from './DocumentContentProvider';
43
import { ClassDefinition } from '../utils/classDefinition';
54

65
export class WorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
@@ -11,41 +10,53 @@ export class WorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
1110
if (query.length < 3) {
1211
return null;
1312
}
13+
return Promise.all([this.byClasses(query), this.byMethods(query)]).then(([classes, methods]) => [
14+
...classes,
15+
...methods
16+
]);
17+
}
18+
19+
async byClasses(query: string): Promise<vscode.SymbolInformation[]> {
1420
query = query.toUpperCase();
1521
query = `*${query}*`;
1622
let library = query.replace(/%(\b\w+\b(?!\.))/, '%LIBRARY.$1');
1723
let sql = `
18-
SELECT TOP 10 ID FROM %Dictionary.ClassDefinition WHERE %SQLUPPER Name %MATCHES ? OR %SQLUPPER Name %MATCHES ?
19-
UNION
20-
SELECT TOP 10 ID FROM %Dictionary.MethodDefinition WHERE %SQLUPPER Name %MATCHES ?
21-
`;
24+
SELECT TOP 10 Name ClassName FROM %Dictionary.ClassDefinition WHERE %SQLUPPER Name %MATCHES ? OR %SQLUPPER Name %MATCHES ?`;
25+
let api = new AtelierAPI();
26+
const data = await api.actionQuery(sql, [library, query]);
27+
return data.result.content.map(({ ClassName }) => ({
28+
name: ClassName,
29+
kind: vscode.SymbolKind.Class,
30+
location: {
31+
uri: new ClassDefinition(ClassName).uri
32+
}
33+
}));
34+
}
35+
36+
async byMethods(query: string): Promise<vscode.SymbolInformation[]> {
37+
query = query.toUpperCase();
38+
query = `*${query}*`;
39+
const getLocation = async (className, name) => {
40+
let classDef = new ClassDefinition(className);
41+
return classDef.getMemberLocation(name);
42+
};
43+
let sql = `
44+
SELECT TOP 10 Parent ClassName, Name FROM %Dictionary.MethodDefinition WHERE %SQLUPPER Name %MATCHES ?`;
2245
let api = new AtelierAPI();
23-
return api.actionQuery(sql, [library, query, query]).then(data => {
24-
let result = data.result.content;
25-
return result.map(el => {
26-
let item;
27-
let [className, method] = el.ID.split('||');
28-
let uri = DocumentContentProvider.getUri(ClassDefinition.normalizeClassName(className, true));
29-
if (method) {
30-
item = {
31-
name: method,
32-
container: className,
33-
kind: vscode.SymbolKind.Method,
34-
location: {
35-
uri
36-
}
37-
};
38-
} else {
39-
item = {
40-
name: el.ID,
41-
kind: vscode.SymbolKind.Class,
42-
location: {
43-
uri
44-
}
45-
};
46-
}
47-
return item;
48-
});
49-
});
46+
return api
47+
.actionQuery(sql, [query])
48+
.then(
49+
(data): Promise<vscode.SymbolInformation>[] =>
50+
data.result.content.map(
51+
async ({ ClassName, Name }): Promise<vscode.SymbolInformation> =>
52+
new vscode.SymbolInformation(
53+
Name,
54+
vscode.SymbolKind.Method,
55+
ClassName,
56+
await getLocation(ClassName, Name)
57+
)
58+
)
59+
)
60+
.then(data => Promise.all(data));
5061
}
5162
}

Diff for: utils/classDefinition.ts

+31-41
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { workspaceState } from '../extension';
77
export class ClassDefinition {
88
private _className: string;
99
private _classFileName: string;
10+
1011
public static normalizeClassName(className, withExtension = false): string {
1112
return className.replace(/^%(\b\w+\b)$/, '%Library.$1') + (withExtension ? '.cls' : '');
1213
}
@@ -19,6 +20,14 @@ export class ClassDefinition {
1920
this._classFileName = ClassDefinition.normalizeClassName(className, true);
2021
}
2122

23+
get uri(): vscode.Uri {
24+
return DocumentContentProvider.getUri(this._classFileName);
25+
}
26+
27+
async getDocument(): Promise<vscode.TextDocument> {
28+
return vscode.workspace.openTextDocument(this.uri);
29+
}
30+
2231
store(kind: string, data: any): any {
2332
workspaceState.update(`${this._classFileName}|${kind}`, data);
2433
return data;
@@ -106,11 +115,13 @@ export class ClassDefinition {
106115
.actionQuery(sql, [this._className])
107116
.then(
108117
data =>
109-
data.result.content.reduce(
110-
(list: string[], el: { PrimarySuper: string }) =>
111-
list.concat(el.PrimarySuper.split('~').filter(el => el.length)),
112-
[]
113-
)
118+
data.result.content
119+
.reduce(
120+
(list: string[], el: { PrimarySuper: string }) =>
121+
list.concat(el.PrimarySuper.split('~').filter(el => el.length)),
122+
[]
123+
)
124+
.filter((name: string) => name !== this._className)
114125
// .filter(name => !['%Library.Base', '%Library.SystemBase'].includes(name))
115126
)
116127
.then(data => this.store('super', data));
@@ -136,53 +147,32 @@ export class ClassDefinition {
136147
.then(data => this.store('includeCode', data));
137148
}
138149

139-
async getPosition(name: string, document?: vscode.TextDocument): Promise<vscode.Location[]> {
150+
async getMemberLocation(name: string): Promise<vscode.Location> {
140151
let pattern;
141152
if (name.startsWith('#')) {
142153
pattern = `(Parameter) ${name.substr(1)}(?!\w)`;
143154
} else {
144155
pattern = `((Class)?Method|Property|RelationShip) ${name}(?!\w)`;
145156
}
146-
let foundLine;
147-
if (document) {
157+
return this.getDocument().then(document => {
148158
for (let i = 0; i < document.lineCount; i++) {
149159
let line = document.lineAt(i);
150160
if (line.text.match(pattern)) {
151-
foundLine = i;
152-
break;
161+
return new vscode.Location(this.uri, new vscode.Position(i, 0));
153162
}
154163
}
155-
}
156-
let result: vscode.Location[] = [];
157-
if (foundLine) {
158-
result.push({
159-
uri: DocumentContentProvider.getUri(this._classFileName),
160-
range: new vscode.Range(foundLine, 0, foundLine, 0)
161-
});
162-
}
163-
let extendList = await this.super();
164-
let api = new AtelierAPI();
165-
let docs = [];
166-
extendList.forEach(async docName => {
167-
docName = ClassDefinition.normalizeClassName(docName, true);
168-
docs.push(api.getDoc(docName));
169-
});
170-
return Promise.all(docs).then((docs: any[]) => {
171-
for (let doc of docs) {
172-
if (doc && doc.result.content) {
173-
let docName = doc.result.name;
174-
let content = doc.result.content;
175-
for (let line of content.keys()) {
176-
if (content[line].match(pattern)) {
177-
result.push({
178-
uri: DocumentContentProvider.getUri(docName),
179-
range: new vscode.Range(line, 0, line, 0)
180-
});
181-
}
182-
}
183-
}
184-
}
185-
return result;
164+
return;
186165
});
187166
}
167+
168+
async getMemberLocations(name: string): Promise<vscode.Location[]> {
169+
let extendList = await this.super();
170+
return Promise.all([
171+
await this.getMemberLocation(name),
172+
...extendList.map(async docName => {
173+
let classDef = new ClassDefinition(docName);
174+
return classDef.getMemberLocation(name);
175+
})
176+
]).then(data => data.filter(el => el != null));
177+
}
188178
}

0 commit comments

Comments
 (0)