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(); } }
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); }
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); }
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); }
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())); }
//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); }
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; } }
public DesignHub GetDesignHub() { if (_ctx != null) { return(_ctx); } lock (this) { if (_ctx == null) { _ctx = new DesignHub(this); } } return(_ctx); }
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); }
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()); }
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); }
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()); }
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); }