Compare commits
6 Commits
084808c3ab
...
fb5372bc8f
Author | SHA1 | Date | |
---|---|---|---|
|
fb5372bc8f | ||
|
f29be4fd8c | ||
|
34bb86c7f4 | ||
|
c0e197e2d0 | ||
|
ae872ed906 | ||
91552ad147 |
35
pom.xml
35
pom.xml
@ -23,6 +23,24 @@
|
|||||||
<version>5.11.0-M2</version>
|
<version>5.11.0-M2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-runtime</artifactId>
|
<artifactId>antlr4-runtime</artifactId>
|
||||||
@ -44,18 +62,6 @@
|
|||||||
<version>3.26.0</version>
|
<version>3.26.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</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>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@ -65,6 +71,11 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
<version>3.0.0-M5</version> <!-- Change the version as needed -->
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-assembly-plugin</artifactId>
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
68
readme.md
Normal file
68
readme.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# "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/ -> MainTest, E2ETests, UtilityTests
|
||||||
|
│ ├── parser/ -> Performs tests on the parser
|
||||||
|
│ └── semantic/ -> Performs tests on the semantic check
|
||||||
|
└── resources/ -> Ressources for running the Tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Class-Diagramm AST
|
||||||
|
|
||||||
|
![AST Diagramm](ast.png)
|
||||||
|
|
||||||
|
## 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 CalculationNode calculationExpression;
|
||||||
public EnumLineOperator operator;
|
public EnumLineOperator operator;
|
||||||
public DotNode dotExpression;
|
public DotNode dotExpression;
|
||||||
private ITypeNode typeNode;
|
|
||||||
|
|
||||||
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
public CalculationNode(CalculationNode calculationExpression, String operator, DotNode dotExpression) {
|
||||||
this.calculationExpression = calculationExpression;
|
this.calculationExpression = calculationExpression;
|
||||||
|
@ -316,11 +316,15 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(IfElseNode toCheck) {
|
public TypeCheckResult analyze(IfElseNode toCheck) {
|
||||||
var resultIf = toCheck.ifStatement.accept(this);
|
var resultIf = toCheck.ifStatement.accept(this);
|
||||||
|
if(toCheck.elseStatement != null){
|
||||||
var resultElse = toCheck.elseStatement.accept(this);
|
var resultElse = toCheck.elseStatement.accept(this);
|
||||||
|
|
||||||
return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID));
|
return new TypeCheckResult(resultIf.isValid() && resultElse.isValid(), new BaseType(TypeEnum.VOID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return new TypeCheckResult(resultIf.isValid(), new BaseType(TypeEnum.VOID));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(MethodCallNode toCheck) {
|
public TypeCheckResult analyze(MethodCallNode toCheck) {
|
||||||
|
|
||||||
@ -454,6 +458,7 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
case PLUS, MINUS:
|
case PLUS, MINUS:
|
||||||
if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType &&
|
if (calcRes.getType() instanceof BaseType calcType && dotRes.getType() instanceof BaseType dotType &&
|
||||||
calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) {
|
calcType.getTypeEnum().equals(TypeEnum.INT) && dotType.getTypeEnum().equals(TypeEnum.INT)) {
|
||||||
|
calcNode.setType(new BaseType(TypeEnum.INT));
|
||||||
return new TypeCheckResult(true, new BaseType(TypeEnum.INT));
|
return new TypeCheckResult(true, new BaseType(TypeEnum.INT));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -461,10 +466,12 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
calcNode.setType(calcNode.getType());
|
||||||
return new TypeCheckResult(calcRes.isValid(), calcRes.getType());
|
return new TypeCheckResult(calcRes.isValid(), calcRes.getType());
|
||||||
}
|
}
|
||||||
} else if (calcNode.dotExpression != null) {
|
} else if (calcNode.dotExpression != null) {
|
||||||
var dotRes = calcNode.dotExpression.accept(this);
|
var dotRes = calcNode.dotExpression.accept(this);
|
||||||
|
calcNode.setType(dotRes.getType());
|
||||||
return new TypeCheckResult(dotRes.isValid(), dotRes.getType());
|
return new TypeCheckResult(dotRes.isValid(), dotRes.getType());
|
||||||
}
|
}
|
||||||
return new TypeCheckResult(false, null);
|
return new TypeCheckResult(false, null);
|
||||||
@ -473,7 +480,9 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotNode toCheck) {
|
public TypeCheckResult analyze(DotNode toCheck) {
|
||||||
if (toCheck.dotSubstractionExpression != null) {
|
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);
|
return new TypeCheckResult(false, null);
|
||||||
}
|
}
|
||||||
@ -481,19 +490,35 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public TypeCheckResult analyze(DotSubstractionNode toCheck) {
|
public TypeCheckResult analyze(DotSubstractionNode toCheck) {
|
||||||
if (toCheck.value != null) {
|
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) {
|
} 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) {
|
} 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) {
|
} else if (toCheck.identifier != null) {
|
||||||
if (currentScope.contains(toCheck.identifier)) {
|
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) {
|
} 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) {
|
} else if (toCheck.calculationExpression != null) {
|
||||||
return toCheck.calculationExpression.accept(this);
|
var result = toCheck.calculationExpression.accept(this);
|
||||||
|
toCheck.setType(result.getType());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -513,8 +538,8 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OR, AND:
|
case OR, AND:
|
||||||
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.INT) &&
|
if (expResult.getType() instanceof BaseType expResultType && expResultType.getTypeEnum().equals(TypeEnum.BOOL) &&
|
||||||
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.INT)) {
|
unaryResult.getType() instanceof BaseType unaryResultType && unaryResultType.getTypeEnum().equals(TypeEnum.BOOL)) {
|
||||||
return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL));
|
return new TypeCheckResult(true, new BaseType(TypeEnum.BOOL));
|
||||||
} else {
|
} else {
|
||||||
errors.add(new TypeMismatchException("Both types must be Boolean"));
|
errors.add(new TypeMismatchException("Both types must be Boolean"));
|
||||||
@ -538,13 +563,17 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
|
|
||||||
if (unary.identifier != null) {
|
if (unary.identifier != null) {
|
||||||
if (currentScope.contains(unary.identifier)) {
|
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) {
|
} else if (currentFields.get(unary.identifier) != null) {
|
||||||
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
MemberAccessNode memberAccessNode = new MemberAccessNode(false);
|
||||||
memberAccessNode.identifiers.add(currentClass.identifier);
|
memberAccessNode.identifiers.add(currentClass.identifier);
|
||||||
memberAccessNode.identifiers.add(unary.identifier);
|
memberAccessNode.identifiers.add(unary.identifier);
|
||||||
unary.memberAccess = memberAccessNode;
|
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) {
|
} else if (unary.statement != null) {
|
||||||
var result = unary.statement.accept(this);
|
var result = unary.statement.accept(this);
|
||||||
unary.setType(result.getType());
|
unary.setType(result.getType());
|
||||||
@ -554,15 +583,19 @@ public class SemanticAnalyzer implements SemanticVisitor {
|
|||||||
}
|
}
|
||||||
} else if (unary.statement != null) {
|
} else if (unary.statement != null) {
|
||||||
var result = unary.statement.accept(this);
|
var result = unary.statement.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.value != null) {
|
} else if (unary.value != null) {
|
||||||
var result = unary.value.accept(this);
|
var result = unary.value.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.memberAccess != null) {
|
} else if (unary.memberAccess != null) {
|
||||||
var result = unary.memberAccess.accept(this);
|
var result = unary.memberAccess.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
} else if (unary.expression != null) {
|
} else if (unary.expression != null) {
|
||||||
var result = unary.expression.accept(this);
|
var result = unary.expression.accept(this);
|
||||||
|
unary.setType(result.getType());
|
||||||
return new TypeCheckResult(result.isValid(), result.getType());
|
return new TypeCheckResult(result.isValid(), result.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ public class Node {
|
|||||||
public void main() {
|
public void main() {
|
||||||
Compiler compiler = new Compiler();
|
Compiler compiler = new Compiler();
|
||||||
int i = compiler.add(5, 8);
|
int i = compiler.add(5, 8);
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,13 +10,7 @@ compile-javac:
|
|||||||
compile-raupenpiler:
|
compile-raupenpiler:
|
||||||
cd ../.. ; mvn -DskipTests install
|
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'"
|
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
|
|
||||||
|
|
||||||
test-javac:
|
|
||||||
# gleich wie bei raupenpiler, kann ich ohne funktionierenden Compiler nicht testen
|
|
||||||
|
|
||||||
|
|
||||||
test-raupenpiler:
|
test-raupenpiler:
|
||||||
# move the compiled class to the test/main folder
|
# move the compiled class to the test/main folder
|
||||||
@ -29,17 +23,19 @@ test-raupenpiler:
|
|||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
# clean output folders
|
# clean main output folders
|
||||||
rm -f ../main/resources/output/*.class
|
rm -f ../main/resources/output/*.class
|
||||||
rm -f ../main/resources/output/*.jar
|
rm -f ../main/resources/output/*.jar
|
||||||
|
# clean resources output folders
|
||||||
rm -f ./resources/output/javac/*.class
|
rm -f ./resources/output/javac/*.class
|
||||||
rm -f ./resources/output/raupenpiler/*.class
|
rm -f ./resources/output/raupenpiler/*.class
|
||||||
|
rm -f ./resources/output/raupenpiler/*.jar
|
||||||
# clean logs
|
# 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
|
# clean test/java/main folders from .class files for End-to-End tests
|
||||||
rm -f ./java/main/*.class
|
rm -f ./java/main/*.class
|
||||||
# clean javac output from combinedFeatureTests
|
# clean javac output from every folder
|
||||||
rm -f ./resources/input/combinedFeatureTests/*.class
|
rm -f ./resources/input/*/*.class
|
||||||
rm -f ./resources/input/singleFeatureTests/*.class
|
# clean test results from maven surefire plugin
|
||||||
rm -f ./resources/input/typedAstFeatureTests/*.class
|
rm -f ../../target/surefire-reports/*.txt
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
|||||||
package main;
|
package main;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
@ -26,13 +27,17 @@ public class InputFilesTest {
|
|||||||
// Assert that the compiler is available
|
// Assert that the compiler is available
|
||||||
assertNotNull(javac, "Java Compiler is not available");
|
assertNotNull(javac, "Java Compiler is not available");
|
||||||
|
|
||||||
File folder1 = new File("src/test/resources/input/combinedFeatureTests");
|
File combinedFeatureTests = new File("src/test/resources/input/combinedFeatureTests");
|
||||||
File folder2 = new File("src/test/resources/input/singleFeatureTests");
|
File endabgabeTests = new File("src/test/resources/input/endabgabeTests");
|
||||||
File folder3 = new File("src/test/resources/input/typedAstFeatureTests");
|
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);
|
List<File> files = getJavaFilesFromDirectory(combinedFeatureTests);
|
||||||
files.addAll(getJavaFilesFromDirectory(folder2));
|
// files.addAll(getJavaFilesFromDirectory(endabgabeTests));
|
||||||
files.addAll(getJavaFilesFromDirectory(folder3));
|
// files.addAll(getJavaFilesFromDirectory(singleFeatureSemanticTests));
|
||||||
|
files.addAll(getJavaFilesFromDirectory(singleFeatureTests));
|
||||||
|
// files.addAll(getJavaFilesFromDirectory(typedAstFeatureTests));
|
||||||
|
|
||||||
if (!files.isEmpty()) {
|
if (!files.isEmpty()) {
|
||||||
for (File file : files) {
|
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.
|
* This test method checks if invalid Java files fail to compile as expected.
|
||||||
|
@ -1,28 +1,25 @@
|
|||||||
package main;
|
package main;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.runner.RunWith;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.junit.runners.Suite;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import parser.ParserTest;
|
||||||
|
import parser.ScannerTest;
|
||||||
import java.io.IOException;
|
import semantic.EndToTypedAstTest;
|
||||||
import java.nio.file.Paths;
|
import semantic.SemanticTest;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* run every test: mvn test
|
* This class is a test suite that runs all the test classes in the project.
|
||||||
* Nutzen dieser Klasse: Eigentlich nicht vorhanden, in der Main gibts nichts zu testen
|
* <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 {
|
public class MainTest {
|
||||||
@Test
|
// This class remains empty, it is used only as a holder for the above annotations
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -281,6 +281,74 @@ public class EndToTypedAstTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void VariableCompare(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/VariableCompare.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void IfExpressionInt(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/IfExpressionInt.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
assertInstanceOf(TypeMismatchException.class, SemanticAnalyzer.errors.getFirst());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void SelectWrongMethodCauseParameter(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/SelectWrongMethodCauseParameter.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertFalse(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
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());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void Expression(){
|
||||||
|
|
||||||
|
ASTNode tast = SemanticHelper.generateTypedASTFrom("src/test/resources/input/singleFeatureSemanticTests/Expression.java");
|
||||||
|
|
||||||
|
SemanticAnalyzer.generateTast(tast);
|
||||||
|
|
||||||
|
assertTrue(SemanticAnalyzer.errors.isEmpty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------ Helpers ------------------
|
// ------------------ Helpers ------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,9 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class SemanticHelper {
|
public class SemanticHelper {
|
||||||
public static ASTNode generateTypedASTFrom(String filePath) {
|
public static ASTNode generateTypedASTFrom(String filePath) {
|
||||||
|
|
||||||
|
SemanticAnalyzer.clearAnalyzer();
|
||||||
|
|
||||||
CharStream testFile = null;
|
CharStream testFile = null;
|
||||||
try {
|
try {
|
||||||
testFile = CharStreams.fromFileName(filePath);
|
testFile = CharStreams.fromFileName(filePath);
|
||||||
|
@ -1,5 +1,441 @@
|
|||||||
package semantic;
|
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 {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
class VariableCompare{
|
||||||
|
|
||||||
|
void trueMethod(boolean a, int c) {
|
||||||
|
if(a && c == 10){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
// @expected: TypeMismatchException
|
|
||||||
public class Test{
|
public class Test{
|
||||||
|
|
||||||
public void test(int x){
|
public void test(int 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.
Loading…
Reference in New Issue
Block a user