Skip to content

Commit 932ab36

Browse files
fourlscirras
authored andcommitted
Resolve type parameters consecutively
Previously, we were resolving all type parameter constraints before resolving the type parameters themselves. This resulted in unresolved types in cases where a later type parameter relied on a previous type parameter.
1 parent ca225d3 commit 932ab36

File tree

5 files changed

+61
-48
lines changed

5 files changed

+61
-48
lines changed

CHANGELOG.md

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

88
## [Unreleased]
99

10+
### Added
11+
12+
- **API:** `TypeParameterNode::getTypeParameters` method.
13+
14+
### Fixed
15+
16+
- Name resolution failures on generic routine invocations where later type parameters are constrained by earlier type parameters.
17+
1018
## [1.16.0] - 2025-05-09
1119

1220
### Added

delphi-frontend/src/main/java/au/com/integradev/delphi/antlr/ast/node/GenericDefinitionNodeImpl.java

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,12 @@
1919
package au.com.integradev.delphi.antlr.ast.node;
2020

2121
import au.com.integradev.delphi.antlr.ast.visitors.DelphiParserVisitor;
22-
import au.com.integradev.delphi.type.generic.TypeParameterTypeImpl;
23-
import com.google.common.collect.ImmutableList;
2422
import java.util.List;
2523
import java.util.stream.Collectors;
2624
import org.antlr.runtime.Token;
27-
import org.sonar.plugins.communitydelphi.api.ast.ConstraintNode;
2825
import org.sonar.plugins.communitydelphi.api.ast.DelphiNode;
2926
import org.sonar.plugins.communitydelphi.api.ast.GenericDefinitionNode;
30-
import org.sonar.plugins.communitydelphi.api.ast.NameDeclarationNode;
3127
import org.sonar.plugins.communitydelphi.api.ast.TypeParameterNode;
32-
import org.sonar.plugins.communitydelphi.api.type.Constraint;
33-
import org.sonar.plugins.communitydelphi.api.type.Type.TypeParameterType;
3428

