private static string GetValueType(MoaiMethod method) { MoaiOutParameter[] outParameters = method.Overloads .Where(overload => overload.OutParameters.Any()) .Select(overload => overload.OutParameters.First()) .ToArray(); // There must be overloads defining a (first) return type if (!outParameters.Any()) return null; // All overloads must have the same return type if (outParameters.Any(outParameter => outParameter.Type != outParameters.First().Type)) return null; // nil doesn't count. string valueType = outParameters.First().Type.Name; if (valueType == "nil") return null; return valueType; }
private void ParseMethodDocumentation(MoaiType type, Annotation[] annotations, MethodPosition methodPosition) { // Check that there is a single @name annotation and that it isn't a duplicate. Otherwise exit. int nameAnnotationCount = annotations.OfType<NameAnnotation>().Count(); if (nameAnnotationCount == 0) { log.WarnFormat("Missing @name annotation. [{0}]", methodPosition); return; } if (nameAnnotationCount > 1) { log.WarnFormat("Multiple @name annotations. [{0}]", methodPosition); } var nameAnnotation = annotations.OfType<NameAnnotation>().Single(); if (type.Members.Any(member => member.Name == nameAnnotation.Value)) { log.WarnFormat("Multiple members with name '{0}'. [{1}]", nameAnnotation.Value, methodPosition); return; } // Check that @name annotation sticks to convention if (!methodPosition.NativeMethodName.StartsWith("_")) { log.WarnFormat( "Unexpected C++ method name '{0}'. By convention, the name of a Lua method implementation shold start with an underscore. [{1}]", methodPosition.NativeMethodName, methodPosition); } string expectedName = methodPosition.NativeMethodName.Substring(1); if (nameAnnotation.Value != expectedName) { log.WarnFormat( "@name annotation has unexpected value '{0}'. By convention expected '{1}'. [{2}]", nameAnnotation.Value, expectedName, methodPosition); } // Check that there is a single @text annotation int textAnnotationCount = annotations.OfType<TextAnnotation>().Count(); if (textAnnotationCount == 0) { log.WarnFormat("Missing @text annotation. [{0}]", methodPosition); } else if (textAnnotationCount > 1) { log.WarnFormat("Multiple @text annotations. [{0}]", methodPosition); } // Check that there is at least one @out annotation if (!annotations.OfType<OutParameterAnnotation>().Any()) { log.WarnFormat( "Missing @out annotation. Even for void methods, an @out annotation with type nil is expected. [{0}]", methodPosition); } // Parse annotations // Guess if the method is static bool isStatic = annotations .OfType<InParameterAnnotation>() .All(param => param.Name != "self"); var method = new MoaiMethod { MethodPosition = methodPosition, Name = nameAnnotation.Value, OwningType = type, IsStatic = isStatic }; type.Members.Add(method); MoaiMethodOverload currentOverload = null; foreach (var annotation in annotations) { if (annotation is NameAnnotation) { // Nothing to do - name has already been set. } else if (annotation is TextAnnotation) { // Set method description method.Description = ((TextAnnotation) annotation).Value; } else if (annotation is ParameterAnnotation) { if (currentOverload == null) { currentOverload = new MoaiMethodOverload { OwningMethod = method }; method.Overloads.Add(currentOverload); } var parameterAnnotation = (ParameterAnnotation) annotation; string paramName = parameterAnnotation.Name; if (annotation is InParameterAnnotation | annotation is OptionalInParameterAnnotation) { // Add input parameter if (currentOverload.InParameters.Any(param => param.Name == paramName)) { log.WarnFormat("Multiple '{0}' params for single overload. [{1}]", paramName, methodPosition); } var inParameter = new MoaiInParameter { Name = paramName, Description = parameterAnnotation.Description, Type = GetOrCreateType(parameterAnnotation.Type, methodPosition), IsOptional = annotation is OptionalInParameterAnnotation }; currentOverload.InParameters.Add(inParameter); } else { // Add output parameter var outParameter = new MoaiOutParameter { Name = paramName, Type = GetOrCreateType(parameterAnnotation.Type, methodPosition), Description = parameterAnnotation.Description }; currentOverload.OutParameters.Add(outParameter); } } else if (annotation is OverloadAnnotation) { // Let the next parameter annotation start a new override currentOverload = null; } else { log.WarnFormat("Unexpected {0} annotation. [{1}]", annotation.Command, methodPosition); } } }
private LuaTable CreateMemberTable(MoaiMethod method) { StringBuilder description = new StringBuilder(); description.AppendLine(method.Description); if (method.Overloads.Count == 1) { description.AppendLine(); description.Append(GetOverloadInfo(method.Overloads.Single())); } else if (method.Overloads.Any()) { foreach (var overload in method.Overloads) { description.AppendLine(); description.AppendLine("Overload:"); description.Append(GetOverloadInfo(overload)); } } var memberTable = new LuaTable { { "type", method.IsStatic ? "function" : "method" }, { "description", ConvertString(description.ToString().Trim()) }, { "args", method.InParameterSignature != null ? method.InParameterSignature.ToString(SignatureGrouping.Any) : null }, { "returns", method.OutParameterSignature != null ? method.OutParameterSignature.ToString(SignatureGrouping.Any) : null }, { "valuetype", GetValueType(method)} }; return memberTable; }