Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a12545e8f | ||
|
|
a5c8d93e4c | ||
|
|
e70f071c63 | ||
|
|
f66499b4fe |
No files matched your search
@@ -0,0 +1,3 @@
|
|||||||
|
public class Bug421 {
|
||||||
|
public m() { return 1 } // Missing semicolon
|
||||||
|
}
|
||||||
@@ -2,9 +2,8 @@ package de.dhbwstuttgart.exceptions;
|
|||||||
|
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
public class ParserError extends TypeinferenceException{
|
public class ParserError extends RuntimeException{
|
||||||
|
public ParserError(String message) {
|
||||||
public ParserError(Token offset){
|
super(message);
|
||||||
super("Fehler beim Parsen", offset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.dhbwstuttgart.parser;
|
package de.dhbwstuttgart.parser;
|
||||||
|
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
|
import de.dhbwstuttgart.exceptions.ParserError;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
import de.dhbwstuttgart.parser.antlr.Java17Lexer;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
import de.dhbwstuttgart.parser.antlr.Java17Parser;
|
||||||
@@ -8,9 +9,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
|||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
|
||||||
import de.dhbwstuttgart.util.Logger;
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
|
||||||
import org.antlr.v4.runtime.CommonTokenStream;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -21,13 +20,25 @@ public class JavaTXParser {
|
|||||||
|
|
||||||
public static Logger logger = new Logger("Parser");
|
public static Logger logger = new Logger("Parser");
|
||||||
|
|
||||||
|
public static class ThrowingErrorListener extends BaseErrorListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
|
||||||
|
int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||||
|
throw new ParserError("Syntax error at line " + line + ":" + charPositionInLine + " - " + msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
public static Java17Parser.SourceFileContext parse(File source) throws IOException, java.lang.ClassNotFoundException {
|
||||||
InputStream stream = new FileInputStream(source);
|
InputStream stream = new FileInputStream(source);
|
||||||
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
// DEPRECATED: ANTLRInputStream input = new ANTLRInputStream(stream);
|
||||||
|
var errorListener = new ThrowingErrorListener();
|
||||||
CharStream input = CharStreams.fromStream(stream);
|
CharStream input = CharStreams.fromStream(stream);
|
||||||
Java17Lexer lexer = new Java17Lexer(input);
|
Java17Lexer lexer = new Java17Lexer(input);
|
||||||
|
lexer.addErrorListener(errorListener);
|
||||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||||
Java17Parser parser = new Java17Parser(tokens);
|
Java17Parser parser = new Java17Parser(tokens);
|
||||||
|
parser.addErrorListener(errorListener);
|
||||||
return parser.sourceFile();
|
return parser.sourceFile();
|
||||||
/*
|
/*
|
||||||
* SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); return generator.convert(tree);
|
* SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(source)); return generator.convert(tree);
|
||||||
|
|||||||
@@ -618,7 +618,7 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TargetExpression generateCall(TargetMethod method, List<TargetLocalVar> params, TargetType classType, boolean isInterface) {
|
private static TargetExpression generateCall(TargetMethod method, List<TargetLocalVar> params, TargetType classType) {
|
||||||
var mParams = new ArrayList<TargetExpression>();
|
var mParams = new ArrayList<TargetExpression>();
|
||||||
for (var i = 0; i < params.size(); i++) {
|
for (var i = 0; i < params.size(); i++) {
|
||||||
var tpe = method.signature().parameters().get(i).pattern().type();
|
var tpe = method.signature().parameters().get(i).pattern().type();
|
||||||
@@ -626,11 +626,11 @@ public class ASTToTargetAST {
|
|||||||
}
|
}
|
||||||
TargetExpression caseBody = new TargetMethodCall(
|
TargetExpression caseBody = new TargetMethodCall(
|
||||||
method.signature().returnType(),
|
method.signature().returnType(),
|
||||||
method.isStatic() ? new TargetClassName(classType) : new TargetThis(classType),
|
new TargetThis(classType),
|
||||||
mParams,
|
mParams,
|
||||||
classType,
|
classType,
|
||||||
method.name(),
|
method.name(),
|
||||||
method.isStatic(), isInterface, method.isPrivate()
|
false, false, method.isPrivate()
|
||||||
);
|
);
|
||||||
if (method.signature().returnType() != null) {
|
if (method.signature().returnType() != null) {
|
||||||
caseBody = new TargetReturn(caseBody);
|
caseBody = new TargetReturn(caseBody);
|
||||||
@@ -638,11 +638,11 @@ public class ASTToTargetAST {
|
|||||||
return caseBody;
|
return caseBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType, boolean isInterface) {
|
private TargetExpression generatePatternOverloadsRec(int offset, TargetExpression switchExpr, List<TargetLocalVar> params, List<TargetPattern> patterns, List<TargetMethod> methods, TargetType classType) {
|
||||||
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
if (methods.isEmpty()) throw new DebugException("Couldn't find a candidate for switch overloading");
|
||||||
if (methods.size() == 1) {
|
if (methods.size() == 1) {
|
||||||
var method = methods.getFirst();
|
var method = methods.getFirst();
|
||||||
return generateCall(method, params, classType, isInterface);
|
return generateCall(method, params, classType);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cases = new ArrayList<TargetSwitch.Case>();
|
var cases = new ArrayList<TargetSwitch.Case>();
|
||||||
@@ -691,11 +691,11 @@ public class ASTToTargetAST {
|
|||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
if (candidates.isEmpty()) {
|
if (candidates.isEmpty()) {
|
||||||
var body = new TargetBlock(List.of(generateCall(method, params, classType, isInterface)));
|
var body = new TargetBlock(List.of(generateCall(method, params, classType)));
|
||||||
cases.add(new TargetSwitch.Case(List.of(lastPattern), body));
|
cases.add(new TargetSwitch.Case(List.of(lastPattern), body));
|
||||||
} else {
|
} else {
|
||||||
//candidates.forEach(m -> Target.logger.info(m.getSignature()));
|
//candidates.forEach(m -> Target.logger.info(m.getSignature()));
|
||||||
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType, isInterface);
|
var caseBody = generatePatternOverloadsRec(offset + 1, expr, params, patternsRec, candidates, classType);
|
||||||
var body = new TargetBlock(List.of(caseBody));
|
var body = new TargetBlock(List.of(caseBody));
|
||||||
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
var case_ = new TargetSwitch.Case(List.of(lastPattern), body);
|
||||||
|
|
||||||
@@ -787,7 +787,7 @@ public class ASTToTargetAST {
|
|||||||
var parameters = resParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
var parameters = resParams.stream().map( p -> new TargetLocalVar(p.pattern().type(), p.pattern().name())).toList();
|
||||||
|
|
||||||
var classType = new TargetRefType(clazz.getClassName().toString());
|
var classType = new TargetRefType(clazz.getClassName().toString());
|
||||||
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(resParams.getFirst().pattern().type(), resParams.getFirst().pattern().name()), parameters, List.of(), methods, classType, clazz.isInterface());
|
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(resParams.getFirst().pattern().type(), resParams.getFirst().pattern().name()), parameters, List.of(), methods, classType);
|
||||||
var block = new TargetBlock(List.of(stmt));
|
var block = new TargetBlock(List.of(stmt));
|
||||||
|
|
||||||
var generics = new HashSet<>(firstMethod.signature().generics());
|
var generics = new HashSet<>(firstMethod.signature().generics());
|
||||||
@@ -870,7 +870,7 @@ public class ASTToTargetAST {
|
|||||||
|
|
||||||
// Generate dispatch method
|
// Generate dispatch method
|
||||||
var classType = new TargetRefType(clazz.getClassName().toString());
|
var classType = new TargetRefType(clazz.getClassName().toString());
|
||||||
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType, clazz.isInterface());
|
var stmt = generatePatternOverloadsRec(0, new TargetLocalVar(signatureParams.getFirst().pattern().type(), signatureParams.getFirst().pattern().name()), parameters, List.of(), res, classType);
|
||||||
var block = new TargetBlock(List.of(stmt));
|
var block = new TargetBlock(List.of(stmt));
|
||||||
|
|
||||||
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, group.signature.java, group.signature.tx, firstMethod.base(), null);
|
var bridgeMethod = new TargetMethod(firstMethod.access(), firstMethod.name(), block, group.signature.java, group.signature.tx, firstMethod.base(), null);
|
||||||
|
|||||||
@@ -256,9 +256,9 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
foundMethod = findMethod(receiverName, methodCall.name, signature, converter.compiler).orElseThrow(
|
foundMethod = findMethod(receiverName, methodCall.name, signature, converter.compiler).orElseThrow(
|
||||||
() -> new DebugException("Method " + methodCall.name + " not found (" + finalSignature + ") on class " + receiverName)
|
() -> new DebugException("Method " + methodCall.name + " not found (" + finalSignature + ") on class " + receiverName)
|
||||||
);
|
);
|
||||||
if (foundMethod != null) {
|
//if (foundMethod != null) {
|
||||||
signature = foundMethod.getParameterList().getFormalparalist().stream().map(pattern -> converter.convert(pattern.getType(), generics)).toList();
|
// signature = foundMethod.getParameterList().getFormalparalist().stream().map(pattern -> converter.convert(pattern.getType(), generics)).toList();
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isFunNType) {
|
if (!isFunNType) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.CodeGenException;
|
import de.dhbwstuttgart.bytecode.CodeGenException;
|
||||||
import de.dhbwstuttgart.core.ConsoleInterface;
|
import de.dhbwstuttgart.core.ConsoleInterface;
|
||||||
|
import de.dhbwstuttgart.exceptions.ParserError;
|
||||||
import de.dhbwstuttgart.exceptions.WarningsException;
|
import de.dhbwstuttgart.exceptions.WarningsException;
|
||||||
import de.dhbwstuttgart.util.Logger;
|
import de.dhbwstuttgart.util.Logger;
|
||||||
import de.dhbwstuttgart.util.Logger.LogLevel;
|
import de.dhbwstuttgart.util.Logger.LogLevel;
|
||||||
@@ -1083,6 +1084,7 @@ public class TestComplete {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPatternMatchingInterface() throws Exception {
|
public void testPatternMatchingInterface() throws Exception {
|
||||||
|
ConsoleInterface.logLevel = LogLevel.INFO;
|
||||||
var classFiles = generateClassFiles(createClassLoader(), false, "Matcher.jav", "PatternMatchingInterface.jav");
|
var classFiles = generateClassFiles(createClassLoader(), false, "Matcher.jav", "PatternMatchingInterface.jav");
|
||||||
var Intf = classFiles.get("Interface");
|
var Intf = classFiles.get("Interface");
|
||||||
var clazz = classFiles.get("PatternMatchingInterface");
|
var clazz = classFiles.get("PatternMatchingInterface");
|
||||||
@@ -1703,4 +1705,14 @@ public class TestComplete {
|
|||||||
var clazz = classFiles.get("Bug406");
|
var clazz = classFiles.get("Bug406");
|
||||||
clazz.getDeclaredMethod("main", List.class).invoke(null, List.of());
|
clazz.getDeclaredMethod("main", List.class).invoke(null, List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBug421() throws Exception {
|
||||||
|
try {
|
||||||
|
var classFiles = generateClassFiles(createClassLoader(), "Bug421.jav");
|
||||||
|
fail("Shouldn't compile!");
|
||||||
|
} catch (ParserError e) {
|
||||||
|
assertEquals("Syntax error at line 2:26 - no viable alternative at input 'm() { return 1 }'", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user