3529
public final class GenericDefinitionNodeImpl extends DelphiNodeImpl
3630
implements GenericDefinitionNode {
@@ -53,22 +47,10 @@ public <T> T accept(DelphiParserVisitor<T> visitor, T data) {
5347
@Override
5448
public List<TypeParameter> getTypeParameters() {
5549
if (typeParameters == null) {
56-
ImmutableList.Builder<TypeParameter> builder = ImmutableList.builder();
57-
58-
for (TypeParameterNode parameterNode : getTypeParameterNodes()) {
59-
List<Constraint> constraints =
60-
parameterNode.getConstraintNodes().stream()
61-
.map(ConstraintNode::getConstraint)
62-
.collect(Collectors.toUnmodifiableList());
63-
64-
for (NameDeclarationNode name : parameterNode.getTypeParameterNameNodes()) {
65-
TypeParameterType type = TypeParameterTypeImpl.create(name.getImage(), constraints);
66-
TypeParameter typeParameter = new TypeParameterImpl(name, type);
67-
builder.add(typeParameter);
68-
}
69-
}
70-
71-
typeParameters = builder.build();
50+
typeParameters =
51+
getTypeParameterNodes().stream()
52+
.flatMap(node -> node.getTypeParameters().stream())
53+
.collect(Collectors.toList());
7254
}
7355

7456
return typeParameters;
@@ -92,24 +74,4 @@ public String getImage() {
9274
}
9375
return image;
9476
}
95-
96-
private static final class TypeParameterImpl implements TypeParameter {
97-
private final NameDeclarationNode location;
98-
private final TypeParameterType type;
99-
100-
private TypeParameterImpl(NameDeclarationNode location, TypeParameterType type) {
101-
this.location = location;
102-
this.type = type;
103-
}
104-
105-
@Override
106-
public NameDeclarationNode getLocation() {
107-
return location;
108-
}
109-
110-
@Override
111-
public TypeParameterType getType() {
112-
return type;
113-
}
114-
}
11577
}

delphi-frontend/src/main/java/au/com/integradev/delphi/antlr/ast/node/TypeParameterNodeImpl.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
package au.com.integradev.delphi.antlr.ast.node;
2020

2121
import au.com.integradev.delphi.antlr.ast.visitors.DelphiParserVisitor;
22+
import au.com.integradev.delphi.type.generic.TypeParameterTypeImpl;
2223
import java.util.List;
2324
import java.util.stream.Collectors;
2425
import org.antlr.runtime.Token;
2526
import org.sonar.plugins.communitydelphi.api.ast.ConstraintNode;
27+
import org.sonar.plugins.communitydelphi.api.ast.GenericDefinitionNode.TypeParameter;
2628
import org.sonar.plugins.communitydelphi.api.ast.NameDeclarationNode;
2729
import org.sonar.plugins.communitydelphi.api.ast.TypeConstraintNode;
2830
import org.sonar.plugins.communitydelphi.api.ast.TypeParameterNode;
2931
import org.sonar.plugins.communitydelphi.api.ast.TypeReferenceNode;
32+
import org.sonar.plugins.communitydelphi.api.type.Constraint;
33+
import org.sonar.plugins.communitydelphi.api.type.Type.TypeParameterType;
3034

3135
public final class TypeParameterNodeImpl extends DelphiNodeImpl implements TypeParameterNode {
3236
public TypeParameterNodeImpl(Token token) {
@@ -61,4 +65,39 @@ public List<TypeReferenceNode> getTypeConstraintNodes() {
6165
public List<ConstraintNode> getConstraintNodes() {
6266
return findChildrenOfType(ConstraintNode.class);
6367
}
68+
69+
@Override
70+
public List<TypeParameter> getTypeParameters() {
71+
List<Constraint> constraints =
72+
getConstraintNodes().stream()
73+
.map(ConstraintNode::getConstraint)
74+
.collect(Collectors.toUnmodifiableList());
75+
76+
return getTypeParameterNameNodes().stream()
77+
.map(
78+
name ->
79+
new TypeParameterImpl(
80+
name, TypeParameterTypeImpl.create(name.getImage(), constraints)))
81+
.collect(Collectors.toList());
82+
}
83+
84+
private static final class TypeParameterImpl implements TypeParameter {
85+
private final NameDeclarationNode location;
86+
private final TypeParameterType type;
87+
88+
public TypeParameterImpl(NameDeclarationNode location, TypeParameterType type) {
89+
this.location = location;
90+
this.type = type;
91+
}
92+
93+
@Override
94+
public NameDeclarationNode getLocation() {
95+
return location;
96+
}
97+
98+
@Override
99+
public TypeParameterType getType() {
100+
return type;
101+
}
102+
}
64103
}

delphi-frontend/src/main/java/au/com/integradev/delphi/antlr/ast/visitors/SymbolTableVisitor.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@
8888
import org.sonar.plugins.communitydelphi.api.ast.ForToStatementNode;
8989
import org.sonar.plugins.communitydelphi.api.ast.FormalParameterNode.FormalParameterData;
9090
import org.sonar.plugins.communitydelphi.api.ast.GenericDefinitionNode;
91-
import org.sonar.plugins.communitydelphi.api.ast.GenericDefinitionNode.TypeParameter;
9291
import org.sonar.plugins.communitydelphi.api.ast.GotoStatementNode;
9392
import org.sonar.plugins.communitydelphi.api.ast.IfStatementNode;
9493
import org.sonar.plugins.communitydelphi.api.ast.ImplementationSectionNode;
@@ -402,12 +401,14 @@ private static void createTypeParameterDeclarations(
402401
.map(TypeConstraintNodeImpl.class::cast)
403402
.map(TypeConstraintNodeImpl::getTypeNode)
404403
.forEach(data.nameResolutionHelper::resolve);
405-
}
406404

407-
for (TypeParameter typeParameter : definition.getTypeParameters()) {
408-
NameDeclarationNode location = typeParameter.getLocation();
409-
var declaration = new TypeParameterNameDeclarationImpl(location, typeParameter.getType());
410-
data.addDeclaration(declaration, location);
405+
parameterNode
406+
.getTypeParameters()
407+
.forEach(
408+
param ->
409+
data.addDeclaration(
410+
new TypeParameterNameDeclarationImpl(param.getLocation(), param.getType()),
411+
param.getLocation()));
411412
}
412413
}
413414
}

delphi-frontend/src/main/java/org/sonar/plugins/communitydelphi/api/ast/TypeParameterNode.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.sonar.plugins.communitydelphi.api.ast;
2020

2121
import java.util.List;
22+
import org.sonar.plugins.communitydelphi.api.ast.GenericDefinitionNode.TypeParameter;
2223

2324
public interface TypeParameterNode extends DelphiNode {
2425
List<NameDeclarationNode> getTypeParameterNameNodes();
@@ -30,4 +31,6 @@ public interface TypeParameterNode extends DelphiNode {
3031
List<TypeReferenceNode> getTypeConstraintNodes();
3132

3233
List<ConstraintNode> getConstraintNodes();
34+
35+
List<TypeParameter> getTypeParameters();
3336
}

0 commit comments

Comments
 (0)