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())); }
/// <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); }