예제 #1
0
        public Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            int    type    = args.GetInt32();
            string modelId = args.GetString();

            if (type == 1)
            {
                var modelNode = hub.DesignTree.FindModelNode(ModelType.Service, ulong.Parse(modelId));
                if (modelNode == null)
                {
                    throw new Exception($"Cannot find ServiceModel: {modelId}");
                }

                var quickFixes = new List <QuickFix>();

                var document      = hub.TypeSystem.Workspace.CurrentSolution.GetDocument(modelNode.RoslynDocumentId);
                var semanticModel = document.GetSemanticModelAsync().Result;
                IEnumerable <Diagnostic> diagnostics = semanticModel.GetDiagnostics();

                return(Task.FromResult <object>(diagnostics.Select(MakeQuickFix).ToArray()));
            }
            else
            {
                throw ExceptionHelper.NotImplemented();
            }
        }
예제 #2
0
        public async Task GetEntitySymbolTest()
        {
            RuntimeContext.Init(new Core.Tests.MockRuntimeContext(), 10410);

            var session = new MockDeveloperSession();
            var ctx     = new DesignHub(session);
            var apps    = new List <ApplicationModel>()
            {
                Core.Tests.TestHelper.SysAppModel
            };
            var models = new List <ModelBase>
            {
                Core.Tests.TestHelper.EmploeeModel,
                Core.Tests.TestHelper.VehicleStateModel,
                Core.Tests.TestHelper.OrgUnitModel,
                Core.Tests.TestHelper.AdminPermissionModel,
                Core.Tests.TestHelper.DeveloperPermissionModel
            };
            await ctx.DesignTree.LoadForTest(apps, models);

            var symbol = await ctx.TypeSystem.GetEntityIndexSymbolAsync("sys", "Emploee", "UI_Account_Password");

            Assert.NotNull(symbol);
            symbol = await ctx.TypeSystem.GetModelSymbolAsync(ModelType.Entity, "sys", "Emploee");

            Assert.NotNull(symbol);
        }
예제 #3
0
 public DesignHub GetDesignHub()
 {
     if (designHub == null)
     {
         lock (this)
         {
             if (designHub == null)
             {
                 //创建DesignHub实例前,判断当前用户是否具备开发者权限
                 //TODO: fix
                 //if (!AppBox.Core.PermissionService.HasPermission(RuntimeContext.Default, "sys.Developer"))
                 //throw new Exception("当前会话不具备开发人员权限");
                 //尝试从WebSocketManager内获取缓存的WebSession,主要用于Ajax上传通道以指向相同的DesignHub,而不是重新创建一个DesignHub实例
                 if (Owner != null)
                 {
                     designHub = new DesignHub(this);
                 }
                 else
                 {
                     var websocketSession = WebSocketManager.GetSessionByID(SessionID);
                     if (websocketSession == null)
                     {
                         throw new Exception("非WebSocket通道无法创建DesignHub");
                     }
                     designHub = websocketSession.GetDesignHub();
                 }
             }
         }
     }
     return(designHub);
 }
예제 #4
0
        public async Task GenServiceDeclareTest()
        {
            RuntimeContext.Init(new Core.Tests.MockRuntimeContext(), 10410);

            var session = new MockDeveloperSession();
            var ctx     = new DesignHub(session);
            var apps    = new List <ApplicationModel>()
            {
                Core.Tests.TestHelper.SysAppModel
            };
            var models = new List <ModelBase>
            {
                Core.Tests.TestHelper.EmploeeModel,
                Core.Tests.TestHelper.VehicleStateModel,
                Core.Tests.TestHelper.OrgUnitModel
            };
            await ctx.DesignTree.LoadForTest(apps, models);

            //模拟添加, 参照NewServiceModel Handler
            var rootNode   = ctx.DesignTree.FindModelRootNode(Consts.SYS_APP_ID, ModelType.Service);
            var parentNode = rootNode;
            var modelId    = (ulong)Consts.SYS_APP_ID << 32;

            modelId |= (ulong)ModelType.Service << 24;
            modelId |= (ulong)1 << 3;
            modelId |= (ulong)ModelLayer.DEV << 1;
            var model = new ServiceModel(modelId, "HelloService");
            var node  = new ModelNode(model, ctx);

            parentNode.Nodes.Add(node);
            rootNode.AddModelIndex(node);
            node.CheckoutInfo = new CheckoutInfo(node.NodeType, node.CheckoutInfoTargetID, model.Version,
                                                 ctx.Session.Name, ctx.Session.LeafOrgUnitID);

            var sourceCode = Resources.LoadStringResource("Resources.Code.HelloService.cs");
            await ctx.TypeSystem.CreateModelDocumentAsync(node, sourceCode);

            //生成服务声明代码
            var appName       = node.AppNode.Model.Name;
            var doc           = ctx.TypeSystem.Workspace.CurrentSolution.GetDocument(node.RoslynDocumentId);
            var semanticModel = await doc.GetSemanticModelAsync();

            //TODO: 检测虚拟代码错误
            var codegen = new ServiceDeclareGenerator(ctx, appName, semanticModel, (ServiceModel)node.Model);

            codegen.Visit(semanticModel.SyntaxTree.GetRoot());
            var declare = codegen.GetDeclare();

            Console.WriteLine(declare);
        }
