Example #1
0
        public ISymbolValue VisitArrayType(ArrayType t)
        {
            var valueType          = DResolver.StripMemberSymbols(t.ValueType);
            var primitiveValueType = valueType as PrimitiveType;

            ulong arraySize;
            ulong firstElement;

            var arrSymb = Symbol as IDBacktraceArraySymbol;

            if (arrSymb != null)
            {
                arraySize    = (ulong)arrSymb.ArrayLength;
                firstElement = arrSymb.FirstElementOffset;
            }
            else
            {
                if (Symbol.Offset == 0)
                {
                    return(new NullValue(t));
                }

                byte[] arrayInfo = Backtrace.BacktraceHelper.ReadBytes(Symbol.Offset, PointerSize * 2);
                arraySize    = PointerSize == 8 ? BitConverter.ToUInt64(arrayInfo, 0) : (ulong)BitConverter.ToUInt32(arrayInfo, 0);
                firstElement = PointerSize == 8 ? BitConverter.ToUInt64(arrayInfo, 8) : BitConverter.ToUInt32(arrayInfo, 4);
            }

            arraySize = Math.Min(arraySize, DLocalExamBacktrace.MaximumArrayChildrenDisplayCount);

            if (firstElement == 0)
            {
                return(new NullValue(t));
            }

            var values = new List <ISymbolValue>();

            if (primitiveValueType != null)
            {
                var tt        = primitiveValueType.TypeToken;
                var sz        = ExamHelpers.SizeOf(tt, Is64Bit);
                var charBytes = Backtrace.BacktraceHelper.ReadBytes(firstElement, sz * arraySize);

                if (DTokens.IsBasicType_Character(tt))
                {
                    return(new ArrayValue(t, ExamHelpers.GetStringValue(charBytes, tt)));
                }

                for (uint i = 0; i < arraySize; i++)
                {
                    values.Add(new PrimitiveValue(ExamHelpers.GetNumericValue(charBytes, (int)i * sz, tt), primitiveValueType));
                }
            }

            return(new ArrayValue(t, values.ToArray()));
        }
Example #2
0
        /// <summary>
        /// Checks results for implicit type convertability
        /// </summary>
        public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolutionContext ctxt = null)
        {
            var  resToCheck = AbstractType.Get(resultToCheck);
            bool isVariable = resToCheck is MemberSymbol;

            // Initially remove aliases from results
            var _r = DResolver.StripMemberSymbols(resToCheck);

            if (_r == null)
            {
                return(IsEqual(resToCheck, targetType));
            }
            resToCheck = _r;

            if (targetType is DSymbol)
            {
                var tpn = ((DSymbol)targetType).Definition as TemplateParameter.Node;

                if (tpn != null)
                {
                    var par = tpn.Parent as DNode;

                    if (par != null && par.TemplateParameters != null)
                    {
                        var dedParam = new DeducedTypeDictionary(par);

                        return(new TemplateParameterDeduction(dedParam, ctxt).Handle(tpn.TemplateParameter, resToCheck));
                    }
                }
            }

            _r = DResolver.StripMemberSymbols(targetType);
            if (_r == null)
            {
                return(false);
            }
            targetType = _r;

            if (resToCheck is PrimitiveType && targetType is PrimitiveType)
            {
                var sr1 = (PrimitiveType)resToCheck;
                var sr2 = (PrimitiveType)targetType;

                //if (sr1.TypeToken == sr2.TypeToken /*&& sr1.Modifier == sr2.Modifier*/)
                //	return true;

                return(IsPrimitiveTypeImplicitlyConvertible(sr1.TypeToken, sr2.TypeToken));
            }
            else if (resToCheck is UserDefinedType && targetType is UserDefinedType)
            {
                return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType));
            }
            else if (resToCheck is DelegateType && targetType is DelegateType)
            {
                return(IsEqual(resToCheck, targetType));                //TODO: Can non-equal delegates be converted into each other?
            }
            else if (resToCheck is ArrayType && targetType is ArrayType)
            {
                var ar1 = (ArrayType)resToCheck;
                var ar2 = (ArrayType)targetType;

                // Key as well as value types must be matching!
                var ar1_n = ar1.KeyType == null;
                var ar2_n = ar2.KeyType == null;

                if (ar1_n != ar2_n)
                {
                    return(false);
                }

                if (ar1_n || IsImplicitlyConvertible(ar1.KeyType, ar2.KeyType, ctxt))
                {
                    return(IsImplicitlyConvertible(ar1.Base, ar2.Base, ctxt));
                }
            }
            else if (resToCheck is DSymbol && targetType is DSymbol)
            {
                var r1 = resToCheck as DSymbol;
                var r2 = targetType as DSymbol;

                if (r1.Definition == r2.Definition)
                {
                    //TODO: Compare template param deductions
                    return(true);
                }
            }
            else if (resToCheck is DTuple && targetType is DTuple)
            {
                var tup1 = resToCheck as DTuple;
                var tup2 = resToCheck as DTuple;

                //TODO
                return(true);
            }

            /*else if (resultToCheck is ExpressionValueResult && targetType is ExpressionValue)
             * {
             *      return ((ExpressionValueResult)resultToCheck).Value.Equals(((ExpressionValueResult)targetType).Value);
             * }*/

            // http://dlang.org/type.html
            //TODO: Pointer to non-pointer / vice-versa checkability? -- Can it really be done implicitly?
            else if (!isVariable &&
                     resToCheck is ArrayType &&
                     targetType is PointerType && ((targetType = (targetType as PointerType).Base) is PrimitiveType) &&
                     DTokens.IsBasicType_Character((targetType as PrimitiveType).TypeToken))
            {
                return((resultToCheck as ArrayType).IsString);
            }


            return(false);
        }