Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds goto definition for enum statements and enum members #715

Merged
merged 4 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion src/Scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { URI } from 'vscode-uri';
import { LogLevel } from './Logger';
import type { BrsFile } from './files/BrsFile';
import type { DependencyGraph, DependencyChangedEvent } from './DependencyGraph';
import { isBrsFile, isMethodStatement, isClassStatement, isConstStatement, isCustomType, isEnumStatement, isFunctionStatement, isFunctionType, isXmlFile, isNamespaceStatement } from './astUtils/reflection';
import { isBrsFile, isMethodStatement, isClassStatement, isConstStatement, isCustomType, isEnumStatement, isFunctionStatement, isFunctionType, isXmlFile, isNamespaceStatement, isEnumMemberStatement } from './astUtils/reflection';
import { SymbolTable } from './SymbolTable';
import type { Statement } from './parser/AstNode';

Expand Down Expand Up @@ -141,6 +141,31 @@ export class Scope {
return enumeration;
}

/**
* Get an Enum and its containing file by the Enum name
* @param enumMemberName - The Enum name, including the namespace of the enum if possible
* @param containingNamespace - The namespace used to resolve relative enum names. (i.e. the namespace around the current statement trying to find a enum)
*/
public getEnumMemberFileLink(enumMemberName: string, containingNamespace?: string): FileLink<EnumMemberStatement> {
let lowerNameParts = enumMemberName?.split('.');
let memberName = lowerNameParts.splice(lowerNameParts.length - 1, 1)?.[0];
let lowerName = lowerNameParts.join('.').toLowerCase();
const enumMap = this.getEnumMap();

let enumeration = enumMap.get(
util.getFullyQualifiedClassName(lowerName, containingNamespace?.toLowerCase())
);
//if we couldn't find the enum by its full namespaced name, look for a global enum with that name
if (!enumeration) {
enumeration = enumMap.get(lowerName);
}
if (enumeration) {
let member = enumeration.item.findChild<EnumMemberStatement>((child) => isEnumMemberStatement(child) && child.name === memberName);
return member ? { item: member, file: enumeration.file } : undefined;
}
return enumeration;
}

/**
* Get a constant and its containing file by the constant name
* @param constName - The constant name, including the namespace of the constant if possible
Expand Down
36 changes: 36 additions & 0 deletions src/files/BrsFile.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3389,5 +3389,41 @@ describe('BrsFile', () => {
range: util.createRange(5, 26, 5, 33)
}]);
});
it('returns enum locations', () => {
const file = program.setFile<BrsFile>('source/main.bs', `
sub main()
print alpha.beta.people.charlie
end sub
namespace alpha.beta
enum people
charlie = "charles"
end enum
end namespace
`);
program.validate();
//print alpha.beta.char|lie
expect(program.getDefinition(file.srcPath, Position.create(2, 40))).to.eql([{
uri: URI.file(file.srcPath).toString(),
range: util.createRange(5, 25, 5, 31)
}]);
});
it('returns enum member locations', () => {
const file = program.setFile<BrsFile>('source/main.bs', `
sub main()
print alpha.beta.people.charlie
end sub
namespace alpha.beta
enum people
charlie = "charles"
end enum
end namespace
`);
program.validate();
//print alpha.beta.char|lie
expect(program.getDefinition(file.srcPath, Position.create(2, 48))).to.eql([{
uri: URI.file(file.srcPath).toString(),
range: util.createRange(6, 24, 6, 31)
}]);
});
});
});
25 changes: 24 additions & 1 deletion src/files/BrsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1436,7 +1436,7 @@ export class BrsFile {

const expression = this.getClosestExpression(position);
if (expression) {
let containingNamespace = this.getNamespaceStatementForPosition(expression.range.start)?.getName(ParseMode.BrighterScript);
let containingNamespace = expression.findAncestor<NamespaceStatement>(isNamespaceStatement)?.getName(ParseMode.BrighterScript);
const fullName = util.getAllDottedGetParts(expression)?.map(x => x.text).join('.');

//find a constant with this name
Expand All @@ -1450,6 +1450,29 @@ export class BrsFile {
);
return results;
}
if (isDottedGetExpression(expression)) {

const enumLink = scope.getEnumFileLink(fullName, containingNamespace);
if (enumLink) {
results.push(
util.createLocation(
URI.file(enumLink.file.srcPath).toString(),
enumLink.item.tokens.name.range
)
);
return results;
}
const enumMemberLink = scope.getEnumMemberFileLink(fullName, containingNamespace);
if (enumMemberLink) {
results.push(
util.createLocation(
URI.file(enumMemberLink.file.srcPath).toString(),
enumMemberLink.item.tokens.name.range
)
);
return results;
}
}
}

let textToSearchFor = token.text.toLowerCase();
Expand Down