예제 #5
0
        public Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            var fileName = args.GetString();
            var document = hub.TypeSystem.Workspace.GetOpenedDocumentByName(fileName);

            if (document == null)
            {
                throw new Exception(string.Format("Cannot find opened document: {0}", fileName));
            }

            var changes = FormattingWorker.GetFormattedTextChanges(document).Result;

            return(Task.FromResult <object>(changes.ToArray()));
        }
예제 #6
0
        //todo:修改实现,获取Changes集合
        public async Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            int    type        = args.GetInt32();
            string targetID    = args.GetString();
            int    startLine   = args.GetInt32() - 1; //注意:前端传过来的值需要-1
            int    startColumn = args.GetInt32() - 1;
            int    endLine     = args.GetInt32() - 1;
            int    endColumn   = args.GetInt32() - 1;
            string newText     = args.GetString();

            Document document;

            if (type == 1) //服务代码变更
            {
                var modelNode = hub.DesignTree.FindModelNode(ModelType.Service, ulong.Parse(targetID));
                if (modelNode == null)
                {
                    throw new Exception($"Cannot find ServiceModel: {targetID}");
                }

                document = hub.TypeSystem.Workspace.CurrentSolution.GetDocument(modelNode.RoslynDocumentId);
            }
            else if (type == 2) //表达式代码变更
            {
                throw ExceptionHelper.NotImplemented();
                //document = hub.ExpressionDesignService.GetExpressionDocument(targetID);
            }
            else
            {
                throw ExceptionHelper.NotImplemented();
            }

            if (document == null)
            {
                throw new Exception("Can not find opened document: " + targetID);
            }

            var sourceText = await document.GetTextAsync();

            var startOffset = sourceText.Lines.GetPosition(new LinePosition(startLine, startColumn));
            var endOffset   = sourceText.Lines.GetPosition(new LinePosition(endLine, endColumn));

            sourceText = sourceText.WithChanges(new[] {
                new TextChange(new TextSpan(startOffset, endOffset - startOffset), newText)
            });

            hub.TypeSystem.Workspace.OnDocumentChanged(document.Id, sourceText);
            return(null);
        }
예제 #7
0
        private bool disposedValue = false; // To detect redundant calls

        void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    if (designHub != null)
                    {
                        designHub.Dispose();
                        designHub = null;
                    }
                }

                disposedValue = true;
            }
        }
예제 #8
0
        public DesignHub GetDesignHub()
        {
            if (_ctx != null)
            {
                return(_ctx);
            }

            lock (this)
            {
                if (_ctx == null)
                {
                    _ctx = new DesignHub(this);
                }
            }
            return(_ctx);
        }
예제 #9
0
        public async Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            string fileName = args.GetString();
            var    document = hub.TypeSystem.Workspace.GetOpenedDocumentByName(fileName);

            if (document == null)
            {
                throw new Exception($"Cannot find opened document: {fileName}");
            }

            var elements = await GetCodeElementsAsync(document);

            var response = new CodeStructureResponse
            {
                Elements = elements
            };

            return(response);
        }
예제 #10
0
        public async Task GetEnumSymbolTest()
        {
            RuntimeContext.Init(new Core.Tests.MockRuntimeContext(), 10410);

            var session = new MockDeveloperSession();
            var ctx     = new DesignHub(session);
            var apps    = new List <ApplicationModel>()
            {
                Core.Tests.TestHelper.SysAppModel
            };
            var models = new List <ModelBase>
            {
                Core.Tests.TestHelper.OrderStatusModel,
            };
            await ctx.DesignTree.LoadForTest(apps, models);

            var symbol = await ctx.TypeSystem.GetEnumItemSymbolAsync("sys", "OrderStatus", "Paid");

            Assert.NotNull(symbol);
            Assert.Equal("sys.Enums.OrderStatus.Paid", symbol.ToString());
        }
