Compare commits
15 Commits
1bcf396f95
...
Tests
Author | SHA1 | Date | |
---|---|---|---|
|
729f4f23d6 | ||
|
a1a9cce511 | ||
|
f7a4e65093 | ||
|
2934872457 | ||
|
1c327705d8 | ||
|
c0e197e2d0 | ||
|
ae872ed906 | ||
91552ad147 | |||
084808c3ab | |||
d19748766f | |||
|
4bdb65a6ce | ||
|
97e0c228d6 | ||
|
d4be77ceb2 | ||
ca539add98 | |||
|
49195c754c |
35
pom.xml
35
pom.xml
@@ -23,6 +23,24 @@
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-suite-engine</artifactId>
|
||||
<version>1.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
@@ -44,18 +62,6 @@
|
||||
<version>3.26.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>5.11.0-M2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.11.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -65,6 +71,11 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
|
77
readme.md
Normal file
77
readme.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# "Nicht Haskel 2.0" Java Compiler
|
||||
|
||||
Realisation of a subset of the Java Standard Compiler in the course Compiler Construction of the 4th semester Computer Science at the Duale Hochschule Suttgart (Horb).
|
||||
|
||||
This project aims to provide a simplified version of the Java compiler, focusing on key language features and demonstrating the principles of compiler construction.
|
||||
|
||||
## Realised Java syntax
|
||||
|
||||
- **Data types**: `int`, `boolean`, `char`
|
||||
- **Access modifier**: `public`, `protected`, `private`
|
||||
- **Operators**: `=` `+` `-` `*` `%` `/` `>` `<` `>=` `<=` `==` `!=` `!` `&&` `||` `++` `--`
|
||||
- **Keywords**: `class`, `this`, `while`, `do`, `if`, `else`, `for`, `return`, `new`, `switch`, `case`, `break`, `default`, `:`
|
||||
- **Statements**:
|
||||
- `if` ... `if else` ... `else`;
|
||||
- `while` ... ;
|
||||
- `do` ... `while`;
|
||||
- `for`;
|
||||
- `switch` ... `case` ... ;
|
||||
- **Comments**:
|
||||
- Single line: `// comment`
|
||||
- Multi-line: `/* comment */`
|
||||
- **Further functions**:
|
||||
- All methods are overloadable
|
||||
- High maintainability and expandability through implementation of the visitor pattern
|
||||
- Logging Input and Outputs
|
||||
- Error Handling in the Semantic Check
|
||||
|
||||
## Project Structure
|
||||
|
||||
```plain
|
||||
src/
|
||||
└── main/
|
||||
├── java/
|
||||
│ ├── ast/ -> Defining the structure of the AST
|
||||
│ ├── bytecode/ -> Generate Java bytecode
|
||||
│ ├── main/ -> Running the compiler
|
||||
│ ├── parser/
|
||||
│ │ ├── astBuilder/ -> Builder creating the AST
|
||||
│ │ ├── generated/ -> Antlr generated grammar
|
||||
│ │ └── grammar/ -> Antlr grammar
|
||||
│ ├── semantic/ -> Running the semantic check
|
||||
│ └── visitor/ -> Visitor interface
|
||||
└── resources/
|
||||
test/
|
||||
└── java/
|
||||
│ ├── main/
|
||||
│ ├── parser/ -> Performs tests on the parser
|
||||
│ └── semantic/
|
||||
└── resources/ -> Ressources for running the Tests
|
||||
├──input
|
||||
│ ├── combinedFeatureTests
|
||||
│ ├── endabgabeTests
|
||||
│ ├── failureTests
|
||||
│ ├── singleFeatureSemanticTests
|
||||
│ ├── singleFeatureTests
|
||||
│ ├── typedAstExceptionsTests
|
||||
│ └── typedAstFeatureTests
|
||||
└──output
|
||||
├── javac
|
||||
└── raupenpiler
|
||||
```
|
||||
|
||||
## Class-Diagramm AST
|
||||
|
||||

