Skip to content

Commit 6c71005

Browse files
committed
Add support for classes without modifiers
1 parent 39731f1 commit 6c71005

File tree

17 files changed

+531
-209
lines changed

17 files changed

+531
-209
lines changed

src/types/ast/astExtractor/class-extractor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class ClassExtractor extends BaseJavaCstVisitorWithDefaults {
3232
classModifier: this.modifier,
3333
typeIdentifier: this.identifier,
3434
classBody: this.body,
35-
sclass: this.sclass,
35+
extendsTypeIdentifier: this.sclass,
3636
location: cst.location
3737
} as NormalClassDeclaration
3838
}

src/types/ast/astExtractor/method-extractor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class MethodExtractor extends BaseJavaCstVisitorWithDefaults {
6262
]
6363
.filter(x => x !== undefined)
6464
.map(x => (x ? x[0].image : x))
65-
this.modifier.push(possibleModifiers[0] as MethodModifier)
65+
if (possibleModifiers.length > 0) this.modifier.push(possibleModifiers[0] as MethodModifier)
6666
}
6767

6868
result(ctx: ResultCtx) {

src/types/ast/astExtractor/statement-extractor.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ export class StatementExtractor extends BaseJavaCstVisitorWithDefaults {
213213
endColumn: thisKeyword.endColumn
214214
} as Location
215215
}
216+
} else if (ctx.newExpression) {
217+
const expressionExtractor = new ExpressionExtractor()
218+
return expressionExtractor.visit(ctx.newExpression)
216219
}
217220
throw new Error('Unimplemeted extractor.')
218221
}

src/types/ast/types/classes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { Block, VariableDeclarator } from './blocks-and-statements'
22
import { BaseNode } from '.'
33

4-
export type ClassNode = ClassDeclaration
4+
export type ClassNode = ClassDeclaration | ClassBodyDeclaration
55

66
export type ClassDeclaration = NormalClassDeclaration
77

88
export interface NormalClassDeclaration extends BaseNode {
99
kind: 'NormalClassDeclaration'
1010
classModifier: Array<ClassModifier>
1111
typeIdentifier: Identifier
12-
sclass?: Identifier
12+
extendsTypeIdentifier?: Identifier
1313
classBody: Array<ClassBodyDeclaration>
1414
}
1515

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { check } from '..'
2+
import { parse } from '../../ast'
3+
import { Type } from '../../types/type'
4+
5+
const testcases: {
6+
input: string
7+
result: { type: Type | null; errors: Error[] }
8+
only?: boolean
9+
}[] = [
10+
{
11+
input: `
12+
public class Main {
13+
public static void main(String args[]) {}
14+
}
15+
`,
16+
result: { type: null, errors: [] }
17+
},
18+
{
19+
input: `
20+
public class Basic {
21+
public void display() {}
22+
}
23+
24+
public class Main {
25+
public static void main(String[] args) {
26+
Basic basic = new Basic();
27+
basic.display();
28+
}
29+
}
30+
`,
31+
result: { type: null, errors: [] }
32+
},
33+
{
34+
input: `
35+
class Parent {
36+
void greet() {}
37+
}
38+
39+
class Child extends Parent {
40+
@Override
41+
void greet() {}
42+
}
43+
44+
public class Main {
45+
public static void main(String[] args) {
46+
Parent parent = new Parent();
47+
Parent child = new Child(); // Polymorphism
48+
parent.greet();
49+
child.greet();
50+
}
51+
}
52+
`,
53+
result: { type: null, errors: [] }
54+
},
55+
{
56+
input: `
57+
class OverloadedMethods {
58+
void display() {}
59+
void display(String msg) {}
60+
}
61+
62+
public class Main {
63+
public static void main(String[] args) {
64+
OverloadedMethods obj = new OverloadedMethods();
65+
obj.display();
66+
obj.display("Overloaded method with one parameter.");
67+
}
68+
}
69+
`,
70+
result: { type: null, errors: [] }
71+
},
72+
{
73+
input: `
74+
class MultipleConstructors {
75+
MultipleConstructors() {}
76+
MultipleConstructors(String message) {}
77+
}
78+
79+
public class Main {
80+
public static void main(String[] args) {
81+
new MultipleConstructors();
82+
new MultipleConstructors("Overloaded constructor with a String.");
83+
}
84+
}
85+
`,
86+
result: { type: null, errors: [] },
87+
only: true
88+
}
89+
]
90+
91+
describe('Type Checker', () => {
92+
testcases.map(testcase => {
93+
let it = test
94+
if (testcase.only) it = test.only
95+
it(`Checking classes for '${testcase.input}'`, () => {
96+
const program = testcase.input
97+
const ast = parse(program)
98+
if (!ast) throw new Error('Program parsing returns null.')
99+
const result = check(ast)
100+
if (result.currentType === null) expect(result.currentType).toBe(testcase.result.type)
101+
else expect(result.currentType).toBeInstanceOf(testcase.result.type)
102+
if (testcase.result.errors.length > result.errors.length) {
103+
testcase.result.errors.forEach((error, index) => {
104+
if (!result.errors[index]) expect('').toBe(error.message)
105+
expect(result.errors[index].message).toBe(error.message)
106+
})
107+
} else {
108+
result.errors.forEach((error, index) => {
109+
console.log(error)
110+
if (!testcase.result.errors[index]) expect(error.message).toBe('')
111+
expect(error.message).toBe(testcase.result.errors[index].message)
112+
})
113+
}
114+
})
115+
})
116+
})

src/types/checker/checker.ts

Whitespace-only changes.

0 commit comments

Comments
 (0)