Skip to content

Commit

Permalink
support library read, support multi workspace root
Browse files Browse the repository at this point in the history
  • Loading branch information
CppCXY committed Apr 18, 2024
1 parent a1e96a0 commit 7c0ecd5
Show file tree
Hide file tree
Showing 11 changed files with 148 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ public override void Analyze(AnalyzeContext analyzeContext)
}
} while (resolveDependencyGraph.CalcDependency());

foreach (var unResolve in resolveDependencyGraph.UnResolvedList)
{
var unResolved = unResolve.UnResolved;
var state = unResolve.State;
switch (state)
{
case ResolveState.UnResolvedType:
{
FinalResolveType(unResolved);
break;
}
}
}

Context.ClearCache();
}

Expand Down Expand Up @@ -152,6 +166,15 @@ private void ResolveType(UnResolved unResolved)
}
}

private void FinalResolveType(UnResolved unResolved)
{
if (unResolved is UnResolvedDeclaration unResolvedDeclaration)
{
var declaration = unResolvedDeclaration.LuaDeclaration;
declaration.DeclarationType = new LuaNamedType(declaration.Ptr.Stringify);
}
}

private void ResolveIndex(UnResolved unResolved)
{
if (unResolved is UnResolvedDeclaration unResolvedDeclaration)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ public IEnumerable<CanResolved> CanResolvedList
}
}

public IEnumerable<CanResolved> UnResolvedList
{
get
{
foreach (var (unResolved, dict) in Dependencies)
{
foreach (var (state, _) in dict)
{
yield return new CanResolved(unResolved, state);
}
}
}
}

public bool CalcDependency()
{
var changed = false;
Expand Down
77 changes: 67 additions & 10 deletions EmmyLua/CodeAnalysis/Workspace/LuaWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ namespace EmmyLua.CodeAnalysis.Workspace;

public class LuaWorkspace
{
private string MainWorkspace { get; set; } = string.Empty;

public LuaFeatures Features { get; set; }

private Dictionary<LuaDocumentId, LuaDocument> Documents { get; set; } = new();
Expand Down Expand Up @@ -36,7 +38,7 @@ public static LuaWorkspace Create(string workspacePath, LuaFeatures features)
var workspace = new LuaWorkspace(features);
if (workspacePath.Length != 0)
{
workspace.LoadWorkspace(workspacePath);
workspace.LoadMainWorkspace(workspacePath);
}

return workspace;
Expand All @@ -50,20 +52,41 @@ public LuaWorkspace(LuaFeatures features)
ModuleGraph.UpdatePattern(features.RequirePattern);
if (features.InitStdLib)
{
var stdLib = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "std");
LoadWorkspace(stdLib, true);
InitStdLib();
}
}

public void LoadWorkspace(string workspace, bool notFilter = false)
private void InitStdLib()
{
var stdLib = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "std");
LoadWorkspace(stdLib);
}

private IEnumerable<string> CollectFiles(string directory)
{
var excludeFolders = Features.ExcludeFolders.Select(it => Path.Combine(directory, it.Trim('\\', '/'))).ToList();
return Features.Extensions.SelectMany(it =>
Directory.GetFiles(directory, it, SearchOption.AllDirectories))
.Where(it => !excludeFolders.Any(it.StartsWith));
}

/// this will load all third libraries and workspace files
public void LoadMainWorkspace(string workspace)
{
MainWorkspace = workspace;
Monitor?.OnStartLoadWorkspace();
var excludeFolders = Features.ExcludeFolders.Select(it => Path.Combine(workspace, it.Trim('\\', '/'))).ToList();
var files =
Features.Extensions.SelectMany(it => Directory.GetFiles(workspace, it, SearchOption.AllDirectories));
if (!notFilter)
var thirdPartyRoots = Features.ThirdPartyRoots.Select(PreProcessPath);
var files = new List<string>();
foreach (var thirdPartyRoot in thirdPartyRoots)
{
files.AddRange(CollectFiles(thirdPartyRoot));
ModuleGraph.AddPackageRoot(thirdPartyRoot);
}
files.AddRange(CollectFiles(workspace));
ModuleGraph.AddPackageRoot(workspace);
foreach (var workspaceRoot in Features.WorkspaceRoots.Select(PreProcessPath))
{
files = files.Where(it => !excludeFolders.Any(it.StartsWith));
ModuleGraph.AddPackageRoot(workspaceRoot);
}

var documents =
Expand All @@ -86,12 +109,46 @@ public void LoadWorkspace(string workspace, bool notFilter = false)
PathToDocument[document.Path] = document.Id;
}

