mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Added '->' operator, static indexer fix, RefCounted<T>
This commit is contained in:
parent
dd7986aaa9
commit
abd511a93d
14 changed files with 302 additions and 20 deletions
|
@ -6,7 +6,7 @@ namespace System
|
||||||
interface IRefCounted
|
interface IRefCounted
|
||||||
{
|
{
|
||||||
void AddRef();
|
void AddRef();
|
||||||
void ReleaseRef();
|
void Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
class RefCounted : IRefCounted
|
class RefCounted : IRefCounted
|
||||||
|
@ -63,5 +63,167 @@ namespace System
|
||||||
Debug.Assert(refCount >= 0);
|
Debug.Assert(refCount >= 0);
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRefCounted.Release()
|
||||||
|
{
|
||||||
|
ReleaseRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Alloc
|
||||||
|
{
|
||||||
|
public void* Alloc(Type type, int size, int align)
|
||||||
|
{
|
||||||
|
int sizeAdd = size + Math.Max(align, sizeof(int));
|
||||||
|
|
||||||
|
void* data = Internal.Malloc(sizeAdd);
|
||||||
|
return (uint8*)data + sizeAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RefCounted<T> : IRefCounted where T : class, delete
|
||||||
|
{
|
||||||
|
public T mVal;
|
||||||
|
public int mRefCount = 1;
|
||||||
|
|
||||||
|
public int RefCount => mRefCount;
|
||||||
|
public T Value => mVal;
|
||||||
|
|
||||||
|
protected this()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ~this()
|
||||||
|
{
|
||||||
|
Debug.Assert(mRefCount == 0);
|
||||||
|
delete mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
[OnCompile(.TypeInit), Comptime]
|
||||||
|
static void Init()
|
||||||
|
{
|
||||||
|
String emitStr = scope .();
|
||||||
|
|
||||||
|
for (var methodInfo in typeof(T).GetMethods(.Public))
|
||||||
|
{
|
||||||
|
if (methodInfo.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (!methodInfo.IsConstructor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
emitStr.AppendF("public static RefCounted<T> Create(");
|
||||||
|
methodInfo.GetParamsDecl(emitStr);
|
||||||
|
emitStr.AppendF(")\n");
|
||||||
|
emitStr.AppendF("{{\n");
|
||||||
|
emitStr.AppendF("\treturn new [Friend] RefCountedAppend<T>(");
|
||||||
|
methodInfo.GetArgsList(emitStr);
|
||||||
|
emitStr.AppendF(");\n}}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(typeof(Self), emitStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RefCounted<T> Attach(T val)
|
||||||
|
{
|
||||||
|
return new Self() { mVal = val };
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void DeleteSelf()
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteUnchecked()
|
||||||
|
{
|
||||||
|
mRefCount = 0;
|
||||||
|
DeleteSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRef()
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref mRefCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
int refCount = Interlocked.Decrement(ref mRefCount);
|
||||||
|
Debug.Assert(refCount >= 0);
|
||||||
|
if (refCount == 0)
|
||||||
|
DeleteSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReleaseLastRef()
|
||||||
|
{
|
||||||
|
int refCount = Interlocked.Decrement(ref mRefCount);
|
||||||
|
Debug.Assert(refCount == 0);
|
||||||
|
if (refCount == 0)
|
||||||
|
DeleteSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ReleaseRefNoDelete()
|
||||||
|
{
|
||||||
|
int refCount = Interlocked.Decrement(ref mRefCount);
|
||||||
|
Debug.Assert(refCount >= 0);
|
||||||
|
return refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual T Detach()
|
||||||
|
{
|
||||||
|
var val = mVal;
|
||||||
|
mVal = null;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T operator->(Self self)
|
||||||
|
{
|
||||||
|
return self.mVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static T operator implicit(Self self)
|
||||||
|
{
|
||||||
|
return self.mVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RefCountedAppend<T> : RefCounted<T> where T : class, new, delete
|
||||||
|
{
|
||||||
|
protected ~this()
|
||||||
|
{
|
||||||
|
Debug.Assert(mRefCount == 0);
|
||||||
|
delete:append mVal;
|
||||||
|
mVal = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[OnCompile(.TypeInit), Comptime]
|
||||||
|
static void Init()
|
||||||
|
{
|
||||||
|
String emitStr = scope .();
|
||||||
|
|
||||||
|
for (var methodInfo in typeof(T).GetMethods(.Public))
|
||||||
|
{
|
||||||
|
if (methodInfo.IsStatic)
|
||||||
|
continue;
|
||||||
|
if (!methodInfo.IsConstructor)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
emitStr.AppendF("[AllowAppend]\nprotected this(");
|
||||||
|
methodInfo.GetParamsDecl(emitStr);
|
||||||
|
emitStr.AppendF(")\n");
|
||||||
|
emitStr.AppendF("{{\n");
|
||||||
|
emitStr.AppendF("\tvar val = append T(");
|
||||||
|
methodInfo.GetArgsList(emitStr);
|
||||||
|
emitStr.AppendF(");\n");
|
||||||
|
emitStr.AppendF("\tmVal = val;\n");
|
||||||
|
emitStr.AppendF("}}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(typeof(Self), emitStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override T Detach()
|
||||||
|
{
|
||||||
|
Runtime.FatalError("Can only detach from objects created via RefCounted<T>.Attach");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,9 @@ namespace System.Reflection
|
||||||
public bool IsReadOnly => Compiler.IsComptime ?
|
public bool IsReadOnly => Compiler.IsComptime ?
|
||||||
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.ReadOnly) :
|
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.ReadOnly) :
|
||||||
mData.mMethodData.[Friend]mFlags.HasFlag(.ReadOnly);
|
mData.mMethodData.[Friend]mFlags.HasFlag(.ReadOnly);
|
||||||
|
public bool IsStatic => Compiler.IsComptime ?
|
||||||
|
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.HasFlag(.Static) :
|
||||||
|
mData.mMethodData.[Friend]mFlags.HasFlag(.Static);
|
||||||
|
|
||||||
public StringView Name => Compiler.IsComptime ?
|
public StringView Name => Compiler.IsComptime ?
|
||||||
Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) :
|
Type.[Friend]Comptime_Method_GetName(mData.mComptimeMethodInstance) :
|
||||||
|
@ -112,6 +115,19 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TypeInstance.ParamFlags GetParamFlags(int paramIdx)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
return Type.[Friend]Comptime_Method_GetParamInfo(mData.mComptimeMethodInstance, (.)paramIdx).mParamFlags;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Assert((uint)paramIdx < (uint)mData.mMethodData.mParamCount);
|
||||||
|
return mData.mMethodData.mParamData[paramIdx].mParamFlags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Result<T> GetParamCustomAttribute<T>(int paramIdx) where T : Attribute
|
public Result<T> GetParamCustomAttribute<T>(int paramIdx) where T : Attribute
|
||||||
{
|
{
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
|
@ -967,19 +983,60 @@ namespace System.Reflection
|
||||||
strBuffer.Append(' ');
|
strBuffer.Append(' ');
|
||||||
strBuffer.Append(mData.mMethodData.mName);
|
strBuffer.Append(mData.mMethodData.mName);
|
||||||
strBuffer.Append('(');
|
strBuffer.Append('(');
|
||||||
|
|
||||||
|
int useParamIdx = 0;
|
||||||
for (int paramIdx < mData.mMethodData.mParamCount)
|
for (int paramIdx < mData.mMethodData.mParamCount)
|
||||||
{
|
{
|
||||||
if (paramIdx > 0)
|
|
||||||
strBuffer.Append(", ");
|
|
||||||
let paramData = mData.mMethodData.mParamData[paramIdx];
|
let paramData = mData.mMethodData.mParamData[paramIdx];
|
||||||
let paramType = Type.[Friend]GetType(paramData.mType);
|
let paramType = Type.[Friend]GetType(paramData.mType);
|
||||||
|
if (paramData.mParamFlags.HasFlag(.Implicit))
|
||||||
|
continue;
|
||||||
|
if (useParamIdx > 0)
|
||||||
|
strBuffer.Append(", ");
|
||||||
paramType.ToString(strBuffer);
|
paramType.ToString(strBuffer);
|
||||||
strBuffer.Append(' ');
|
strBuffer.Append(' ');
|
||||||
strBuffer.Append(paramData.mName);
|
strBuffer.Append(paramData.mName);
|
||||||
|
useParamIdx++;
|
||||||
}
|
}
|
||||||
strBuffer.Append(')');
|
strBuffer.Append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void GetParamsDecl(String strBuffer)
|
||||||
|
{
|
||||||
|
int useParamIdx = 0;
|
||||||
|
for (int paramIdx < ParamCount)
|
||||||
|
{
|
||||||
|
var flag = GetParamFlags(paramIdx);
|
||||||
|
if (flag.HasFlag(.Implicit))
|
||||||
|
continue;
|
||||||
|
if (useParamIdx > 0)
|
||||||
|
strBuffer.Append(", ");
|
||||||
|
if (flag.HasFlag(.Params))
|
||||||
|
strBuffer.Append("params ");
|
||||||
|
strBuffer.Append(GetParamType(paramIdx));
|
||||||
|
strBuffer.Append(" ");
|
||||||
|
strBuffer.Append(GetParamName(paramIdx));
|
||||||
|
useParamIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetArgsList(String strBuffer)
|
||||||
|
{
|
||||||
|
int useParamIdx = 0;
|
||||||
|
for (int paramIdx < ParamCount)
|
||||||
|
{
|
||||||
|
var flag = GetParamFlags(paramIdx);
|
||||||
|
if (flag.HasFlag(.Implicit))
|
||||||
|
continue;
|
||||||
|
if (useParamIdx > 0)
|
||||||
|
strBuffer.Append(", ");
|
||||||
|
if (flag.HasFlag(.Params))
|
||||||
|
strBuffer.Append("params ");
|
||||||
|
strBuffer.Append(GetParamName(paramIdx));
|
||||||
|
useParamIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct Enumerator : IEnumerator<MethodInfo>
|
public struct Enumerator : IEnumerator<MethodInfo>
|
||||||
{
|
{
|
||||||
BindingFlags mBindingFlags;
|
BindingFlags mBindingFlags;
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace System
|
||||||
[Ordered]
|
[Ordered]
|
||||||
class String : IHashable, IFormattable, IPrintable
|
class String : IHashable, IFormattable, IPrintable
|
||||||
{
|
{
|
||||||
enum CreateFlags
|
public enum CreateFlags
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
NullTerminate = 1
|
NullTerminate = 1
|
||||||
|
|
|
@ -852,7 +852,8 @@ namespace System.Reflection
|
||||||
None = 0,
|
None = 0,
|
||||||
Splat = 1,
|
Splat = 1,
|
||||||
Implicit = 2,
|
Implicit = 2,
|
||||||
AppendIdx = 4
|
AppendIdx = 4,
|
||||||
|
Params = 8
|
||||||
}
|
}
|
||||||
|
|
||||||
[CRepr, AlwaysInclude]
|
[CRepr, AlwaysInclude]
|
||||||
|
|
|
@ -1768,6 +1768,7 @@ const char* Beefy::BfGetOpName(BfUnaryOp unaryOp)
|
||||||
{
|
{
|
||||||
case BfUnaryOp_None: return "";
|
case BfUnaryOp_None: return "";
|
||||||
case BfUnaryOp_AddressOf: return "&";
|
case BfUnaryOp_AddressOf: return "&";
|
||||||
|
case BfUnaryOp_Arrow: return "->";
|
||||||
case BfUnaryOp_Dereference: return "*";
|
case BfUnaryOp_Dereference: return "*";
|
||||||
case BfUnaryOp_Negate: return "-";
|
case BfUnaryOp_Negate: return "-";
|
||||||
case BfUnaryOp_Not: return "!";
|
case BfUnaryOp_Not: return "!";
|
||||||
|
@ -1862,6 +1863,8 @@ BfUnaryOp Beefy::BfTokenToUnaryOp(BfToken token)
|
||||||
return BfUnaryOp_Dereference;
|
return BfUnaryOp_Dereference;
|
||||||
case BfToken_Ampersand:
|
case BfToken_Ampersand:
|
||||||
return BfUnaryOp_AddressOf;
|
return BfUnaryOp_AddressOf;
|
||||||
|
case BfToken_Arrow:
|
||||||
|
return BfUnaryOp_Arrow;
|
||||||
case BfToken_Minus:
|
case BfToken_Minus:
|
||||||
return BfUnaryOp_Negate;
|
return BfUnaryOp_Negate;
|
||||||
case BfToken_Bang:
|
case BfToken_Bang:
|
||||||
|
|
|
@ -1901,6 +1901,7 @@ enum BfUnaryOp
|
||||||
{
|
{
|
||||||
BfUnaryOp_None,
|
BfUnaryOp_None,
|
||||||
BfUnaryOp_AddressOf,
|
BfUnaryOp_AddressOf,
|
||||||
|
BfUnaryOp_Arrow,
|
||||||
BfUnaryOp_Dereference,
|
BfUnaryOp_Dereference,
|
||||||
BfUnaryOp_Negate,
|
BfUnaryOp_Negate,
|
||||||
BfUnaryOp_Not,
|
BfUnaryOp_Not,
|
||||||
|
|
|
@ -1857,6 +1857,14 @@ bool BfAutoComplete::CheckMemberReference(BfAstNode* target, BfAstNode* dotToken
|
||||||
|
|
||||||
bool isStatic = false;
|
bool isStatic = false;
|
||||||
BfTypedValue targetValue = LookupTypeRefOrIdentifier(target, &isStatic, (BfEvalExprFlags)(BfEvalExprFlags_IgnoreNullConditional | BfEvalExprFlags_NoCast), expectingType);
|
BfTypedValue targetValue = LookupTypeRefOrIdentifier(target, &isStatic, (BfEvalExprFlags)(BfEvalExprFlags_IgnoreNullConditional | BfEvalExprFlags_NoCast), expectingType);
|
||||||
|
if ((targetValue) && (dotToken->mToken == BfToken_Arrow))
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreClassifying(mModule->mIsInsideAutoComplete, true);
|
||||||
|
BfExprEvaluator exprEvaluator(mModule);
|
||||||
|
auto arrowValue = exprEvaluator.PerformUnaryOperation_TryOperator(targetValue, NULL, BfUnaryOp_Arrow, BfNodeDynCast<BfTokenNode>(dotToken), BfUnaryOpFlag_None);
|
||||||
|
if (arrowValue)
|
||||||
|
targetValue = arrowValue;
|
||||||
|
}
|
||||||
|
|
||||||
bool hadResults = false;
|
bool hadResults = false;
|
||||||
bool doAsNamespace = true;
|
bool doAsNamespace = true;
|
||||||
|
|
|
@ -2527,8 +2527,7 @@ void BfMethodMatcher::FlushAmbiguityError()
|
||||||
error = mModule->Fail("Ambiguous method call", mTargetSrc);
|
error = mModule->Fail("Ambiguous method call", mTargetSrc);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
auto unspecializedType = mModule->GetUnspecializedTypeInstance(mBestMethodTypeInstance);
|
BfMethodInstance* bestMethodInstance = mModule->GetUnspecializedMethodInstance(mBestRawMethodInstance, true);
|
||||||
BfMethodInstance* bestMethodInstance = mModule->GetRawMethodInstance(unspecializedType, mBestMethodDef);
|
|
||||||
BfTypeVector* typeGenericArguments = NULL;
|
BfTypeVector* typeGenericArguments = NULL;
|
||||||
if (mBestMethodTypeInstance->mGenericTypeInfo != NULL)
|
if (mBestMethodTypeInstance->mGenericTypeInfo != NULL)
|
||||||
typeGenericArguments = &mBestMethodTypeInstance->mGenericTypeInfo->mTypeGenericArguments;
|
typeGenericArguments = &mBestMethodTypeInstance->mGenericTypeInfo->mTypeGenericArguments;
|
||||||
|
@ -4580,6 +4579,16 @@ void BfExprEvaluator::FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType
|
||||||
mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance);
|
mModule->mCompiler->mResolvePassData->mAutoComplete->FixitAddMember(typeInst, fieldType, fieldName, isStatic, mModule->mCurTypeInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfTypedValue BfExprEvaluator::TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken)
|
||||||
|
{
|
||||||
|
auto arrowValue = PerformUnaryOperation_TryOperator(typedValue, NULL, BfUnaryOp_Arrow, arrowToken, BfUnaryOpFlag_None);
|
||||||
|
if (arrowValue)
|
||||||
|
return arrowValue;
|
||||||
|
if (mModule->PreFail())
|
||||||
|
mModule->Fail(StrFormat("Type '%s' does not contain a '->' operator", mModule->TypeToString(typedValue.mType).c_str()), arrowToken);
|
||||||
|
return typedValue;
|
||||||
|
}
|
||||||
|
|
||||||
BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInlined)
|
BfTypedValue BfExprEvaluator::LoadProperty(BfAstNode* targetSrc, BfTypedValue target, BfTypeInstance* typeInstance, BfPropertyDef* prop, BfLookupFieldFlags flags, BfCheckedKind checkedKind, bool isInlined)
|
||||||
{
|
{
|
||||||
if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
|
if ((flags & BfLookupFieldFlag_IsAnonymous) == 0)
|
||||||
|
@ -17635,6 +17644,9 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
}
|
}
|
||||||
thisValue = mResult;
|
thisValue = mResult;
|
||||||
mResult = BfTypedValue();
|
mResult = BfTypedValue();
|
||||||
|
|
||||||
|
if ((thisValue) && (memberRefExpression->mDotToken != NULL) && (memberRefExpression->mDotToken->mToken == BfToken_Arrow))
|
||||||
|
thisValue = TryArrowLookup(thisValue, memberRefExpression->mDotToken);
|
||||||
}
|
}
|
||||||
else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||||
{
|
{
|
||||||
|
@ -20795,10 +20807,11 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx
|
||||||
|
|
||||||
bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot);
|
bool isNullCondLookup = (memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_QuestionDot);
|
||||||
bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot));
|
bool isCascade = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_DotDot));
|
||||||
|
bool isArrowLookup = ((memberRefExpr->mDotToken != NULL) && (memberRefExpr->mDotToken->GetToken() == BfToken_Arrow));
|
||||||
|
|
||||||
BfIdentifierNode* nameLeft = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mTarget);
|
BfIdentifierNode* nameLeft = BfNodeDynCast<BfIdentifierNode>(memberRefExpr->mTarget);
|
||||||
BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName);
|
BfIdentifierNode* nameRight = BfIdentifierCast(memberRefExpr->mMemberName);
|
||||||
if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade))
|
if ((nameLeft != NULL) && (nameRight != NULL) && (!isNullCondLookup) && (!isCascade) && (!isArrowLookup))
|
||||||
{
|
{
|
||||||
bool hadError = false;
|
bool hadError = false;
|
||||||
LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError);
|
LookupQualifiedName(memberRefExpr, nameLeft, nameRight, true, &hadError);
|
||||||
|
@ -20856,6 +20869,9 @@ void BfExprEvaluator::DoMemberReference(BfMemberReferenceExpression* memberRefEx
|
||||||
if (isNullCondLookup)
|
if (isNullCondLookup)
|
||||||
thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken);
|
thisValue = SetupNullConditional(thisValue, memberRefExpr->mDotToken);
|
||||||
|
|
||||||
|
if ((isArrowLookup) && (thisValue))
|
||||||
|
thisValue = TryArrowLookup(thisValue, memberRefExpr->mDotToken);
|
||||||
|
|
||||||
mResult = LookupField(nameRefNode, thisValue, findName);
|
mResult = LookupField(nameRefNode, thisValue, findName);
|
||||||
|
|
||||||
if ((!mResult) && (mPropDef == NULL))
|
if ((!mResult) && (mPropDef == NULL))
|
||||||
|
@ -21093,7 +21109,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
||||||
mPropDef = foundProp;
|
mPropDef = foundProp;
|
||||||
if (foundProp->mIsStatic)
|
if (foundProp->mIsStatic)
|
||||||
{
|
{
|
||||||
mPropTarget = BfTypedValue(curCheckType);
|
mPropTarget = BfTypedValue(foundPropTypeInst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -508,6 +508,7 @@ public:
|
||||||
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget);
|
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr, BfAllocTarget& allocTarget);
|
||||||
void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
||||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
||||||
|
BfTypedValue TryArrowLookup(BfTypedValue typedValue, BfTokenNode* arrowToken);
|
||||||
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
||||||
BfTypedValue PerformUnaryOperation_TryOperator(const BfTypedValue& inValue, 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);
|
void PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken, BfUnaryOpFlags opFlags);
|
||||||
|
|
|
@ -7136,7 +7136,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
ParamFlag_None = 0,
|
ParamFlag_None = 0,
|
||||||
ParamFlag_Splat = 1,
|
ParamFlag_Splat = 1,
|
||||||
ParamFlag_Implicit = 2,
|
ParamFlag_Implicit = 2,
|
||||||
ParamFlag_AppendIdx = 4
|
ParamFlag_AppendIdx = 4,
|
||||||
|
ParamFlag_Params = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
SizedArray<BfIRValue, 8> paramVals;
|
SizedArray<BfIRValue, 8> paramVals;
|
||||||
|
@ -7150,6 +7151,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
|
||||||
if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_AppendIdx)
|
if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_AppendIdx)
|
||||||
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx);
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx);
|
||||||
|
if (defaultMethod->GetParamKind(paramIdx) == BfParamKind_Params)
|
||||||
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params);
|
||||||
|
|
||||||
BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule);
|
BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule);
|
||||||
|
|
||||||
|
|
|
@ -2556,9 +2556,12 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate, bool disablePrepro
|
||||||
mToken = BfToken_MinusEquals;
|
mToken = BfToken_MinusEquals;
|
||||||
mSrcIdx++;
|
mSrcIdx++;
|
||||||
}
|
}
|
||||||
else if ((mCompatMode) && (mSrc[mSrcIdx] == '>'))
|
else if (mSrc[mSrcIdx] == '>')
|
||||||
{
|
{
|
||||||
mToken = BfToken_Dot;
|
if (mCompatMode)
|
||||||
|
mToken = BfToken_Dot;
|
||||||
|
else
|
||||||
|
mToken = BfToken_Arrow;
|
||||||
mSrcIdx++;
|
mSrcIdx++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -2913,7 +2913,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
|
||||||
{
|
{
|
||||||
exprLeft = CreateIndexerExpression(exprLeft);
|
exprLeft = CreateIndexerExpression(exprLeft);
|
||||||
}
|
}
|
||||||
else if ((token == BfToken_Dot) || (token == BfToken_DotDot) || (token == BfToken_QuestionDot))
|
else if ((token == BfToken_Dot) || (token == BfToken_DotDot) || (token == BfToken_QuestionDot) || (token == BfToken_Arrow))
|
||||||
{
|
{
|
||||||
if ((token == BfToken_DotDot) && ((createExprFlags & CreateExprFlags_BreakOnCascade) != 0))
|
if ((token == BfToken_DotDot) && ((createExprFlags & CreateExprFlags_BreakOnCascade) != 0))
|
||||||
return exprLeft;
|
return exprLeft;
|
||||||
|
@ -5506,7 +5506,10 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
|
||||||
|
|
||||||
// If the previous dotted span failed (IE: had chevrons) then don't insert qualified names in the middle of it
|
// If the previous dotted span failed (IE: had chevrons) then don't insert qualified names in the middle of it
|
||||||
auto prevNodeToken = BfNodeDynCast<BfTokenNode>(prevNode);
|
auto prevNodeToken = BfNodeDynCast<BfTokenNode>(prevNode);
|
||||||
if ((prevNodeToken != NULL) && ((prevNodeToken->GetToken() == BfToken_Dot) || (prevNodeToken->GetToken() == BfToken_QuestionDot)))
|
if ((prevNodeToken != NULL) &&
|
||||||
|
((prevNodeToken->GetToken() == BfToken_Dot) ||
|
||||||
|
(prevNodeToken->GetToken() == BfToken_QuestionDot) ||
|
||||||
|
(prevNodeToken->GetToken() == BfToken_Arrow)))
|
||||||
return leftIdentifier;
|
return leftIdentifier;
|
||||||
|
|
||||||
mVisitorPos.MoveNext(); // past .
|
mVisitorPos.MoveNext(); // past .
|
||||||
|
@ -8120,7 +8123,7 @@ BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target)
|
||||||
|
|
||||||
BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNode* target)
|
BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNode* target)
|
||||||
{
|
{
|
||||||
auto tokenNode = ExpectTokenAfter(target, BfToken_Dot, BfToken_DotDot, BfToken_QuestionDot);
|
auto tokenNode = ExpectTokenAfter(target, BfToken_Dot, BfToken_DotDot, BfToken_QuestionDot, BfToken_Arrow);
|
||||||
|
|
||||||
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
|
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
|
||||||
if (target != NULL)
|
if (target != NULL)
|
||||||
|
@ -9356,7 +9359,8 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
|
||||||
if ((paramIdx == 0) && (
|
if ((paramIdx == 0) && (
|
||||||
(token == BfToken_In) || (token == BfToken_Out) || (token == BfToken_Ref) || (token == BfToken_Mut) ||
|
(token == BfToken_In) || (token == BfToken_Out) || (token == BfToken_Ref) || (token == BfToken_Mut) ||
|
||||||
(token == BfToken_Delegate) || (token == BfToken_Function) ||
|
(token == BfToken_Delegate) || (token == BfToken_Function) ||
|
||||||
(token == BfToken_Comptype) || (token == BfToken_Decltype) ||
|
(token == BfToken_Comptype) || (token == BfToken_Decltype) ||
|
||||||
|
(token == BfToken_AllocType) || (token == BfToken_RetType) ||
|
||||||
(token == BfToken_Params) || (token == BfToken_LParen) ||
|
(token == BfToken_Params) || (token == BfToken_LParen) ||
|
||||||
(token == BfToken_Var) || (token == BfToken_LBracket) ||
|
(token == BfToken_Var) || (token == BfToken_LBracket) ||
|
||||||
(token == BfToken_ReadOnly) || (token == BfToken_DotDotDot)))
|
(token == BfToken_ReadOnly) || (token == BfToken_DotDotDot)))
|
||||||
|
@ -9413,7 +9417,8 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
|
||||||
BfToken token = tokenNode->GetToken();
|
BfToken token = tokenNode->GetToken();
|
||||||
if ((token == BfToken_Var) || (token == BfToken_LParen) ||
|
if ((token == BfToken_Var) || (token == BfToken_LParen) ||
|
||||||
(token == BfToken_Delegate) || (token == BfToken_Function) ||
|
(token == BfToken_Delegate) || (token == BfToken_Function) ||
|
||||||
(token == BfToken_Comptype) || (token == BfToken_Decltype) ||
|
(token == BfToken_Comptype) || (token == BfToken_Decltype) ||
|
||||||
|
(token == BfToken_AllocType) || (token == BfToken_RetType) ||
|
||||||
(token == BfToken_DotDotDot))
|
(token == BfToken_DotDotDot))
|
||||||
{
|
{
|
||||||
mVisitorPos.MoveNext();
|
mVisitorPos.MoveNext();
|
||||||
|
|
|
@ -6011,11 +6011,28 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
_Fail("paramIdx is out of range");
|
_Fail("paramIdx is out of range");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum ParamFlags
|
||||||
|
{
|
||||||
|
ParamFlag_None = 0,
|
||||||
|
ParamFlag_Splat = 1,
|
||||||
|
ParamFlag_Implicit = 2,
|
||||||
|
ParamFlag_AppendIdx = 4,
|
||||||
|
ParamFlag_Params = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
ParamFlags paramFlags = ParamFlag_None;
|
||||||
|
if (methodInstance->GetParamIsSplat(paramIdx))
|
||||||
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
|
||||||
|
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_AppendIdx)
|
||||||
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Implicit | ParamFlag_AppendIdx);
|
||||||
|
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
|
||||||
|
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Params);
|
||||||
|
|
||||||
addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
|
addr_ce stringAddr = GetString(methodInstance->GetParamName(paramIdx));
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
|
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
|
||||||
*(int16*)(stackPtr + 4) = 0; // Flags
|
*(int16*)(stackPtr + 4) = (int16)paramFlags;
|
||||||
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
|
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetGenericArg)
|
||||||
|
|
|
@ -709,6 +709,13 @@ namespace Tests
|
||||||
Test.Assert(sA == 222);
|
Test.Assert(sA == 222);
|
||||||
Val += 1000;
|
Val += 1000;
|
||||||
Test.Assert(sA == 1222);
|
Test.Assert(sA == 1222);
|
||||||
|
|
||||||
|
RefCounted<String> rcStr = .Create("Abc");
|
||||||
|
Test.Assert(rcStr->Length == 3);
|
||||||
|
rcStr->Clear();
|
||||||
|
rcStr.Release();
|
||||||
|
|
||||||
|
//RefCounted<StructB> rcB = .Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IntStruct
|
struct IntStruct
|
||||||
|
@ -740,8 +747,6 @@ namespace Tests
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestCompareWithCastOperator()
|
public static void TestCompareWithCastOperator()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue