private static void BuildResultListNoResult(ICSharpUsingCollection usingCollection, IList <ICSharpParameter> resultList, ref string parameterListText, ref string parameterNameListText, out string resultTypeText) { resultTypeText = "void"; foreach (ICSharpParameter Result in resultList) { ICSharpScopeAttributeFeature ResultAttribute = Result.Feature; ICSharpType ParameterType = ResultAttribute.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string TypeString = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); string AttributeString = CSharpNames.ToCSharpIdentifier(Result.Name); if (parameterListText.Length > 0) { parameterListText += ", "; } if (parameterNameListText.Length > 0) { parameterNameListText += ", "; } parameterListText += $"out {TypeString} {AttributeString}"; parameterNameListText += $"out {AttributeString}"; } }
/// <summary> /// Builds a list of parameters, with and without their type. /// </summary> /// <param name="usingCollection">The collection of using directives.</param> /// <param name="parameterList">The list of parameters.</param> /// <param name="parameterListText">The list of parameters with type upon return.</param> /// <param name="parameterNameListText">The list of parameters without type upon return.</param> public static void BuildParameterList(ICSharpUsingCollection usingCollection, IList <ICSharpParameter> parameterList, out string parameterListText, out string parameterNameListText) { parameterListText = string.Empty; parameterNameListText = string.Empty; foreach (ICSharpParameter Parameter in parameterList) { if (parameterListText.Length > 0) { parameterListText += ", "; } if (parameterNameListText.Length > 0) { parameterNameListText += ", "; } string ParameterName = Parameter.Name; ICSharpType ParameterType = Parameter.Feature.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ParameterText = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); string ParameterNameText = CSharpNames.ToCSharpIdentifier(ParameterName); parameterListText += $"{ParameterText} {ParameterNameText}"; parameterNameListText += ParameterNameText; } }
/// <summary> /// Gets the source code corresponding to the expression. /// </summary> /// <param name="writer">The stream on which to write.</param> /// <param name="expressionContext">The context.</param> /// <param name="skippedIndex">Index of a destination to skip.</param> public override void WriteCSharp(ICSharpWriter writer, ICSharpExpressionContext expressionContext, int skippedIndex) { Debug.Assert(WriteDown); Debug.Assert(TypeList.Count > 0); string CloneMethod = Source.Type == BaseNode.CloneType.Shallow ? "CloneShallow" : "Clone"; ICSharpExpressionContext SourceExpressionContext = new CSharpExpressionContext(); SourceExpression.WriteCSharp(writer, SourceExpressionContext, -1); IList <string> ResultList = new List <string>(); int ReturnValueIndex = SourceExpressionContext.ReturnValueIndex; string ReturnValue = SourceExpressionContext.ReturnValue; if (TypeList.Count == 1) { ICSharpType ClonedType = TypeList[0]; string SourceTypeText = ClonedType.Type2CSharpString(writer, CSharpTypeFormats.Normal, CSharpNamespaceFormats.None); string SourceText = SourceExpressionContext.ReturnValue; Debug.Assert(SourceText != null); expressionContext.SetSingleReturnValue($"({SourceTypeText})({SourceText}).{CloneMethod}()"); } else { for (int i = 0; i < SourceExpressionContext.CompleteDestinationNameList.Count; i++) { if (i == ReturnValueIndex) { Debug.Assert(ReturnValue != null); ResultList.Add(ReturnValue); } else { ResultList.Add(SourceExpressionContext.CompleteDestinationNameList[i]); } } Debug.Assert(TypeList.Count == ResultList.Count); IList <string> OutgoingResultList = new List <string>(); for (int i = 0; i < TypeList.Count; i++) { ICSharpType ClonedType = TypeList[i]; string SourceTypeText = ClonedType.Type2CSharpString(writer, CSharpTypeFormats.Normal, CSharpNamespaceFormats.None); string SourceText = ResultList[i]; OutgoingResultList.Add($"({SourceTypeText})({SourceText}).{CloneMethod}()"); } expressionContext.SetMultipleResult(OutgoingResultList, ReturnValueIndex); } }
/// <summary> /// Initializes the feature overloads and bodies. /// </summary> /// <param name="context">The initialization context.</param> public override void InitOverloadsAndBodies(ICSharpContext context) { Type = CSharpType.Create(context, Source.ResolvedEffectiveType.Item); if (Source.DefaultValue.IsAssigned) { DefaultValue = CSharpExpression.Create(context, Source.DefaultValue.Item); } }
/// <summary> /// Builds a list of parameters, with and without their type. /// </summary> /// <param name="usingCollection">The collection of using directives.</param> /// <param name="parameterList">The list of parameters.</param> /// <param name="resultList">The list of results.</param> /// <param name="featureTextType">The write mode.</param> /// <param name="parameterListText">The list of parameters with type upon return.</param> /// <param name="parameterNameListText">The list of parameters without type upon return.</param> /// <param name="resultTypeText">The type text upon return.</param> public static void BuildParameterList(ICSharpUsingCollection usingCollection, IList <ICSharpParameter> parameterList, IList <ICSharpParameter> resultList, CSharpFeatureTextTypes featureTextType, out string parameterListText, out string parameterNameListText, out string resultTypeText) { parameterListText = string.Empty; parameterNameListText = string.Empty; foreach (ICSharpParameter Parameter in parameterList) { if (parameterListText.Length > 0) { parameterListText += ", "; } if (parameterNameListText.Length > 0) { parameterNameListText += ", "; } string ParameterName = Parameter.Name; ICSharpType ParameterType = Parameter.Feature.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ParameterText = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); string ParameterNameText = CSharpNames.ToCSharpIdentifier(ParameterName); parameterListText += $"{ParameterText} {ParameterNameText}"; parameterNameListText += ParameterNameText; } if (resultList.Count == 1) { BuildResultListSingle(usingCollection, resultList, out resultTypeText); } else { int ResultIndex = -1; for (int i = 0; i < resultList.Count; i++) { ICSharpParameter Result = resultList[i]; if (Result.Name == nameof(BaseNode.Keyword.Result)) { ResultIndex = i; break; } } if (ResultIndex < 0) { BuildResultListNoResult(usingCollection, resultList, ref parameterListText, ref parameterNameListText, out resultTypeText); } else { BuildResultListWithResult(usingCollection, resultList, ResultIndex, ref parameterListText, ref parameterNameListText, out resultTypeText); } } }
/// <summary> /// Updates the number type of the expression from a type. /// </summary> /// <param name="type">The type that may be a number.</param> /// <param name="isChanged">True upon return if a number type was changed.</param> protected void UpdateNumberType(ICSharpType type, ref bool isChanged) { if (type.IsNumberType && (NumberType == CSharpNumberTypes.NotApplicable || NumberType == CSharpNumberTypes.Unknown)) { if (type.NumberType == CSharpNumberTypes.Integer || type.NumberType == CSharpNumberTypes.Real) { NumberType = type.NumberType; isChanged = true; } } }
/// <summary> /// Initializes a new instance of the <see cref="CSharpAttachment"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="parentInstruction">The parent instruction.</param> /// <param name="source">The Easly node from which the C# node is created.</param> protected CSharpAttachment(ICSharpContext context, ICSharpAttachmentInstruction parentInstruction, IAttachment source) : base(source) { ParentInstruction = parentInstruction; foreach (IScopeAttributeFeature Entity in source.ResolvedLocalEntitiesList) { ICSharpType NewType = CSharpType.Create(context, Entity.ResolvedEffectiveType.Item); AttachTypeList.Add(NewType); } Instructions = CSharpScope.Create(context, parentInstruction.ParentFeature, (IScope)source.Instructions); }
/// <summary> /// Initializes a new instance of the <see cref="CSharpCloneOfExpression"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly expression from which the C# expression is created.</param> protected CSharpCloneOfExpression(ICSharpContext context, ICloneOfExpression source) : base(context, source) { SourceExpression = Create(context, (IExpression)source.Source); IResultType SourceResult = SourceExpression.Source.ResolvedResult.Item; Debug.Assert(SourceResult.Count > 0); foreach (IExpressionType ExpressionType in SourceResult) { ICompiledType ClonedType = ExpressionType.ValueType; ICSharpType Type = CSharpType.Create(context, ClonedType); TypeList.Add(Type); } }
/// <summary> /// Initializes a new instance of the <see cref="CSharpClassType"/> class. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly type from which the C# type is created.</param> protected CSharpClassType(ICSharpContext context, IClassType source) : base(context, source) { Class = context.GetClass(source.BaseClass); foreach (ICSharpGeneric Generic in Class.GenericList) { string GenericName = Generic.Name; Debug.Assert(Source.TypeArgumentTable.ContainsKey(GenericName)); ICompiledType Type = Source.TypeArgumentTable[GenericName]; ICSharpType TypeArgument = Create(context, Type); TypeArgumentList.Add(TypeArgument); } ConformingClassTypeList.Add(this); NumberType = IsNumberType ? CSharpNumberTypes.Unknown : CSharpNumberTypes.NotApplicable; }
/// <summary> /// Creates a new C# type. /// </summary> /// <param name="context">The creation context.</param> /// <param name="source">The Easly type from which the C# type is created.</param> public static ICSharpType Create(ICSharpContext context, ICompiledType source) { ICSharpType Result = null; // A typedef is required for IFunctionType and IProcedureType. switch (source) { case IClassType AsClassType: Result = CSharpClassType.Create(context, AsClassType); break; case IFormalGenericType AsFormalGenericType: Result = CSharpFormalGenericType.Create(context, AsFormalGenericType); break; case IFunctionType AsFunctionType: Result = CSharpFunctionType.Create(context, AsFunctionType); break; case IProcedureType AsProcedureType: Result = CSharpProcedureType.Create(context, AsProcedureType); break; case IIndexerType AsIndexerType: Result = CSharpIndexerType.Create(context, AsIndexerType); break; case IPropertyType AsPropertyType: Result = CSharpPropertyType.Create(context, AsPropertyType); break; case ITupleType AsTupleType: Result = CSharpTupleType.Create(context, AsTupleType); break; } Debug.Assert(Result != null); return(Result); }
/// <summary> /// Get the name of a type. /// </summary> /// <param name="usingCollection">The collection of using directives.</param> /// <param name="cSharpTypeFormat">The type format.</param> /// <param name="cSharpNamespaceFormat">The namespace format.</param> public override string Type2CSharpString(ICSharpUsingCollection usingCollection, CSharpTypeFormats cSharpTypeFormat, CSharpNamespaceFormats cSharpNamespaceFormat) { SetUsedInCode(); string Result; // TODO: detect delegate call parameters to select the proper overload if (OriginatingTypedef != null) { string DelegateName = CSharpNames.ToCSharpIdentifier(OriginatingTypedef.Name); Result = CommandOverloadType2CSharpString(DelegateName, Source.OverloadList[0]); } else { ICSharpCommandOverloadType OverloadType = OverloadTypeList[0]; string ActionArgumentText = BaseType.Type2CSharpString(usingCollection, CSharpTypeFormats.AsInterface, CSharpNamespaceFormats.None); foreach (ICSharpParameter Parameter in OverloadType.ParameterList) { ICSharpType ParameterType = Parameter.Feature.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ParameterText = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); ActionArgumentText += $", {ParameterText}"; } Result = $"Action<{ActionArgumentText}>"; usingCollection.AddUsing(nameof(System)); } return(Result); }
private static void BuildResultListWithResult(ICSharpUsingCollection usingCollection, IList <ICSharpParameter> resultList, int resultIndex, ref string parameterListText, ref string parameterNameListText, out string resultTypeText) { resultTypeText = null; for (int i = 0; i < resultList.Count; i++) { ICSharpParameter Result = resultList[i]; ICSharpScopeAttributeFeature ResultAttribute = Result.Feature; ICSharpType ParameterType = ResultAttribute.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string TypeString = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); string AttributeString = CSharpNames.ToCSharpIdentifier(Result.Name); if (i == resultIndex) { resultTypeText = TypeString; } else { if (parameterListText.Length > 0) { parameterListText += ", "; } if (parameterNameListText.Length > 0) { parameterNameListText += ", "; } parameterListText += $"out {TypeString} {AttributeString}"; parameterNameListText += $"out {AttributeString}"; } } Debug.Assert(resultTypeText != null); }
/// <summary> /// Writes down the C# overload of a feature. /// </summary> /// <param name="writer">The stream on which to write.</param> /// <param name="featureTextType">The write mode.</param> /// <param name="isOverride">True if the feature is an override.</param> /// <param name="nameString">The composed feature name.</param> /// <param name="exportStatus">The feature export status.</param> /// <param name="isConstructor">True if the feature is a constructor.</param> /// <param name="isFirstFeature">True if the feature is the first in a list.</param> /// <param name="isMultiline">True if there is a separating line above.</param> public void WriteCSharp(ICSharpWriter writer, CSharpFeatureTextTypes featureTextType, bool isOverride, string nameString, CSharpExports exportStatus, bool isConstructor, ref bool isFirstFeature, ref bool isMultiline) { Debug.Assert(WriteDown); IList <ICSharpParameter> SelectedParameterList = ParameterList; IList <ICSharpParameter> SelectedResultList = ResultList; if (isOverride && Precursor != null) { SelectedParameterList = Precursor.ParameterList; SelectedResultList = Precursor.ResultList; } CSharpArgument.BuildParameterList(writer, SelectedParameterList, SelectedResultList, featureTextType, out string ArgumentEntityList, out string ArgumentNameList, out string ResultType); string ExportStatusText; if (featureTextType == CSharpFeatureTextTypes.Implementation) { bool IsHandled = false; switch (Body) { case ICSharpDeferredBody AsDeferredBody: CSharpAssertion.WriteContract(writer, AsDeferredBody.RequireList, AsDeferredBody.EnsureList, CSharpContractLocations.Other, true, ref isFirstFeature, ref isMultiline); ExportStatusText = CSharpNames.ComposedExportStatus(false, true, false, exportStatus); writer.WriteIndentedLine($"{ExportStatusText} {ResultType} {nameString}({ArgumentEntityList});"); isMultiline = false; IsHandled = true; break; case ICSharpEffectiveBody AsEffectiveBody: CSharpAssertion.WriteContract(writer, AsEffectiveBody.RequireList, AsEffectiveBody.EnsureList, CSharpContractLocations.Other, true, ref isFirstFeature, ref isMultiline); CSharpBodyFlags Flags = CSharpBodyFlags.MandatoryCurlyBrackets; string ResultString = string.Empty; List <string> InitialisationStringList = new List <string>(); if (ResultList.Count == 1) { Flags |= CSharpBodyFlags.HasResult; ICSharpParameter Result = ResultList[0]; ResultString = Result.Feature.Type.Type2CSharpString(writer, CSharpTypeFormats.AsInterface, CSharpNamespaceFormats.None); } else { if (ResultType != "void") { Flags |= CSharpBodyFlags.HasResult; ResultString = ResultType; } foreach (ICSharpParameter Item in ResultList) { string InitValueString; ICSharpType ResultEntityType = Item.Feature.Type; if (ResultEntityType is ICSharpClassType AsClassType) { // TODO: when the type inherit from Enumeration if (AsClassType.Class.Source.ClassGuid == LanguageClasses.AnyOptionalReference.Guid) { InitValueString = "new OptionalReference<>(null)"; // TODO } else if (AsClassType.Class.Source.ClassGuid == LanguageClasses.String.Guid) { InitValueString = "\"\""; } else if (AsClassType.Class.Source.ClassGuid == LanguageClasses.Boolean.Guid) { InitValueString = "false"; } else if (AsClassType.Class.Source.ClassGuid == LanguageClasses.Character.Guid) { InitValueString = "'\0'"; } else if (AsClassType.Class.Source.ClassGuid == LanguageClasses.Number.Guid) { InitValueString = "0"; } else { InitValueString = "null"; } } else { InitValueString = "null"; // TODO : tuples } string InitNameString = CSharpNames.ToCSharpIdentifier(Item.Name); InitialisationStringList.Add($"{InitNameString} = {InitValueString};"); } } ExportStatusText = CSharpNames.ComposedExportStatus(isOverride, false, false, exportStatus); writer.WriteIndentedLine($"{ExportStatusText} {ResultType} {nameString}({ArgumentEntityList})"); AsEffectiveBody.WriteCSharp(writer, Flags, ResultString, false, InitialisationStringList); isMultiline = true; IsHandled = true; break; case ICSharpPrecursorBody AsPrecursorBody: if (isMultiline) { writer.WriteEmptyLine(); } ExportStatusText = CSharpNames.ComposedExportStatus(true, false, false, exportStatus); writer.WriteIndentedLine($"{ExportStatusText} {ResultType} {nameString}({ArgumentEntityList})"); writer.WriteIndentedLine("{"); writer.IncreaseIndent(); writer.WriteIndentedLine($"return base.{nameString}({ArgumentNameList});"); writer.DecreaseIndent(); writer.WriteIndentedLine("}"); isMultiline = true; IsHandled = true; break; } Debug.Assert(IsHandled); } else { writer.WriteIndentedLine($"{ResultType} {nameString}({ArgumentEntityList});"); isMultiline = false; } }
/// <summary> /// Writes C# code for the type to a file in the directory at <paramref name="path"/>. /// </summary> public static void WriteToDirectory(this ICSharpType type, string path) => type.WriteToFile(Path.Combine(path, type.Identifier.Name + ".cs"));
/// <summary> /// Writes C# code for the type to a file at <paramref name="path"/>. /// </summary> public static void WriteToFile(this ICSharpType type, string path) => File.WriteAllText(path, type.ToSyntax().ToFullString(), Encoding.UTF8);
/// <summary> /// Get the name of a type. /// </summary> /// <param name="usingCollection">The collection of using directives.</param> /// <param name="cSharpTypeFormat">The type format.</param> /// <param name="cSharpNamespaceFormat">The namespace format.</param> public override string Type2CSharpString(ICSharpUsingCollection usingCollection, CSharpTypeFormats cSharpTypeFormat, CSharpNamespaceFormats cSharpNamespaceFormat) { SetUsedInCode(); string Result; if (OriginatingTypedef != null) { // TODO: detect delegate call parameters to select the proper overload string DelegateName = CSharpNames.ToCSharpIdentifier(OriginatingTypedef.Name); Result = QueryOverloadType2CSharpString(DelegateName, Source.OverloadList[0]); } else { ICSharpQueryOverloadType OverloadType = OverloadTypeList[0]; string ActionArgumentText = BaseType.Type2CSharpString(usingCollection, CSharpTypeFormats.AsInterface, CSharpNamespaceFormats.None); foreach (ICSharpParameter Parameter in OverloadType.ParameterList) { ICSharpType ParameterType = Parameter.Feature.Type; CSharpTypeFormats ParameterFormat = ParameterType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ParameterText = ParameterType.Type2CSharpString(usingCollection, ParameterFormat, CSharpNamespaceFormats.None); ActionArgumentText += $", {ParameterText}"; } Debug.Assert(OverloadType.ResultList.Count >= 1); if (OverloadType.ResultList.Count == 1) { ICSharpParameter Parameter = OverloadType.ResultList[0]; ICSharpType ResultType = Parameter.Feature.Type; CSharpTypeFormats ResultFormat = ResultType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ResultText = ResultType.Type2CSharpString(usingCollection, ResultFormat, CSharpNamespaceFormats.None); ActionArgumentText += $", {ResultText}"; } else { string FuncResultText = string.Empty; foreach (ICSharpParameter Parameter in OverloadType.ResultList) { if (FuncResultText.Length > 0) { FuncResultText += ", "; } ICSharpType ResultType = Parameter.Feature.Type; CSharpTypeFormats ResultFormat = ResultType.HasInterfaceText ? CSharpTypeFormats.AsInterface : CSharpTypeFormats.Normal; string ResultText = ResultType.Type2CSharpString(usingCollection, ResultFormat, CSharpNamespaceFormats.None); FuncResultText += $", {ResultText}"; } ActionArgumentText += $", Tuple<{FuncResultText}>"; } Result = $"Func<{ActionArgumentText}>"; usingCollection.AddUsing(nameof(System)); } return(Result); }