Skip to content

Commit 9b53cf6

Browse files
committed
Extract addition of class methods in type checker to fix bug
1 parent 2a8abd5 commit 9b53cf6

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

src/types/checker/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { createArrayType } from '../typeFactories/arrayFactory'
2525
import { ClassImpl } from '../types/classes'
2626
import { Method } from '../types/methods'
2727
import { Frame } from './environment'
28-
import { addClassesToFrame, resolveClassRelationships } from './prechecks'
28+
import { addClasses, addClassMethods, addClassParents } from './prechecks'
2929

3030
export type Result = {
3131
currentType: Type | null
@@ -41,10 +41,12 @@ export const OK_RESULT: Result = newResult(null)
4141

4242
export const check = (node: Node, frame: Frame = Frame.globalFrame()): Result => {
4343
const typeCheckingFrame = frame.newChildFrame()
44-
const addClassesResult = addClassesToFrame(node, typeCheckingFrame)
44+
const addClassesResult = addClasses(node, typeCheckingFrame)
4545
if (addClassesResult.errors.length > 0) return addClassesResult
46-
const resolveClassesResult = resolveClassRelationships(node, typeCheckingFrame)
47-
if (resolveClassesResult.errors.length > 0) return resolveClassesResult
46+
const addClassParentsResult = addClassParents(node, typeCheckingFrame)
47+
if (addClassParentsResult.errors.length > 0) return addClassParentsResult
48+
const addClassMethodsResult = addClassMethods(node, typeCheckingFrame)
49+
if (addClassMethodsResult.errors.length > 0) return addClassMethodsResult
4850
return typeCheckBody(node, typeCheckingFrame)
4951
}
5052

src/types/checker/prechecks.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,40 @@
11
import { Class, ClassImpl, ObjectClass } from '../types/classes'
22
import { ConstructorDeclaration, MethodDeclaration } from '../ast/types/classes'
3-
import { createClass } from '../typeFactories/classFactory'
3+
import { createClassFieldsAndMethods } from '../typeFactories/classFactory'
44
import { createMethodSignature } from '../typeFactories/methodFactory'
55
import { CyclicInheritanceError } from '../errors'
66
import { MethodSignature } from '../types/methods'
77
import { Node } from '../ast/types'
88
import { Frame } from './environment'
99
import { newResult, OK_RESULT, Result } from '.'
1010

11-
export const addClassesToFrame = (node: Node, frame: Frame): Result => {
11+
export const addClasses = (node: Node, frame: Frame): Result => {
1212
switch (node.kind) {
1313
case 'CompilationUnit': {
1414
const errors: Error[] = []
1515
for (const classDeclaration of node.topLevelClassOrInterfaceDeclarations) {
16-
const result = addClassesToFrame(classDeclaration, frame)
16+
const result = addClasses(classDeclaration, frame)
17+
if (result.errors.length > 0) errors.push(...result.errors)
18+
}
19+
if (errors.length > 0) return newResult(null, errors)
20+
return OK_RESULT
21+
}
22+
case 'NormalClassDeclaration': {
23+
const classType = new ClassImpl(node.typeIdentifier)
24+
frame.setType(node.typeIdentifier, classType)
25+
return newResult(classType)
26+
}
27+
default:
28+
return OK_RESULT
29+
}
30+
}
31+
32+
export const addClassMethods = (node: Node, frame: Frame): Result => {
33+
switch (node.kind) {
34+
case 'CompilationUnit': {
35+
const errors: Error[] = []
36+
for (const classDeclaration of node.topLevelClassOrInterfaceDeclarations) {
37+
const result = addClassMethods(classDeclaration, frame)
1738
if (result.errors.length > 0) errors.push(...result.errors)
1839
}
1940
if (errors.length > 0) return newResult(null, errors)
@@ -27,12 +48,12 @@ export const addClassesToFrame = (node: Node, frame: Frame): Result => {
2748
}
2849
case 'NormalClassDeclaration': {
2950
const createMethod = (node: ConstructorDeclaration | MethodDeclaration) => {
30-
const result = addClassesToFrame(node, frame)
51+
const result = addClassMethods(node, frame)
3152
if (result.errors.length > 0) return result.errors[0]
3253
return result.currentType as MethodSignature
3354
}
3455

35-
const classType = createClass(node, frame, createMethod, createMethod)
56+
const classType = createClassFieldsAndMethods(node, frame, createMethod, createMethod)
3657
if (classType instanceof Error) return newResult(null, [classType])
3758
return newResult(classType)
3859
}
@@ -41,12 +62,12 @@ export const addClassesToFrame = (node: Node, frame: Frame): Result => {
4162
}
4263
}
4364

44-
export const resolveClassRelationships = (node: Node, frame: Frame): Result => {
65+
export const addClassParents = (node: Node, frame: Frame): Result => {
4566
switch (node.kind) {
4667
case 'CompilationUnit': {
4768
const errors: Error[] = []
4869
for (const classDeclaration of node.topLevelClassOrInterfaceDeclarations) {
49-
const result = resolveClassRelationships(classDeclaration, frame)
70+
const result = addClassParents(classDeclaration, frame)
5071
if (result.errors.length > 0) errors.push(...result.errors)
5172
}
5273
if (errors.length > 0) return newResult(null, errors)

src/types/typeFactories/classFactory.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import { Method, MethodSignature } from '../types/methods'
1010
type CreateMethod = (node: MethodDeclaration) => MethodSignature | Error
1111
type CreateConstructor = (node: ConstructorDeclaration) => MethodSignature | Error
1212

13-
export const createClass = (
13+
export const createClassFieldsAndMethods = (
1414
node: NormalClassDeclaration,
1515
frame: Frame,
1616
createConstructor: CreateConstructor,
1717
createMethod: CreateMethod
1818
): Class | Error => {
19-
const classType = new ClassImpl(node.typeIdentifier)
20-
frame.setType(node.typeIdentifier, classType)
19+
const classType = frame.getType(node.typeIdentifier)
20+
if (classType instanceof Error) throw new Error('expected class type to be retrieved')
21+
if (!(classType instanceof ClassImpl)) throw new Error('expected class type to be retrieved')
2122

2223
for (const bodyNode of node.classBody) {
2324
switch (bodyNode.kind) {

0 commit comments

Comments
 (0)