|
||||
|
||||
## Used Tools
|
||||
|
||||
- [Maven 4.0](https://maven.apache.org/index.html)
|
||||
- Used for automating the build process and managing dependencies.
|
||||
- [ANTLR4 v.13.1](https://www.antlr.org/)
|
||||
- Used to parse the input Java code into the Abstract Syntax Tree.
|
||||
|
||||
|
||||
## How to run the compiler
|
||||
## Download
|
||||
```bash
|
@@ -9,7 +9,6 @@ public class CalculationNode extends BinaryNode {
|
||||
public CalculationNode calculationExpression;
|
||||
public EnumLineOperator operator;
|
||||
public DotNode dotExpression;
|
||||
private ITypeNode typeNode;
|
||||
|
||||
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
||||
this.calculationExpression = calculationExpression;
|
||||
|
@@ -1,11 +0,0 @@
|
||||
package ast.statement;
|
||||
|
||||
import ast.statements.IStatementNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockStatementNode {
|
||||
List<IStatementNode> statements;
|
||||
|
||||
public BlockStatementNode(List<IStatementNode> statements) {this.statements = statements;}
|
||||
}
|
@@ -281,8 +281,13 @@ public class ASTBuilder extends SimpleJavaBaseVisitor<ASTNode> {
|
||||
|
||||
@Override
|
||||
public ASTNode visitIfElseStatement(SimpleJavaParser.IfElseStatementContext ctx) {
|
||||
IfElseNode ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()),
|
||||
IfElseNode ifElseStatementNode;
|
||||
if(ctx.elseStatement() != null) {
|
||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()),
|
||||
(ElseNode) visit(ctx.elseStatement()));
|
||||
} else {
|
||||
ifElseStatementNode = new IfElseNode((IfNode) visit(ctx.ifStatement()), null);
|
||||
}
|
||||
|
||||
for (SimpleJavaParser.ElseIfStatementContext elseIf : ctx.elseIfStatement()){
|
||||
ifElseStatementNode.addElseIfStatement(((IfNode) visit(elseIf)));
|
||||
|
@@ -325,6 +325,12 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
public TypeCheckResult analyze(MethodCallNode toCheck) {
|
||||
|
||||
if (toCheck.target != null) {
|
||||
if(toCheck.target.memberAccess == null){
|
||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||
memberAccessNode.identifiers.add(toCheck.target.identifier);
|
||||
toCheck.target.memberAccess = memberAccessNode;
|
||||
}
|
||||
if (toCheck.target.identifier != null) {
|
||||
var targetType = currentScope.getLocalVar(toCheck.target.identifier);
|
||||
if (targetType == null) {
|
||||
@@ -448,6 +454,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
case PLUS, MINUS:
|
||||
if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType &&
|
||||
calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) {
|
||||
calcNode.setType(new BaseType(TypeEnum.INT));
|
||||
return new TypeCheckResult(true, new BaseType(TypeEnum.INT));
|
||||
}
|
||||
break;
|
||||
@@ -455,10 +462,12 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
}
|
||||
|
||||
} else {
|
||||
calcNode.setType(calcNode.getType());
|
||||
return new TypeCheckResult(calcRes.isValid(), calcRes.getType());
|
||||
}
|
||||
} else if (calcNode.dotExpression != null) {
|
||||
var dotRes = calcNode.dotExpression.accept(this);
|
||||
calcNode.setType(dotRes.getType());
|
||||
return new TypeCheckResult(dotRes.isValid(), dotRes.getType());
|
||||
}
|
||||
return new TypeCheckResult(false, null);
|
||||
@@ -467,7 +476,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
@Override
|
||||
public TypeCheckResult analyze(DotNode toCheck) {
|
||||
if (toCheck.dotSubstractionExpression != null) {
|
||||
return toCheck.dotSubstractionExpression.accept(this);
|
||||
var result = toCheck.dotSubstractionExpression.accept(this);
|
||||
toCheck.setType(result.getType());
|
||||
return result;
|
||||
}
|
||||
return new TypeCheckResult(false, null);
|
||||
}
|
||||
@@ -475,19 +486,35 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
@Override
|
||||
public TypeCheckResult analyze(DotSubstractionNode toCheck) {
|
||||
if (toCheck.value != null) {
|
||||
return toCheck.value.accept(this);
|
||||
var result = toCheck.value.accept(this);
|
||||
toCheck.setType(result.getType());
|
||||
return result;
|
||||
} else if (toCheck.memberAccess != null) {
|
||||
return toCheck.memberAccess.accept(this);
|
||||
var result = toCheck.memberAccess.accept(this);
|
||||
toCheck.setType(result.getType());
|
||||
return result;
|
||||
} else if (toCheck.methodCall != null) {
|
||||
return toCheck.methodCall.accept(this);
|
||||
var result = toCheck.methodCall.accept(this);
|
||||
toCheck.setType(result.getType());
|
||||
return result;
|
||||
} else if (toCheck.identifier != null) {
|
||||
if (currentScope.contains(toCheck.identifier)) {
|
||||
return new TypeCheckResult(true, currentScope.getLocalVar(toCheck.identifier));
|
||||
var type = currentScope.getLocalVar(toCheck.identifier);
|
||||
toCheck.setType(type);
|
||||
return new TypeCheckResult(true, type);
|
||||
} else if (currentFields.get(toCheck.identifier) != null) {
|
||||
return new TypeCheckResult(true, currentFields.get(toCheck.identifier));
|
||||
var type = currentFields.get(toCheck.identifier);
|
||||
toCheck.setType(type);
|
||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||
memberAccessNode.identifiers.add(toCheck.identifier);
|
||||
toCheck.memberAccess = memberAccessNode;
|
||||
return new TypeCheckResult(true, type);
|
||||
}
|
||||
} else if (toCheck.calculationExpression != null) {
|
||||
return toCheck.calculationExpression.accept(this);
|
||||
var result = toCheck.calculationExpression.accept(this);
|
||||
toCheck.setType(result.getType());
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -507,8 +534,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
}
|
||||
break;
|
||||
case OR, AND:
|
||||
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) &&
|
||||
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) {
|
||||
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.BOOL) &&
|
||||
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.BOOL)) {
|
||||
return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL));
|
||||
} else {
|
||||
errors.add(new TypeMismatchException("Both types must be Boolean"));
|
||||
@@ -532,13 +559,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
if (unary.identifier != null) {
|
||||
if (currentScope.contains(unary.identifier)) {
|
||||
return new TypeCheckResult(valid, currentScope.getLocalVar(unary.identifier));
|
||||
var type = currentScope.getLocalVar(unary.identifier);
|
||||
unary.setType(type);
|
||||
return new TypeCheckResult(valid, type);
|
||||
} else if (currentFields.get(unary.identifier) != null) {
|
||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||
memberAccessNode.identifiers.add(unary.identifier);
|
||||
unary.memberAccess = memberAccessNode;
|
||||
return new TypeCheckResult(valid, currentFields.get(unary.identifier));
|
||||
var type = currentFields.get(unary.identifier);
|
||||
unary.setType(type);
|
||||
return new TypeCheckResult(valid,type );
|
||||
} else if (unary.statement != null) {
|
||||
var result = unary.statement.accept(this);
|
||||
unary.setType(result.getType());
|
||||
@@ -548,15 +579,19 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
}
|
||||
} else if (unary.statement != null) {
|
||||
var result = unary.statement.accept(this);
|
||||
unary.setType(result.getType());
|
||||
return new TypeCheckResult(result.isValid(), result.getType());
|
||||
} else if (unary.value != null) {
|
||||
var result = unary.value.accept(this);
|
||||
unary.setType(result.getType());
|
||||
return new TypeCheckResult(result.isValid(), result.getType());
|
||||
} else if (unary.memberAccess != null) {
|
||||
var result = unary.memberAccess.accept(this);
|
||||
unary.setType(result.getType());
|
||||
return new TypeCheckResult(result.isValid(), result.getType());
|
||||
} else if (unary.expression != null) {
|
||||
var result = unary.expression.accept(this);
|
||||
unary.setType(result.getType());
|
||||
return new TypeCheckResult(result.isValid(), result.getType());
|
||||
}
|
||||
|
||||
@@ -612,6 +647,11 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
||||
|
||||
if (targetNode.memberAccess != null) {
|
||||
return targetNode.memberAccess.accept(this);
|
||||
} else if(targetNode.identifier != null) {
|
||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||
memberAccessNode.identifiers.add(targetNode.identifier);
|
||||
targetNode.memberAccess = memberAccessNode;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ public class Node {
|
||||
public void main() {
|
||||
Compiler compiler = new Compiler();
|
||||
int i = compiler.add(5, 8);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ compile-javac:
|
||||
compile-raupenpiler:
|
||||
cd ../.. ; mvn -DskipTests install
|
||||
cd ../.. ; mvn exec:java -DgenJar=true -DgenClass=true -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output'"
|
||||
cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
|
||||
# cp ../main/resources/output/CompilerInput.class .java/resources/output/raupenpiler
|
||||
|
||||
test: compile-javac compile-raupenpiler test-javac test-raupenpiler
|
||||
|
||||
@@ -29,17 +29,19 @@ test-raupenpiler:
|
||||
|
||||
|
||||
clean:
|
||||
# clean output folders
|
||||
# clean main output folders
|
||||
rm -f ../main/resources/output/*.class
|
||||
rm -f ../main/resources/output/*.jar
|
||||
# clean resources output folders
|
||||
rm -f ./resources/output/javac/*.class
|
||||
rm -f ./resources/output/raupenpiler/*.class
|
||||
rm -f ./resources/output/raupenpiler/*.jar
|
||||
# clean logs
|
||||
rm -f ../main/resources/logs/*.log
|
||||
rm -f ../main/resources/logs/*
|
||||
# clean test/java/main folders from .class files for End-to-End tests
|
||||
rm -f ./java/main/*.class
|
||||
# clean javac output from combinedFeatureTests
|
||||
rm -f ./resources/input/combinedFeatureTests/*.class
|
||||
rm -f ./resources/input/singleFeatureTests/*.class
|
||||
rm -f ./resources/input/typedAstFeatureTests/*.class
|
||||
# clean javac output from every folder
|
||||
rm -f ./resources/input/*/*.class
|
||||
# clean test results from maven surefire plugin
|
||||
rm -f ../../target/surefire-reports/*.txt
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
package main;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.tools.JavaCompiler;
|
||||
@@ -26,13 +27,17 @@ public class InputFilesTest {
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File folder1 = new File("src/test/resources/input/combinedFeatureTests");
|
||||
File folder2 = new File("src/test/resources/input/singleFeatureTests");
|
||||
File folder3 = new File("src/test/resources/input/typedAstFeatureTests");
|
||||
File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests");
|
||||
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
||||
File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests");
|
||||
File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests");
|
||||
File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(folder1);
|
||||
files.addAll(getJavaFilesFromDirectory(folder2));
|
||||
files.addAll(getJavaFilesFromDirectory(folder3));
|
||||
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
||||
// files.addAll(getJavaFilesFromDirectory(endabgabeTests));
|
||||
// files.addAll(getJavaFilesFromDirectory(singleFeatureSemanticTests));
|
||||
files.addAll(getJavaFilesFromDirectory(singleFeatureTests));
|
||||
// files.addAll(getJavaFilesFromDirectory(typedAstFeatureTests));
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
@@ -47,6 +52,133 @@ public class InputFilesTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void areCombinedFeatureTestsValid() throws IOException {
|
||||
// Get the system Java compiler
|
||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
// Try to compile the file and get the result
|
||||
int result = javac.run(null, null, null, file.getPath());
|
||||
|
||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directories.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void areEndabgabeTestsActuallyValid() throws IOException {
|
||||
// Get the system Java compiler
|
||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(endabgabeTests);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
// Try to compile the file and get the result
|
||||
int result = javac.run(null, null, null, file.getPath());
|
||||
|
||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directories.");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void areSingleFeatureSemanticTestsActuallyValid() throws IOException {
|
||||
// Get the system Java compiler
|
||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File singleFeatureSemanticTests = new File("src/test/resources/input/singleFeatureSemanticTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(singleFeatureSemanticTests);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
// Try to compile the file and get the result
|
||||
int result = javac.run(null, null, null, file.getPath());
|
||||
|
||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directories.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void areSingleFeatureTestsActuallyValid() throws IOException {
|
||||
// Get the system Java compiler
|
||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File singleFeatureTests = new File("src/test/resources/input/singleFeatureTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(singleFeatureTests);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
// Try to compile the file and get the result
|
||||
int result = javac.run(null, null, null, file.getPath());
|
||||
|
||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directories.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void areTypedAstFeatureTestsActuallyValid() throws IOException {
|
||||
// Get the system Java compiler
|
||||
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
|
||||
// Assert that the compiler is available
|
||||
assertNotNull(javac, "Java Compiler is not available");
|
||||
|
||||
File typedAstFeatureTests = new File("src/test/resources/input/typedAstFeatureTests");
|
||||
|
||||
List<File> files = getJavaFilesFromDirectory(typedAstFeatureTests);
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
for (File file : files) {
|
||||
// Try to compile the file and get the result
|
||||
int result = javac.run(null, null, null, file.getPath());
|
||||
|
||||
// Assert that the compilation succeeded (i.e., the result is zero)
|
||||
assertEquals(0, result, "Expected compilation success for " + file.getName());
|
||||
}
|
||||
} else {
|
||||
System.out.println("No files found in the directories.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This test method checks if invalid Java files fail to compile as expected.
|
||||
|
@@ -1,28 +1,25 @@
|
||||
package main;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Suite;
|
||||
import parser.ParserTest;
|
||||
import parser.ScannerTest;
|
||||
import semantic.EndToTypedAstTest;
|
||||
import semantic.SemanticTest;
|
||||
|
||||
/**
|
||||
* run every test: mvn test
|
||||
* Nutzen dieser Klasse: Eigentlich nicht vorhanden, in der Main gibts nichts zu testen
|
||||
* This class is a test suite that runs all the test classes in the project.
|
||||
* <p> run: <code> mvn test </code>
|
||||
* <p> check results in console or <code> target/surefire-reports </code>
|
||||
*/
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({
|
||||
InputFilesTest.class,
|
||||
ScannerTest.class,
|
||||
ParserTest.class,
|
||||
SemanticTest.class,
|
||||
EndToTypedAstTest.class
|
||||
})
|
||||
public class MainTest {
|
||||
@Test
|
||||
void test() {
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.java"));
|
||||
Main.compileFile(codeCharStream, "src/main/test/resources/output");
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading the file: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
// This class remains empty, it is used only as a holder for the above annotations
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,145 +0,0 @@
|
||||
package main;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
public class ReflectionsTest {
|
||||
|
||||
@Test
|
||||
public void testSimpleJavaLexerClass() throws ClassNotFoundException, NoSuchMethodException {
|
||||
Class<?> clazz = Class.forName("parser.generated.SimpleJavaLexer");
|
||||
|
||||
// Class Name
|
||||
assertEquals("parser.generated.SimpleJavaLexer", clazz.getName());
|
||||
|
||||
// Constructors
|
||||
Constructor<?>[] actualConstructors = clazz.getDeclaredConstructors();
|
||||
assertTrue(actualConstructors.length > 0, "No constructors found");
|
||||
|
||||
Constructor<?> expectedConstructor = clazz.getConstructor(CharStream.class);
|
||||
|
||||
boolean constructorFound = false;
|
||||
for (Constructor<?> constructor : actualConstructors) {
|
||||
if (constructor.equals(expectedConstructor)) {
|
||||
constructorFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(constructorFound, "Expected constructor not found in actual constructors");
|
||||
|
||||
|
||||
|
||||
// Methods
|
||||
Method[] actualMethodNames = clazz.getDeclaredMethods();
|
||||
assertTrue(actualMethodNames.length > 0);
|
||||
Arrays.stream(actualMethodNames).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||
|
||||
List<String> expectedMethodNames = Arrays.asList(
|
||||
"getTokenNames",
|
||||
"getVocabulary",
|
||||
"getGrammarFileName",
|
||||
"getRuleNames",
|
||||
"getSerializedATN",
|
||||
"getChannelNames",
|
||||
"getModeNames",
|
||||
"getATN",
|
||||
"makeRuleNames",
|
||||
"makeLiteralNames",
|
||||
"makeSymbolicNames"
|
||||
);
|
||||
|
||||
for (Method method : actualMethodNames) {
|
||||
assertTrue(expectedMethodNames.contains(method.getName()));
|
||||
}
|
||||
|
||||
for (String expectedMethodName : expectedMethodNames) {
|
||||
boolean methodFound = false;
|
||||
for (Method method : actualMethodNames) {
|
||||
if (method.getName().equals(expectedMethodName)) {
|
||||
methodFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(methodFound, "Expected method " + expectedMethodName + " not found in actual methods");
|
||||
}
|
||||
|
||||
|
||||
// Fields
|
||||
Field[] actualFieldNames = clazz.getDeclaredFields();
|
||||
assertTrue(actualFieldNames.length > 0);
|
||||
Arrays.stream(actualFieldNames).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||
|
||||
List<String> expectedFieldNames = Arrays.asList(
|
||||
"_decisionToDFA",
|
||||
"_sharedContextCache",
|
||||
"channelNames",
|
||||
"modeNames",
|
||||
"ruleNames",
|
||||
"_LITERAL_NAMES",
|
||||
"_SYMBOLIC_NAMES",
|
||||
"VOCABULARY",
|
||||
"tokenNames",
|
||||
"_serializedATN",
|
||||
"_ATN"
|
||||
);
|
||||
|
||||
for (Field field : actualFieldNames) {
|
||||
assertTrue(expectedFieldNames.contains(field.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleJavaParserClass() throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName("parser.generated.SimpleJavaParser");
|
||||
|
||||
// Class Name
|
||||
assertEquals("parser.generated.SimpleJavaParser", clazz.getName());
|
||||
|
||||
// Constructors
|
||||
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||
assertTrue(constructors.length > 0);
|
||||
|
||||
// Methods
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
assertTrue(methods.length > 0);
|
||||
Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||
|
||||
// Fields
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
assertTrue(fields.length > 0);
|
||||
Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testASTBuilderClass() throws ClassNotFoundException {
|
||||
Class<?> clazz = Class.forName("parser.astBuilder.ASTBuilder");
|
||||
|
||||
// Class Name
|
||||
assertEquals("parser.astBuilder.ASTBuilder", clazz.getName());
|
||||
|
||||
// Constructors
|
||||
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
|
||||
assertTrue(constructors.length > 0);
|
||||
|
||||
// Methods
|
||||
Method[] methods = clazz.getDeclaredMethods();
|
||||
assertTrue(methods.length > 0);
|
||||
Arrays.stream(methods).forEach(method -> System.out.println("Method: " + method.getName()));
|
||||
|
||||
// Fields
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
assertTrue(fields.length > 0);
|
||||
Arrays.stream(fields).forEach(field -> System.out.println("Field: " + field.getName()));
|
||||
}
|
||||
|
||||
// Similarly, you can add tests for SemanticAnalyzer and ByteCodeGenerator
|
||||
}
|
@@ -333,6 +333,92 @@ class AstBuilderTest {
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("If Test")
|
||||
public void ifTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
||||
|
||||
BlockNode ifBlock = new BlockNode();
|
||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
block.addStatement(new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), null));
|
||||
|
||||
block.addStatement(new ReturnNode(null));
|
||||
|
||||
ConstructorNode constructor = new ConstructorNode("public", "If", block);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "If");
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode expected = new ProgramNode();
|
||||
expected.addClass(class1);
|
||||
|
||||
ASTNode actual = Helper.generateAST(directoryPath + "If.java");
|
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("If Else Test")
|
||||
public void ifElseTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
||||
|
||||
BlockNode ifBlock = new BlockNode();
|
||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
BlockNode elseBlock = new BlockNode();
|
||||
elseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
block.addStatement(new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), new ElseNode(elseBlock)));
|
||||
|
||||
block.addStatement(new ReturnNode(null));
|
||||
|
||||
ConstructorNode constructor = new ConstructorNode("public", "IfElse", block);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "IfElse");
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode expected = new ProgramNode();
|
||||
expected.addClass(class1);
|
||||
|
||||
ASTNode actual = Helper.generateAST(directoryPath + "IfElse.java");
|
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("If Else If ElseTest")
|
||||
public void ifElseIfElseTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
block.addStatement(new LocalVariableDeclarationNode(new BaseType(TypeEnum.INT), "intValue", "=", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))));
|
||||
|
||||
BlockNode ifBlock = new BlockNode();
|
||||
ifBlock.addStatement(new DecrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
BlockNode elseBlock = new BlockNode();
|
||||
elseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
|
||||
IfElseNode ifElseStatement = new IfElseNode(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "5"))), ifBlock), new ElseNode(elseBlock));
|
||||
|
||||
BlockNode ifElseBlock = new BlockNode();
|
||||
ifElseBlock.addStatement(new IncrementNode(CrementType.SUFFIX, new AssignableNode("intValue")));
|
||||
ifElseStatement.addElseIfStatement(new IfNode(new NonCalculationNode(new UnaryNode("intValue"), "==", new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "4"))), ifElseBlock));
|
||||
|
||||
block.addStatement(ifElseStatement);
|
||||
|
||||
block.addStatement(new ReturnNode(null));
|
||||
|
||||
ConstructorNode constructor = new ConstructorNode("public", "IfElseIfElse", block);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "IfElseIfElse");
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode expected = new ProgramNode();
|
||||
expected.addClass(class1);
|
||||
|
||||
ASTNode actual = Helper.generateAST(directoryPath + "IfElseIfElse.java");
|
||||
|
||||
assertThat(actual).isEqualToComparingFieldByFieldRecursively(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Self Reference Test")
|
||||
public void selfReferneceTest(){
|
||||
|
@@ -1,45 +0,0 @@
|
||||
package semantic;
|
||||
|
||||
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.Test;
|
||||
import parser.astBuilder.ASTBuilder;
|
||||
import parser.generated.SimpleJavaLexer;
|
||||
import parser.generated.SimpleJavaParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BeginnToTAST {
|
||||
|
||||
@Test
|
||||
public void FieldTests() {
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/input/johnsTests/FieldTests.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);
|
||||
|
||||
var result = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
}
|
||||
|
||||
}
|
@@ -26,10 +26,7 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import semantic.exceptions.AlreadyDeclaredException;
|
||||
import semantic.exceptions.MultipleReturnTypes;
|
||||
import semantic.exceptions.NotDeclaredException;
|
||||
import semantic.exceptions.TypeMismatchException;
|
||||
import semantic.exceptions.*;
|
||||
import semantic.exceptions.NotDeclaredException;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -170,7 +167,7 @@ public class EndToTypedAstTest {
|
||||
|
||||
@Test
|
||||
public void typeMismatchTest() {
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/johnsTests/TypeMismatchIntBool.java");
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/TypeMismatchIntBool.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
@@ -180,7 +177,7 @@ public class EndToTypedAstTest {
|
||||
|
||||
@Test
|
||||
public void parameterAlreadyDecleared() {
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/johnsTests/ParameterAlreadyDecleared.java");
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ParameterAlreadyDecleared.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
@@ -190,7 +187,7 @@ public class EndToTypedAstTest {
|
||||
|
||||
@Test
|
||||
public void fieldAlreadyDecleared(){
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/johnsTests/FieldAlreadyDecleared.java");
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/FieldAlreadyDecleared.java");
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
@@ -200,7 +197,7 @@ public class EndToTypedAstTest {
|
||||
|
||||
@Test
|
||||
public void typeMismatchRefType(){
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/johnsTests/TypeMismatchRefType.java");
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/TypeMismatchRefType.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
@@ -210,47 +207,97 @@ public class EndToTypedAstTest {
|
||||
|
||||
@Test
|
||||
public void correctRetType(){
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/CorrectRetType.java");
|
||||
|
||||
CharStream codeCharStream = null;
|
||||
try {
|
||||
codeCharStream = CharStreams.fromPath(Paths.get("src/test/resources/semantic/endToTAST/CorrectRetType.java"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
}
|
||||
SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream);
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
@Test
|
||||
public void retTypeMismatch(){
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/RetTypeMismatch.java");
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleRetType(){
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/MultipleRetTypes.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof MultipleReturnTypes));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void BothTypesMustBeSameGreaterSmallerEqual(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/BothTypesMustBeSame.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof TypeMismatchException));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void NoSuchType(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ClassNotDeclared.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof NotDeclaredException));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void FieldIsNotVisible(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/FieldIsNotVisible.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertTrue(SemanticAnalyzer.errors.stream().anyMatch(c -> c instanceof NotVisibleException));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ChainedMethods(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/ChainedMethods.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retTypeMismatch(){
|
||||
public void VariableCompare(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
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();
|
||||
@Test
|
||||
public void IfExpressionInt(){
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java");
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
@@ -258,27 +305,36 @@ public class EndToTypedAstTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleRetType(){
|
||||
public void SelectWrongMethodCauseParameter(){
|
||||
|
||||
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);
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java");
|
||||
|
||||
SimpleJavaParser parser = new SimpleJavaParser(tokenStream);
|
||||
ParseTree parseTree = parser.program();
|
||||
|
||||
ASTBuilder astBuilder = new ASTBuilder();
|
||||
ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree);
|
||||
|
||||
ASTNode tast = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||
assertInstanceOf(MultipleReturnTypes.class, SemanticAnalyzer.errors.getFirst());
|
||||
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void SelectRightMethodCauseParameter(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectRightMethodCauseParameter.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void VariableCalculation(){
|
||||
|
||||
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCalculation.java");
|
||||
|
||||
SemanticAnalyzer.generateTast(tast);
|
||||
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,9 @@ import java.io.IOException;
|
||||
|
||||
public class SemanticHelper {
|
||||
public static ASTNode generateTypedASTFrom(String filePath) {
|
||||
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
|
||||
CharStream testFile = null;
|
||||
try {
|
||||
testFile = CharStreams.fromFileName(filePath);
|
||||
|
@@ -1,5 +1,441 @@
|
||||
package semantic;
|
||||
|
||||
import ast.ASTNode;
|
||||
import ast.ClassNode;
|
||||
import ast.ProgramNode;
|
||||
import ast.expressions.IExpressionNode;
|
||||
import ast.expressions.unaryexpressions.MemberAccessNode;
|
||||
import ast.expressions.unaryexpressions.UnaryNode;
|
||||
import ast.members.ConstructorNode;
|
||||
import ast.members.FieldNode;
|
||||
import ast.members.MethodNode;
|
||||
import ast.parameters.ParameterNode;
|
||||
import ast.statementexpressions.AssignNode;
|
||||
import ast.statementexpressions.AssignableNode;
|
||||
import ast.statementexpressions.methodcallstatementnexpressions.MethodCallNode;
|
||||
import ast.statements.BlockNode;
|
||||
import ast.statements.ReturnNode;
|
||||
import ast.type.AccessModifierNode;
|
||||
import ast.type.EnumValueNode;
|
||||
import ast.type.ValueNode;
|
||||
import ast.type.type.BaseType;
|
||||
import ast.type.type.TypeEnum;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import parser.Helper;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class SemanticTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
SemanticAnalyzer.clearAnalyzer();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Empty Class Test")
|
||||
public void emptyClassTest() {
|
||||
ClassNode emptyClass = Helper.generateEmptyClass("EmptyClass");
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(emptyClass);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("Multiple Empty Classes Test")
|
||||
public void multipleEmptyClassesTest() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("MultipleClasses");
|
||||
ClassNode class2 = Helper.generateEmptyClass("TestClass2");
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
abstractSyntaxTree.addClass(class2);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DisplayName("Empty Class Test with Constructor")
|
||||
public void emptyClassWithConstructorTest() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("EmptyClassWithConstructor");
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Field Test")
|
||||
public void fieldTest() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("Field");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Field Test with Accessmodifier")
|
||||
public void fieldTestWithModifier() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("FieldWithAccessModifier");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Comments Ignore Test")
|
||||
public void commentsIgnoreTest() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("Comments");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Constructor Parameter Test")
|
||||
public void constructorParameterTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
block.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorParameter", block);
|
||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "b"));
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "ConstructorParameter");
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("This Dot Test")
|
||||
public void thisDotTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
ValueNode value = new ValueNode(EnumValueNode.INT_VALUE, "1");
|
||||
IExpressionNode expression = new UnaryNode(value);
|
||||
|
||||
block.addStatement(new AssignNode(assignable, expression));
|
||||
block.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "ThisDot", block);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "ThisDot");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Constructor This Dot Test")
|
||||
public void constructorThisDotTest() {
|
||||
BlockNode block = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
IExpressionNode expression = new UnaryNode("a");
|
||||
|
||||
block.addStatement(new AssignNode(assignable, expression));
|
||||
block.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorThisDot", block);
|
||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "ConstructorThisDot");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("private"), new BaseType(TypeEnum.INT), "a"));
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Void Methoden Test")
|
||||
public void voidMethodenTest() {
|
||||
ClassNode class1 = Helper.generateEmptyClass("VoidMethod");
|
||||
BlockNode block = new BlockNode();
|
||||
block.addStatement(new ReturnNode(null));
|
||||
class1.addMember(new MethodNode("public", null, true, "test", block));
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Constructor Method call Test")
|
||||
public void constructorMethodCallTest() {
|
||||
BlockNode blockCon = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
IExpressionNode expression = new UnaryNode(new MethodCallNode(null, "testMethod"));
|
||||
|
||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||
blockCon.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCall", blockCon);
|
||||
|
||||
BlockNode blockMethod = new BlockNode();
|
||||
blockMethod.addStatement(new ReturnNode(new UnaryNode(new ValueNode(EnumValueNode.INT_VALUE, "1"))));
|
||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCall");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
class1.addMember(constructor);
|
||||
class1.addMember(method);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Constructor Method call Parameters Test")
|
||||
public void constructorMethodCallParametersTest() {
|
||||
BlockNode blockCon = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
|
||||
methodCall.addExpression(new UnaryNode("a"));
|
||||
IExpressionNode expression = new UnaryNode(methodCall);
|
||||
|
||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||
blockCon.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "ConstructorMethodCallParameters", blockCon);
|
||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
BlockNode blockMethod = new BlockNode();
|
||||
blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
|
||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.INT), false, "testMethod", blockMethod);
|
||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "ConstructorMethodCallParameters");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
class1.addMember(constructor);
|
||||
class1.addMember(method);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Char Test")
|
||||
public void charTest() {
|
||||
BlockNode blockCon = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
MethodCallNode methodCall = new MethodCallNode(null, "testMethod");
|
||||
methodCall.addExpression(new UnaryNode("a"));
|
||||
IExpressionNode expression = new UnaryNode(methodCall);
|
||||
|
||||
blockCon.addStatement(new AssignNode(assignable, expression));
|
||||
blockCon.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "Char", blockCon);
|
||||
constructor.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
||||
|
||||
BlockNode blockMethod = new BlockNode();
|
||||
blockMethod.addStatement(new ReturnNode(new UnaryNode("a")));
|
||||
MethodNode method = new MethodNode("public", new BaseType(TypeEnum.CHAR), false, "testMethod", blockMethod);
|
||||
method.addParameter(new ParameterNode(new BaseType(TypeEnum.CHAR), "a"));
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "Char");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.CHAR), "a"));
|
||||
class1.addMember(constructor);
|
||||
class1.addMember(method);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Null Test")
|
||||
public void nullTest() {
|
||||
BlockNode blockCon = new BlockNode();
|
||||
MemberAccessNode memberAccess = new MemberAccessNode(true);
|
||||
memberAccess.addIdentifier("a");
|
||||
|
||||
AssignableNode assignable = new AssignableNode(memberAccess);
|
||||
|
||||
blockCon.addStatement(new AssignNode(assignable, new UnaryNode(new ValueNode(EnumValueNode.NULL_VALUE, "null"))));
|
||||
blockCon.addStatement(new ReturnNode(null));
|
||||
ConstructorNode constructor = new ConstructorNode("public", "Null", blockCon);
|
||||
|
||||
ClassNode class1 = new ClassNode("public", "Null");
|
||||
class1.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
class1.addMember(constructor);
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(class1);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Self Reference Test")
|
||||
public void selfReferenceTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Variable Compare Test")
|
||||
public void variableCompareTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Variable Calculation Test")
|
||||
public void variableCalculationTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Main Method Test")
|
||||
public void mainMethodTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("While Test")
|
||||
public void whileTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Do While Test")
|
||||
public void doWhileTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("For Test")
|
||||
public void forTest() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Increment Test")
|
||||
public void incrementTest() {
|
||||
ClassNode classNode = Helper.generateEmptyClass("Increment");
|
||||
classNode.addMember(new FieldNode(new AccessModifierNode("public"), new BaseType(TypeEnum.INT), "a"));
|
||||
|
||||
ProgramNode abstractSyntaxTree = new ProgramNode();
|
||||
abstractSyntaxTree.addClass(classNode);
|
||||
|
||||
ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree);
|
||||
for (Exception runtimeException : SemanticAnalyzer.errors) {
|
||||
runtimeException.printStackTrace();
|
||||
}
|
||||
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||
assertNotNull(typedAst);
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
25
src/test/resources/input/endabgabeTests/Car.java
Normal file
25
src/test/resources/input/endabgabeTests/Car.java
Normal file
@@ -0,0 +1,25 @@
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Car myCar = new Car(2020);
|
||||
int tires = 0;
|
||||
int year = myCar.getYear();
|
||||
|
||||
if (year == 2020) {
|
||||
tires = 4;
|
||||
} else {
|
||||
tires = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Car {
|
||||
private int year;
|
||||
|
||||
public Car(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
return this.year;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
public class ControlStructures {
|
||||
|
||||
public int sum(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
public cahr checkNumber(int num) {
|
||||
if (num > 0) {
|
||||
return "p";
|
||||
} else if (num < 0) {
|
||||
return "n";
|
||||
} else {
|
||||
return "z";
|
||||
}
|
||||
}
|
||||
|
||||
public void printNumbersUpTo(int limit) {
|
||||
int even = 0;
|
||||
int uneven = 0;
|
||||
int i = 0;
|
||||
while (i < limit) {
|
||||
if (i % 2 == 0) {
|
||||
even++;
|
||||
} else {
|
||||
uneven = uneven + 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
ControlStructures cs = new ControlStructures();
|
||||
cs.printNumbersUpTo(5);
|
||||
int result = cs.sum(5, 5);
|
||||
}
|
||||
}
|
11
src/test/resources/input/endabgabeTests/Person.java
Normal file
11
src/test/resources/input/endabgabeTests/Person.java
Normal file
@@ -0,0 +1,11 @@
|
||||
public class Person {
|
||||
private int age;
|
||||
|
||||
public Person(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return this.age;
|
||||
}
|
||||
}
|
@@ -5,5 +5,18 @@ public class AllFeaturesClassExample {
|
||||
while (a > bool) {
|
||||
a--;
|
||||
}
|
||||
|
||||
if (a == bool) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if (a < bool) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
public class Test {
|
||||
|
||||
public House h;
|
||||
|
||||
public int test(House h){
|
||||
return h.getW().getSize();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class House {
|
||||
|
||||
private Window w;
|
||||
|
||||
public Window getW(){
|
||||
return w;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Window{
|
||||
|
||||
private int size;
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
}
|
@@ -4,9 +4,4 @@ public class Test {
|
||||
public House1 h;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class House {
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
public class CorrectRetType {
|
||||
public static int testMethod(int x){
|
||||
return x;
|
||||
}
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Test{
|
||||
|
||||
public void test(int x){
|
@@ -0,0 +1,6 @@
|
||||
public class MultipleRetTypes {
|
||||
public static int testMethod(int x, char c){
|
||||
return x;
|
||||
return c;
|
||||
}
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
public class Example {
|
||||
public static int testMethod(char x){
|
||||
return x;
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Test{
|
||||
|
||||
public int i;
|
||||
public boolean b;
|
||||
|
||||
public int test(){
|
||||
|
||||
return test(b);
|
||||
|
||||
}
|
||||
|
||||
public void test(int a){
|
||||
|
||||
}
|
||||
|
||||
public int test(boolean bool){
|
||||
int ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
class VariableCalculation{
|
||||
|
||||
int aPlusB(int a, int b){
|
||||
return a + b;
|
||||
}
|
||||
|
||||
int aMinusB(int a, int b){
|
||||
return a - b;
|
||||
}
|
||||
|
||||
int aTimeB(int a, int b){
|
||||
return a * b;
|
||||
}
|
||||
|
||||
int aDivB(int a, int b){
|
||||
return a / b;
|
||||
}
|
||||
|
||||
int complexCalc (int a, int b){
|
||||
return a * b / 1 * 3;
|
||||
}
|
||||
|
||||
boolean aSmallerB (int a, int b){
|
||||
return a < b;
|
||||
}
|
||||
|
||||
boolean aGreaterB (int a, int b){
|
||||
return a > b;
|
||||
}
|
||||
|
||||
boolean aEqualsB (int a, int b){
|
||||
return a == b;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
class VariableCompare{
|
||||
|
||||
boolean trueMethod() {
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean falseMethod(){
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean trueAndTrueMethod(){
|
||||
return true && true;
|
||||
}
|
||||
|
||||
boolean trueAndFalseMethod(){
|
||||
return true && false;
|
||||
}
|
||||
|
||||
boolean falseAndFalseMethod(){
|
||||
return false && false;
|
||||
}
|
||||
|
||||
boolean trueOrTrueMethod(){
|
||||
return true || true;
|
||||
}
|
||||
|
||||
boolean falseOrFalseMethod(){
|
||||
return false || false;
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
8
src/test/resources/input/singleFeatureTests/If.java
Normal file
8
src/test/resources/input/singleFeatureTests/If.java
Normal file
@@ -0,0 +1,8 @@
|
||||
public class If {
|
||||
public If() {
|
||||
int intValue = 5;
|
||||
if(intValue == 5) {
|
||||
intValue--;
|
||||
}
|
||||
}
|
||||
}
|
10
src/test/resources/input/singleFeatureTests/IfElse.java
Normal file
10
src/test/resources/input/singleFeatureTests/IfElse.java
Normal file
@@ -0,0 +1,10 @@
|
||||
public class IfElse {
|
||||
public IfElse() {
|
||||
int intValue = 5;
|
||||
if(intValue == 5) {
|
||||
intValue--;
|
||||
} else {
|
||||
intValue++;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
public class IfElseIfElse {
|
||||
public IfElseIfElse() {
|
||||
int intValue = 5;
|
||||
if(intValue == 5) {
|
||||
intValue--;
|
||||
} else if(intValue ==4) {
|
||||
intValue++;
|
||||
} else {
|
||||
intValue++;
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,13 +0,0 @@
|
||||
// @expected: TypeMismatchException
|
||||
public class Test{
|
||||
|
||||
public void test(boolean b){
|
||||
if(b == 2){
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user