From cb7a68396fc40eae61718cd8a73d1774172d78d1 Mon Sep 17 00:00:00 2001 From: m0rkeulv Date: Thu, 15 Feb 2024 19:38:55 +0100 Subject: [PATCH] better handling of typeParameters with default values --- .../semantics/HaxeTypeAnnotator.java | 35 ++++++++++++++----- .../haxe/model/HaxeGenericParamModel.java | 9 +++++ .../annotation.semantic/TypeParameterCount.hx | 21 ++++++++++- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeTypeAnnotator.java b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeTypeAnnotator.java index c84eee52f..53c0db60f 100644 --- a/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeTypeAnnotator.java +++ b/src/main/java/com/intellij/plugins/haxe/ide/annotator/semantics/HaxeTypeAnnotator.java @@ -7,6 +7,7 @@ import com.intellij.plugins.haxe.lang.psi.*; import com.intellij.plugins.haxe.model.HaxeClassModel; import com.intellij.plugins.haxe.model.HaxeDocumentModel; +import com.intellij.plugins.haxe.model.HaxeGenericParamModel; import com.intellij.plugins.haxe.model.fixer.HaxeFixer; import com.intellij.plugins.haxe.model.type.HaxeTypeResolver; import com.intellij.plugins.haxe.model.type.SpecificHaxeClassReference; @@ -14,6 +15,8 @@ import com.intellij.psi.PsiIdentifier; import org.jetbrains.annotations.NotNull; +import java.util.List; + import static com.intellij.plugins.haxe.ide.annotator.HaxeSemanticAnnotatorInspections.INVALID_TYPE_NAME; import static com.intellij.plugins.haxe.lang.psi.HaxePsiModifier.DYNAMIC; @@ -81,15 +84,25 @@ private static void checkTypeParametersForType(HaxeType type, AnnotationHolder h if (haxeClass != null) { // Dynamic is special and does not require Type parameter to de specified if (DYNAMIC.equalsIgnoreCase(haxeClass.getName())) return; + String typeName = getTypeName(type.getReferenceExpression().getIdentifier()); + if (typeName.startsWith("$"))return; // ignore when type is from macro variable + int typeParameterCount = type.getTypeParam() == null ? 0 : type.getTypeParam().getTypeList().getTypeListPartList().size(); - int classParameterCount = countTypeParameters(haxeClass); + int classParameterCountMin = minTypeParameters(haxeClass); + int classParameterCountMax = maxTypeParameters(haxeClass); + + if (typeParameterCount < classParameterCountMin) { - if (typeParameterCount != classParameterCount) { - String typeName = getTypeName(type.getReferenceExpression().getIdentifier()); + + holder.newAnnotation(HighlightSeverity.ERROR, + HaxeBundle.message("haxe.inspections.parameter.count.mismatch.description", typeName, classParameterCountMin, typeParameterCount)) + .range(type) + .create(); + } + if (typeParameterCount > classParameterCountMax) { if (typeName.startsWith("$"))return; // ignore when type is from macro variable holder.newAnnotation(HighlightSeverity.ERROR, - HaxeBundle.message("haxe.inspections.parameter.count.mismatch.description", typeName, classParameterCount, - typeParameterCount)) + HaxeBundle.message("haxe.inspections.parameter.count.mismatch.description", typeName, classParameterCountMax, typeParameterCount)) .range(type) .create(); } @@ -98,10 +111,14 @@ private static void checkTypeParametersForType(HaxeType type, AnnotationHolder h } - static private int countTypeParameters(HaxeClass haxeClass) { - HaxeGenericParam param = haxeClass.getGenericParam(); - if (param == null) return 0; - return param.getGenericListPartList().size(); + static private int minTypeParameters(HaxeClass haxeClass) { + List params = haxeClass.getModel().getGenericParams(); + boolean allHasDefaults = params.stream().allMatch(HaxeGenericParamModel::hasDefault); + if (allHasDefaults) return 0; + return params.size(); + } + static private int maxTypeParameters(HaxeClass haxeClass) { + return haxeClass.getModel().getGenericParams().size(); } private static String getTypeName(PsiIdentifier identifier) { diff --git a/src/main/java/com/intellij/plugins/haxe/model/HaxeGenericParamModel.java b/src/main/java/com/intellij/plugins/haxe/model/HaxeGenericParamModel.java index 922930180..b9b8d76a9 100644 --- a/src/main/java/com/intellij/plugins/haxe/model/HaxeGenericParamModel.java +++ b/src/main/java/com/intellij/plugins/haxe/model/HaxeGenericParamModel.java @@ -34,10 +34,14 @@ public class HaxeGenericParamModel { final private HaxeGenericListPart part; final private String name; final private int index; + final private HaxeTypeOrAnonymous defaultType; + final private HaxeFunctionType defaultFunction; public HaxeGenericParamModel(@NotNull HaxeGenericListPart part, int index) { this.index = index; this.part = part; + this.defaultType = part.getTypeOrAnonymous(); + this.defaultFunction = part.getFunctionType(); this.name = part.getComponentName().getText(); } @@ -49,6 +53,11 @@ public String getName() { return this.name; } + public boolean hasDefault() { + return defaultType != null || defaultFunction != null; + } + + public HaxeGenericListPart getPsi() { return part; } @Nullable diff --git a/src/test/resources/testData/annotation.semantic/TypeParameterCount.hx b/src/test/resources/testData/annotation.semantic/TypeParameterCount.hx index 1ec605d29..73754e9ce 100644 --- a/src/test/resources/testData/annotation.semantic/TypeParameterCount.hx +++ b/src/test/resources/testData/annotation.semantic/TypeParameterCount.hx @@ -11,5 +11,24 @@ class Test //Wrong var myMap5:Map = new Map(); var myMap6:Map = new Map(); + + //OK (default type parameters on all) + var defaultTypeParam1:Foo; + var defaultTypeParam2:Foo; + var defaultTypeParam3:Foo; + var defaultTypeParam4:Foo; + + // OK + var defaultTypeParam4:Bar; + // Wrong (all requred when only some have default value) + var defaultTypeParam1:Bar; + var defaultTypeParam2:Bar; + var defaultTypeParam3:Bar; + + } -} \ No newline at end of file +} +class Foo {} + +class Bar {} +