Skip to content
Merged
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
39 changes: 16 additions & 23 deletions src/validators/ClassValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,11 @@ import { DynamicType } from '../types/DynamicType';
export class BsClassValidator {
private scope: Scope;
public diagnostics: BsDiagnostic[];
private classes: Record<string, AugmentedClassStatement>;
private classes: Map<string, AugmentedClassStatement>;

public validate(scope: Scope) {
this.scope = scope;
this.diagnostics = [];
this.classes = {};

this.findClasses();
this.findNamespaceNonNamespaceCollisions();
Expand All @@ -39,10 +38,10 @@ export class BsClassValidator {
*/
private getClassByName(className: string, namespaceName?: string) {
let fullName = util.getFullyQualifiedClassName(className, namespaceName);
let cls = this.classes[fullName.toLowerCase()];
let cls = this.classes.get(fullName.toLowerCase());
//if we couldn't find the class by its full namespaced name, look for a global class with that name
if (!cls) {
cls = this.classes[className.toLowerCase()];
cls = this.classes.get(className.toLowerCase());
}
return cls;
}
Expand Down Expand Up @@ -88,10 +87,9 @@ export class BsClassValidator {
}

private findNamespaceNonNamespaceCollisions() {
for (let name in this.classes) {
let classStatement = this.classes[name];
for (const [className, classStatement] of this.classes) {
//catch namespace class collision with global class
let nonNamespaceClass = this.classes[util.getTextAfterFinalDot(name).toLowerCase()];
let nonNamespaceClass = this.classes.get(util.getTextAfterFinalDot(className).toLowerCase());
if (classStatement.namespaceName && nonNamespaceClass) {
this.diagnostics.push({
...DiagnosticMessages.namespacedClassCannotShareNamewithNonNamespacedClass(
Expand All @@ -112,8 +110,7 @@ export class BsClassValidator {
}

private verifyChildConstructor() {
for (let key in this.classes) {
let classStatement = this.classes[key];
for (const [, classStatement] of this.classes) {
const newMethod = classStatement.memberMap.new as ClassMethodStatement;

if (
Expand Down Expand Up @@ -159,8 +156,7 @@ export class BsClassValidator {
}

private validateMemberCollisions() {
for (let key in this.classes) {
let classStatement = this.classes[key];
for (const [, classStatement] of this.classes) {
let methods = {};
let fields = {};

Expand Down Expand Up @@ -275,8 +271,7 @@ export class BsClassValidator {
* Check the types for fields, and validate they are valid types
*/
private validateFieldTypes() {
for (let key in this.classes) {
let classStatement = this.classes[key];
for (const [, classStatement] of this.classes) {
for (let statement of classStatement.body) {
if (isClassFieldStatement(statement)) {
let fieldType = statement.getType();
Expand Down Expand Up @@ -321,15 +316,14 @@ export class BsClassValidator {

private cleanUp() {
//unlink all classes from their parents so it doesn't mess up the next scope
for (let key in this.classes) {
let classStatement = this.classes[key];
for (const [, classStatement] of this.classes) {
delete classStatement.parentClass;
delete classStatement.file;
}
}

private findClasses() {
this.classes = {};
this.classes = new Map();
this.scope.enumerateBrsFiles((file) => {
for (let x of file.parser.references.classStatements ?? []) {
let classStatement = x as AugmentedClassStatement;
Expand All @@ -340,11 +334,11 @@ export class BsClassValidator {
}
let lowerName = name.toLowerCase();
//see if this class was already defined
let alreadyDefinedClass = this.classes[lowerName];
let alreadyDefinedClass = this.classes.get(lowerName);

//if we don't already have this class, register it
if (!alreadyDefinedClass) {
this.classes[lowerName] = classStatement;
this.classes.set(lowerName, classStatement);
classStatement.file = file;

//add a diagnostic about this class already existing
Expand All @@ -356,7 +350,7 @@ export class BsClassValidator {
relatedInformation: [{
location: Location.create(
URI.file(alreadyDefinedClass.file.pathAbsolute).toString(),
this.classes[lowerName].range
this.classes.get(lowerName).range
),
message: ''
}]
Expand All @@ -368,8 +362,7 @@ export class BsClassValidator {

private linkClassesWithParents() {
//link all classes with their parents
for (let key in this.classes) {
let classStatement = this.classes[key];
for (const [, classStatement] of this.classes) {
let parentClassName = classStatement.parentClassName?.getName(ParseMode.BrighterScript);
if (parentClassName) {
let relativeName: string;
Expand All @@ -394,8 +387,8 @@ export class BsClassValidator {
relativeName = parentClassName;
}

let relativeParent = this.classes[relativeName.toLowerCase()];
let absoluteParent = this.classes[absoluteName.toLowerCase()];
let relativeParent = this.classes.get(relativeName.toLowerCase());
let absoluteParent = this.classes.get(absoluteName.toLowerCase());

let parentClass: AugmentedClassStatement;
//if we found a relative parent class
Expand Down