Semantic Tests refactored
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
This commit is contained in:
parent
eb313464f0
commit
d594bacb7d
@ -1,7 +1,7 @@
|
||||
package semantic;
|
||||
|
||||
import ast.type.type.*;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exceptions.AlreadyDeclearedException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Stack;
|
||||
|
@ -25,7 +25,7 @@ import ast.statement.statementexpression.crementExpression.IncrementExpressionNo
|
||||
import ast.statement.statementexpression.methodcallstatementnexpression.MethodCallStatementExpressionNode;
|
||||
import ast.type.type.*;
|
||||
import semantic.context.Context;
|
||||
import semantic.exeptions.*;
|
||||
import semantic.exceptions.*;
|
||||
import typechecker.TypeCheckResult;
|
||||
|
||||
public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package semantic.exeptions;
|
||||
package semantic.exceptions;
|
||||
|
||||
public class AlreadyDeclearedException extends RuntimeException {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package semantic.exeptions;
|
||||
package semantic.exceptions;
|
||||
|
||||
public class AlreadyDefinedException extends RuntimeException {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package semantic.exeptions;
|
||||
package semantic.exceptions;
|
||||
|
||||
public class MultipleReturnTypes extends RuntimeException {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package semantic.exeptions;
|
||||
package semantic.exceptions;
|
||||
|
||||
public class NotDeclearedException extends RuntimeException {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package semantic.exeptions;
|
||||
package semantic.exceptions;
|
||||
|
||||
public class TypeMismatchException extends RuntimeException {
|
||||
|
9
src/main/java/semantic/exceptions/UnknownException.java
Normal file
9
src/main/java/semantic/exceptions/UnknownException.java
Normal file
@ -0,0 +1,9 @@
|
||||
package semantic.exceptions;
|
||||
|
||||
public class UnknownException extends RuntimeException {
|
||||
|
||||
public UnknownException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@ -1,282 +0,0 @@
|
||||
package semantic;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ProgramNode;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import semantic.exeptions.MultipleReturnTypes;
|
||||
import semantic.exeptions.NotDeclearedException;
|
||||
import semantic.exeptions.TypeMismatchException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class EndToTAST {
|
||||
|
||||
@BeforeEach
|
||||
public void setup(){
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CorrectTest(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/CorrectTest.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
|
||||
assertEquals(SemanticAnalyzer.errors.size(), 0);
|
||||
assertNotNull(tast);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notDecleared() {
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/NotDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program(); // parse the input
|
||||
|
||||
/* ------------------------- AST builder -> AST ------------------------- */
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(NotDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatch(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/TypeMismatchIntBool.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parameterAlreadyDecleared(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/ParameterAlreadyDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldAlreadyDecleared(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/FieldAlreadyDecleared.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMismatchRefType(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/TypeMismatchRefType.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void correctRetType(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/CorrectRetType.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retTypeMismatch(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/retTypeMismatch.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleRetType(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/MultipleRetTypes.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(MultipleReturnTypes.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wrongTypeInIfClause(){
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/WrongIfClause.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
}
|
218
src/test/java/semantic/EndToTypedAstTest.java
Normal file
218
src/test/java/semantic/EndToTypedAstTest.java
Normal file
@ -0,0 +1,218 @@
|
||||
package semantic;
|
||||
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ProgramNode;
|
||||
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class EndToTypedAstTest {
|
||||
private static final Map<String, Class<?>> exceptionMap = new HashMap<>();
|
||||
|
||||
@Test
|
||||
public void exceptionsTest() {
|
||||
String directoryPath = "src/test/resources/input/typedAstExceptionsTests";
|
||||
File folder = new File(directoryPath);
|
||||
|
||||
try {
|
||||
loadCustomExceptions();
|
||||
System.out.println("Custom exceptions loaded successfully.");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load custom exceptions", e);
|
||||
|
||||
}
|
||||
|
||||
if (folder.isDirectory()) {
|
||||
File[] files = folder.listFiles((_, name) -> name.endsWith(".java"));
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
String expectedException = extractExpectedException(file);
|
||||
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
CharStream codeCharStream;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get(file.getPath()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
if (expectedException != null) {
|
||||
System.out.println("Testing the file: " + file.getName());
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty(), "Expected an exception, but none was found.");
|
||||
assertInstanceOf(getExceptionClass(expectedException), SemanticAnalyzer.errors.getFirst());
|
||||
} else {
|
||||
System.out.println("No expected exception specified.");
|
||||
// If no expected exception is specified, you might want to add a different check
|
||||
// e.g., assertTrue(SemanticAnalyzer.errors.isEmpty(), "No exceptions expected, but some were found.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directory.");
|
||||
}
|
||||
} else {
|
||||
System.out.println("The provided path is not a directory.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void featureTest(){
|
||||
String directoryPath = "src/test/resources/input/typedAstFeaturesTests";
|
||||
File folder = new File(directoryPath);
|
||||
if (folder.isDirectory()) {
|
||||
File[] files = folder.listFiles((_, name) -> name.endsWith(".java"));
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
CharStream codeCharStream;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get(file.getPath()));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
System.out.println("Testing the file: " + file.getName());
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directory.");
|
||||
}
|
||||
} else {
|
||||
System.out.println("The provided path is not a directory.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// ------------------ Helpers ------------------
|
||||
/**
|
||||
* This method is used to extract the expected exception from a given file.
|
||||
* It reads the file line by line and uses a regular expression to match the expected exception annotation.
|
||||
* The expected exception annotation should be in the format: "// @expected: ExceptionName".
|
||||
* If the expected exception annotation is found, it returns the name of the expected exception.
|
||||
* If the expected exception annotation is not found, it returns null.
|
||||
*
|
||||
* @param file The file from which the expected exception is to be extracted.
|
||||
* @return The name of the expected exception, or null if the expected exception annotation is not found.
|
||||
*/
|
||||
private String extractExpectedException(File file) {
|
||||
String annotationPattern = "//\\s*@expected:\\s*(\\S+)";
|
||||
Pattern pattern = Pattern.compile(annotationPattern);
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
if (matcher.find()) {
|
||||
return matcher.group(1);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to retrieve the Class object associated with a given exception name.
|
||||
* It first prints the original exception name, then appends the package name to the exception name and prints it.
|
||||
* It then retrieves the Class object from the exceptionMap using the fully qualified exception name.
|
||||
* If the Class object is not found in the exceptionMap, it throws a RuntimeException.
|
||||
*
|
||||
* @param exceptionName The name of the exception for which the Class object is to be retrieved.
|
||||
* @return The Class object associated with the given exception name.
|
||||
* @throws RuntimeException If the Class object for the given exception name is not found in the exceptionMap.
|
||||
*/
|
||||
private Class<?> getExceptionClass(String exceptionName) {
|
||||
System.out.println(exceptionName);
|
||||
exceptionName = "semantic.exceptions." + exceptionName;
|
||||
System.out.println(exceptionName);
|
||||
Class<?> exceptionClass = exceptionMap.get(exceptionName);
|
||||
if (exceptionClass == null) {
|
||||
throw new RuntimeException("Exception class not found: " + exceptionName);
|
||||
}
|
||||
return exceptionClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to load custom exceptions from a specified package.
|
||||
* It first constructs the directory path from the package name and checks if the directory exists.
|
||||
* If the directory does not exist, it throws an IllegalArgumentException.
|
||||
* It then creates a URLClassLoader to load the classes from the directory.
|
||||
* It iterates over all the files in the directory, and for each file, it constructs the class name and loads the class.
|
||||
* If the loaded class is a subtype of Throwable, it adds the class to the exceptionMap.
|
||||
*
|
||||
* @throws Exception If any error occurs during class loading.
|
||||
*/
|
||||
private static void loadCustomExceptions() throws Exception {
|
||||
final String packName = "semantic.exceptions";
|
||||
final String dirForMyClasses = "src/main/java/%s".formatted(packName.replace(".", "/"));
|
||||
File folder = new File(dirForMyClasses);
|
||||
if (!folder.isDirectory()) {
|
||||
throw new IllegalArgumentException("The provided path is not a directory.");
|
||||
}
|
||||
|
||||
URL[] urls = {folder.toURI().toURL()};
|
||||
URLClassLoader classLoader;
|
||||
try {
|
||||
classLoader = new URLClassLoader(urls);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to create class loader", e);
|
||||
}
|
||||
|
||||
for (File file : Objects.requireNonNull(folder.listFiles())) {
|
||||
String className = packName + "." + file.getName().replaceAll("\\.(?:class|java)$", "");
|
||||
System.out.printf("Loading custom exception: %s (=> %s)", file.getName(), className);
|
||||
Class<?> cls = classLoader.loadClass(className);
|
||||
|
||||
if (Throwable.class.isAssignableFrom(cls)) { // Check if the class is a subtype of Throwable
|
||||
exceptionMap.put(className, cls);
|
||||
System.out.println("Loaded custom exception: " + className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,5 @@
|
||||
package semantic;
|
||||
|
||||
import ast.*;
|
||||
import ast.member.FieldNode;
|
||||
import ast.member.MemberNode;
|
||||
import ast.member.MethodNode;
|
||||
import ast.parameter.ParameterNode;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import semantic.exeptions.AlreadyDeclearedException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class SemanticTest {
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// @expected: AlreadyDeclearedException
|
||||
public class Example {
|
||||
|
||||
public int a;
|
@ -1,3 +1,4 @@
|
||||
// @expected: MultipleReturnTypes
|
||||
public class Example {
|
||||
|
||||
public static int testMethod(int x, char c){
|
@ -1,3 +1,4 @@
|
||||
// @expected: NotDeclearedException
|
||||
public class Test {
|
||||
public static int testMethod(int x){
|
||||
int a = b;
|
@ -1,3 +1,4 @@
|
||||
// @expected: AlreadyDeclearedException
|
||||
public class Example {
|
||||
|
||||
public static int testMethod(char a, int a){
|
@ -1,3 +1,4 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Example {
|
||||
|
||||
public static int testMethod(char x){
|
@ -1,3 +1,4 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Test {
|
||||
|
||||
public boolean b;
|
@ -1,3 +1,4 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Test {
|
||||
|
||||
public static int testMethod(ExampleA exampleA, ExampleB exampleB){
|
@ -1,3 +1,4 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Example {
|
||||
|
||||
public static void testMethod(int x){
|
Loading…
Reference in New Issue
Block a user