Skip to content

Commit f824cc3

Browse files
committed
Fix type resolution failures on class reference constructors
1 parent f6d56e2 commit f824cc3

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
- Name resolution failures on generic routine invocations where later type parameters are constrained by earlier type parameters.
1717
- Type resolution failures on `as` casts where the type is returned from a routine invocation.
18+
- Inaccurate type resolution when calling a constructor on a class reference type.
1819

1920
## [1.16.0] - 2025-05-09
2021

delphi-frontend/src/main/java/au/com/integradev/delphi/symbol/resolve/NameResolver.java

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,17 +1103,27 @@ private void disambiguateArguments(List<ExpressionNode> argumentExpressions, boo
11031103
}
11041104

11051105
private void resolveReturnType(Invocable invocable, List<InvocationArgument> arguments) {
1106-
if (!isConstructor((NameDeclaration) invocable)) {
1107-
Type returnType = invocable.getReturnType();
1108-
if (returnType instanceof IntrinsicReturnType) {
1109-
List<Type> argumentTypes =
1110-
arguments.stream()
1111-
.map(InvocationArgument::getType)
1112-
.collect(Collectors.toUnmodifiableList());
1113-
returnType = ((IntrinsicReturnType) returnType).getReturnType(argumentTypes);
1106+
// Constructors are a special case - they return the type they are invoked on
1107+
if (isConstructor((NameDeclaration) invocable)) {
1108+
if (currentType.isClassReference()) {
1109+
// Calling the constructor on a class reference type returns an instance of that class
1110+
updateType(((ClassReferenceType) currentType).classType());
11141111
}
1115-
updateType(returnType);
1112+
1113+
return;
11161114
}
1115+
1116+
Type returnType = invocable.getReturnType();
1117+
1118+
if (returnType instanceof IntrinsicReturnType) {
1119+
List<Type> argumentTypes =
1120+
arguments.stream()
1121+
.map(InvocationArgument::getType)
1122+
.collect(Collectors.toUnmodifiableList());
1123+
returnType = ((IntrinsicReturnType) returnType).getReturnType(argumentTypes);
1124+
}
1125+
1126+
updateType(returnType);
11171127
}
11181128

11191129
private void createCandidates(InvocationResolver resolver) {

delphi-frontend/src/test/java/au/com/integradev/delphi/executor/DelphiSymbolTableExecutorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ void testClassReferenceArgumentResolution() {
458458
@Test
459459
void testClassReferenceConstructorTypeResolution() {
460460
execute("classReferences/ConstructorTypeResolution.pas");
461-
verifyUsages(15, 10, reference(22, 2));
461+
verifyUsages(15, 10, reference(22, 2), reference(23, 2));
462462
verifyUsages(8, 16, reference(22, 11));
463463
}
464464

delphi-frontend/src/test/resources/au/com/integradev/delphi/symbol/classReferences/ConstructorTypeResolution.pas

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ procedure Proc(Obj: TObject);
2020
procedure Test(Bar: Boolean; Baz: TMetaFoo);
2121
begin
2222
Proc(Baz.Create(Bar));
23+
Proc(TMetaFoo.Create(Bar));
2324
end;
2425

2526
end.

0 commit comments

Comments
 (0)