예제 #11
0
        public async Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            string fileName = args.GetString();
            int    line     = args.GetInt32() - 1; //注意:前端传过来的值需要-1
            int    column   = args.GetInt32() - 1;

            var document = hub.TypeSystem.Workspace.GetOpenedDocumentByName(fileName);

            if (document == null)
            {
                throw new Exception($"Cannot find opened document: {fileName}");
            }

            var invocation = await GetInvocation(document, line, column);

            if (invocation == null)
            {
                return(null);
            }

            var response = new SignatureHelpResponse();

            // define active parameter by position
            foreach (var comma in invocation.Separators)
            {
                if (comma.Span.Start > invocation.Position)
                {
                    break;
                }
                response.ActiveParameter += 1;
            }

            // process all signatures, define active signature by types
            var signaturesSet = new HashSet <SignatureHelpItem>();
            var bestScore     = int.MinValue;
            SignatureHelpItem bestScoredItem = null;

            var     types         = invocation.ArgumentTypes;
            ISymbol throughSymbol = null;
            ISymbol throughType   = null;
            var     methodGroup   = invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType <IMethodSymbol>();

            if (invocation.Receiver is MemberAccessExpressionSyntax)
            {
                var throughExpression = ((MemberAccessExpressionSyntax)invocation.Receiver).Expression;
                throughSymbol = invocation.SemanticModel.GetSpeculativeSymbolInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsExpression).Symbol;
                throughType   = invocation.SemanticModel.GetSpeculativeTypeInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsTypeOrNamespace).Type;
                var includeInstance = (throughSymbol != null && !(throughSymbol is ITypeSymbol)) ||
                                      throughExpression is LiteralExpressionSyntax ||
                                      throughExpression is TypeOfExpressionSyntax;
                var includeStatic = (throughSymbol is INamedTypeSymbol) || throughType != null;
                methodGroup = methodGroup.Where(m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance));
            }
            else if (invocation.Receiver is SimpleNameSyntax && invocation.IsInStaticContext)
            {
                methodGroup = methodGroup.Where(m => m.IsStatic || m.MethodKind == MethodKind.LocalFunction);
            }

            foreach (var methodOverload in methodGroup)
            {
                var signature = BuildSignature(methodOverload);
                signaturesSet.Add(signature);

                var score = InvocationScore(methodOverload, types);
                if (score > bestScore)
                {
                    bestScore      = score;
                    bestScoredItem = signature;
                }
            }

            var signaturesList = signaturesSet.ToList();

            response.Signatures      = signaturesList;
            response.ActiveSignature = signaturesList.IndexOf(bestScoredItem);

            return(response);
        }
예제 #12
0
        public async Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            int       type           = args.GetInt32();     //TODO: remove it
            string    fileName       = args.GetString();
            int       line           = args.GetInt32() - 1; //注意:前端传过来的值需要-1
            int       column         = args.GetInt32() - 1;
            string    wordToComplete = args.GetString();
            WantsType wants          = WantsType.WantDocumentationForEveryCompletionResult | WantsType.WantKind | WantsType.WantReturnType; //暂默认

            var completions = new HashSet <AutoCompleteItem>();

            var document = hub.TypeSystem.Workspace.GetOpenedDocumentByName(fileName);

            if (document == null)
            {
                throw new Exception($"Cannot find opened document: {fileName}");
            }

            var sourceText = await document.GetTextAsync();

            var position       = sourceText.Lines.GetPosition(new LinePosition(line, column));
            var service        = CompletionService.GetService(document);
            var completionList = await service.GetCompletionsAsync(document, position);

            if (completionList != null)
            {
                // Only trigger on space if Roslyn has object creation items
                //if (request.TriggerCharacter == " " && !completionList.Items.Any(i => i.IsObjectCreationCompletionItem()))
                //{
                //    return completions;
                //}

                // get recommened symbols to match them up later with SymbolCompletionProvider
                var semanticModel = await document.GetSemanticModelAsync();

                var recommendedSymbols = await Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, position, hub.TypeSystem.Workspace);

                foreach (var item in completionList.Items)
                {
                    var completionText = item.DisplayText;
                    if (completionText.IsValidCompletionFor(wordToComplete))
                    {
                        var symbols = await item.GetCompletionSymbolsAsync(recommendedSymbols, document);

                        if (symbols.Any())
                        {
                            foreach (var symbol in symbols)
                            {
                                if (item.UseDisplayTextAsCompletionText())
                                {
                                    completionText = item.DisplayText;
                                }
                                else if (item.TryGetInsertionText(out var insertionText))
                                {
                                    completionText = insertionText;
                                }
                                else
                                {
                                    completionText = symbol.Name;
                                }

                                if (symbol != null)
                                {
                                    if ((wants & WantsType.WantSnippet) == WantsType.WantSnippet)
                                    {
                                        // foreach (var completion in MakeSnippetedResponses(request, symbol, completionText))
                                        // {
                                        //     completions.Add(completion);
                                        // }
                                    }
                                    else
                                    {
                                        completions.Add(MakeAutoCompleteResponse(wants, symbol, completionText));
                                    }
                                }
                            }

                            // if we had any symbols from the completion, we can continue, otherwise it means
                            // the completion didn't have an associated symbol so we'll add it manually
                            continue;
                        }

                        // for other completions, i.e. keywords, create a simple AutoCompleteResponse
                        // we'll just assume that the completion text is the same
                        // as the display text.
                        var response = new AutoCompleteItem()
                        {
                            CompletionText = item.DisplayText,
                            DisplayText    = item.DisplayText,
                            Snippet        = item.DisplayText,
                            Kind           = (wants & WantsType.WantKind) == WantsType.WantKind ? item.Tags.First() : null
                        };

                        completions.Add(response);
                    }
                }
            }

            //todo: 处理overloads
            return(completions
                   .OrderByDescending(c => c.CompletionText.IsValidCompletionStartsWithExactCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsValidCompletionStartsWithIgnoreCase(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsCamelCaseMatch(wordToComplete))
                   .ThenByDescending(c => c.CompletionText.IsSubsequenceMatch(wordToComplete))
                   .ThenBy(c => c.DisplayText, StringComparer.OrdinalIgnoreCase)
                   .ThenBy(c => c.CompletionText, StringComparer.OrdinalIgnoreCase)
                   .ToArray());
        }
