Skip to content

Commit

Permalink
Add loading file to project manager
Browse files Browse the repository at this point in the history
todo: fix infinity loop
  • Loading branch information
keyroll-99 committed May 30, 2024
1 parent 8e53b3d commit a70d50c
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Fiona.IDE.Tokenizer\Fiona.IDE.Tokenizer.csproj" />
</ItemGroup>

</Project>
53 changes: 50 additions & 3 deletions ide/src/Fiona.IDE.ProjectManager/Models/Class.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,59 @@
using Fiona.IDE.Tokenizer;

namespace Fiona.IDE.ProjectManager.Models;

public sealed class Class
{
public IReadOnlyCollection<Dependency> Dependencies => _dependencies.AsReadOnly();

private List<Dependency> _dependencies = new();
public string Namespace => _namespace;
public string Route => _route;
public IReadOnlyCollection<Endpoint> Endpoints => _endpoints.AsReadOnly();
public IReadOnlyCollection<string> Usings => _usings.AsReadOnly();
public string Name => _name;

private List<Dependency> _dependencies;
private string _route;
private List<Endpoint> _endpoints = new();
private List<Endpoint> _endpoints;
private List<string> _usings;
private string _name;
private string _namespace;

private Class(string name, string @namespace, List<Dependency> dependencies, string route, List<Endpoint> endpoints, List<string> usings)
{
_name = name;
_dependencies = dependencies;
_route = route;
_endpoints = endpoints;
_usings = usings;
_namespace = @namespace;
}

public static async Task<Class> Load(string path)
{
await using FileStream file = File.Open(path, FileMode.Open);
using StreamReader reader = new(file);
IReadOnlyCollection<IToken> tokens = await Tokenizer.Tokenizer.GetTokensAsync(reader);

List<Dependency> dependencies = [];
List<Endpoint> endpoints = [];

string @namespace = tokens.GetNamespaceToken()?.Value!;
(List<IToken> usings, int indexOfUsingEndToken) = tokens.GetUsingTokens();
(IToken classToken, int indexOfClassToken) = tokens.GetClassToken(indexOfUsingEndToken);
(IToken? classDependency, int indexOfDependencyToken) = tokens.GetClassDependency(indexOfClassToken);
(IToken? classRoute, int indexOfClassRouteToken) = tokens.GetClassRoute(indexOfClassToken);
int indexOfStartEndpointsSearch = indexOfClassToken;
if (classDependency is not null)
{
dependencies = Dependency.GetDependenciesFromToken(classDependency);
indexOfStartEndpointsSearch = indexOfDependencyToken;
}
if(classRoute is not null && indexOfClassRouteToken > indexOfStartEndpointsSearch)
{
indexOfStartEndpointsSearch = indexOfClassRouteToken;
}


return new Class(classToken.Value!, @namespace, dependencies, classRoute?.Value ?? string.Empty, endpoints, usings.Select(x => x.Value!).ToList());
}
}
19 changes: 19 additions & 0 deletions ide/src/Fiona.IDE.ProjectManager/Models/Dependency.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
using Fiona.IDE.Tokenizer;

namespace Fiona.IDE.ProjectManager.Models;