ModuleGraph.AddDocuments(workspace, documents);
ModuleGraph.AddDocuments(documents);
Compilation.AddSyntaxTrees(documents.Select(it => (it.Id, it.SyntaxTree)));
Monitor?.OnFinishLoadWorkspace();
}

public void LoadWorkspace(string workspace)
{
workspace = PreProcessPath(workspace);
Monitor?.OnStartLoadWorkspace();
var files = CollectFiles(workspace).ToList();
var documents =
files.AsParallel().Select(file => LuaDocument.OpenDocument(file, Features.Language)).ToList();
ModuleGraph.AddPackageRoot(workspace);
foreach (var document in documents)
{
if (!PathToDocument.TryGetValue(document.Path, out var id))
{
document.Id = AllocateId();
Documents.Add(document.Id, document);
}
else
{
document.Id = id;
Documents[document.Id] = document;
}

UrlToDocument[document.Uri] = document.Id;
PathToDocument[document.Path] = document.Id;
}

ModuleGraph.AddDocuments(documents);
Compilation.AddSyntaxTrees(documents.Select(it => (it.Id, it.SyntaxTree)));
Monitor?.OnFinishLoadWorkspace();
}

private string PreProcessPath(string path)
{
return path.Replace("${workspaceFolder}", MainWorkspace);
}

private LuaDocumentId AllocateId()
{
return new LuaDocumentId(_idCounter++);
Expand Down
23 changes: 16 additions & 7 deletions EmmyLua/CodeAnalysis/Workspace/Module/ModuleGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,26 @@ public void UpdatePattern(List<string> pattern)
}
}

public void AddDocuments(string workspace, List<LuaDocument> documents)
public void AddPackageRoot(string packageRoot)
{
workspace = Path.GetFullPath(workspace);
if (!WorkspaceModule.TryGetValue(workspace, out var root))
packageRoot = Path.GetFullPath(packageRoot);
if (!WorkspaceModule.ContainsKey(packageRoot))
{
root = new ModuleNode();
WorkspaceModule.Add(workspace, root);
WorkspaceModule.Add(packageRoot, new ModuleNode());
}
}

public void AddDocuments(List<LuaDocument> documents)
{
foreach (var document in documents)
{
var workspace = GetWorkspace(document);
if (!WorkspaceModule.TryGetValue(workspace, out var root))
{
root = new ModuleNode();
WorkspaceModule.Add(workspace, root);
}

AddDocument(root, workspace, document);
}
}
Expand Down Expand Up @@ -87,6 +96,7 @@ public void AddDocument(ModuleNode root, string workspace, LuaDocument document)
{
documentIds.Add(documentId);
}

break;
}
}
Expand Down Expand Up @@ -164,10 +174,9 @@ public string GetWorkspace(LuaDocument document)
var documentFullPath = Path.GetFullPath(document.Path);
foreach (var node in WorkspaceModule)
{
if (documentFullPath.StartsWith(node.Key))
if (node.Key.Length > workspace.Length && documentFullPath.StartsWith(node.Key))
{
workspace = node.Key;
break;
}
}

Expand Down
3 changes: 3 additions & 0 deletions EmmyLua/Configuration/ConfigSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ public class Workspace
NullValueHandling = NullValueHandling.Ignore)]
public List<string> Library { get; set; } = new();