예제 #13
0
        public async Task GenServiceCodeTest()
        {
            var mockRuntimeCtx = new Core.Tests.MockRuntimeContext();

            mockRuntimeCtx.AddModel(Core.Tests.TestHelper.CityModel);
            mockRuntimeCtx.AddModel(Core.Tests.TestHelper.CustomerModel);
            mockRuntimeCtx.AddModel(Core.Tests.TestHelper.OrderModel);
            RuntimeContext.Init(mockRuntimeCtx, 10410);

            var session = new MockDeveloperSession();
            var ctx     = new DesignHub(session);
            var apps    = new List <ApplicationModel>()
            {
                Core.Tests.TestHelper.SysAppModel
            };
            var models = new List <ModelBase>
            {
                Core.Tests.TestHelper.EmploeeModel,
                Core.Tests.TestHelper.VehicleStateModel,
                Core.Tests.TestHelper.OrgUnitModel,
                Core.Tests.TestHelper.CityModel,
                Core.Tests.TestHelper.CustomerModel,
                Core.Tests.TestHelper.OrderModel,
                Core.Tests.TestHelper.AdminPermissionModel,
                Core.Tests.TestHelper.DeveloperPermissionModel
            };
            await ctx.DesignTree.LoadForTest(apps, models);

            //模拟添加存储模型,参照NewDataStore Handler
            var storeNode = ctx.DesignTree.StoreRootNode.AddModel(Core.Tests.TestHelper.SqlStoreModel, ctx);

            ctx.TypeSystem.CreateStoreDocument(storeNode);

            //模拟添加服务模型, 参照NewServiceModel Handler
            var serviceRootNode = ctx.DesignTree.FindModelRootNode(Consts.SYS_APP_ID, ModelType.Service);
            var parentNode      = serviceRootNode;

            //测试被调用的服务
            var modelId = (ulong)Consts.SYS_APP_ID << 32;

            modelId |= (ulong)ModelType.Service << 24;
            modelId |= (ulong)1 << 3;
            modelId |= (ulong)ModelLayer.DEV << 1;
            var model = new ServiceModel(modelId, "TestService");
            var node  = new ModelNode(model, ctx);

            parentNode.Nodes.Add(node);
            serviceRootNode.AddModelIndex(node);
            node.CheckoutInfo = new CheckoutInfo(node.NodeType, node.CheckoutInfoTargetID, model.Version,
                                                 ctx.Session.Name, ctx.Session.LeafOrgUnitID);
            var souceCode = Resources.LoadStringResource("Resources.Code.TestService.cs");
            await ctx.TypeSystem.CreateModelDocumentAsync(node, souceCode);

            //测试生成用的服务
            var modelId1 = (ulong)Consts.SYS_APP_ID << 32;

            modelId1 |= (ulong)ModelType.Service << 24;
            modelId1 |= (ulong)1 << 5;
            modelId1 |= (ulong)ModelLayer.DEV << 1;
            var model1 = new ServiceModel(modelId1, "HelloService");
            var node1  = new ModelNode(model1, ctx);

            parentNode.Nodes.Add(node1);
            serviceRootNode.AddModelIndex(node1);
            node1.CheckoutInfo = new CheckoutInfo(node1.NodeType, node1.CheckoutInfoTargetID, model1.Version,
                                                  ctx.Session.Name, ctx.Session.LeafOrgUnitID);
            var souceCode1 = Resources.LoadStringResource("Resources.Code.HelloService.cs");
            await ctx.TypeSystem.CreateModelDocumentAsync(node1, souceCode1);

            //生成服务代码
            var data = await PublishService.CompileServiceAsync(ctx, model1);

            Assert.NotNull(data);
        }