@vlocode/apex
Version:
Salesforce APEX Parser and Grammar
159 lines • 6.03 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClassDeclarationVisitor = void 0;
const types_1 = require("../types");
const methodDeclarationVisitor_1 = require("./methodDeclarationVisitor");
const typeRefVisitor_1 = require("./typeRefVisitor");
const declarationVisitor_1 = require("./declarationVisitor");
const fieldDeclarationVisitor_1 = require("./fieldDeclarationVisitor");
const propertyDeclarationVisitor_1 = require("./propertyDeclarationVisitor");
const blockVisitor_1 = require("./blockVisitor");
class ClassDeclarationVisitor extends declarationVisitor_1.DeclarationVisitor {
constructor(state) {
super(state ?? {
name: '',
methods: [],
properties: [],
fields: [],
implements: [],
extends: undefined,
nested: [],
refs: [],
sourceRange: types_1.ApexSourceRange.empty,
});
}
visitAnnotation(ctx) {
if (ctx?.qualifiedName().getText().toLocaleLowerCase() === 'istest') {
this.state.isTest = true;
}
return this.state;
}
visitModifier(ctx) {
if (ctx.ABSTRACT()) {
this.state.isAbstract = true;
}
if (ctx.VIRTUAL()) {
this.state.isVirtual = true;
}
this.visitAnnotation(ctx.annotation());
this.visitAccessModifier(ctx) || this.visitSharingModifier(ctx);
return this.state;
}
visitSharingModifier(ctx) {
if (ctx.WITH()) {
this.state.sharing = 'with';
}
else if (ctx.WITHOUT()) {
this.state.sharing = 'without';
}
else if (ctx.INHERITED()) {
this.state.sharing = 'inherited';
}
else if (!ctx.SHARING()) {
return false;
}
return true;
}
visitClassDeclaration(ctx) {
this.state.name = ctx.id().getText();
if (ctx.EXTENDS()) {
// Parse `extends XXX`
const extendedType = ctx.typeRef()?.accept(new typeRefVisitor_1.TypeRefVisitor());
if (extendedType) {
this.state.extends = extendedType;
this.addRef(extendedType, 'extends');
}
}
if (ctx.IMPLEMENTS()) {
// Parse `implements XXX, YYY`
this.state.implements = ctx.typeList()?.typeRef().map(typeRef => new typeRefVisitor_1.TypeRefVisitor().visit(typeRef)) ?? [];
this.addRef(this.state.implements, 'implements');
}
ctx.classBody().accept(this);
return this.state;
}
visitClassBody(ctx) {
// Parse all the fields and properties first so that we know which are locals
new FieldAndPropertyDeclarationVisitor(this.state).visitChildren(ctx);
// Now visit all members using this visitor
this.visitChildren(ctx);
// Update references for all methods and properties
this.updateReferences();
return this.state;
}
visitClassBodyDeclaration(ctx) {
ctx.memberDeclaration()?.accept(this);
return this.state;
}
visitMemberDeclaration(ctx) {
const classDeclaration = ctx.classDeclaration();
if (classDeclaration) {
const nestedClass = new ClassDeclarationVisitor().visit(classDeclaration);
if (nestedClass) {
nestedClass.sourceRange = types_1.ApexSourceRange.fromToken(classDeclaration);
this.addRef(nestedClass.refs);
this.state.nested.push(nestedClass);
}
return this.state;
}
return this.visitChildren(ctx);
}
visitMethodDeclaration(ctx) {
const memberContext = ctx.parent?.parent;
if (memberContext) {
const visitor = new methodDeclarationVisitor_1.MethodDeclarationVisitor();
const method = visitor.visit(memberContext);
if (method) {
// Remove references to local variables and properties
visitor.updateReferences(this.state);
method.sourceRange = types_1.ApexSourceRange.fromToken(memberContext);
this.addRef(method.returnType);
this.addRef(method.refs);
this.state.methods.push(method);
}
}
return this.state;
}
updateReferences() {
for (const property of this.state.properties) {
if (property.getter) {
new blockVisitor_1.BlockVisitor(property.getter).updateReferences(this.state);
this.addRef(property.getter?.refs);
}
if (property.setter) {
new blockVisitor_1.BlockVisitor(property.setter).updateReferences(this.state);
this.addRef(property.setter?.refs);
}
}
}
}
exports.ClassDeclarationVisitor = ClassDeclarationVisitor;
class FieldAndPropertyDeclarationVisitor extends declarationVisitor_1.DeclarationVisitor {
constructor(state) {
super(state);
}
visitPropertyDeclaration(ctx) {
const memberContext = ctx.parent?.parent;
if (memberContext) {
const property = new propertyDeclarationVisitor_1.PropertyDeclarationVisitor().visit(memberContext);
if (property) {
property.sourceRange = types_1.ApexSourceRange.fromToken(memberContext);
this.addRef(property.type, 'property');
this.state.properties.push(property);
}
}
return this.state;
}
visitFieldDeclaration(ctx) {
const memberContext = ctx.parent?.parent;
if (memberContext) {
const field = new fieldDeclarationVisitor_1.FieldDeclarationVisitor().visit(memberContext);
if (field) {
this.addRef(field.type, 'field');
this.state.fields.push(field);
}
}
return this.state;
}
}
//# sourceMappingURL=classDeclarationVisitor.js.map