private void ParseTypeDocumentation(MoaiType type, Annotation[] annotations, MoaiType[] baseTypes, TypePosition typePosition) { // Check that there is a single @name annotation int nameAnnotationCount = annotations.OfType<NameAnnotation>().Count(); if (nameAnnotationCount == 0) { log.WarnFormat("Missing @name annotation. [{0}].", typePosition); } else if (nameAnnotationCount > 1) { log.WarnFormat("Multiple @name annotations. [{0}]", typePosition); } // Check that there is a single @text annotation int textAnnotationCount = annotations.OfType<TextAnnotation>().Count(); if (textAnnotationCount == 0) { log.WarnFormat("Missing @text annotation. [{0}]", typePosition); } else if (textAnnotationCount > 1) { log.WarnFormat("Multiple @text annotations. [{0}]", typePosition); } // Store base types type.BaseTypes.AddRange(baseTypes); // Parse annotations foreach (var annotation in annotations) { if (annotation is NameAnnotation) { // Nothing to do. Name is already set. Just make sure the annotation is correct. var nameAnnotation = (NameAnnotation) annotation; if (nameAnnotation.Value != type.Name) { log.WarnFormat("@name annotation has inconsistent value '{0}'. [{1}]", nameAnnotation.Value, typePosition); } } else if (annotation is TextAnnotation) { // Set type description type.Description = ((TextAnnotation) annotation).Value; } else if (annotation is FieldAnnotation) { // Add field (constant, flag, or attribute) var fieldAnnotation = (FieldAnnotation) annotation; MoaiField field = (annotation is ConstantAnnotation) ? new MoaiConstant() : (annotation is FlagAnnotation) ? (MoaiField) new MoaiFlag() : new MoaiAttribute(); field.OwningType = type; field.Name = fieldAnnotation.Name; field.Description = fieldAnnotation.Description; type.Members.Add(field); } else { log.WarnFormat("Unexpected {0} annotation. [{1}]", annotation.Command, typePosition); } } }
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); } } }