[JsonProperty("workspaceRoots", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
public List<string> WorkspaceRoots { get; set; } = new();

[JsonProperty("preloadFileSize", Required = Required.Default, NullValueHandling = NullValueHandling.Ignore)]
public int PreloadFileSize { get; set; } = 2048000;
}
2 changes: 2 additions & 0 deletions EmmyLua/Configuration/SettingManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void Watch(string workspace)
if (Watcher is null)
{
Watcher = new FileSystemWatcher();
Watcher.Created += OnChanged;
Watcher.Changed += OnChanged;
Watcher.Path = Workspace;
Watcher.Filter = ConfigName;
Expand Down Expand Up @@ -99,6 +100,7 @@ public LuaFeatures GetLuaFeatures()
features.ExcludeFolders.AddRange(setting.Workspace.IgnoreDir.Where(it => !excludeHash.Contains(it)));
features.DontIndexMaxFileSize = setting.Workspace.PreloadFileSize;
features.ThirdPartyRoots.AddRange(setting.Workspace.Library);
features.WorkspaceRoots.AddRange(setting.Workspace.WorkspaceRoots);
features.Language.LanguageLevel = setting.Runtime.Version;
features.DiagnosticConfig.Globals.UnionWith(setting.Diagnostics.Globals);
features.DiagnosticConfig.WorkspaceDisabledCodes.UnionWith(setting.Diagnostics.Disable);
Expand Down
7 changes: 6 additions & 1 deletion EmmyLua/Resources/std/global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ function setmetatable(table, metatable) end
---@overload fun(e:string):any
---@param e string
---@param base number
---@return any
---@return number
function tonumber(e, base) end

---
Expand Down Expand Up @@ -355,3 +355,8 @@ _VERSION = "Lua 5.3"
---@param msgh fun():string
---@return any
function xpcall(f, msgh, arg1, ...) end

---@generic T1, T2, T3, T4
---@param t [T1, T2, T3, T4]
---@return T1, T2, T3, T4
function unpack(t) end
7 changes: 3 additions & 4 deletions EmmyLua/Resources/std/table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,11 @@ function table.sort(list, comp) end
--- Returns the elements from the given list. This function is equivalent to
--- return `list[i]`, `list[i+1]`, `···`, `list[j]`
--- By default, i is 1 and j is #list.
---@generic T...
---@param list [...T]
---@generic T1, T2, T3, T4
---@param i number
---@param j number
---@return ...T
---@overload fun(list:[...T]): ...T
---@param list [T1, T2, T3, T4]
---@return T1, T2, T3, T4
function table.unpack(list, i, j) end

return table
16 changes: 9 additions & 7 deletions LanguageServer/Server/ServerContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using EmmyLua.Configuration;
using LanguageServer.Server.Monitor;
using LanguageServer.Util;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
Expand Down Expand Up @@ -35,7 +34,7 @@ public void StartServer(string workspacePath)
SettingManager.Watch(workspacePath);
SettingManager.OnSettingChanged += OnConfigChanged;
LuaWorkspace.Features = SettingManager.GetLuaFeatures();
LuaWorkspace.LoadWorkspace(workspacePath);
LuaWorkspace.LoadMainWorkspace(workspacePath);
PushWorkspaceDiagnostics();
}
finally
Expand Down Expand Up @@ -92,15 +91,18 @@ private void OnConfigChanged(SettingManager settingManager)
private void UpdateFeatures(LuaFeatures newFeatures)
{
var oldFeatures = LuaWorkspace.Features;
var requirePatternChanged = !newFeatures.RequirePattern.SequenceEqual(oldFeatures.RequirePattern);
var excludeFoldersChanged = !newFeatures.ExcludeFolders.SequenceEqual(oldFeatures.ExcludeFolders);
var extensionsChanged = !newFeatures.Extensions.SequenceEqual(oldFeatures.Extensions);
if (requirePatternChanged || excludeFoldersChanged || extensionsChanged)
var workspaceNeedReload = false;
workspaceNeedReload |= !newFeatures.RequirePattern.SequenceEqual(oldFeatures.RequirePattern);
workspaceNeedReload |= !newFeatures.ExcludeFolders.SequenceEqual(oldFeatures.ExcludeFolders);
workspaceNeedReload |= !newFeatures.Extensions.SequenceEqual(oldFeatures.Extensions);
workspaceNeedReload |= !newFeatures.WorkspaceRoots.SequenceEqual(oldFeatures.WorkspaceRoots);
workspaceNeedReload |= !newFeatures.ThirdPartyRoots.SequenceEqual(oldFeatures.ThirdPartyRoots);
if (workspaceNeedReload)
{
LuaWorkspace = LuaWorkspace.Create();
LuaWorkspace.Monitor = Monitor;
LuaWorkspace.Features = newFeatures;
LuaWorkspace.LoadWorkspace(MainWorkspacePath);
LuaWorkspace.LoadMainWorkspace(MainWorkspacePath);
PushWorkspaceDiagnostics();
}
else // TODO check condition
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ You can currently use EmmyLuaAnalyzer's language service by checking `Use EmmyLu

Currently in beta, everyone is welcome to test and make suggestions. There is still a lot of work in progress and needs to be improved.

## LICENSE
## LICENSE

[MIT](./LICENSE)
2 changes: 2 additions & 0 deletions README._CN.md → README_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@ TODO
当前处于测试版,欢迎大家测试并提出建议, 有很多工作还在进行中,还需要完善

## LICENSE

[MIT](./LICENSE)

0 comments on commit 7c0ecd5

Please sign in to comment.