-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/refactor fix more tests #173
Conversation
Currently it still fails, though.
…ded by an expansion with generic arguments
… for Definitions shadowing globals
@@ -469,4 +470,8 @@ public int hashCode() { | |||
result = 31 * result + (hasUnknowns ? 1 : 0); | |||
return result; | |||
} | |||
|
|||
public boolean hasInvalidTypes() { | |||
return Stream.of(parameters).anyMatch(p -> p.type.isInvalid()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Thought: While writing this I found out we have BasicTypeID.INVALID
and InvalidTypeID
.
Do we need to change some calls that only compare for == BasicTypeID.INVALID
to check for isInvalid()
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should change that.
@@ -27,13 +28,19 @@ public interface ResolvedType { | |||
default Optional<Expression> tryCastExplicit(TypeID target, ExpressionCompiler compiler, CodePosition position, Expression value, boolean optional) { | |||
return findCaster(target) | |||
.filter(caster -> !caster.getModifiers().isImplicit()) | |||
.map(caster -> caster.call(compiler.at(position), value, CallArguments.EMPTY)); | |||
.flatMap(caster -> MatchedCallArguments.match(compiler, position, Collections.singletonList(caster), target, TypeID.NONE) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes were done since we need the ExpansionTypeParameters even for a caster.
Is there a better way than matching the method like this or is this fine?
Optional<IGlobal> global = context.findGlobal(name.name); | ||
if (global.isPresent()) | ||
return global.map(g -> g.getExpression(position, name.arguments).compile(this)); | ||
// Resolve a local type first so that functions can shadow Globals |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have any side-effects that could cause us trouble?
@@ -74,6 +75,10 @@ public Statement transform(ExpressionTransformer transformer, ConcatMap<LoopStat | |||
|
|||
@Override | |||
public Optional<TypeID> getReturnType() { | |||
if(statements.length == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure if this check should be a special-case check here or further below if the collect
List is empty?
|
||
int i = 1; | ||
int i = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Thought: We probably need to do similar changes to the other methods in this class, but so far only this one caused Tests to fail 🤷🏽♂️
return resolvedType.findImplicitConstructor() | ||
.map(constructor -> constructor.casted(compiler, position, cast, null, this)) | ||
.orElseGet(() -> cast.invalid(CompileErrors.invalidArrayType(cast.type))); | ||
Optional<CastedExpression> implicitConstructor = resolvedType.findImplicitConstructor() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In theory this and check and the cast.of(eval())
branch cause implicit ctors to be checked twice.
But if we remove this here, some matching didn't work so I left it in
compiled.setBody(body.compile(compiler.forMethod(compiled.header.withReturnType(BasicTypeID.VOID)))); | ||
|
||
// Implicit .ctors return the created object, but "normal" ones don't, so for non-implict .ctors we change the header to return VOID | ||
FunctionHeader compilingHeader = modifiers.isImplicit() ? compiled.header : compiled.header.withReturnType(BasicTypeID.VOID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Question: Is this the proper place for that check?
78dc709
to
55af6be
Compare
@@ -559,4 +567,12 @@ public static CompileError invalidPropertySetter(TypeID type, String name) { | |||
public static CompileError invalidPropertyPair(TypeID type, String name) { | |||
return new CompileError(CompileExceptionCode.INVALID_PROPERTY_PAIR, "Setter and getter of property " + name + " in type " + type + " have different types"); | |||
} | |||
|
|||
public static CompileError invalidLambdaHeader(FunctionHeader header) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏷️ Naming: We probably need a better name here
@@ -1,4 +1,5 @@ | |||
#error: 4:TYPE_NOT_INFERRED | |||
#error: 5:TYPE_NOT_INFERRED | |||
#error: 5:MISSING_RETURN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Question: Should this report both errors?
* @param statement the statement to validate | ||
* @param validator the validator used to log errors | ||
*/ | ||
public static void validate(TypeID returnType, Statement statement, Validator validator) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Are all members checked by now?
- FunctionalMembers (methods, operators, ...)
- Getters
- Implicit constructors (only implicit)
- FunctionsDefinition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setters also, with return type void
* @param validator the validator used to log errors | ||
*/ | ||
public static void validate(TypeID returnType, Statement statement, Validator validator) { | ||
if (returnType == BasicTypeID.VOID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Discussion: We could move the returnType check outside this function and only ever call this function if we know the type is not void. Which approach do we like more?
.map(it -> it.content.accept(this)) | ||
.reduce(ReturnKind::branches) | ||
.orElse(ReturnKind.NEVER_RETURNS); | ||
ReturnKind finallyClause = statement.finallyClause == null ? ReturnKind.NEVER_RETURNS : statement.finallyClause.accept(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Question: Do we actually allow return
statements inside finally blocks?
for (Statement statement : statements) { | ||
if (result == ReturnKind.ALWAYS_RETURNS) { | ||
validator.logError(statement.position, CompileErrors.unreachableStatement()); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓ Question: Should we log this for all following statements or is the first one fine?
public static ReturnKind branches(ReturnKind a, ReturnKind b) { | ||
if (a == NEVER_RETURNS && b == NEVER_RETURNS) { | ||
return NEVER_RETURNS; | ||
} | ||
if (a == ALWAYS_RETURNS && b == ALWAYS_RETURNS) { | ||
return ALWAYS_RETURNS; | ||
} | ||
return RETURNS_IN_SOME_CASES; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💭 Discussion: The same functionality would be achieved by the code block below.
I find the explicit if/else structure more readable, what do you think?
public static ReturnKind branches(ReturnKind a, ReturnKind b) { | |
if (a == NEVER_RETURNS && b == NEVER_RETURNS) { | |
return NEVER_RETURNS; | |
} | |
if (a == ALWAYS_RETURNS && b == ALWAYS_RETURNS) { | |
return ALWAYS_RETURNS; | |
} | |
return RETURNS_IN_SOME_CASES; | |
} | |
public static ReturnKind branches(ReturnKind a, ReturnKind b) { | |
return a == b ? a : RETURNS_IN_SOME_CASES; | |
} |
@@ -469,4 +470,8 @@ public int hashCode() { | |||
result = 31 * result + (hasUnknowns ? 1 : 0); | |||
return result; | |||
} | |||
|
|||
public boolean hasInvalidTypes() { | |||
return Stream.of(parameters).anyMatch(p -> p.type.isInvalid()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we should change that.
|
||
@Override | ||
public ReturnKind visitForeach(ForeachStatement statement) { | ||
return statement.getContent().accept(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not correct if there are zero elements
* @param statement the statement to validate | ||
* @param validator the validator used to log errors | ||
*/ | ||
public static void validate(TypeID returnType, Statement statement, Validator validator) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setters also, with return type void
No description provided.