protected static void CollectInformations(MethodEntity methodEntity, ref bool needStorage, ref bool varargs) { int outParameters = 0; int refParameters = 0; int blockParameters = 0; varargs = false; foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { if (methodParameterEntity.IsOut) { outParameters++; } if (methodParameterEntity.IsByRef) { refParameters++; } if (methodParameterEntity.IsBlock) { blockParameters++; } if (!varargs && methodParameterEntity.Type.StartsWith("params")) { varargs = true; } } needStorage = (outParameters + refParameters + blockParameters) > 0; }
private static List <MethodEntity> SheetRangeToEntityList(IList <IList <object> > sheetRange) { List <MethodEntity> methodList = new List <MethodEntity>(); if (sheetRange != null && sheetRange.Count > 0) { foreach (var row in sheetRange) { var methodEntity = new MethodEntity { Repository = row[0].ToString().Trim(), Project = row[1].ToString().Trim(), Class = row[2].ToString().Trim(), Method = row[3].ToString().Trim(), Coverage = int.Parse(row[4].ToString()), Team = row[6].ToString().Trim(), UpdatedDate = row.Count < 10 ? string.Empty : row[9].ToString().Trim(), RawData = row, }; if (string.IsNullOrWhiteSpace(methodEntity.Method) == false) { methodList.Add(methodEntity); } } } return(methodList); }
public override void ProcessClosures(Context ctx) { if (MustInferArgTypes) { var name = Arguments.First(a => a.Type == typeof(UnspecifiedType)).Name; Error(CompilerMessages.LambdaArgTypeUnknown, name); } // get evaluated return type var retType = _inferredReturnType ?? Body.Resolve(ctx); if (retType == typeof(NullType)) { Error(CompilerMessages.LambdaReturnTypeUnknown); } if (retType.IsVoid()) { retType = typeof(void); } _method = ctx.Scope.CreateClosureMethod(ctx, Arguments, retType); _method.Body = Body; var outerMethod = ctx.CurrentMethod; ctx.CurrentMethod = _method; _method.Body.ProcessClosures(ctx); ctx.CurrentMethod = outerMethod; }
protected void AppendDocumentation(MethodEntity methodEntity, bool extensionParameter = false, bool opaqueParameter = false) { // Append method comments this.Writer.WriteLineFormat(2, "/// <summary>"); foreach (String line in methodEntity.Summary) { this.Writer.WriteLineFormat(2, "/// <para>{0}</para>", line.EscapeAll()); } this.Writer.WriteLineFormat(2, "/// <para>Original signature is '{0}'</para>", methodEntity.Signature.EscapeAll()); this.AppendAvailability(2, methodEntity); this.Writer.WriteLineFormat(2, "/// </summary>"); // Add extra parameter if (extensionParameter) { this.Writer.WriteLineFormat(2, "/// <param name=\"__target\">The target instance.</param>"); } // Append parameters' comments foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { this.Writer.WriteLineFormat(2, "/// <param name=\"{0}\">{1}</param>", methodParameterEntity.Name.Trim('@'), methodParameterEntity.Summary.Count > 0 ? methodParameterEntity.Summary [0].EscapeAll() : "MISSING"); } // Append returns' comments if (!String.Equals(methodEntity.ReturnType, "void")) { this.Writer.WriteLineFormat(2, "/// <returns>{0}</returns>", methodEntity.ReturnsDocumentation.EscapeAll()); } }
private PropertyEntity ExtractProperty(PropertyDeclaration propertyDeclaration) { PropertyEntity propertyEntity = new PropertyEntity(); propertyEntity.Name = propertyDeclaration.Name; propertyEntity.Static = (propertyDeclaration.Modifier & Modifiers.Static) == Modifiers.Static; // Get the method's comment IEnumerable <Comment> comments = this.GetDocumentationCommentsBefore(propertyDeclaration); AppendComment(propertyEntity, comments); // Extract getter MethodEntity getterEntity = new MethodEntity(); propertyEntity.Getter = getterEntity; // Extract signature from comments Comment signatureComment = comments.FirstOrDefault(c => CommentHelper.IsSignature(c.CommentText.Trim())); if (signatureComment != null) { getterEntity.Signature = signatureComment.Trim("Original signature is", "'", ";", "private"); } // Extract selector MethodSelectorExtractor extractor = new MethodSelectorExtractor(getterEntity.Signature); getterEntity.Selector = extractor.Extract(); // Parse the signature for return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(getterEntity.Signature); if (signatureEnumerator.MoveNext()) { bool isOut, isByRef, isBlock; propertyEntity.Type = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), out isOut, out isByRef, out isBlock, this.Logger); } else { propertyEntity.Type = "Id"; } if (propertyDeclaration.HasSetRegion) { MethodEntity setterEntity = new MethodEntity(); setterEntity.Selector = "MISSING"; MethodParameterEntity methodParameterEntity = new MethodParameterEntity(); methodParameterEntity.Name = "value"; methodParameterEntity.Type = propertyEntity.Type; setterEntity.Parameters.Add(methodParameterEntity); setterEntity.ReturnType = "void"; propertyEntity.Setter = setterEntity; } return(propertyEntity); }
private static string GetExtraParameter(ClassEntity classEntity, MethodEntity methodEntity, bool extension) { if (extension && !methodEntity.Static) { return(String.Format("this {0} __target", classEntity.Name)); } return(String.Empty); }
/// <summary> /// Gets the name of the method. /// </summary> /// <param name = "methodEntity">The method entity.</param> /// <returns></returns> internal static String GetMethodName(MethodEntity methodEntity) { String[] parts = methodEntity.Selector.Split (new[] {':'}, StringSplitOptions.RemoveEmptyEntries); StringBuilder builder = new StringBuilder (); foreach (String part in parts) { String token = part.UpperCaseFirstLetter (); builder.Append (token); } return builder.ToString (); }
public GlobalPropertyInfo(int id, Type propType, bool hasGetter, bool hasSetter, MethodEntity getterMethod, MethodEntity setterMethod) { PropertyId = id; PropertyType = propType; HasGetter = hasGetter; HasSetter = hasSetter; GetterMethod = getterMethod; SetterMethod = setterMethod; }
private MethodEntity DeriveMethodEntity(MethodEntity methodEntity, bool is64Bits) { MethodEntity result = new MethodEntity(methodEntity); result.ReturnType = this.GetRealType(result.ReturnType, is64Bits); foreach (MethodParameterEntity parameter in result.Parameters) { parameter.Type = this.GetRealType(parameter.Type, is64Bits); } return(result); }
protected void ExtractDelegateMethods(ClassEntity classEntity, XElement root) { IEnumerable <XElement> methods = from el in root.Descendants("div") where (String)el.Attribute("class") == "api delegateMethod" select el; foreach (XElement methodElement in methods) { MethodEntity methodEntity = this.MethodParser.Parse(classEntity, methodElement); classEntity.DelegateMethods.Add(methodEntity); } }
/// <summary> /// Gets the name of the method. /// </summary> /// <param name = "methodEntity">The method entity.</param> /// <returns></returns> internal static String GetMethodName(MethodEntity methodEntity) { String[] parts = methodEntity.Selector.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries); StringBuilder builder = new StringBuilder(); foreach (String part in parts) { String token = part.UpperCaseFirstLetter(); builder.Append(token); } return(builder.ToString()); }
private void GenerateConstructorBody(int indent, string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool needStorage, bool varargs) { //bool hasReturn = !String.Equals (methodEntity.ReturnType, "void"); //bool mixed = (innerMethodEntity != null); this.GenerateLocalsAllocation(indent, methodEntity, innerMethodEntity); this.GenerateLocalsMarshalling(indent, methodEntity, innerMethodEntity); String invocation = GetMethodInvocation(target, methodEntity, innerMethodEntity, true, false); this.Writer.WriteLineFormat(indent, "this.NativePointer = {0}", invocation); this.GenerateLocalsUnmarshalling(indent, methodEntity, innerMethodEntity); this.GenerateLocalsDeallocation(indent, methodEntity, innerMethodEntity); }
protected void GenerateLocalsMarshalling(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut) { if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains(methodParameterEntity.Type)) // Boolean // TODO: Add zeroing { index++; } else if ("float,double".Contains(methodParameterEntity.Type)) { // TODO: Add zeroing index++; } else if (IsMixedType(methodParameterEntity.Type)) { // TODO: Add zeroing index++; } else { this.Writer.WriteLineFormat(indent, "Marshal.WriteIntPtr(__local{0}, IntPtr.Zero);", index++); } } else if (methodParameterEntity.IsByRef) { if (IsMixedType(methodParameterEntity.Type)) { this.Writer.WriteLineFormat(indent, "Marshal.StructureToPtr(({0}) {1}, __local{2}, false);", innerMethodParameterEntity.Type, methodParameterEntity.Name, index++); } else { this.Writer.WriteLineFormat(indent, "Marshal.StructureToPtr({0}, __local{1}, false);", methodParameterEntity.Name, index++); } } else if (methodParameterEntity.IsBlock) { index++; } } }
protected static String GetMessageParameterList(MethodEntity methodEntity, MethodEntity innerMethodEntity, bool withColonFirst) { StringBuilder builder = new StringBuilder(); int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (!innerMethodParameterEntity.Generate) { continue; } if (i > 0 || withColonFirst) { builder.Append(", "); } if (innerMethodParameterEntity.IsOut) { builder.AppendFormat("__local{0}", index++); } else if (innerMethodParameterEntity.IsByRef) { builder.AppendFormat("__local{0}", index++); } else if (innerMethodParameterEntity.IsBlock) { builder.AppendFormat("__local{0}", index++); } else { if (String.Equals(methodParameterEntity.Type, innerMethodParameterEntity.Type)) { builder.AppendFormat("{0}", innerMethodParameterEntity.Name); } else { builder.AppendFormat("({0}) {1}", innerMethodParameterEntity.Type, innerMethodParameterEntity.Name); } } } return(builder.ToString()); }
private static String GetTarget(ClassEntity classEntity, MethodEntity methodEntity, bool extension) { if (methodEntity.Static) { if (extension) { return(String.Format("{0}.{0}Class", classEntity.Name)); } return(String.Format("{0}Class", classEntity.Name)); } if (extension) { return("__target"); } return("this"); }
public override MethodEntity ParseMethod() { if (this.RetVar != null) { this.StatementProcessor.RegisterNewExpressionAssignment(RetVar, new TypeDescriptor(RetVar.Type, false)); } var descriptor = new MethodEntityDescriptor(this.MethodDescriptor); //EntityFactory.Create(this.MethodDescriptor, this.Dispatcher); var methodEntity = new MethodEntity(this.MethodDescriptor, this.MethodInterfaceData, this.PropGraph, descriptor, this.InstantiatedTypes, false); return(methodEntity); }
protected static bool AreMethodTypesEqual(MethodEntity methodEntity1, MethodEntity methodEntity2) { if (!String.Equals(methodEntity1.ReturnType, methodEntity2.ReturnType)) { return(false); } for (int i = 0; i < methodEntity1.Parameters.Count; i++) { if (!String.Equals(methodEntity1.Parameters [i].Type, methodEntity2.Parameters [i].Type)) { return(false); } } return(true); }
/// <summary> /// Creates a wrapper from a method entity. /// </summary> private MethodWrapper WrapMethod(MethodEntity method, bool isPartial = false) { return(new MethodWrapper { Name = method.Name, Type = method.ContainerType.TypeInfo, IsStatic = method.IsStatic, IsVirtual = method.IsVirtual, IsPartiallyApplied = isPartial, IsVariadic = method.IsVariadic, MethodInfo = method.MethodInfo, ArgumentTypes = method.GetArgumentTypes(this), ReturnType = method.ReturnType }); }
/// <summary> /// 尋找 Kind = Method 的各階層的項目 /// </summary> /// <param name="result">回傳值</param> /// <param name="source">目前的階層</param> private void FindMethod(List <MethodEntity> result, string assembly, string parentName, List <DotCoverReportChild> source) { if (source == null) { return; } foreach (var item in source) { var iName = parentName; if (item.Kind == Kind.Method) { var covearge = new MethodEntity { Project = assembly, Class = iName.Remove(iName.Length - 1, 1), Method = item.Name, Coverage = (int)item.CoveragePercent, }; result.Add(covearge); } else if (item.Kind == Kind.Type) { var coverage = new MethodEntity { Project = assembly, Class = iName + item.Name, Method = "*", Coverage = (int)item.CoveragePercent, }; result.Add(coverage); iName += $"{item.Name}."; FindMethod(result, assembly, iName, item.Children); } else if (item.Kind == Kind.Assembly) { assembly = item.Name; FindMethod(result, assembly, iName, item.Children); } else { iName += $"{item.Name}."; FindMethod(result, assembly, iName, item.Children); } } }
protected void GenerateLocalsDeallocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; //MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { this.Writer.WriteLineFormat(indent, "Marshal.FreeHGlobal(__local{0});", index++); } else if (methodParameterEntity.IsBlock) { this.Writer.WriteLineFormat(indent, "__local{0}.Dispose();", index++); } } }
protected void GenerateMethodBody(int indent, string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool needStorage, bool varargs) { bool hasReturn = !String.Equals(methodEntity.ReturnType, "void"); bool mixed = (innerMethodEntity != null); bool mixedReturnType = mixed && !String.Equals(methodEntity.ReturnType, innerMethodEntity.ReturnType); this.GenerateLocalsAllocation(indent, methodEntity, innerMethodEntity); this.GenerateLocalsMarshalling(indent, methodEntity, innerMethodEntity); String invocation = GetMethodInvocation(target, methodEntity, innerMethodEntity, hasReturn, varargs); if (hasReturn) { if (needStorage) { String prefix = methodEntity.ReturnType + " __result = "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } else { String prefix = "return "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } } this.Writer.WriteLineFormat(indent, invocation); this.GenerateLocalsUnmarshalling(indent, methodEntity, innerMethodEntity); this.GenerateLocalsDeallocation(indent, methodEntity, innerMethodEntity); if (hasReturn && needStorage) { this.Writer.WriteLineFormat(indent, "return __result;"); } }
public void Test涵蓋率未下降則不發通知() { //// Arrange var coverageEntity = new CoverageEntity { Repository = "Phanerozoic" }; var methodUnchange = new MethodEntity { Class = "AClass", Method = "AMethod", Status = CoverageStatus.Unchange, Coverage = 23, }; var methodUp = new MethodEntity { Class = "AClass", Method = "AMethod", Status = CoverageStatus.Up, Coverage = 23, }; var methodList = new List <MethodEntity> { methodUnchange, methodUp, }; var stringBuilder = new StringBuilder(); stringBuilder.AppendLine(methodUnchange.ToString()); var expectedMessage = stringBuilder.ToString(); //// Act var target = GetTarget(); target.Notify(coverageEntity, methodList); //// Assert this._stubSlackService.DidNotReceiveWithAnyArgs().SendAsync(string.Empty, Arg.Any <string>()); }
protected void ExtractMethods(ClassEntity classEntity, XElement root) { // Extract name String compoundname = (from el in root.Descendants("compoundname") select el.TrimAll()).FirstOrDefault(); IEnumerable <XElement> memberDefs = (from el in root.Descendants("memberdef") where el.Attribute("kind").Value == "function" select el); foreach (XElement memberDef in memberDefs) { String definition = memberDef.Element("definition").TrimAll(); if (!definition.Contains(compoundname + "::")) { continue; } MethodEntity methodEntity = this.MethodParser.Parse(classEntity, memberDef); classEntity.Methods.Add(methodEntity); } }
public override MethodEntity ParseMethod() { Contract.Assert(this.methodNode != null); var propGraphGenerator = new MethodSyntaxVisitor(this.model, this.RoslynMethod, this, this.containingTypeNode, this.methodNode); propGraphGenerator.Visit(this.methodNode); var descriptor = new MethodEntityDescriptor(propGraphGenerator.MethodDescriptor); //EntityFactory.Create(this.MethodDescriptor, this.Dispatcher); var declarationInfo = CodeGraphHelper.GetMethodDeclarationInfo(this.methodNode, this.RoslynMethod); var referenceInfo = CodeGraphHelper.GetMethodReferenceInfo(this.methodNode); var methodEntity = new MethodEntity(propGraphGenerator.MethodDescriptor, propGraphGenerator.MethodInterfaceData, propGraphGenerator.PropGraph, descriptor, propGraphGenerator.InstantiatedTypes, propGraphGenerator.StatementProcessor.AnonymousMethods, declarationInfo, referenceInfo); return(methodEntity); }
protected void ExtractMethods(ClassEntity classEntity, XElement root) { XElement listMarker = (from el in root.Descendants("h2") where el.Value == "Methods" select el).FirstOrDefault(); XElement list = listMarker != null?listMarker.ElementsAfterSelf("dl").FirstOrDefault() : null; if (list != null) { // Collect names List <String> names = new List <string> (); foreach (XElement term in list.Descendants("dt")) { String name = term.Value.TrimAll(); names.Add(name.Trim('-', '+')); } // Search for a table with preceding by an anchor containing the name foreach (String name in names) { XElement marker = (from el in list.ElementsAfterSelf("a") where el.Attribute("name") != null && el.Attribute("name").Value.EndsWith("/" + name) select el).FirstOrDefault(); if (marker != null) { //XElement startElement = marker.ElementsAfterSelf ("table").FirstOrDefault (); IEnumerable <XElement> elements = marker.ElementsAfterSelf().TakeWhile(el => el.Name != "a"); MethodEntity methodEntity = this.MethodParser.Parse(classEntity, name, elements); classEntity.Methods.Add(methodEntity); } else { this.Logger.WriteLine("MISSING marker for method " + name); } } } }
private List <MethodEntity> GetCurrentMethodList() { var now = this._dateTimeHelper.Now; var startIndex = 1; var maxRow = string.Empty; List <MethodEntity> methodLogList = new List <MethodEntity>(); IList <IList <object> > values = this._googleSheetsService.GetValues(this._sheetsId, $"{now.Year}!A{startIndex + 1}:I{maxRow}"); var index = startIndex; if (values != null && values.Count > 0) { foreach (var row in values) { if (row.Count < 4) { continue; } index++; var methodEntity = new MethodEntity { Repository = row[0].ToString().Trim(), Project = row[1].ToString().Trim(), Class = row[2].ToString().Trim(), Method = row[3].ToString().Trim(), RawIndex = index, RawData = row, }; if (string.IsNullOrWhiteSpace(methodEntity.Method) == false) { methodLogList.Add(methodEntity); } } } return(methodLogList); }
protected void GenerateLocalsAllocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains(methodParameterEntity.Type)) { this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type); } else if ("IntPtr".Contains(methodParameterEntity.Type)) { this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(IntPtr.Size);", index++); } else if ("float,double".Contains(methodParameterEntity.Type)) { this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type); } else if (IsMixedType(methodParameterEntity.Type)) { this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, innerMethodParameterEntity.Type); } else { this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (IntPtr)));", index++); } } else if (methodParameterEntity.IsBlock) { this.Writer.WriteLineFormat(indent, "Block __local{0} = ObjectiveCRuntime.CreateBlock({1});", index++, methodParameterEntity.Name); } } }
protected static String GetKeywords(MethodEntity methodEntity, bool implementation, bool extension, bool markedAsNew) { String keywords = String.Empty; if (!implementation) { return(keywords); } keywords = "public "; if (markedAsNew) { keywords += "new "; } if (methodEntity.Static || extension) { keywords += "static "; } else if (!markedAsNew) { keywords += "virtual "; } return(keywords); }
public void Test涵蓋率下降的方法發出通知() { //// Arrange var coverageEntity = new CoverageEntity { Repository = "Phanerozoic" }; var method = new MethodEntity { Class = "AClass", Method = "AMethod", Status = CoverageStatus.Down, Coverage = 23, }; var methodList = new List <MethodEntity> { method, }; var stringBuilder = new StringBuilder(); stringBuilder.AppendLine(method.ToString()); var expectedMessage = stringBuilder.ToString(); var webHookUrl = "http://abc.com"; this._stubConfiguration["Slack:WebHookUrl"].Returns(webHookUrl); //// Act var target = GetTarget(); target.Notify(coverageEntity, methodList); //// Assert this._stubSlackService.Received(1).SendAsync(webHookUrl, Arg.Any <string>()); }
private static string GetMethodInvocation(string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool hasReturn, bool varargs) { StringBuilder builder = new StringBuilder(); String suffix = varargs ? "VarArgs" : String.Empty; if (hasReturn) { String returnType = innerMethodEntity != null ? innerMethodEntity.ReturnType : methodEntity.ReturnType; builder.AppendFormat("ObjectiveCRuntime.SendMessage{0}<{1}>", suffix, returnType); } else { builder.AppendFormat("ObjectiveCRuntime.SendMessage{0}", suffix); } String selector = innerMethodEntity != null ? innerMethodEntity.Selector : methodEntity.Selector; builder.AppendFormat("({0}, \"{1}\"", target, selector); builder.Append(GetMessageParameterList(methodEntity, innerMethodEntity, true)); builder.Append(");"); return(builder.ToString()); }
/// <summary> /// Appends the documentation. /// </summary> private void AppendDocumentation(int indent, MethodEntity methodEntity) { // Append method comments this.Writer.WriteLineFormat(indent, "/// <summary>"); foreach (String line in methodEntity.Summary) { this.Writer.WriteLineFormat(indent, "/// <para>{0}</para>", line.EscapeAll()); } this.Writer.WriteLineFormat(indent, "/// <para>Original signature is '{0}'</para>", methodEntity.Signature.EscapeAll()); this.AppendAvailability(indent, methodEntity); this.Writer.WriteLineFormat(indent, "/// </summary>"); // Append parameters' comments foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { this.Writer.WriteLineFormat(indent, "/// <param name=\"{0}\">{1}</param>", methodParameterEntity.Name.Trim('@'), methodParameterEntity.Summary.Count > 0 ? methodParameterEntity.Summary [0].EscapeAll() : "MISSING"); } // Append returns' comments if (!String.Equals(methodEntity.ReturnType, "void")) { this.Writer.WriteLineFormat(indent, "/// <returns>{0}</returns>", methodEntity.ReturnsDocumentation.EscapeAll()); } }
protected void GenerateLocalsUnmarshalling(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { switch (methodParameterEntity.Type) { case "bool": case "byte": this.Writer.WriteLineFormat (indent, "{0} = (Marshal.ReadByte(__local{1}) != 0);", methodParameterEntity.Name, index++); break; case "short": this.Writer.WriteLineFormat (indent, "{0} = Marshal.ReadInt16(__local{1});", methodParameterEntity.Name, index++); break; case "ushort": this.Writer.WriteLineFormat (indent, "{0} = (ushort) Marshal.ReadInt16(__local{1});", methodParameterEntity.Name, index++); break; case "int": this.Writer.WriteLineFormat (indent, "{0} = Marshal.ReadInt32(__local{1});", methodParameterEntity.Name, index++); break; case "uint": this.Writer.WriteLineFormat (indent, "{0} = (uint) Marshal.ReadInt32(__local{1});", methodParameterEntity.Name, index++); break; case "long": this.Writer.WriteLineFormat (indent, "{0} = Marshal.ReadInt64(__local{1});", methodParameterEntity.Name, index++); break; case "ulong": this.Writer.WriteLineFormat (indent, "{0} = (ulong) Marshal.ReadInt64(__local{1});", methodParameterEntity.Name, index++); break; case "IntPtr": this.Writer.WriteLineFormat (indent, "{0} = Marshal.ReadIntPtr(__local{1});", methodParameterEntity.Name, index++); break; case "float": case "double": this.Writer.WriteLineFormat (indent, "{0} = ({1}) Marshal.PtrToStructure(__local{2}, typeof({1}));", methodParameterEntity.Name, methodParameterEntity.Type, index++); break; default: if (IsMixedType (methodParameterEntity.Type) || methodParameterEntity.IsStruct) { if (methodParameterEntity.Type.Equals (innerMethodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "{0} = ({1}) Marshal.PtrToStructure(__local{2}, typeof({1}));", methodParameterEntity.Name, methodParameterEntity.Type, index++, innerMethodParameterEntity.Type); } else { this.Writer.WriteLineFormat (indent, "{0} = ({1}) ({3}) Marshal.PtrToStructure(__local{2}, typeof({3}));", methodParameterEntity.Name, methodParameterEntity.Type, index++, innerMethodParameterEntity.Type); } } else { this.Writer.WriteLineFormat (indent, "{0} = ObjectiveCRuntime.GetInstance<{1}>(Marshal.ReadIntPtr(__local{2}));", methodParameterEntity.Name, methodParameterEntity.Type, index++); } break; } } else if (methodParameterEntity.IsBlock) { index++; } } }
/// <summary> /// Appends the documentation. /// </summary> private void AppendDocumentation(int indent, MethodEntity methodEntity) { // Append method comments this.Writer.WriteLineFormat (indent, "/// <summary>"); foreach (String line in methodEntity.Summary) { this.Writer.WriteLineFormat (indent, "/// <para>{0}</para>", line.EscapeAll ()); } this.Writer.WriteLineFormat (indent, "/// <para>Original signature is '{0}'</para>", methodEntity.Signature.EscapeAll()); this.AppendAvailability (indent, methodEntity); this.Writer.WriteLineFormat (indent, "/// </summary>"); // Append parameters' comments foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { this.Writer.WriteLineFormat (indent, "/// <param name=\"{0}\">{1}</param>", methodParameterEntity.Name.Trim ('@'), methodParameterEntity.Summary.Count > 0 ? methodParameterEntity.Summary [0].EscapeAll () : "MISSING"); } // Append returns' comments if (!String.Equals (methodEntity.ReturnType, "void")) { this.Writer.WriteLineFormat (indent, "/// <returns>{0}</returns>", methodEntity.ReturnsDocumentation.EscapeAll ()); } }
private PropertyEntity ExtractProperty(PropertyDeclaration propertyDeclaration) { PropertyEntity propertyEntity = new PropertyEntity (); propertyEntity.Name = propertyDeclaration.Name; propertyEntity.Static = (propertyDeclaration.Modifier & Modifiers.Static) == Modifiers.Static; // Get the method's comment IEnumerable<Comment> comments = this.GetDocumentationCommentsBefore (propertyDeclaration); AppendComment (propertyEntity, comments); // Extract getter MethodEntity getterEntity = new MethodEntity (); propertyEntity.Getter = getterEntity; // Extract signature from comments Comment signatureComment = comments.FirstOrDefault (c => CommentHelper.IsSignature (c.CommentText.Trim ())); if (signatureComment != null) { getterEntity.Signature = signatureComment.Trim ("Original signature is", "'", ";", "private"); } // Extract selector MethodSelectorExtractor extractor = new MethodSelectorExtractor (getterEntity.Signature); getterEntity.Selector = extractor.Extract (); // Parse the signature for return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator (getterEntity.Signature); if (signatureEnumerator.MoveNext ()) { bool isOut, isByRef, isBlock; propertyEntity.Type = this.TypeManager.ConvertType (signatureEnumerator.Current.TrimAll (), out isOut, out isByRef, out isBlock, this.Logger); } else { propertyEntity.Type = "Id"; } if (propertyDeclaration.HasSetRegion) { MethodEntity setterEntity = new MethodEntity (); setterEntity.Selector = "MISSING"; MethodParameterEntity methodParameterEntity = new MethodParameterEntity (); methodParameterEntity.Name = "value"; methodParameterEntity.Type = propertyEntity.Type; setterEntity.Parameters.Add (methodParameterEntity); setterEntity.ReturnType = "void"; propertyEntity.Setter = setterEntity; } return propertyEntity; }
private MethodEntity ExtractMethod(MethodDeclaration methodDeclaration) { MethodEntity methodEntity = new MethodEntity (); methodEntity.Name = methodDeclaration.Name; // Get the method's comment IEnumerable<Comment> comments = this.GetDocumentationCommentsBefore (methodDeclaration); // Extract signature from comments Comment signatureComment = comments.FirstOrDefault (c => CommentHelper.IsSignature (c.CommentText.Trim ())); if (signatureComment != null) { methodEntity.Signature = signatureComment.Trim ("Original signature is", "'", ";", "private"); } AppendComment (methodEntity, comments); methodEntity.Static = (methodDeclaration.Modifier & Modifiers.Static) == Modifiers.Static; // Extract selector MethodSelectorExtractor extractor = new MethodSelectorExtractor (methodEntity.Signature); methodEntity.Selector = extractor.Extract (); // Parse the signature for return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator (methodEntity.Signature); if (signatureEnumerator.MoveNext ()) { bool isOut, isByRef, isBlock; methodEntity.ReturnType = this.TypeManager.ConvertType (signatureEnumerator.Current.TrimAll (), out isOut, out isByRef, out isBlock, this.Logger); } else { methodEntity.ReturnType = "Id"; } // Parse signature for parameter names and types MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator (methodEntity.Signature, false); MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator (methodEntity.Signature, true); while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext()) { MethodParameterEntity parameterEntity = new MethodParameterEntity (); bool isOut, isByRef, isBlock; parameterEntity.Type = this.TypeManager.ConvertType (parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger); parameterEntity.IsOut = isOut; parameterEntity.IsByRef = isByRef; parameterEntity.IsBlock = isBlock; parameterEntity.Name = parameterNamesEnumerator.Current.Trim (); methodEntity.Parameters.Add (parameterEntity); } // Extract the corresponding comments foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters) { String s = comments.GetParameterDescription (methodParameterEntity.Name); methodParameterEntity.Summary.Add (s); } return methodEntity; }
protected static bool AreMethodTypesEqual(MethodEntity methodEntity1, MethodEntity methodEntity2) { if (!String.Equals (methodEntity1.ReturnType, methodEntity2.ReturnType)) { return false; } for (int i = 0; i < methodEntity1.Parameters.Count; i++) { if (!String.Equals (methodEntity1.Parameters [i].Type, methodEntity2.Parameters [i].Type)) { return false; } } return true; }
protected void GenerateMethodBody(int indent, string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool needStorage, bool varargs) { bool hasReturn = !String.Equals (methodEntity.ReturnType, "void"); bool mixed = (innerMethodEntity != null); bool mixedReturnType = mixed && !String.Equals (methodEntity.ReturnType, innerMethodEntity.ReturnType); this.GenerateLocalsAllocation (indent, methodEntity, innerMethodEntity); this.GenerateLocalsMarshalling (indent, methodEntity, innerMethodEntity); String invocation = GetMethodInvocation (target, methodEntity, innerMethodEntity, hasReturn, varargs); if (hasReturn) { if (needStorage) { String prefix = methodEntity.ReturnType + " __result = "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } else { String prefix = "return "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } } this.Writer.WriteLineFormat (indent, invocation); this.GenerateLocalsUnmarshalling (indent, methodEntity, innerMethodEntity); this.GenerateLocalsDeallocation (indent, methodEntity, innerMethodEntity); if (hasReturn && needStorage) { this.Writer.WriteLineFormat (indent, "return __result;"); } }
protected static String GetKeywords(MethodEntity methodEntity, bool implementation, bool extension, bool markedAsNew) { String keywords = String.Empty; if (!implementation) { return keywords; } keywords = "public "; if (markedAsNew) { keywords += "new "; } if (methodEntity.Static || extension) { keywords += "static "; } else if (!markedAsNew) { keywords += "virtual "; } return keywords; }
private MethodEntity DeriveMethodEntity(MethodEntity methodEntity, bool is64Bits) { MethodEntity result = new MethodEntity (methodEntity); result.ReturnType = this.GetRealType (result.ReturnType, is64Bits); foreach (MethodParameterEntity parameter in result.Parameters) { parameter.Type = this.GetRealType (parameter.Type, is64Bits); } return result; }
private static string GetMethodInvocation(string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool hasReturn, bool varargs) { StringBuilder builder = new StringBuilder (); String suffix = varargs ? "VarArgs" : String.Empty; if (hasReturn) { String returnType = innerMethodEntity != null ? innerMethodEntity.ReturnType : methodEntity.ReturnType; builder.AppendFormat ("ObjectiveCRuntime.SendMessage{0}<{1}>", suffix, returnType); } else { builder.AppendFormat ("ObjectiveCRuntime.SendMessage{0}", suffix); } String selector = innerMethodEntity != null ? innerMethodEntity.Selector : methodEntity.Selector; builder.AppendFormat ("({0}, \"{1}\"", target, selector); builder.Append (GetMessageParameterList (methodEntity, innerMethodEntity, true)); builder.Append (");"); return builder.ToString (); }
/// <summary> /// Parses the specified method element. /// </summary> /// <param name = "methodElement">The method element.</param> /// <returns></returns> public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement) { MethodEntity methodEntity = new MethodEntity(); XElement selectorElement = methodElement.Element("h3"); methodEntity.Selector = selectorElement.TrimAll(); methodEntity.Name = GetMethodName(methodEntity); this.Logger.WriteLine(" Method '" + methodEntity.Selector + "'"); // Extract signature XElement signatureElement = (from el in methodElement.Elements("div") where (String) el.Attribute("class") == "declaration" select el).FirstOrDefault(); methodEntity.Signature = signatureElement.TrimAll(); methodEntity.Signature = methodEntity.Signature.TrimEnd(';'); methodEntity.Signature = methodEntity.Signature.Replace(", ...", ",..."); // MethodParametersEnumerator needs this format methodEntity.Static = methodEntity.Signature.StartsWith("+"); // Extract abstract XElement abstractElement = (from el in methodElement.Elements("p") where (String) el.Attribute("class") == "abstract" select el).FirstOrDefault(); methodEntity.Summary.Add(abstractElement.TrimAll()); //// Extract discussion //IEnumerable<XElement> paragraphs = (from el in methodElement.Elements("p").Elements("p") // where (String) el.Parent.Attribute("class") == "api discussion" // select el); //foreach (XElement paragraph in paragraphs) //{ // methodEntity.Summary.Add(paragraph.TrimAll()); //} // Extract return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature); if (signatureEnumerator.MoveNext()) { methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger); } else { methodEntity.ReturnType = "Id"; } // Extract parameter type and name MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false); MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true); while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext()) { MethodParameterEntity parameterEntity = new MethodParameterEntity(); bool isOut, isByRef, isBlock; parameterEntity.Type = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger); parameterEntity.IsOut = isOut; parameterEntity.IsByRef = isByRef; parameterEntity.IsBlock = isBlock; parameterEntity.Name = parameterNamesEnumerator.Current.Trim(); methodEntity.Parameters.Add(parameterEntity); // Correct names that end in a single period if (parameterEntity.Name.EndsWith(".") && !parameterEntity.Name.EndsWith("..")) { parameterEntity.Name = parameterEntity.Name.Substring(0, parameterEntity.Name.Length - 1); } // Handle variadic parameters Match r = VARARG_PARAMETER_REGEX.Match (parameterEntity.Name); if (r.Success) { // Fix the last parameter name by removing "..." parameterEntity.Name = r.Groups [1].Value.Trim (); // Add a new variadic parameter parameterEntity = new MethodParameterEntity(); parameterEntity.Type = "params Object[]"; parameterEntity.Name = "values"; parameterEntity.Summary.Add("Variable argument values"); methodEntity.Parameters.Add(parameterEntity); } } // Extract parameter documentation if (methodEntity.Parameters.Count > 0) { XElement termList = (from el in methodElement.Elements("div").Elements("dl") where (String) el.Parent.Attribute("class") == "api parameters" && (String) el.Attribute("class") == "termdef" select el).FirstOrDefault(); if (termList != null) { IEnumerable<XElement> dtList = from el in termList.Elements("dt") select el; IEnumerable<XElement> ddList = from el in termList.Elements("dd") select el; if (dtList.Count() == ddList.Count()) { // Iterate over definitions for (int i = 0; i < dtList.Count(); i++) { String term = dtList.ElementAt(i).TrimAll(); //String summary = ddList.ElementAt(i).TrimAll(); IEnumerable<String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll()); // Find the parameter MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term) || (VARARG_PARAMETER_REGEX.Match(term).Success && term.StartsWith(p.Name))); if (parameterEntity != null) { //parameterEntity.Summary.Add(summary); foreach (string sum in summaries) { parameterEntity.Summary.Add(sum); } } } } } } // Fix the name only after looking for the documentation for (int i = 0; i < methodEntity.Parameters.Count; i++) { methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name); } // Get the summary for return type if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase)) { IEnumerable<String> documentations = (from el in methodElement.Elements("div").Elements("p") where (String) el.Parent.Attribute("class") == "return_value" select el.Value.TrimAll()); methodEntity.ReturnsDocumentation = String.Join(" ", documentations.ToArray()); } // Get the availability String minAvailability = (from el in methodElement.Elements("div").Elements("ul").Elements("li") where (String) el.Parent.Parent.Attribute("class") == "api availability" select el.Value).FirstOrDefault(); methodEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability.TrimAll()); return methodEntity; }
public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement) { MethodEntity methodEntity = new MethodEntity (); bool isStatic = (methodElement.Attribute ("static").Value == "yes"); String selector = methodElement.Element ("name").TrimAll (); String returnType = methodElement.Element ("type").TrimAll (); // Elements for brief description IEnumerable<XElement> abstractElements = methodElement.Element ("briefdescription").Elements ("para"); // Extract for detailed description IEnumerable<XElement> detailsElements = (from el in methodElement.Element ("detaileddescription").Elements ("para") where !el.Elements ("simplesect").Any () && el.Elements ("parameterlist").Any () && el.Elements ("xrefsect").Any () select el); // Element for parameters IEnumerable<XElement> parameterElements = methodElement.Elements ("param"); // Element for detailed description XElement detailedDescriptionElement = methodElement.Element ("detaileddescription"); // Sets some data methodEntity.Selector = selector; methodEntity.Name = GetMethodName (methodEntity); methodEntity.Static = isStatic; // Add brief description foreach (XElement paragraph in abstractElements) { methodEntity.Summary.Add (paragraph.TrimAll ()); } foreach (XElement paragraph in detailsElements) { methodEntity.Summary.Add (paragraph.TrimAll ()); } // Recreate the signature StringBuilder signature = new StringBuilder (); signature.Append (isStatic ? "+ " : "- "); signature.AppendFormat ("({0})", returnType); if (selector.IndexOf (":") != -1) { String[] parts = selector.Split (':'); for (int i = 0; i < parameterElements.Count(); i++) { XElement parameterElement = parameterElements.ElementAt (i); String parameterType = parameterElement.Element ("type").TrimAll (); String parameterName; if (parameterType.Equals ("...")) { parameterName = String.Empty; } else { parameterName = parameterElement.Element ("declname").TrimAll (); if (parameterElement.Element ("defname") != null) { parameterName = parameterElement.Element ("defname").TrimAll (); } } signature.Append (parts [i]); signature.AppendFormat (":({0}){1} ", parameterType, parameterName); } } else { signature.Append (selector); } methodEntity.Signature = signature.ToString ().Trim () + ";"; // Set the return type methodEntity.ReturnType = this.TypeManager.ConvertType (returnType, this.Logger); // Extract documentation for return type if (!String.Equals (returnType, "void", StringComparison.OrdinalIgnoreCase)) { XElement returnTypeSectionElement = (from el in detailedDescriptionElement.Descendants ("simplesect") where el.Attribute ("kind") != null && el.Attribute ("kind").Value == "return" select el).FirstOrDefault (); if (returnTypeSectionElement != null) { IEnumerable<String> documentations = (from el in returnTypeSectionElement.Elements ("para") select el.TrimAll ()); methodEntity.ReturnsDocumentation = String.Join (" ", documentations.ToArray ()); } } // Create the parameters for (int i = 0; i < parameterElements.Count(); i++) { XElement parameterElement = parameterElements.ElementAt (i); String parameterType = parameterElement.Element ("type").TrimAll (); String parameterName; if (parameterType.Equals ("...")) { parameterType = "params Object[]"; parameterName = "values"; } else { parameterName = parameterElement.Element ("declname").TrimAll (); if (parameterElement.Element ("defname") != null) { parameterName = parameterElement.Element ("defname").TrimAll (); } } MethodParameterEntity parameterEntity = new MethodParameterEntity (); bool isOut, isByRef, isBlock; parameterEntity.Type = this.TypeManager.ConvertType (parameterType, out isOut, out isByRef, out isBlock, this.Logger); parameterEntity.IsOut = isOut; parameterEntity.IsByRef = isByRef; parameterEntity.IsBlock = isBlock; parameterEntity.Name = parameterName; methodEntity.Parameters.Add (parameterEntity); } // Extract documentation for parameters XElement parameterSectionElement = (from el in detailedDescriptionElement.Descendants ("parameterlist") where el.Attribute ("kind") != null && el.Attribute ("kind").Value == "param" select el).FirstOrDefault (); if (parameterSectionElement != null) { IEnumerable<XElement> parameterItemElements = parameterSectionElement.Elements ("parameteritem"); for (int i = 0; i < parameterElements.Count(); i++) { XElement parameterElement = parameterElements.ElementAt (i); String parameterType = parameterElement.Element ("type").TrimAll (); String parameterName; if (parameterType.Equals ("...")) { continue; } else { parameterName = parameterElement.Element ("declname").TrimAll (); if (parameterElement.Element ("defname") != null) { parameterName = parameterElement.Element ("defname").TrimAll (); } } MethodParameterEntity parameterEntity = methodEntity.Parameters.Find (p => String.Equals (p.Name, parameterName)); IEnumerable<XElement> documentations = (from el in parameterItemElements let filter = el.Element ("parameternamelist").Value.TrimAll () where String.Equals (filter, parameterName) select el); if (documentations.Count () > 0) { XElement documentation = documentations.Elements ("parameterdescription").First (); foreach (XElement element in documentation.Elements("para")) { parameterEntity.Summary.Add (element.TrimAll ()); } } } } // Fix the name only after looking for the documentation for (int i = 0; i < methodEntity.Parameters.Count; i++) { methodEntity.Parameters [i].Name = this.TypeManager.ConvertName (methodEntity.Parameters [i].Name); } /* * // Get the availability if (availabilityElement != null) { methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll()); } */ return methodEntity; }
protected static String GetMessageParameterList(MethodEntity methodEntity, MethodEntity innerMethodEntity, bool withColonFirst) { StringBuilder builder = new StringBuilder (); int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (!innerMethodParameterEntity.Generate) { continue; } if (i > 0 || withColonFirst) { builder.Append (", "); } if (innerMethodParameterEntity.IsOut) { builder.AppendFormat ("__local{0}", index++); } else if (innerMethodParameterEntity.IsByRef) { builder.AppendFormat ("__local{0}", index++); } else if (innerMethodParameterEntity.IsBlock) { builder.AppendFormat ("__local{0}", index++); } else { if (String.Equals (methodParameterEntity.Type, innerMethodParameterEntity.Type)) { builder.AppendFormat ("{0}", innerMethodParameterEntity.Name); } else { builder.AppendFormat ("({0}) {1}", innerMethodParameterEntity.Type, innerMethodParameterEntity.Name); } } } return builder.ToString (); }
protected static void CollectInformations(MethodEntity methodEntity, ref bool needStorage, ref bool varargs) { int outParameters = 0; int refParameters = 0; int blockParameters = 0; varargs = false; foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { if (methodParameterEntity.IsOut) { outParameters++; } if (methodParameterEntity.IsByRef) { refParameters++; } if (methodParameterEntity.IsBlock) { blockParameters++; } if (!varargs && methodParameterEntity.Type.StartsWith ("params")) { varargs = true; } } needStorage = (outParameters + refParameters + blockParameters) > 0; }
protected void GenerateLocalsDeallocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; //MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { this.Writer.WriteLineFormat (indent, "Marshal.FreeHGlobal(__local{0});", index++); } else if (methodParameterEntity.IsBlock) { this.Writer.WriteLineFormat (indent, "__local{0}.Dispose();", index++); } } }
protected void GenerateLocalsMarshalling(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut) { if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains (methodParameterEntity.Type)) { // Boolean // TODO: Add zeroing index++; } else if ("float,double".Contains (methodParameterEntity.Type)) { // TODO: Add zeroing index++; } else if (IsMixedType (methodParameterEntity.Type)) { // TODO: Add zeroing index++; } else { this.Writer.WriteLineFormat (indent, "Marshal.WriteIntPtr(__local{0}, IntPtr.Zero);", index++); } } else if (methodParameterEntity.IsByRef) { if (IsMixedType (methodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "Marshal.StructureToPtr(({0}) {1}, __local{2}, false);", innerMethodParameterEntity.Type, methodParameterEntity.Name, index++); } else { this.Writer.WriteLineFormat (indent, "Marshal.StructureToPtr({0}, __local{1}, false);", methodParameterEntity.Name, index++); } } else if (methodParameterEntity.IsBlock) { index++; } } }
private static String GetTarget(ClassEntity classEntity, MethodEntity methodEntity, bool extension) { if (methodEntity.Static) { if (extension) { return String.Format ("{0}.{0}Class", classEntity.Name); } return String.Format ("{0}Class", classEntity.Name); } if (extension) { return "__target"; } return "this"; }
private void GenerateConstructorBody(int indent, string target, MethodEntity methodEntity, MethodEntity innerMethodEntity, bool needStorage, bool varargs) { //bool hasReturn = !String.Equals (methodEntity.ReturnType, "void"); //bool mixed = (innerMethodEntity != null); this.GenerateLocalsAllocation (indent, methodEntity, innerMethodEntity); this.GenerateLocalsMarshalling (indent, methodEntity, innerMethodEntity); String invocation = GetMethodInvocation (target, methodEntity, innerMethodEntity, true, false); this.Writer.WriteLineFormat (indent, "this.NativePointer = {0}", invocation); this.GenerateLocalsUnmarshalling (indent, methodEntity, innerMethodEntity); this.GenerateLocalsDeallocation (indent, methodEntity, innerMethodEntity); }
protected void GenerateLocalsAllocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity) { int index = 1; for (int i = 0; i < methodEntity.Parameters.Count; i++) { MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i]; MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity; if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains (methodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type); } else if ("IntPtr".Contains (methodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "IntPtr __local{0} = Marshal.AllocHGlobal(IntPtr.Size);", index++); } else if ("float,double".Contains (methodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type); } else if (IsMixedType (methodParameterEntity.Type)) { this.Writer.WriteLineFormat (indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, innerMethodParameterEntity.Type); } else { this.Writer.WriteLineFormat (indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (IntPtr)));", index++); } } else if (methodParameterEntity.IsBlock) { this.Writer.WriteLineFormat (indent, "Block __local{0} = ObjectiveCRuntime.CreateBlock({1});", index++, methodParameterEntity.Name); } } }
protected void AppendDocumentation(MethodEntity methodEntity, bool extensionParameter = false, bool opaqueParameter = false) { // Append method comments this.Writer.WriteLineFormat (2, "/// <summary>"); foreach (String line in methodEntity.Summary) { this.Writer.WriteLineFormat (2, "/// <para>{0}</para>", line.EscapeAll ()); } this.Writer.WriteLineFormat (2, "/// <para>Original signature is '{0}'</para>", methodEntity.Signature.EscapeAll ()); this.AppendAvailability (2, methodEntity); this.Writer.WriteLineFormat (2, "/// </summary>"); // Add extra parameter if (extensionParameter) { this.Writer.WriteLineFormat (2, "/// <param name=\"__target\">The target instance.</param>"); } // Append parameters' comments foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { this.Writer.WriteLineFormat (2, "/// <param name=\"{0}\">{1}</param>", methodParameterEntity.Name.Trim ('@'), methodParameterEntity.Summary.Count > 0 ? methodParameterEntity.Summary [0].EscapeAll () : "MISSING"); } // Append returns' comments if (!String.Equals (methodEntity.ReturnType, "void")) { this.Writer.WriteLineFormat (2, "/// <returns>{0}</returns>", methodEntity.ReturnsDocumentation.EscapeAll ()); } }
private static string GetExtraParameter(ClassEntity classEntity, MethodEntity methodEntity, bool extension) { if (extension && !methodEntity.Static) { return String.Format ("this {0} __target", classEntity.Name); } return String.Empty; }
/// <summary> /// Generates the specified entity. /// </summary> /// <param name = "classEntity">The class entity.</param> /// <param name = "methodEntity">The method entity.</param> /// <param name = "implementation">if set to <c>true</c> generate the implementation.</param> /// <param name = "extension">if set to <c>true</c> this method is an extension method.</param> public void Generate(ClassEntity classEntity, MethodEntity methodEntity, bool implementation = true, bool extension = false, bool markedAsNew = false) { // Don't generate if required if (!methodEntity.Generate) { return; } // Append static condition if needed this.AppendStartCondition (methodEntity); // Append documentation this.AppendDocumentation (methodEntity, extension && !methodEntity.Static); // Append method selector if (!implementation) { this.Writer.WriteLineFormat (2, "[ObjectiveCMessage(\"{0}\")]", methodEntity.Selector); } // Append Obsolete attribute this.AppendObsoleteAttribute (methodEntity); // Create Method signature StringBuilder signature = new StringBuilder (); // Append keywords String keywords = GetKeywords (methodEntity, implementation, extension, markedAsNew); signature.Append (keywords); // Append return type and name signature.AppendFormat ("{0} {1}", methodEntity.ReturnType, methodEntity.Name); signature.Append ("("); // Append parameters List<String> parameters = new List<String> (); String extraParameter = GetExtraParameter (classEntity, methodEntity, extension); if (!String.IsNullOrEmpty (extraParameter)) { parameters.Add (extraParameter); } foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { parameters.Add (GetTypeSignature (methodParameterEntity)); } signature.Append (String.Join (", ", parameters.ToArray ())); signature.Append (")"); signature.Append (implementation ? String.Empty : ";"); this.Writer.WriteLineFormat (2, signature.ToString ()); // Write implementation if (implementation) { // Collect information bool needStorage = false; bool varargs = false; CollectInformations (methodEntity, ref needStorage, ref varargs); // Collect information on 32/64 bits invocations to check if they differ MethodEntity methodEntity32 = DeriveMethodEntity (methodEntity, false); MethodEntity methodEntity64 = DeriveMethodEntity (methodEntity, true); bool useMixedInvocation = !AreMethodTypesEqual (methodEntity32, methodEntity64); this.Writer.WriteLineFormat (2, "{{"); String target = GetTarget (classEntity, methodEntity, extension); if (useMixedInvocation && needStorage) { #if MIXED_MODE this.Writer.WriteLineFormat(3, "if (ObjectiveCRuntime.Is64Bits)"); this.Writer.WriteLineFormat(3, "{{"); this.GenerateMethodBody(4, target, methodEntity, methodEntity64, needStorage, varargs); this.Writer.WriteLineFormat(3, "}}"); this.Writer.WriteLineFormat(3, "else"); this.Writer.WriteLineFormat(3, "{{"); #endif this.GenerateMethodBody (4, target, methodEntity, methodEntity32, needStorage, varargs); #if MIXED_MODE this.Writer.WriteLineFormat(3, "}}"); #endif } else { this.GenerateMethodBody (3, target, methodEntity, null, needStorage, varargs); } this.Writer.WriteLineFormat (2, "}}"); } // Append static condition if needed this.AppendEndCondition(methodEntity); // Update statistics this.Statistics.Methods++; }
public MethodEntity Parse(TypedEntity typedEntity, String selector, IEnumerable<XElement> elements) { MethodEntity methodEntity = new MethodEntity(); XElement declarationElement = (from el in elements where el.Name == "div" && el.Attribute("class") != null && el.Attribute("class").Value == "declaration_indent" select el).FirstOrDefault(); XElement parameterElement = (from el in elements where el.Name == "div" && el.Attribute("class") != null && el.Attribute("class").Value == "param_indent" select el).FirstOrDefault(); XElement returnValueElement = (from el in elements where el.Name == "h5" && el.Value.Trim() == "Return Value" select el).FirstOrDefault(); //XElement discussionElement = (from el in elements // where el.Name == "h5" && el.Value.Trim() == "Discussion" // select el).FirstOrDefault(); XElement availabilityElement = (from el in elements let term = el.Descendants("dt").FirstOrDefault() let definition = el.Descendants("dd").FirstOrDefault() where el.Name == "dl" && term != null && term.Value.Trim() == "Availability" select definition).FirstOrDefault(); methodEntity.Selector = selector; methodEntity.Name = GetMethodName(methodEntity); methodEntity.Signature = declarationElement.TrimAll(); methodEntity.Signature = methodEntity.Signature.TrimEnd(';'); methodEntity.Static = methodEntity.Signature.StartsWith("+"); // Extract abstract IEnumerable<XElement> abstractElements = elements.SkipWhile(el => el.Name != "p").TakeWhile(el => el.Name == "p"); foreach (XElement element in abstractElements) { String line = element.TrimAll(); if (!String.IsNullOrEmpty(line)) { methodEntity.Summary.Add(line); } } //// Extract discussion //if (discussionElement != null) //{ // IEnumerable<XElement> discussionElements = discussionElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p"); // foreach (XElement element in discussionElements) // { // String line = element.TrimAll(); // if (!String.IsNullOrEmpty(line)) // { // methodEntity.Summary.Add(line); // } // } //} // Extract return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature); if (signatureEnumerator.MoveNext()) { methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger); } else { methodEntity.ReturnType = "Id"; } // Extract parameter type and name MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false); MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true); while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext()) { MethodParameterEntity parameterEntity = new MethodParameterEntity(); bool isOut, isByRef, isBlock; parameterEntity.Type = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger); parameterEntity.IsOut = isOut; parameterEntity.IsByRef = isByRef; parameterEntity.IsBlock = isBlock; parameterEntity.Name = parameterNamesEnumerator.Current.Trim(); methodEntity.Parameters.Add(parameterEntity); } if (methodEntity.Parameters.Count > 0 && parameterElement != null) { XElement termList = parameterElement.Descendants("dl").FirstOrDefault(); if (termList != null) { IEnumerable<XElement> dtList = from el in termList.Elements("dt") select el; IEnumerable<XElement> ddList = from el in termList.Elements("dd") select el; if (dtList.Count() == ddList.Count()) { // Iterate over definitions for (int i = 0; i < dtList.Count(); i++) { String term = dtList.ElementAt(i).TrimAll(); //String summary = ddList.ElementAt(i).TrimAll(); IEnumerable<String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll()); // Find the parameter MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term)); if (parameterEntity != null) { //parameterEntity.Summary.Add(summary); foreach (string sum in summaries) { parameterEntity.Summary.Add(sum); } } } } } } // Fix the name only after looking for the documentation for (int i = 0; i < methodEntity.Parameters.Count; i++) { methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name); } // Get the summary for return type if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase) && returnValueElement != null) { IEnumerable<XElement> returnTypeElements = returnValueElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p"); methodEntity.ReturnsDocumentation = String.Empty; foreach (XElement element in returnTypeElements) { String line = element.TrimAll(); if (!String.IsNullOrEmpty(line)) { methodEntity.ReturnsDocumentation += line; } } } // Get the availability if (availabilityElement != null) { methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll()); } return methodEntity; }
public void GenerateConstructor(ClassEntity classEntity, MethodEntity methodEntity) { // Don't generate if required if (!methodEntity.Generate) { return; } // Clone the method and change the return type methodEntity = new MethodEntity (methodEntity); methodEntity.ReturnType = "IntPtr"; // Collect information bool needStorage = false; bool varargs = false; CollectInformations (methodEntity, ref needStorage, ref varargs); // Don't generate if varargs if (varargs) { return; } // Collect information about the return type and the parameters bool hasReturn = !String.Equals (methodEntity.ReturnType, "void"); bool hasReturnParameters = hasReturn && needStorage; // Collect information on 32/64 bits invocations to check if they differ MethodEntity methodEntity32 = DeriveMethodEntity (methodEntity, false); MethodEntity methodEntity64 = DeriveMethodEntity (methodEntity, true); bool useMixedInvocation = false; // !AreMethodTypesEqual(methodEntity32, methodEntity64); // Append static condition if needed this.AppendStartCondition (methodEntity); // Append documentation this.AppendDocumentation (methodEntity); // Append Method signature StringBuilder signature = new StringBuilder (); signature.AppendFormat ("public {0}(", classEntity.Name); // Append parameters List<String> parameters = new List<String> (); foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { parameters.Add (GetTypeSignature (methodParameterEntity)); } signature.Append (String.Join (", ", parameters.ToArray ())); signature.Append (")"); this.Writer.WriteLineFormat (2, signature.ToString ()); // Write base call StringBuilder baseCall = new StringBuilder (); if (useMixedInvocation || hasReturnParameters) { baseCall.AppendFormat (" : this(ObjectiveCRuntime.SendMessage<IntPtr>({0}Class, \"alloc\"))", classEntity.Name); } else { baseCall.AppendFormat (" : base(\"{0}\"", methodEntity.Selector); foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters.Where(p => p.Generate)) { baseCall.AppendFormat (", {0}", methodParameterEntity.Name); } baseCall.Append (")"); } this.Writer.WriteLineFormat (3, baseCall.ToString ()); // Write implementation this.Writer.WriteLineFormat (2, "{{"); String target = "this"; if (useMixedInvocation) { #if MIXED_MODE this.Writer.WriteLineFormat(3, "if (ObjectiveCRuntime.Is64Bits)"); this.Writer.WriteLineFormat(3, "{{"); this.GenerateConstructorBody(4, target, methodEntity, methodEntity64, needStorage, varargs); this.Writer.WriteLineFormat(3, "}}"); this.Writer.WriteLineFormat(3, "else"); this.Writer.WriteLineFormat(3, "{{"); #endif this.GenerateConstructorBody (4, target, methodEntity, methodEntity32, needStorage, varargs); #if MIXED_MODE this.Writer.WriteLineFormat(3, "}}"); #endif } else if (hasReturnParameters) { this.GenerateConstructorBody (4, target, methodEntity, null, needStorage, varargs); } this.Writer.WriteLineFormat (2, "}}"); // Append static condition if needed this.AppendEndCondition (methodEntity); // Update statistics this.Statistics.Methods++; }