2019-08-23 11:56:54 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "BfCompiler.h"
|
|
|
|
#include "BfSourceClassifier.h"
|
|
|
|
|
|
|
|
NS_BF_BEGIN
|
|
|
|
|
|
|
|
enum BfArgFlags
|
|
|
|
{
|
|
|
|
BfArgFlag_None = 0,
|
|
|
|
BfArgFlag_DelegateBindAttempt = 1,
|
|
|
|
BfArgFlag_LambdaBindAttempt = 2,
|
|
|
|
BfArgFlag_UnqualifiedDotAttempt = 4,
|
|
|
|
BfArgFlag_DeferredValue = 8,
|
|
|
|
BfArgFlag_FromParamComposite = 0x10,
|
|
|
|
BfArgFlag_UntypedDefault = 0x20,
|
|
|
|
BfArgFlag_DeferredEval = 0x40,
|
|
|
|
BfArgFlag_ExpectedTypeCast = 0x80,
|
|
|
|
BfArgFlag_VariableDeclaration = 0x100,
|
2020-09-07 15:24:42 -07:00
|
|
|
BfArgFlag_ParamsExpr = 0x200,
|
2020-11-11 05:46:52 -08:00
|
|
|
BfArgFlag_UninitializedExpr = 0x400,
|
2020-12-03 05:58:15 -08:00
|
|
|
BfArgFlag_StringInterpolateFormat = 0x800,
|
2021-01-02 08:11:07 -08:00
|
|
|
BfArgFlag_StringInterpolateArg = 0x1000,
|
|
|
|
BfArgFlag_Cascade = 0x2000
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
2020-12-27 10:55:30 -08:00
|
|
|
enum BfResolveArgsFlags
|
|
|
|
{
|
|
|
|
BfResolveArgsFlag_None = 0,
|
|
|
|
BfResolveArgsFlag_DeferFixits = 1,
|
|
|
|
BfResolveArgsFlag_DeferParamValues = 2, // We still evaluate but don't generate code until the method is selected (for SkipCall support)
|
|
|
|
BfResolveArgsFlag_DeferParamEval = 4,
|
|
|
|
BfResolveArgsFlag_AllowUnresolvedTypes = 8,
|
2021-10-31 10:17:41 -07:00
|
|
|
BfResolveArgsFlag_InsideStringInterpolationAlloc = 0x10,
|
|
|
|
BfResolveArgsFlag_FromIndexer = 0x20
|
2020-12-27 10:55:30 -08:00
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
enum BfResolveArgFlags
|
|
|
|
{
|
|
|
|
BfResolveArgFlag_None = 0,
|
2021-01-14 06:24:34 -08:00
|
|
|
BfResolveArgFlag_FromGeneric = 1,
|
|
|
|
BfResolveArgFlag_FromGenericParam = 2
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
2021-07-20 11:10:10 -07:00
|
|
|
enum BfCreateCallFlags
|
2021-01-26 11:06:17 -08:00
|
|
|
{
|
2021-07-20 11:10:10 -07:00
|
|
|
BfCreateCallFlags_None,
|
|
|
|
BfCreateCallFlags_BypassVirtual = 1,
|
|
|
|
BfCreateCallFlags_SkipThis = 2,
|
|
|
|
BfCreateCallFlags_AllowImplicitRef = 4,
|
|
|
|
BfCreateCallFlags_TailCall = 8,
|
|
|
|
BfCreateCallFlags_GenericParamThis = 0x10
|
2021-01-26 11:06:17 -08:00
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
class BfResolvedArg
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BfTypedValue mTypedValue;
|
|
|
|
BfType* mResolvedType;
|
|
|
|
BfAstNode* mExpression;
|
|
|
|
BfArgFlags mArgFlags;
|
|
|
|
BfType* mExpectedType;
|
|
|
|
BfType* mBestBoundType;
|
|
|
|
bool mWantsRecalc;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BfResolvedArg()
|
|
|
|
{
|
|
|
|
mResolvedType = NULL;
|
|
|
|
mExpression = NULL;
|
|
|
|
mArgFlags = BfArgFlag_None;
|
|
|
|
mExpectedType = NULL;
|
|
|
|
mBestBoundType = NULL;
|
|
|
|
mWantsRecalc = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsDeferredEval()
|
|
|
|
{
|
|
|
|
return (mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_UntypedDefault | BfArgFlag_DeferredEval)) != 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BfResolvedArgs
|
|
|
|
{
|
|
|
|
SizedArray<BfResolvedArg, 4> mResolvedArgs;
|
|
|
|
BfTokenNode* mOpenToken;
|
|
|
|
const BfSizedArray<BfExpression*>* mArguments;
|
|
|
|
const BfSizedArray<BfTokenNode*>* mCommas;
|
|
|
|
BfTokenNode* mCloseToken;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BfResolvedArgs()
|
|
|
|
{
|
|
|
|
mOpenToken = NULL;
|
|
|
|
mArguments = NULL;
|
|
|
|
mCommas = NULL;
|
|
|
|
mCloseToken = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
BfResolvedArgs(BfSizedArray<BfExpression*>* args)
|
|
|
|
{
|
|
|
|
mOpenToken = NULL;
|
|
|
|
mArguments = args;
|
|
|
|
mCommas = NULL;
|
|
|
|
mCloseToken = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
BfResolvedArgs(BfTokenNode* openToken, BfSizedArray<BfExpression*>* args, BfSizedArray<BfTokenNode*>* commas, BfTokenNode* closeToken)
|
|
|
|
{
|
|
|
|
mOpenToken = openToken;
|
|
|
|
mArguments = args;
|
|
|
|
mCommas = commas;
|
|
|
|
mCloseToken = closeToken;
|
|
|
|
}
|
|
|
|
|
2020-11-11 05:46:52 -08:00
|
|
|
void Init(BfTokenNode* openToken, BfSizedArray<BfExpression*>* args, BfSizedArray<BfTokenNode*>* commas, BfTokenNode* closeToken)
|
|
|
|
{
|
|
|
|
mOpenToken = openToken;
|
|
|
|
mArguments = args;
|
|
|
|
mCommas = commas;
|
|
|
|
mCloseToken = closeToken;
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
void Init(const BfSizedArray<BfExpression*>* args)
|
|
|
|
{
|
|
|
|
mOpenToken = NULL;
|
|
|
|
mArguments = args;
|
|
|
|
mCommas = NULL;
|
|
|
|
mCloseToken = NULL;
|
|
|
|
}
|
|
|
|
|
2020-11-11 05:46:52 -08:00
|
|
|
void HandleFixits(BfModule* module);
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
2020-06-03 05:22:11 -07:00
|
|
|
class BfGenericInferContext
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
HashSet<BfType*> mCheckedTypeSet;
|
|
|
|
BfModule* mModule;
|
|
|
|
BfTypeVector* mCheckMethodGenericArguments;
|
|
|
|
SizedArray<BfIRValue, 4> mPrevArgValues;
|
2021-06-28 11:40:50 -07:00
|
|
|
int mInferredCount;
|
2020-06-03 05:22:11 -07:00
|
|
|
|
|
|
|
public:
|
2020-10-06 05:37:33 -07:00
|
|
|
BfGenericInferContext()
|
|
|
|
{
|
|
|
|
mModule = NULL;
|
2021-06-28 11:40:50 -07:00
|
|
|
mInferredCount = 0;
|
2020-10-06 05:37:33 -07:00
|
|
|
}
|
2020-06-03 05:22:11 -07:00
|
|
|
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
|
2020-10-06 05:37:33 -07:00
|
|
|
int GetUnresolvedCount()
|
|
|
|
{
|
|
|
|
return (int)mCheckMethodGenericArguments->size() - mInferredCount;
|
|
|
|
}
|
2021-01-15 14:28:21 -08:00
|
|
|
bool InferGenericArguments(BfMethodInstance* methodInstance, int srcGenericIdx);
|
2021-01-14 06:24:34 -08:00
|
|
|
void InferGenericArguments(BfMethodInstance* methodInstance);
|
2020-06-03 05:22:11 -07:00
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
class BfMethodMatcher
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct BfAmbiguousEntry
|
|
|
|
{
|
|
|
|
BfMethodInstance* mMethodInstance;
|
|
|
|
BfTypeVector mBestMethodGenericArguments;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum MatchFailKind
|
|
|
|
{
|
|
|
|
MatchFailKind_None,
|
|
|
|
MatchFailKind_Protection,
|
|
|
|
MatchFailKind_CheckedMismatch
|
|
|
|
};
|
|
|
|
|
2020-12-03 11:34:56 -08:00
|
|
|
enum BackupMatchKind
|
|
|
|
{
|
|
|
|
BackupMatchKind_None,
|
|
|
|
BackupMatchKind_TooManyArgs,
|
|
|
|
BackupMatchKind_EarlyMismatch,
|
|
|
|
BackupMatchKind_PartialLastArgMatch
|
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
public:
|
|
|
|
BfAstNode* mTargetSrc;
|
2020-06-03 05:22:11 -07:00
|
|
|
BfTypedValue mTarget;
|
2020-12-01 11:35:10 -08:00
|
|
|
BfTypedValue mOrigTarget;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfModule* mModule;
|
2019-11-17 09:28:39 -08:00
|
|
|
BfTypeDef* mActiveTypeDef;
|
2020-06-03 05:22:11 -07:00
|
|
|
String mMethodName;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfMethodInstance* mInterfaceMethodInstance;
|
|
|
|
SizedArrayImpl<BfResolvedArg>& mArguments;
|
|
|
|
BfMethodType mMethodType;
|
|
|
|
BfCheckedKind mCheckedKind;
|
|
|
|
bool mHadExplicitGenericArguments;
|
2020-06-01 07:32:40 -07:00
|
|
|
bool mHasVarArguments;
|
|
|
|
bool mHadVarConflictingReturnType;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mBypassVirtual;
|
|
|
|
bool mAllowImplicitThis;
|
2021-01-26 11:06:17 -08:00
|
|
|
bool mAllowImplicitRef;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mAllowStatic;
|
|
|
|
bool mAllowNonStatic;
|
2020-06-01 07:32:40 -07:00
|
|
|
bool mSkipImplicitParams;
|
2021-07-05 14:36:39 -07:00
|
|
|
bool mAutoFlushAmbiguityErrors;
|
2020-09-25 06:07:46 -07:00
|
|
|
BfEvalExprFlags mBfEvalExprFlags;
|
2020-06-03 05:22:11 -07:00
|
|
|
int mMethodCheckCount;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfType* mExplicitInterfaceCheck;
|
|
|
|
MatchFailKind mMatchFailKind;
|
|
|
|
|
2020-06-03 05:22:11 -07:00
|
|
|
BfTypeVector mCheckMethodGenericArguments;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
BfType* mSelfType; // Only when matching interfaces when 'Self' needs to refer back to the implementing type
|
|
|
|
BfMethodDef* mBackupMethodDef;
|
2020-12-03 11:34:56 -08:00
|
|
|
BackupMatchKind mBackupMatchKind;
|
2019-11-02 06:04:26 -07:00
|
|
|
int mBackupArgMatchCount;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfMethodDef* mBestMethodDef;
|
|
|
|
BfTypeInstance* mBestMethodTypeInstance;
|
2020-06-01 07:32:40 -07:00
|
|
|
BfMethodInstance* mBestRawMethodInstance;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfModuleMethodInstance mBestMethodInstance;
|
|
|
|
SizedArray<int, 4> mBestMethodGenericArgumentSrcs;
|
|
|
|
BfTypeVector mBestMethodGenericArguments;
|
|
|
|
BfTypeVector mExplicitMethodGenericArguments;
|
|
|
|
bool mFakeConcreteTarget;
|
2020-06-03 05:22:11 -07:00
|
|
|
Array<BfAmbiguousEntry> mAmbiguousEntries;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
public:
|
2020-12-27 10:55:30 -08:00
|
|
|
BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType, BfTypeVector* genericArgumentsSubstitute, BfType *origCheckType = NULL, BfResolveArgFlags flags = BfResolveArgFlag_None);
|
2021-01-15 14:28:21 -08:00
|
|
|
bool InferFromGenericConstraints(BfMethodInstance* methodInstance, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs);
|
2019-08-23 11:56:54 -07:00
|
|
|
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
|
|
|
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
|
|
|
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
|
|
|
void FlushAmbiguityError();
|
2020-05-29 16:10:16 -07:00
|
|
|
bool IsType(BfTypedValue& val, BfType* type);
|
2020-08-01 07:48:59 -07:00
|
|
|
int GetMostSpecificType(BfType* lhs, BfType* rhs); // 0, 1, or -1
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
public:
|
|
|
|
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
|
|
|
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments = NULL);
|
|
|
|
void Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
2019-11-17 09:28:39 -08:00
|
|
|
bool IsMemberAccessible(BfTypeInstance* typeInst, BfTypeDef* declaringType);
|
2020-06-03 05:22:11 -07:00
|
|
|
bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass, bool forceOuterCheck = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass);
|
|
|
|
bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef);
|
2020-02-20 17:18:53 -08:00
|
|
|
bool CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass);
|
2019-10-09 16:11:49 -07:00
|
|
|
void TryDevirtualizeCall(BfTypedValue target, BfTypedValue* origTarget = NULL, BfTypedValue* staticResult = NULL);
|
2020-06-01 07:32:40 -07:00
|
|
|
bool HasVarGenerics();
|
|
|
|
bool IsVarCall(BfType*& outReturnType);
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BfBaseClassWalker
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
struct Entry
|
|
|
|
{
|
|
|
|
BfType* mSrcType;
|
|
|
|
BfTypeInstance* mTypeInstance;
|
|
|
|
|
|
|
|
Entry(BfType* srcType, BfTypeInstance* typeInstance)
|
|
|
|
{
|
|
|
|
mSrcType = srcType;
|
|
|
|
mTypeInstance = typeInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
Entry()
|
|
|
|
{
|
|
|
|
mSrcType = NULL;
|
|
|
|
mTypeInstance = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const Entry& rhs)
|
|
|
|
{
|
|
|
|
return (mSrcType == rhs.mSrcType) && (mTypeInstance == rhs.mTypeInstance);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
BfTypeInstance* mTypes[2];
|
|
|
|
Array<Entry> mManualList;
|
|
|
|
bool mMayBeFromInterface;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BfBaseClassWalker();
|
|
|
|
BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* module);
|
|
|
|
void AddConstraints(BfType* srcType, BfGenericParamInstance* genericParam);
|
|
|
|
|
|
|
|
public:
|
|
|
|
Entry Next();
|
|
|
|
};
|
|
|
|
|
|
|
|
class BfFunctionBindResult
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BfTypedValue mOrigTarget;
|
|
|
|
BfTypedValue mTarget;
|
|
|
|
BfIRValue mFunc;
|
|
|
|
BfMethodInstance* mMethodInstance;
|
2020-07-10 06:40:24 -07:00
|
|
|
BfType* mBindType;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mSkipThis;
|
2019-09-29 07:43:36 -07:00
|
|
|
bool mSkipMutCheck;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mWantsArgs;
|
|
|
|
bool mCheckedMultipleMethods;
|
|
|
|
SizedArray<BfIRValue, 2> mIRArgs;
|
|
|
|
|
|
|
|
public:
|
|
|
|
BfFunctionBindResult()
|
|
|
|
{
|
|
|
|
mMethodInstance = NULL;
|
2020-07-10 06:40:24 -07:00
|
|
|
mBindType = NULL;
|
2019-09-29 07:43:36 -07:00
|
|
|
mSkipMutCheck = false;
|
2019-08-23 11:56:54 -07:00
|
|
|
mWantsArgs = false;
|
|
|
|
mSkipThis = false;
|
|
|
|
mCheckedMultipleMethods = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DeferredTupleAssignData
|
|
|
|
{
|
|
|
|
struct Entry
|
|
|
|
{
|
|
|
|
BfExpression* mExpr;
|
|
|
|
BfExprEvaluator* mExprEvaluator;
|
|
|
|
DeferredTupleAssignData* mInnerTuple;
|
|
|
|
};
|
|
|
|
|
|
|
|
Array<Entry> mChildren;
|
2020-06-04 15:02:46 -07:00
|
|
|
BfTypeInstance* mTupleType;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
~DeferredTupleAssignData();
|
|
|
|
};
|
|
|
|
|
|
|
|
enum BfImplicitParamKind
|
|
|
|
{
|
|
|
|
BfImplicitParamKind_General,
|
|
|
|
BfImplicitParamKind_GenericMethodMember,
|
|
|
|
BfImplicitParamKind_GenericTypeMember,
|
|
|
|
BfImplicitParamKind_GenericTypeMember_Addr,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum BfLookupFieldFlags
|
|
|
|
{
|
|
|
|
BfLookupFieldFlag_None = 0,
|
|
|
|
BfLookupFieldFlag_IsImplicitThis = 1,
|
2020-12-06 07:32:01 -08:00
|
|
|
BfLookupFieldFlag_BaseLookup = 2,
|
|
|
|
BfLookupFieldFlag_CheckingOuter = 4,
|
|
|
|
BfLookupFieldFlag_IgnoreProtection = 8,
|
|
|
|
BfLookupFieldFlag_BindOnly = 0x10
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
2020-09-18 17:00:33 -07:00
|
|
|
enum BfUnaryOpFlags
|
|
|
|
{
|
|
|
|
BfUnaryOpFlag_None = 0,
|
|
|
|
BfUnaryOpFlag_IsConstraintCheck = 1
|
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
enum BfBinOpFlags
|
|
|
|
{
|
|
|
|
BfBinOpFlag_None = 0,
|
|
|
|
BfBinOpFlag_NoClassify = 1,
|
2020-08-23 05:42:42 -07:00
|
|
|
BfBinOpFlag_ForceLeftType = 2,
|
|
|
|
BfBinOpFlag_IgnoreOperatorWithWrongResult = 4,
|
2021-01-22 11:37:39 -08:00
|
|
|
BfBinOpFlag_IsConstraintCheck = 8,
|
|
|
|
BfBinOpFlag_DeferRight = 0x10
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class BfExprEvaluator : public BfStructuralVisitor
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
BfModule* mModule;
|
|
|
|
BfTypedValue mResult;
|
|
|
|
BfEvalExprFlags mBfEvalExprFlags;
|
|
|
|
BfLocalVariable* mResultLocalVar;
|
2020-02-19 06:35:52 -08:00
|
|
|
BfFieldInstance* mResultFieldInstance;
|
2019-08-23 11:56:54 -07:00
|
|
|
int mResultLocalVarField;
|
|
|
|
int mResultLocalVarFieldCount; // > 1 for structs with multiple members
|
|
|
|
BfAstNode* mResultLocalVarRefNode;
|
|
|
|
BfAstNode* mPropSrc;
|
|
|
|
BfTypedValue mPropTarget;
|
|
|
|
BfTypedValue mOrigPropTarget;
|
|
|
|
BfGetMethodInstanceFlags mPropGetMethodFlags;
|
|
|
|
BfCheckedKind mPropCheckedKind;
|
|
|
|
BfPropertyDef* mPropDef;
|
|
|
|
BfType* mExpectingType;
|
|
|
|
BfAttributeState* mPrefixedAttributeState;
|
|
|
|
BfTypedValue* mReceivingValue;
|
|
|
|
BfFunctionBindResult* mFunctionBindResult;
|
|
|
|
SizedArray<BfResolvedArg, 2> mIndexerValues;
|
|
|
|
BfAstNode* mDeferCallRef;
|
|
|
|
BfScopeData* mDeferScopeAlloc;
|
|
|
|
bool mUsedAsStatement;
|
|
|
|
bool mPropDefBypassVirtual;
|
|
|
|
bool mExplicitCast;
|
|
|
|
bool mResolveGenericParam;
|
|
|
|
bool mNoBind;
|
|
|
|
bool mIsVolatileReference;
|
|
|
|
bool mIsHeapReference;
|
|
|
|
bool mResultIsTempComposite;
|
|
|
|
bool mAllowReadOnlyReference;
|
2020-01-18 14:43:42 -08:00
|
|
|
bool mInsidePendingNullable;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
public:
|
|
|
|
BfExprEvaluator(BfModule* module);
|
|
|
|
~BfExprEvaluator();
|
|
|
|
|
|
|
|
void GetLiteral(BfAstNode* refNode, const BfVariant& variant);
|
|
|
|
void FinishExpressionResult();
|
|
|
|
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
|
|
|
|
BfAutoComplete* GetAutoComplete();
|
2021-01-08 16:21:03 -08:00
|
|
|
bool IsComptime();
|
|
|
|
bool IsComptimeEntry();
|
2020-12-22 04:50:37 -08:00
|
|
|
int GetStructRetIdx(BfMethodInstance* methodInstance, bool forceStatic = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
|
|
|
|
void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true);
|
|
|
|
BfType* BindGenericType(BfAstNode* node, BfType* bindType);
|
|
|
|
BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
|
|
|
void ResolveGenericType();
|
2020-12-27 10:55:30 -08:00
|
|
|
void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgsFlags flags = BfResolveArgsFlag_None);
|
2020-03-09 06:34:16 -07:00
|
|
|
BfAllocTarget ResolveAllocTarget(BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL);
|
2020-09-07 15:24:42 -07:00
|
|
|
BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal, BfIdentifierNode* paramNameNode = NULL);
|
2020-08-29 14:18:05 -07:00
|
|
|
BfMethodDef* GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef);
|
2020-03-09 06:51:41 -07:00
|
|
|
void CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt);
|
2020-02-11 08:37:52 -08:00
|
|
|
bool HasResult();
|
|
|
|
BfTypedValue GetResult(bool clearResult = false, bool resolveGenericType = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
void CheckResultForReading(BfTypedValue& typedValue);
|
|
|
|
void MarkResultUsed();
|
|
|
|
void MarkResultAssigned();
|
|
|
|
void MakeResultAsValue();
|
2020-02-21 09:26:02 -08:00
|
|
|
bool CheckIsBase(BfAstNode* checkNode);
|
2021-01-20 08:53:43 -08:00
|
|
|
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false, bool emitWarning = false, bool skipCopyOnMutate = false);
|
2020-02-20 11:57:25 -08:00
|
|
|
bool CheckGenericCtor(BfGenericParamType* genericParamType, BfResolvedArgs& argValues, BfAstNode* targetSrc);
|
|
|
|
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
|
2019-08-23 11:56:54 -07:00
|
|
|
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
|
|
|
|
void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
|
|
|
void LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError = NULL);
|
|
|
|
void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError);
|
|
|
|
void LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError);
|
2019-10-05 10:26:26 -07:00
|
|
|
bool CheckConstCompare(BfBinaryOp binaryOp, BfAstNode* opToken, const BfTypedValue& leftValue, const BfTypedValue& rightValue);
|
2020-02-28 09:20:43 -08:00
|
|
|
void AddStrings(const BfTypedValue& leftValue, const BfTypedValue& rightValue, BfAstNode* refNode);
|
2021-02-26 14:47:11 -08:00
|
|
|
bool PerformBinaryOperation_NullCoalesce(BfTokenNode* opToken, BfExpression* leftExpression, BfExpression* rightExpression, BfTypedValue leftValue, BfType* wantType, BfTypedValue* assignTo = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
void PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken);
|
|
|
|
void PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue);
|
|
|
|
void PerformBinaryOperation(BfExpression* leftNode, BfExpression* rightNode, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue);
|
|
|
|
void PerformBinaryOperation(BfExpression* leftNode, BfExpression* rightNode, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags);
|
|
|
|
BfTypedValue LoadLocal(BfLocalVariable* varDecl, bool allowRef = false);
|
|
|
|
BfTypedValue LookupIdentifier(BfAstNode* identifierNode, const StringImpl& findName, bool ignoreInitialError = false, bool* hadError = NULL);
|
|
|
|
BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
|
|
|
void AddCallDependencies(BfMethodInstance* methodInstance);
|
2019-10-09 16:11:49 -07:00
|
|
|
void PerformCallChecks(BfMethodInstance* methodInstance, BfAstNode* targetSrc);
|
2021-07-20 11:10:10 -07:00
|
|
|
BfTypedValue CreateCall(BfAstNode* targetSrc, BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, BfCreateCallFlags callFlags = BfCreateCallFlags_None);
|
|
|
|
BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, BfCreateCallFlags callFlags, SizedArrayImpl<BfResolvedArg>& argValues, BfTypedValue* argCascade = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
|
|
|
|
void MakeBaseConcrete(BfTypedValue& typedValue);
|
|
|
|
void SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs);
|
2020-08-25 07:33:55 -07:00
|
|
|
void PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat = false, bool disableLowering = false, bool isIntrinsic = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck = false);
|
|
|
|
BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType,
|
|
|
|
BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
|
|
|
BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues);
|
|
|
|
BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name,
|
|
|
|
BfResolvedArgs& argValue, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
|
|
|
BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target);
|
2021-01-20 06:42:44 -08:00
|
|
|
BfModuleMethodInstance GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher, BfType** overrideReturnType = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
|
|
|
bool HasVariableDeclaration(BfAstNode* checkNode);
|
|
|
|
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
|
|
|
int GetMixinVariable();
|
|
|
|
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
|
|
|
void InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArgs);
|
|
|
|
void SetMethodElementType(BfAstNode* target);
|
2020-09-01 15:57:08 -07:00
|
|
|
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode, int shadowIdx);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind = BfImplicitParamKind_General, const BfTypedValue& methodRefTarget = BfTypedValue());
|
2020-09-11 10:33:16 -07:00
|
|
|
bool CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod = NULL, BfType* origMethodExpectingType = NULL, BfTypeVector* methodGenericArgumentsSubstitute = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
bool IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams = false);
|
|
|
|
BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType);
|
|
|
|
void ConstResolve(BfExpression* expr);
|
|
|
|
void ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed);
|
2019-11-26 13:11:17 -08:00
|
|
|
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget);
|
2019-08-23 11:56:54 -07:00
|
|
|
void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
|
|
|
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
2020-09-18 17:00:33 -07:00
|
|
|
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
|
|
|
BfTypedValue PerformUnaryOperation_TryOperator(const BfTypedValue& inValue, BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
|
|
|
void PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
2019-08-23 11:56:54 -07:00
|
|
|
void PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue = NULL);
|
|
|
|
void PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExr, DeferredTupleAssignData& deferredTupleAssignData);
|
|
|
|
void AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue);
|
|
|
|
void DoTupleAssignment(BfAssignmentExpression* assignExpr);
|
|
|
|
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
|
2021-01-20 06:42:44 -08:00
|
|
|
void FinishDeferredEvals(BfResolvedArgs& argValues);
|
2019-08-23 11:56:54 -07:00
|
|
|
bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName);
|
2021-09-10 14:21:25 -07:00
|
|
|
void DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token);
|
2019-08-23 11:56:54 -07:00
|
|
|
//void InitializedSizedArray(BfTupleExpression* createExpr, BfSizedArrayType* arrayType);
|
|
|
|
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
2019-08-29 17:40:17 -07:00
|
|
|
void CheckDotToken(BfTokenNode* tokenNode);
|
2019-08-23 11:56:54 -07:00
|
|
|
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
|
2020-11-11 05:46:52 -08:00
|
|
|
void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType);
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2020-05-26 06:10:51 -07:00
|
|
|
virtual void Visit(BfErrorNode* errorNode) override;
|
2019-08-23 11:56:54 -07:00
|
|
|
virtual void Visit(BfTypeReference* typeRef) override;
|
|
|
|
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
|
|
|
virtual void Visit(BfBlock* blockExpr) override;
|
|
|
|
virtual void Visit(BfVariableDeclaration* varDecl) override;
|
|
|
|
virtual void Visit(BfCaseExpression* caseExpr) override;
|
|
|
|
virtual void Visit(BfTypedValueExpression* typedValueExpr) override;
|
|
|
|
virtual void Visit(BfLiteralExpression* literalExpr) override;
|
2020-11-11 05:46:52 -08:00
|
|
|
virtual void Visit(BfStringInterpolationExpression* stringInterpolationExpression) override;
|
2019-08-23 11:56:54 -07:00
|
|
|
virtual void Visit(BfIdentifierNode* identifierNode) override;
|
|
|
|
virtual void Visit(BfAttributedIdentifierNode* attrIdentifierNode) override;
|
|
|
|
virtual void Visit(BfQualifiedNameNode* nameNode) override;
|
|
|
|
virtual void Visit(BfThisExpression* thisExpr) override;
|
|
|
|
virtual void Visit(BfBaseExpression* baseExpr) override;
|
|
|
|
virtual void Visit(BfMixinExpression* mixinExpr) override;
|
|
|
|
virtual void Visit(BfSizedArrayCreateExpression* createExpr) override;
|
2020-06-18 06:12:14 -07:00
|
|
|
virtual void Visit(BfInitializerExpression* initExpr) override;
|
2020-05-19 09:42:11 -07:00
|
|
|
virtual void Visit(BfCollectionInitializerExpression* initExpr) override;
|
2019-08-23 11:56:54 -07:00
|
|
|
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
|
|
|
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
|
|
|
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
|
|
|
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
2021-09-10 14:21:25 -07:00
|
|
|
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
|
2019-08-23 11:56:54 -07:00
|
|
|
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
|
|
|
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
|
|
|
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
|
|
|
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
|
|
|
virtual void Visit(BfCastExpression* castExpr) override;
|
|
|
|
virtual void Visit(BfDelegateBindExpression* delegateBindExpr) override;
|
|
|
|
virtual void Visit(BfLambdaBindExpression* lambdaBindExpr) override;
|
|
|
|
virtual void Visit(BfObjectCreateExpression* objCreateExpr) override;
|
|
|
|
virtual void Visit(BfBoxExpression* boxExpr) override;
|
|
|
|
virtual void Visit(BfInvocationExpression* invocationExpr) override;
|
|
|
|
virtual void Visit(BfConditionalExpression* condExpr) override;
|
|
|
|
virtual void Visit(BfAssignmentExpression* assignExpr) override;
|
|
|
|
virtual void Visit(BfParenthesizedExpression* parenExpr) override;
|
|
|
|
virtual void Visit(BfTupleExpression* tupleExpr) override;
|
|
|
|
virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override;
|
|
|
|
virtual void Visit(BfIndexerExpression* indexerExpr) override;
|
|
|
|
virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override;
|
|
|
|
virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_BF_END
|