Skip to content

Commit

Permalink
Treat optional fields/parameters types as null<> wrapped types.
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed Aug 24, 2024
1 parent fd9057f commit d434c7b
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ public interface HaxePsiField extends HaxeComponent, PsiField, HaxeModelTarget {

@Nullable
HaxeVarInit getVarInit();

boolean isOptional();
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static com.intellij.plugins.haxe.metadata.psi.HaxeMeta.OPTIONAL;

/**
* Created by srikanthg on 10/9/14.
*/
Expand Down Expand Up @@ -111,7 +113,14 @@ public PsiIdentifier getNameIdentifier() {
}

public boolean isOptional() {
return this instanceof HaxeOptionalFieldDeclaration;
if(this instanceof HaxeOptionalFieldDeclaration) return true;
if(this instanceof HaxeAnonymousTypeField field) {
return field.getOptionalMark() != null;
}
if(this instanceof HaxeFieldDeclaration fieldDeclaration) {
return fieldDeclaration.hasCompileTimeMetadata(OPTIONAL);
}
return false;
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,14 +499,22 @@ static ResultHolder handleParameter(
if (typeTag != null) {
ResultHolder typeFromTypeTag = HaxeTypeResolver.getTypeFromTypeTag(typeTag, parameter);
ResultHolder resolve = resolver.resolve(typeFromTypeTag);
if (!resolve.isUnknown()) return resolve;
if (resolve != null && !resolve.isUnknown()) typeFromTypeTag = resolve;
// if parameter is optional then its nullable and should be Null<T>
if (parameter.getOptionalMark() != null && !typeFromTypeTag.isNullWrappedType()) {
return typeFromTypeTag.wrapInNullType();
}
return typeFromTypeTag;
}

HaxeVarInit init = parameter.getVarInit();
if (init != null) {
ResultHolder holder = handle(init, context, resolver);
if (!holder.isUnknown()) {
if (parameter.getOptionalMark() != null && !holder.isNullWrappedType()) {
// if parameter is optional then its nullable and should be Null<T>
return holder.wrapInNullType();
}
return holder;
}
}else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ static private ResultHolder getFieldType(HaxeNamedComponent comp, HaxeGenericRes
if (resolver != null) {
ResultHolder resolved = resolver.resolve(typeFromTag);
if (resolved != null) typeFromTag = resolved;
if (psiField.isOptional() && !typeFromTag.isNullWrappedType()) {
typeFromTag = typeFromTag.wrapInNullType();
}
}
final Object initConstant = result != null ? result.getType().getConstant() : null;
if (typeFromTag != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,14 @@ public ResultHolder tryUnwrapNullType() {
}
return this;
}

public boolean isNullWrappedType() {
SpecificHaxeClassReference classType = getClassType();
return classType != null && classType.isNullType();
}

public ResultHolder wrapInNullType() {
SpecificTypeReference typeToWrap = getType();
return SpecificHaxeClassReference.getNull(typeToWrap.getElementContext(), typeToWrap.createHolder()).createHolder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ public void testSimpleVarHints() throws Exception {
public void testLocalVarMacros() throws Exception {
doTest(hintsProvider);
}
@Test
public void testOptionalFieldsHints() throws Exception {
doTest(hintsProvider);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package testData.inlay.haxe.local.variable;
typedef SomeTypeDef = {
var normalA:Int;
final normalB:String;
@:optional var optionalC:String;
}
typedef SomeStruct = {
?optinal:Int,
}
class NullWrapping {
public function optionalStruct(s:SomeStruct) {
var x/*<# :Null<Int> #>*/ = s.optinal;
}
public function optionalTypeDef(s:SomeTypeDef) {
var a/*<# :Int #>*/ = s.normalA;
var b/*<# :String #>*/ = s.normalB;
var c/*<# :Null<String> #>*/ = s.optionalC;
}

public function optionalTypeA(?i:String) {
var x/*<# :Null<String> #>*/ = i;
}

public function optionalTypeB(?i = "Str") {
var x/*<# :Null<String> #>*/ = i;
}

public function optionalTypeParameter<T>(?i:T) {
var x/*<# :Null<T> #>*/ = i;
}

public function defaultType(i = "String") {
var x/*<# :String #>*/ = i;
}
}

0 comments on commit d434c7b

Please sign in to comment.