public sealed class Dependency(string name, string type)
{
public string Name { get; } = name;
public string Type { get; } = type;


public static List<Dependency> GetDependenciesFromToken(IToken token)
{
List<Dependency> result = [];
foreach (string dependency in token.ArrayOfValues ?? [])
{
(string name, string type) = dependency.Split(":") switch
{
{ Length: 2 } array => (array[0], array[1]),
_ => throw new Exception("Invalid dependency declaration")
};

result.Add(new Dependency(name, type));
}

return result;
}
}
22 changes: 14 additions & 8 deletions ide/src/Fiona.IDE.ProjectManager/Models/ProjectFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ public sealed class ProjectFile
{
public string Path { get; }
public string Name { get; }
public string Namespace { get; }

public Class Class { get; }
public const string Extension = "fn";

private Class @class;


[JsonConstructor]
private ProjectFile(string path)
{
Path = path;
Name = path.Split(System.IO.Path.DirectorySeparatorChar).Last();
Namespace = path.Replace(System.IO.Path.DirectorySeparatorChar.ToString(), ".").Split(":").Last().Replace(".fn", "")[1..];
Class = Class.Load(path).GetAwaiter().GetResult();
}

private ProjectFile(string path, Class @class)
{
Path = path;
Name = path.Split(System.IO.Path.DirectorySeparatorChar).Last();
Class = @class;
}

internal static async Task<ProjectFile> Create(string path)
Expand All @@ -32,9 +36,11 @@ internal static async Task<ProjectFile> Create(string path)
// We have to close file after create
fileHandler.Close();

ProjectFile projectFile = new(path);
ProjectFile projectFile = new(path, null!); // dommy class create to create inital conent

await projectFile.SaveContentAsync(projectFile.GetBaseContent());

projectFile = new ProjectFile(path);

return projectFile;
}
Expand All @@ -56,8 +62,8 @@ public static string GetBaseContent(this ProjectFile projectFile)
using Fiona.Hosting.Routing;
using Fiona.Hosting.Routing.Attributes;
usingEnd;
namespace: {projectFile.Namespace}
class: {projectFile.Name}
namespace: {projectFile.Path.Replace(System.IO.Path.DirectorySeparatorChar.ToString(), ".").Split(":").Last().Replace(".fn", "")[1..]};
class {projectFile.Name};
""";
}

Expand Down
2 changes: 1 addition & 1 deletion ide/src/Fiona.IDE.ProjectManager/ProjectManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async Task LoadProject(string path)
public IEnumerable<ProjectFile> GetFiles()
=> Project?.ProjectFileUrl ?? Enumerable.Empty<ProjectFile>() ;
public ProjectFile GetProjectFileByNamespace(string @namespace)
=> Project?.ProjectFileUrl.FirstOrDefault(x => x.Namespace == @namespace) ?? throw new ProjectFileNotFoundException(@namespace);
=> Project?.ProjectFileUrl.FirstOrDefault(x => x.Class.Namespace == @namespace) ?? throw new ProjectFileNotFoundException(@namespace);

Check warning on line 42 in ide/src/Fiona.IDE.ProjectManager/ProjectManager.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'source' in 'ProjectFile? Enumerable.FirstOrDefault<ProjectFile>(IEnumerable<ProjectFile> source, Func<ProjectFile, bool> predicate)'.

public Task CreateFileAsync(string name, string folderPath)
{
Expand Down
2 changes: 1 addition & 1 deletion ide/src/Fiona.IDE.Tokenizer/IToken.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ public interface IToken
public string? Value { get; }
public TokenType Type { get; }
public string[]? ArrayOfValues { get; }
}
}
2 changes: 1 addition & 1 deletion ide/src/Fiona.IDE.Tokenizer/Token.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ public Token(TokenType type, params string[] arrayOfValue)
ArrayOfValues = arrayOfValue;
Type = type;
}
}
}
82 changes: 82 additions & 0 deletions ide/src/Fiona.IDE.Tokenizer/TokenListHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
namespace Fiona.IDE.Tokenizer;

public static class TokenListHelper
{
public static (List<IToken> tokens, int endSearchIndex) GetUsingTokens(this IReadOnlyCollection<IToken> tokens, int startSearchIndex = 0)
{
List<IToken> result = [];
bool isUsingPart = false;
for (int i = startSearchIndex; i < tokens.Count; i++)
{
IToken currentToken = tokens.ElementAt(i);
switch (currentToken.Type)
{
case TokenType.UsingBegin:
isUsingPart = true;
break;
case TokenType.UsingEnd:
isUsingPart = false;
break;
case TokenType.Using:
if (isUsingPart)
{
result.Add(currentToken);
}
return (result, i);
case TokenType.Comment:
continue;
}
}

return (result, tokens.Count);
}

public static IToken? GetNamespaceToken(this IReadOnlyCollection<IToken> tokens)
=> tokens.FirstOrDefault(x => x.Type == TokenType.Namespace);

public static (IToken classToken, int findIndex) GetClassToken(this IReadOnlyCollection<IToken> tokens, int startSearchIndex = 0)
{
for (int i = startSearchIndex; i < tokens.Count; i++)
{
IToken currentToken = tokens.ElementAt(i);
if (currentToken.Type == TokenType.Class)
{
return (currentToken, i);
}
}
throw new Exception("class token not found");
}

public static (IToken? token, int findIndex) GetClassDependency(this IReadOnlyCollection<IToken> tokens, int startSearchIndex)
{
for (int i = startSearchIndex; i < tokens.Count; i++)
{
IToken currentToken = tokens.ElementAt(i);
if (currentToken.Type == TokenType.Dependency)
{
return (currentToken, i);
}
}

return (null, tokens.Count);
}

public static (IToken? token, int findIndex) GetClassRoute(this IReadOnlyCollection<IToken> tokens, int startSearchIndex)
{
for (int i = startSearchIndex; i < tokens.Count; i++)
{
IToken currentToken = tokens.ElementAt(i);
if (currentToken.Type == TokenType.Route)
{
return (currentToken, i);
}
// it's mean class doesn't have route define
if (currentToken.Type == TokenType.Endpoint)
{
return (null, tokens.Count);
}
}

return (null, tokens.Count);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@

private void OpenFile(ProjectFile projectFile)
{
NavManager.NavigateTo($"/project-editor/{projectFile.Namespace}");
NavManager.NavigateTo($"/project-editor/{projectFile.Class.Namespace}");
}
}

Expand Down

0 comments on commit a70d50c

Please sign in to comment.