private void TryPolyStruct(TypeDefinitionSyntax pNode, StructInitializerSyntax pInitializer) { //Number of generic type parameters on the type does not match //the number of type arguments specified at the initialization site if (pInitializer.Struct.GenericArguments.Count != pNode.TypeParameters.Count) { CompilerErrors.TypePolyArgumentCount(pInitializer.Struct, pNode.TypeParameters.Count, pInitializer.Span); } //We just create a dictionary of T,int; T2,string; etc... and feed that to the type //When the type is emitted it will create a copy of itself for each unique generic argument Dictionary <string, SmallType> types = new Dictionary <string, SmallType>(); for (int i = 0; i < pNode.TypeParameters.Count; i++) { types.Add(pNode.TypeParameters[i], pInitializer.Struct.GenericArguments[i].Type); } pNode.AddTypeMapping(types); //We also need to add the same type mappings for any trait implementations var name = SyntaxHelper.GetFullTypeName(pNode.GetApplicableType()); if (_implements.ContainsKey(name)) { foreach (var impl in _implements[name]) { impl.AddTypeMapping(types); } } }
protected override void VisitStructInitializerSyntax(StructInitializerSyntax pNode) { //Check if the type exists if (pNode.Struct.Type == SmallTypeCache.Undefined) { CompilerErrors.UndeclaredType(pNode.Struct.ToString(), pNode.Span); } //Check if the type is a trait else if (pNode.Struct.Type.IsTrait) { CompilerErrors.AttemptDeclareTrait(pNode.Struct.Type, pNode.Span); } //Ensure the constructor arguments else if (pNode.Struct.Type.HasDefinedConstructor()) { var m = pNode.Struct.Type.GetConstructor(); for (int i = 0; i < m.ArgumentTypes.Count; i++) { if (!CanCast(pNode.Arguments[i].Type, m.ArgumentTypes[i])) { CompilerErrors.TypeCastError(pNode.Arguments[i].Type, m.ArgumentTypes[i], pNode.Arguments[i].Span); } } } base.VisitStructInitializerSyntax(pNode); }
protected virtual void VisitStructInitializerSyntax(StructInitializerSyntax pNode) { Visit(pNode.Struct); foreach (var a in pNode.Arguments) { Visit(a); } }
protected override void VisitStructInitializerSyntax(StructInitializerSyntax pNode) { //This is a initialization of a generic struct, try to poly the definition to match this call site if (pNode.Struct.GenericArguments.Count > 0 && _structsToPoly.ContainsKey(pNode.Struct.Value)) { var s = _structsToPoly[pNode.Struct.Value]; TryPolyStruct(s, pNode); } base.VisitStructInitializerSyntax(pNode); }
protected override void VisitStructInitializerSyntax(StructInitializerSyntax pNode) { base.VisitStructInitializerSyntax(pNode); for (int i = 0; i < pNode.Values.Count; i++) { if (pNode.Values[i] is MemberAccessSyntax) { Visit(pNode.Values[i]); } } var m = pNode.Type.GetConstructor(); if (m.ArgumentTypes != null && m.ArgumentTypes.Count != pNode.Arguments.Count) { CompilerErrors.ConstructorMethodArguments(pNode.Type, m.ArgumentTypes.Count, pNode.Arguments.Count, pNode.Span); } }
protected virtual SyntaxNode VisitStructInitializerSyntax(StructInitializerSyntax pNode) { List <IdentifierSyntax> variables = new List <IdentifierSyntax>(pNode.Values.Count); foreach (var v in pNode.Values) { variables.Add((IdentifierSyntax)Visit(v)); } var t = (TypeSyntax)Visit(pNode.Struct); List <SyntaxNode> arguments = new List <SyntaxNode>(pNode.Arguments.Count); foreach (var a in pNode.Arguments) { arguments.Add(Visit(a)); } return(SyntaxFactory.StructInitializer(variables, t, arguments)); }