public TemplateParameterSymbol(TemplateParameter tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null) : base(tpn != null ? tpn.Representation : null, AbstractType.Get(typeOrValue), paramIdentifier) { IsKnowinglyUndetermined = TemplateInstanceHandler.IsNonFinalArgument(typeOrValue); this.Parameter = tpn; this.ParameterValue = typeOrValue as ISymbolValue; }
/// <summary> /// Checks results for implicit type convertability /// </summary> public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolverContextStack ctxt = null) { var resToCheck = AbstractType.Get(resultToCheck); // Initially remove aliases from results var _r = DResolver.StripMemberSymbols(resToCheck); if (_r == null) { return(IsEqual(resToCheck, targetType)); } resToCheck = _r; targetType = DResolver.StripAliasSymbol(targetType); if (targetType is DSymbol) { var tpn = ((DSymbol)targetType).Definition as TemplateParameterNode; if (tpn != null) { var par = tpn.Parent as DNode; if (par != null && par.TemplateParameters != null) { var dedParam = new DeducedTypeDictionary { ParameterOwner = par }; foreach (var tp in par.TemplateParameters) { dedParam[tp.Name] = null; } 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); } switch (sr2.TypeToken) { case DTokens.Int: return(sr1.TypeToken == DTokens.Uint); case DTokens.Uint: return(sr1.TypeToken == DTokens.Int); //TODO: Further types that can be converted into each other implicitly } } else if (resToCheck is UserDefinedType && targetType is UserDefinedType) { return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType)); } else if (resToCheck is DelegateType && targetType is DelegateType) { //TODO } 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 TypeTuple && targetType is TypeTuple) { return(true); } else if (resToCheck is ExpressionTuple && targetType is ExpressionTuple) { 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? return(false); }
static StaticProperties() { var props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.Generic] = props; props.AddProp(new StaticPropertyInfo("init", "A type's or variable's static initializer expression") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props.AddProp(new StaticPropertyInfo("sizeof", "Size of a type or variable in bytes", DTokens.Uint)); // Do not define it as size_t due to unnecessary recursive definition as typeof(int.sizeof) props.AddProp(new StaticPropertyInfo("alignof", "Variable offset", DTokens.Uint) { RequireThis = true }); props.AddProp(new StaticPropertyInfo("mangleof", "String representing the ‘mangled’ representation of the type", "string")); props.AddProp(new StaticPropertyInfo("stringof", "String representing the source representation of the type", "string") { ValueGetter = (vp, v) => { var t = AbstractType.Get(v); if (t == null) { return(new NullValue()); } return(new ArrayValue(Evaluation.GetStringType(vp.ResolutionContext), (t is DSymbol) ? DNode.GetNodePath((t as DSymbol).Definition, true) : t.ToCode())); } }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.Integral] = props; props.AddProp(new StaticPropertyInfo("max", "Maximum value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props.AddProp(new StaticPropertyInfo("min", "Minimum value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.FloatingPoint] = props; props.AddProp(new StaticPropertyInfo("infinity", "Infinity value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props.AddProp(new StaticPropertyInfo("nan", "Not-a-Number value") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props.AddProp(new StaticPropertyInfo("dig", "Number of decimal digits of precision", DTokens.Int)); props.AddProp(new StaticPropertyInfo("epsilon", "Smallest increment to the value 1") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType }); props.AddProp(new StaticPropertyInfo("mant_dig", "Number of bits in mantissa", DTokens.Int)); props.AddProp(new StaticPropertyInfo("max_10_exp", "Maximum int value such that 10^max_10_exp is representable", DTokens.Int)); props.AddProp(new StaticPropertyInfo("max_exp", "Maximum int value such that 2^max_exp-1 is representable", DTokens.Int)); props.AddProp(new StaticPropertyInfo("min_10_exp", "Minimum int value such that 10^max_10_exp is representable", DTokens.Int)); props.AddProp(new StaticPropertyInfo("min_exp", "Minimum int value such that 2^max_exp-1 is representable", DTokens.Int)); props.AddProp(new StaticPropertyInfo("min_normal", "Number of decimal digits of precision", DTokens.Int)); props.AddProp(new StaticPropertyInfo("re", "Real part") { TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true }); props.AddProp(new StaticPropertyInfo("im", "Imaginary part") { TypeGetter = help_ReflectNonComplexType, ResolvedBaseTypeGetter = help_ReflectResolvedNonComplexType, RequireThis = true }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.Array] = props; props.AddProp(new StaticPropertyInfo("length", "Array length", DTokens.Int) { RequireThis = true, ValueGetter = (vp, v) => { var av = v as ArrayValue; return(new PrimitiveValue(DTokens.Int, av.Elements != null ? av.Elements.Length : 0, null, 0m)); } }); props.AddProp(new StaticPropertyInfo("dup", "Create a dynamic array of the same size and copy the contents of the array into it.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true }); props.AddProp(new StaticPropertyInfo("idup", "D2.0 only! Creates immutable copy of the array") { TypeGetter = (t, ctxt) => new MemberFunctionAttributeDecl(DTokens.Immutable) { InnerType = help_ReflectType(t, ctxt) }, RequireThis = true }); props.AddProp(new StaticPropertyInfo("reverse", "Reverses in place the order of the elements in the array. Returns the array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true }); props.AddProp(new StaticPropertyInfo("sort", "Sorts in place the order of the elements in the array. Returns the array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true }); props.AddProp(new StaticPropertyInfo("ptr", "Returns pointer to the array") { ResolvedBaseTypeGetter = (t, ctxt) => new PointerType((t as DerivedDataType).Base, t.DeclarationOrExpressionBase), TypeGetter = (t, ctxt) => new PointerDecl(DTypeToTypeDeclVisitor.GenerateTypeDecl((t as DerivedDataType).Base)), RequireThis = true }); props = new Dictionary <int, StaticPropertyInfo>(props); // Copy from arrays' properties! Properties[PropOwnerType.AssocArray] = props; props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the associative array. Unlike for dynamic arrays, it is read-only.", "size_t") { RequireThis = true }); props.AddProp(new StaticPropertyInfo("keys", "Returns dynamic array, the elements of which are the keys in the associative array.") { TypeGetter = (t, ctxt) => new ArrayDecl { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType) }, RequireThis = true }); props.AddProp(new StaticPropertyInfo("values", "Returns dynamic array, the elements of which are the values in the associative array.") { TypeGetter = (t, ctxt) => new ArrayDecl { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType) }, RequireThis = true }); props.AddProp(new StaticPropertyInfo("rehash", "Reorganizes the associative array in place so that lookups are more efficient. rehash is effective when, for example, the program is done loading up a symbol table and now needs fast lookups in it. Returns a reference to the reorganized array.") { TypeGetter = help_ReflectType, ResolvedBaseTypeGetter = help_ReflectResolvedType, RequireThis = true }); props.AddProp(new StaticPropertyInfo("byKey", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the keys of the associative array.") { TypeGetter = (t, ctxt) => new DelegateDeclaration() { ReturnType = new ArrayDecl() { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType) } }, RequireThis = true }); props.AddProp(new StaticPropertyInfo("byValue", "Returns a delegate suitable for use as an Aggregate to a ForeachStatement which will iterate over the values of the associative array.") { TypeGetter = (t, ctxt) => new DelegateDeclaration() { ReturnType = new ArrayDecl() { ValueType = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).ValueType) } }, RequireThis = true }); props.AddProp(new StaticPropertyInfo("get", null) { RequireThis = true, NodeGetter = (t, ctxt) => { var ad = t as AssocArrayType; var valueType = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.ValueType); return(new DMethod() { Name = "get", Description = "Looks up key; if it exists returns corresponding value else evaluates and returns defaultValue.", Type = valueType, Parameters = new List <INode> { new DVariable() { Name = "key", Type = DTypeToTypeDeclVisitor.GenerateTypeDecl(ad.KeyType) }, new DVariable() { Name = "defaultValue", Type = valueType, Attributes = new List <DAttribute> { new Modifier(DTokens.Lazy) } } } }); } }); props.AddProp(new StaticPropertyInfo("remove", null) { RequireThis = true, NodeGetter = (t, ctxt) => new DMethod { Name = "remove", Description = "remove(key) does nothing if the given key does not exist and returns false. If the given key does exist, it removes it from the AA and returns true.", Type = new DTokenDeclaration(DTokens.Bool), Parameters = new List <INode> { new DVariable { Name = "key", Type = DTypeToTypeDeclVisitor.GenerateTypeDecl((t as AssocArrayType).KeyType) } } } }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.TypeTuple] = props; props.AddProp(new StaticPropertyInfo("length", "Returns number of values in the type tuple.", "size_t") { RequireThis = true, ValueGetter = (vp, v) => { var tt = v as DTuple; if (tt == null && v is TypeValue) { tt = (v as TypeValue).RepresentedType as DTuple; } return(tt != null ? new PrimitiveValue(DTokens.Int, tt.Items == null ? 0m : (decimal)tt.Items.Length, null, 0m) : null); } }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.Delegate] = props; props.AddProp(new StaticPropertyInfo("ptr", "The .ptr property of a delegate will return the frame pointer value as a void*.", (ITypeDeclaration) new PointerDecl(new DTokenDeclaration(DTokens.Void))) { RequireThis = true }); props.AddProp(new StaticPropertyInfo("funcptr", "The .funcptr property of a delegate will return the function pointer value as a function type.") { RequireThis = true }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.ClassLike] = props; props.AddProp(new StaticPropertyInfo("classinfo", "Information about the dynamic type of the class", (ITypeDeclaration) new IdentifierDeclaration("TypeInfo_Class") { ExpressesVariableAccess = true, InnerDeclaration = new IdentifierDeclaration("object") }) { RequireThis = true }); props = new Dictionary <int, StaticPropertyInfo>(); Properties[PropOwnerType.Struct] = props; props.AddProp(new StaticPropertyInfo("sizeof", "Size in bytes of struct", DTokens.Uint)); props.AddProp(new StaticPropertyInfo("alignof", "Size boundary struct needs to be aligned on", DTokens.Uint)); props.AddProp(new StaticPropertyInfo("tupleof", "Gets type tuple of fields") { TypeGetter = (t, ctxt) => { var members = GetStructMembers(t as StructType, ctxt); var l = new List <IExpression>(); var vis = new DTypeToTypeDeclVisitor(); foreach (var member in members) { var mt = DResolver.StripMemberSymbols(member); if (mt == null) { l.Add(null); continue; } var td = mt.Accept(vis); if (td == null) { l.Add(null); continue; } l.Add(td as IExpression ?? new TypeDeclarationExpression(td)); } return(new TemplateInstanceExpression(new IdentifierDeclaration("Tuple")) { Arguments = l.ToArray() }); }, ResolvedBaseTypeGetter = (t, ctxt) => { var members = GetStructMembers(t as StructType, ctxt); var tupleItems = new List <ISemantic>(); foreach (var member in members) { var mt = DResolver.StripMemberSymbols(member); if (mt != null) { tupleItems.Add(mt); } } return(new DTuple(t.DeclarationOrExpressionBase, tupleItems)); } }); }
/// <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); }
public TemplateParameterSymbol(TemplateParameter tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null) : base(tpn != null ? tpn.Representation : null, AbstractType.Get(typeOrValue), paramIdentifier) { this.Parameter = tpn; this.ParameterValue = typeOrValue as ISymbolValue; }
public TemplateParameterSymbol(TemplateParameter.Node tpn, ISemantic typeOrValue, ISyntaxRegion paramIdentifier = null) : base(tpn, AbstractType.Get(typeOrValue), paramIdentifier) { this.Parameter = tpn.TemplateParameter; this.ParameterValue = typeOrValue as ISymbolValue; }