private string GenerateMethod(MethodInfo methodInfo) { var sb = new StringBuilder(); var methodParameters = string.Join(",", methodInfo.Parameters.Select(p => p.Type + " " + p.Name)); var methodParameterNames = string.Join(",", methodInfo.Parameters.Select(p => p.Name)); var typesNotReturned = new[] {"void", "System.Threading.Tasks.Task"}; var returnValue = typesNotReturned.All(t => t != methodInfo.ReturnTypeName); // Method declaration sb.AppendLine("public " + (methodInfo.IsAsync? "async ":"") + methodInfo.ReturnTypeName + " " + methodInfo.Name + "(" + methodParameters + ")"); sb.AppendLine("{"); if(returnValue) { var retType = methodInfo.IsAsync ? methodInfo.GetTaskRetunTypeName() : methodInfo.ReturnTypeName; sb.AppendLine("var ret = default("+ retType + ");"); } // Try-catch if (DecoratorInfo.OnExceptionExist) { sb.AppendLine("try"); sb.AppendLine("{"); } // Init sb.AppendLine((methodInfo.IsAsync ? "await InitAsync" : "Init") + "(\""+ methodInfo.Name + "\", new object[] { " + methodParameterNames + " });"); // OnEntry method if (DecoratorInfo.OnEntryExist) { sb.AppendLine("OnEntry();"); } if (returnValue) { sb.Append("ret = "); } sb.AppendLine((methodInfo.IsAsync ? "await " : " ") + _decoratedComponent + "." + methodInfo.Name + "(" + methodParameterNames + ");"); // OnExit method if (DecoratorInfo.OnExitExist) { sb.AppendLine("OnExit();"); } // Try-catch if (DecoratorInfo.OnExceptionExist) { sb.AppendLine("}"); sb.AppendLine("catch(System.Exception e)"); sb.AppendLine("{"); sb.AppendLine("OnException(e);"); sb.AppendLine("}"); // Finally if (DecoratorInfo.OnFinallyExist) { sb.AppendLine("finally"); sb.AppendLine("{"); sb.AppendLine("OnFinally();"); sb.AppendLine("}"); } } if (returnValue) { sb.AppendLine("return ret;"); } sb.AppendLine("}"); return sb.ToString(); }
public IReadOnlyCollection<ICodeClassDecoratorGenerator> GetDecorators() { var ret = new List<ICodeClassDecoratorGenerator>(); foreach (var cls in _configuration.DecoratedClass) { // Init var codeClassGenerator = new CodeClassDecoratorGenerator(); var decoratedClassInfo = new DecoratorInfo() { DecoratedClassTypeFullName = cls.SourceClassName, DecoratorClassTypeShortName = cls.TargetClassName }; codeClassGenerator.DecoratorInfo = decoratedClassInfo; // Get decorated class var decoratedClass = _syntaxWalker.GetClassByFullName(cls.SourceClassName); if(decoratedClass==null) { codeClassGenerator.AnalysisError = string.Format("Decorated class {0} not found!", cls.SourceClassName); ret.Add(codeClassGenerator); continue; } decoratedClassInfo.DecoratedClassTypeShortName = decoratedClass.Name; decoratedClassInfo.Namespace = decoratedClass.ContainingNamespace.ToString(); decoratedClassInfo.DecoratorClassTypeFullName = decoratedClassInfo.Namespace + "." + cls.TargetClassName; //decoratedClassInfo.RequiredNamespaces = _syntaxWalker.GetUsings(decoratedClass); // Get decorator class var decoratorClass = _syntaxWalker.GetClassByFullName(decoratedClassInfo.DecoratorClassTypeFullName); if (decoratorClass == null) { codeClassGenerator.AnalysisError = string.Format("Partial decorator class {0} not found!", decoratedClassInfo.DecoratorClassTypeFullName); ret.Add(codeClassGenerator); continue; } // Get methods for decorating var methods = decoratedClass.GetMembers() .Where(m => m.Kind == SymbolKind.Method && m.DeclaredAccessibility == Accessibility.Public && m.MetadataName != ".ctor") .Select(m=> m as IMethodSymbol) .Where(m => m.AssociatedSymbol == null || m.AssociatedSymbol.Kind != SymbolKind.Property) .ToList(); // Get methods from decorator var decoratorImplementedMethods = decoratorClass.GetMembers() .Where(m => m.Kind == SymbolKind.Method) .Select(m => m as IMethodSymbol) .ToList(); foreach (var m in methods) { // Skip already decorated methods if(decoratorImplementedMethods.Any(dm => dm.Name == m.Name)) continue; var method = new MethodInfo() { Name = m.Name, ReturnTypeName = m.ReturnType.ToString(), IsAsync = m.IsAsync, ReturnTypeIsNullble = !m.ReturnType.IsValueType, Parameters = m.Parameters.Select(p => new ParameterInfo() { Name = p.Name, Type = p.Type.ToString() }).ToList(), }; decoratedClassInfo.MethodInfos.Add(method); } // Set flags for include decorator methods decoratedClassInfo.OnEntryExist = decoratorImplementedMethods.FirstOrDefault(m => m.Name == _entryMethodName) != null; decoratedClassInfo.OnExitExist = decoratorImplementedMethods.FirstOrDefault(m => m.Name == _exitMethodName) != null; decoratedClassInfo.OnExceptionExist = decoratorImplementedMethods.FirstOrDefault(m => m.Name == _exceptionMethodName) != null; decoratedClassInfo.OnFinallyExist = decoratorImplementedMethods.FirstOrDefault(m => m.Name == _finallyMethodName) != null; ret.Add(codeClassGenerator); } return ret; }