forked from csaroff/MiniJava-Compiler
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInitializationBeforeUseChecker.java
More file actions
85 lines (81 loc) · 3.36 KB
/
Copy pathInitializationBeforeUseChecker.java
File metadata and controls
85 lines (81 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTreeProperty;
import java.util.*;
public class InitializationBeforeUseChecker extends MinijavaBaseVisitor<Set<Symbol>> {
MinijavaParser parser;
final Map<String, Klass> klasses;
//Stack<Scope> scopes = new Stack<Scope>();
ParseTreeProperty<Scope> scopes;
Scope currentScope = null;
//Set<Symbol> initializedInIf = null;
//Set<Symbol> initializedInElse = null;
public InitializationBeforeUseChecker(final Map<String, Klass> klasses, ParseTreeProperty<Scope> scopes, MinijavaParser parser){
this.scopes=scopes;
this.klasses=klasses;
this.parser=parser;
}
@Override public Set<Symbol> visitClassDeclaration(@NotNull MinijavaParser.ClassDeclarationContext ctx) {
enterScope(ctx);
visitChildren(ctx);
exitScope();
return null;
}
@Override public Set<Symbol> visitMethodDeclaration(@NotNull MinijavaParser.MethodDeclarationContext ctx) {
enterScope(ctx);
visitChildren(ctx);
exitScope();
return null;
}
//@Override public void enterIfElseStatement(@NotNull MinijavaParser.IfElseStatementContext ctx) {}
@Override public Set<Symbol> visitIfElseStatement(@NotNull MinijavaParser.IfElseStatementContext ctx) {
visit(ctx.expression());
Set<Symbol> initializedVariables = visit(ctx.ifBlock());
initializedVariables.retainAll(visit(ctx.elseBlock()));
for(Symbol sym : initializedVariables){
currentScope.initialize(sym);
}
return initializedVariables;
}
@Override public Set<Symbol> visitIfBlock(@NotNull MinijavaParser.IfBlockContext ctx) {
enterScope(ctx);
visitChildren(ctx);
Set<Symbol> ifInit = currentScope.getInitializedVariables();
exitScope();
return ifInit;
}
@Override public Set<Symbol> visitElseBlock(@NotNull MinijavaParser.ElseBlockContext ctx) {
enterScope(ctx);
visitChildren(ctx);
Set<Symbol> elseInit = currentScope.getInitializedVariables();
exitScope();
return elseInit;
}
@Override public Set<Symbol> visitWhileStatement(@NotNull MinijavaParser.WhileStatementContext ctx) {
enterScope(ctx);
visitChildren(ctx);
exitScope();
return null;
}
@Override public Set<Symbol> visitVariableAssignmentStatement(@NotNull MinijavaParser.VariableAssignmentStatementContext ctx) {
Set<Symbol> sym = visitChildren(ctx);
currentScope.initialize(currentScope.lookup(ctx.Identifier().getText()));
return sym;
}
@Override public Set<Symbol> visitIdentifierExpression(@NotNull MinijavaParser.IdentifierExpressionContext ctx) {
String identifier = ctx.Identifier().getText();
if(!currentScope.hasBeenInitialized(identifier)){
ErrorPrinter.printVariableMayNotHaveBeenInitializedError(parser, ctx.Identifier().getSymbol(), identifier);
}
return visitChildren(ctx);
}
public void enterScope(ParserRuleContext ctx){
currentScope = scopes.get(ctx);
}
private void exitScope(){
currentScope = currentScope.getEnclosingScope();
}
}