Skip to content

Commit

Permalink
more monomorphism improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed Sep 15, 2024
1 parent ed3d3f2 commit 5bae23f
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,32 @@ public static CallExpressionValidation checkMethodCall(@NotNull HaxeCallExpressi
inheritTypeParametersFromArgument(unresolvedParameterType, argumentType, argumentResolver, resolver, typeParamTable);
}

// heck if functionType has untyped open parameterlist, if so inherit type
if (parameterType.isFunctionType() && argumentType.isFunctionType()
&& argument instanceof HaxeFunctionLiteral literal && literal.getOpenParameterList() != null) {
// hack if functionType has untyped open parameterlist, if so inherit type, (lambdas can also be missing type)
if (parameterType.isFunctionType() && argumentType.isFunctionType() && argument instanceof HaxeFunctionLiteral literal) {
SpecificFunctionReference paramFn = parameterType.getFunctionType();
SpecificFunctionReference argFn = argumentType.getFunctionType();
argumentType = new SpecificFunctionReference(paramFn.getArguments(), argFn.getReturnType(), null, literal, literal).createHolder();
if(literal.getOpenParameterList() != null) {
argumentType = new SpecificFunctionReference(paramFn.getArguments(), argFn.getReturnType(), null, literal, literal).createHolder();
}else if (literal.getParameterList() != null) {
List<HaxeParameter> list = literal.getParameterList().getParameterList();
List<SpecificFunctionReference.Argument> argumentsArgs = argFn.getArguments();
List<SpecificFunctionReference.Argument> paramsArgs = paramFn.getArguments();
int min = Math.min(Math.min(list.size(), argumentsArgs.size()),paramsArgs.size());

for (int i = 0; i < min; i++) {
HaxeParameter haxeParameter = list.get(i);
if (haxeParameter.getTypeTag() == null && haxeParameter.getVarInit() == null) {
SpecificFunctionReference.Argument argArg = argumentsArgs.get(i);
SpecificFunctionReference.Argument paramArg = paramsArgs.get(i);
ResultHolder argArgType = argArg.getType();
ResultHolder paramArgType = paramArg.getType();
if(argArgType.isUnknown() && !paramArgType.isUnknown()) {
argumentsArgs.set(i, argArg.withType(paramArgType));
}
}
}
argumentType = new SpecificFunctionReference(argumentsArgs, argFn.getReturnType(), null, literal, literal).createHolder();
}
}

//TODO properly resolve typedefs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ static ResultHolder _handle(final PsiElement element,
ResultHolder typeHolder) {
// if new expression is missing typeParameters try to resolve from usage
HaxeType type = expression.getType();
if (type.getTypeParam() == null && typeHolder.getClassType() != null && typeHolder.getClassType().getSpecifics().length > 0) {
if (type != null && type.getTypeParam() == null && typeHolder.getClassType() != null && typeHolder.getClassType().getSpecifics().length > 0) {
HaxePsiField fieldDeclaration = PsiTreeUtil.getParentOfType(expression, HaxePsiField.class);
if (fieldDeclaration != null && fieldDeclaration.getTypeTag() == null) {
SpecificHaxeClassReference classType = typeHolder.getClassType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ else if (subelement instanceof HaxeSwitchCaseExpr caseExpr) {
else {
// attempt to resolve sub-element using default handle logic
if (!(subelement instanceof PsiPackage)) {
typeHolder = handleWithRecursionGuard(subelement, context, resolver);//TODO null should probably block result cache
typeHolder = handleWithRecursionGuard(subelement, context, resolver);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,22 @@ public static ResultHolder searchReferencesForTypeParameters(final HaxeComponent
PsiElement parent = expression.getParent();

if (reference instanceof HaxeReferenceExpression referenceExpression) {
ResultHolder unified = tryFindTypeWhenUsedAsParameterInCallExpression(resultHolder, referenceExpression, parent);
if (unified != null) return unified;
ResultHolder result = tryFindTypeWhenUsedAsParameterInCallExpression(resultHolder, referenceExpression, parent);
if (result != null) return mapTypeParameter(resultHolder, result);
}

if (parent instanceof HaxeAssignExpression assignExpression) {
ResultHolder result = tryTypeFromAssignExpression(context, resolver, resultHolder, assignExpression);
if (result != null) return result;
ResultHolder result = tryTypeFromAssignExpression(context, resolver, resultHolder, assignExpression, componentName);
if (result != null) return mapTypeParameter(resultHolder, result);
}
if (parent instanceof HaxeReferenceExpression referenceExpression) {
ResultHolder resolve = tryFindTypeFromMethodCallOnReference(resultHolder, referenceExpression, isFirst);
if (resolve != null) return resolve;
ResultHolder result = tryFindTypeFromMethodCallOnReference(resultHolder, referenceExpression, isFirst);
if (result != null) return mapTypeParameter(resultHolder, result);
}

if (parent instanceof HaxeObjectLiteralElement literalElement) {
ResultHolder result = tryTypeFromObjectLiteral(context, resolver, literalElement);
if (result != null) return result;
if (result != null) return mapTypeParameter(resultHolder, result);
}

if (parent instanceof HaxeArrayAccessExpression arrayAccessExpression) {
Expand All @@ -141,6 +141,13 @@ public static ResultHolder searchReferencesForTypeParameters(final HaxeComponent
return resultHolder;
}

private static @NotNull ResultHolder mapTypeParameter(ResultHolder current, ResultHolder found) {
if(current.canAssign(found)) {
return found;
}
return current;
}

private static void tryUpdateTypePAramFromOjbectLiteral(HaxeExpressionEvaluatorContext context,
HaxeGenericResolver resolver,
HaxeObjectLiteralElement literalElement,
Expand Down Expand Up @@ -316,11 +323,37 @@ private static void tryUpdateTypeParamFromArrayAccess(HaxeExpressionEvaluatorCon
}

private static @Nullable ResultHolder tryTypeFromAssignExpression(HaxeExpressionEvaluatorContext context,
HaxeGenericResolver resolver,
ResultHolder resultHolder,
HaxeAssignExpression assignExpression) {
HaxeGenericResolver resolver,
ResultHolder resultHolder,
HaxeAssignExpression assignExpression, HaxeComponentName componentName) {
boolean isRight = false;
boolean isLeft = false;

HaxeExpression rightExpression = assignExpression.getRightExpression();
ResultHolder result = handleWithRecursionGuard(rightExpression, context, resolver);
HaxeExpression leftExpression = assignExpression.getLeftExpression();


if(rightExpression instanceof HaxeReferenceExpression referenceExpression) {
PsiElement resolve = referenceExpression.resolve();
if(resolve instanceof HaxeNamedComponent namedComponent) {
if(namedComponent.getComponentName() == componentName) {
isRight = true;
}
}
}
if(!isRight) {
if (leftExpression instanceof HaxeReferenceExpression referenceExpression) {
PsiElement resolve = referenceExpression.resolve();
if (resolve instanceof HaxeNamedComponent namedComponent) {
if (namedComponent.getComponentName() == componentName) {
isLeft = true;
}
}
}
}

if(isLeft || isRight) {
ResultHolder result = handleWithRecursionGuard(isLeft ? rightExpression : leftExpression, context, resolver);
if (result != null && !result.isUnknown() && result.getType().isSameType(resultHolder.getType())) {
HaxeGenericResolver resultResolver = result.getClassType().getGenericResolver();
HaxeGenericResolver resultResolverWithoutUnknowns = resultResolver.withoutUnknowns();
Expand All @@ -329,6 +362,8 @@ private static void tryUpdateTypeParamFromArrayAccess(HaxeExpressionEvaluatorCon
return result;
}
}
}

return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -591,14 +591,6 @@ else if (entry.type().equals(specific)) {
return null;
}

public void addAssignHint(HaxeGenericResolver resolver) {
Optional<ResolverEntry> assign = resolver.findAssignToType();
if(assign.isPresent()) {
// remove old if present
resolvers.removeIf(entry -> entry.resolveSource() == ResolveSource.ASSIGN_TYPE);
resolvers.add(assign.get().copy());
}
}

public SpecificFunctionReference substituteTypeParamsWithAssignHintTypes(SpecificFunctionReference type) {
Optional<ResolverEntry> assignHint = findAssignToType();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class MonomorphTest {
mapDelayed.set(<error descr="Type mismatch (Expected: 'String' got: 'Int')">1</error>, <error descr="Type mismatch (Expected: 'Int' got: 'String')">"test"</error>);
}

var myMap = new Map<String,Int>();

public function advancemonomorphism(morphA, morphB):Void {
var arr = [""];
arr.push(morphA);
Expand All @@ -48,6 +50,12 @@ class MonomorphTest {

morphB = <error descr="Incompatible type: String should be Int">""</error>; // Wrong already morphed Int
var <error descr="Incompatible type: Int should be String">test2:String = morphB</error>; // Wrong already morphed Int

var someMap = new Map();
myMap = someMap;

someMap.set(<error descr="Type mismatch (Expected: 'String' got: 'Int')">1</error>,1); // Wrong already morphed to Map<String, Int>

}

}

0 comments on commit 5bae23f

Please sign in to comment.