diff --git a/Runtime/Files/FilePath.cs b/Runtime/Files/FilePath.cs index dd8cf53..6846223 100644 --- a/Runtime/Files/FilePath.cs +++ b/Runtime/Files/FilePath.cs @@ -107,6 +107,17 @@ namespace Rokojori } } + public T LoadJSON() where T:new() + { + return (T) FilesSync.LoadJSON( absolutePath ); + } + + public string LoadUTF8() + { + return FilesSync.LoadUTF8( absolutePath ); + } + + public static FilePath Create( string path, FilePathType type = FilePathType.Relative, FilePath parent = null ) { @@ -154,7 +165,7 @@ namespace Rokojori } } - public string absoluteParentPath + public string parentAbsolutePath { get { @@ -164,7 +175,7 @@ namespace Rokojori public FilePath ChangeFileName( string fileName ) { - var parentPath = absoluteParentPath; + var parentPath = parentAbsolutePath; if ( ! parentPath.EndsWith( "/" ) ) { @@ -225,7 +236,7 @@ namespace Rokojori if ( ! ownIsDir ) { - itPath = absoluteParentPath; + itPath = parentAbsolutePath; } itPath = itPath.ReplaceStart( commonPath ); @@ -273,7 +284,12 @@ namespace Rokojori return MakeRelative( relativePath ); } - public FilePath CreateRelativeFromAbsolutePathWithParent( string absolutePath, FilePath absoluteParent ) + public FilePath MakeRelative( FilePath path ) + { + return CreateRelativeFromAbsolutePathWithParent( path.absolutePath, this ); + } + + public static FilePath CreateRelativeFromAbsolutePathWithParent( string absolutePath, FilePath absoluteParent ) { var rp = new FilePath(); diff --git a/Runtime/Files/FilesSync.cs b/Runtime/Files/FilesSync.cs index 3da4c55..5d777ad 100644 --- a/Runtime/Files/FilesSync.cs +++ b/Runtime/Files/FilesSync.cs @@ -95,6 +95,11 @@ namespace Rokojori } return list; + } + + public static List GetFilesRecursive( string path, System.Func evaluator = null ) + { + return GetFiles( path, evaluator, true ); } public static List GetFiles( string path, System.Func evaluator = null, bool recursive = false ) diff --git a/Runtime/Text/Lexing/LexerEvent.cs b/Runtime/Text/Lexing/LexerEvent.cs index afe9b97..c169f4e 100644 --- a/Runtime/Text/Lexing/LexerEvent.cs +++ b/Runtime/Text/Lexing/LexerEvent.cs @@ -8,10 +8,10 @@ namespace Rokojori { public class LexerEvent { - string _type; - int _offset; - int _length; - string _match; + protected string _type; + protected int _offset; + protected int _length; + protected string _match; public string match => _match; @@ -20,6 +20,13 @@ namespace Rokojori Set( type, offset, length ); } + public static LexerEvent WithMatch( string type, int offset, string match ) + { + var le = new LexerEvent( type, offset, offset + match.Length ); + le._match = match; + return le; + } + public string type { get { return _type; } } public int offset { get { return _offset; } } public int length { get { return _length; } } @@ -80,6 +87,7 @@ namespace Rokojori { get { return this._offset + _length; } } + public override string ToString() { if ( match != null ) @@ -185,7 +193,7 @@ namespace Rokojori public bool found => FindResultType.Found == type; - public int index; + public int index = -1; public FindResult() @@ -328,6 +336,55 @@ namespace Rokojori return result; } + public static List Seperate( List tokens, int start, int end, string match = "," ) + { + if ( start < 0 || start >= tokens.Count || end < 0 || end >= tokens.Count ) + { + RJLog.Log( "Ivalid range:", start, end, "count:", tokens.Count ); + return null; + } + + var separators = new List(); + + for ( int i = start; i <= end; i++ ) + { + if ( tokens[ i ].MatchIs( match ) ) + { + separators.Add( i ); + } + } + + if ( separators.Count == 0 ) + { + return new List(); + } + + var ranges = new List(); + + // a, b, c // + + if ( separators[ 0 ] != start ) + { + ranges.Add( new RangeI( start, separators[ 0 ] - 1 ) ); + } + + for ( int i = 1; i < separators.Count; i++ ) + { + var before = separators[ i - 1 ]; + ranges.Add( new RangeI( before + 1, separators[ i ] - 1 ) ); + } + + if ( separators[ separators.Count - 1 ] != end ) + { + ranges.Add( new RangeI( separators[ separators.Count - 1 ] + 1, end ) ); + } + + + // RJLog.Log( "Seperated:", ranges.Map( r => r.min + " / " + r.max ).Join( "" ) ); + + return ranges; + } + public static List GetSeparatorsInBrackets( List tokens, int offset, string seperator = "," ) { var openTypes = new List(){ "(","[","{" }; @@ -370,8 +427,8 @@ namespace Rokojori - static List openTypes = new List(){ "(","[","{" }; - static List closingTypes = new List(){ ")","]","}" }; + static List openTypes = new List(){ "(","[","{","<" }; + static List closingTypes = new List(){ ")","]","}",">" }; public static FindResult FindClosingBracket( List tokens, int offset ) { @@ -390,12 +447,12 @@ namespace Rokojori var counter = ( LexerEvent le ) => { - if ( le.Is( LexerMatcherLibrary.BracketMatcher, closer ) ) + if ( le.Is( LexerMatcherLibrary.BracketMatcher, closer ) || le.Is( LexerMatcherLibrary.OperatorMatcher, closer ) ) { return -1; } - if ( le.Is( LexerMatcherLibrary.BracketMatcher, opener ) ) + if ( le.Is( LexerMatcherLibrary.BracketMatcher, opener ) || le.Is( LexerMatcherLibrary.OperatorMatcher, opener ) ) { return 1; } @@ -452,7 +509,8 @@ namespace Rokojori var result = Find( tokens, offset, ( le ) => { - return le.Is( LexerMatcherLibrary.BracketMatcher, blockBracket ) ? FindResultType.Found : FindResultType.KeepSearching; + return le.Is( LexerMatcherLibrary.BracketMatcher, blockBracket ) || le.Is( LexerMatcherLibrary.OperatorMatcher, blockBracket ) + ? FindResultType.Found : FindResultType.KeepSearching; } ); @@ -477,12 +535,12 @@ namespace Rokojori var counter = ( LexerEvent le ) => { - if ( le.Is( LexerMatcherLibrary.BracketMatcher, closer ) ) + if ( le.Is( LexerMatcherLibrary.BracketMatcher, closer ) || le.Is( LexerMatcherLibrary.OperatorMatcher, closer ) ) { return 1; } - if ( le.Is( LexerMatcherLibrary.BracketMatcher, opener ) ) + if ( le.Is( LexerMatcherLibrary.BracketMatcher, opener ) || le.Is( LexerMatcherLibrary.OperatorMatcher, opener ) ) { return -1; } @@ -493,7 +551,19 @@ namespace Rokojori return FindCloser( tokens, offset, counter, false ); } - + public static RangeI GetNextBlock( List tokens, int offset = 0) + { + var opener = FindOpeningBracket( tokens, offset ); + + if ( opener.type != FindResultType.Found ) + { + return null; + } + + var closer = FindClosingBracket( tokens, opener.index ); + + return new RangeI( opener.index, closer.index ); + } public static List GetBlocks( List tokens ) { diff --git a/Runtime/Text/Lexing/LexerLibrary/CSharpLexer.cs b/Runtime/Text/Lexing/LexerLibrary/CSharpLexer.cs index 9b1010e..198f374 100644 --- a/Runtime/Text/Lexing/LexerLibrary/CSharpLexer.cs +++ b/Runtime/Text/Lexing/LexerLibrary/CSharpLexer.cs @@ -4,6 +4,14 @@ using System.Text.RegularExpressions; namespace Rokojori { + public class CSharpObjectDefinition + { + public LexerEvent type; + public LexerEvent name; + + + } + public class CSharpLexer:Lexer { public static List Lex( string source ) @@ -20,10 +28,21 @@ namespace Rokojori return events; } - public static List> GetAllObjectDefinitions( string source ) + public static List GetAllObjectDefinitions( string source ) { var tokens = Lex( source ).Filter( e => ! ( e.isDone || e.isError ) ); + return GetAllObjectDefinitions( tokens ); + } + + public static List GetAllObjectDefinitions( List tokens ) + { + + + var START = Trillean.True; + var END = Trillean.False; + var INSIDE = Trillean.Any; + var sequences = LexerEvent.FindSequences( tokens, ( int index, bool inSequence ) => { @@ -38,19 +57,19 @@ namespace Rokojori le.Is( LexerMatcherLibrary.EnumMatcher ) ) { - return Trillean.True; + return START; } if ( inSequence && le.Is( LexerMatcherLibrary.CwordMatcher ) ) { - return Trillean.False; + return END; } - return Trillean.Any; + return INSIDE; } ); - return sequences; + return sequences.Map( s => new CSharpObjectDefinition{ type = s[ 0 ], name = s[ s.Count - 1 ] } ); } public CSharpLexer() diff --git a/Runtime/Text/Lexing/LexerList.cs b/Runtime/Text/Lexing/LexerList.cs index d5ff0a7..c979039 100644 --- a/Runtime/Text/Lexing/LexerList.cs +++ b/Runtime/Text/Lexing/LexerList.cs @@ -7,17 +7,40 @@ namespace Rokojori public class LexerList { protected List _events; + protected LexerMatcher[] _ignore = null; + + public LexerMatcher[] ignore + { + get { return _ignore; } + set { _ignore = value; } + } public List events => _events; public LexerList Filter( System.Predicate le ) { - return Create( events.Filter( e => le( e ) ) ); + var list = Create( events.Filter( e => le( e ) ), ignore ); + return list; + } + public LexerEvent this[ int index ] + { + get + { + return _events[ index ]; + } + + set + { + _events[ index ] = value; + } + } + + public LexerList GetAll( LexerMatcher lexerMatcher ) { - return Create( events.Filter( e => e.Is( lexerMatcher ) ) ); + return Create( events.Filter( e => e.Is( lexerMatcher ) ), ignore ); } public List Seperate( int start, int end, LexerMatcher[] ignore = null ) @@ -25,8 +48,10 @@ namespace Rokojori return Seperate( ",", start, end, ignore ); } - public List Seperate( string seperator, int start, int end, LexerMatcher[] ignore = null ) + public List Seperate( string seperator, int start, int end, LexerMatcher[] ignoring = null ) { + ignoring = GetIgnore( ignoring ); + var list = new List(); var currentStart = -1; @@ -42,7 +67,7 @@ namespace Rokojori currentStart = -1; } - else if ( ignore != null && _events[ i ].IsAnyOf( ignore ) ) + else if ( ignoring != null && _events[ i ].IsAnyOf( ignoring ) ) { continue; } @@ -81,11 +106,39 @@ namespace Rokojori return LexerEvent.FindOpeningBracket( _events, offset, blockBracket ); } + public LexerEvent.FindResult FindClosingBracket( int offset ) + { + return LexerEvent.FindClosingBracket( _events, offset ); + } + public LexerEvent.FindResult ReverseFindOpeningBracket( int offset ) { return LexerEvent.ReverseFindOpeningBracket( _events, offset ); } + public List GetParameters( int offset ) + { + var opener = FindOpeningBracket( offset, "(" ).index; + + if ( opener == -1 ) + { + RJLog.Log( "No open bracket:", events[ offset ].match ); + return null; + } + + var closer = FindClosingBracket( opener ).index; + + if ( closer == -1 ) + { + RJLog.Log( "No closing bracket:", events[ offset ].match ); + return null; + } + + // RJLog.Log( "GetParameters", opener, closer ); + + return LexerEvent.Seperate( _events, opener + 1, closer - 1 ); + } + public LexerEvent.FindResult ReverseFind( int offset, System.Func evaluator ) { return LexerEvent.Find( _events, offset, evaluator, false ); @@ -95,6 +148,98 @@ namespace Rokojori { return LexerEvent.Find( _events, offset, evaluator, true ); } + + public bool Is( int offset, string type, string match, LexerMatcher[] ignoring ) + { + var next = Get( offset, ignoring ); + + return next.Is( type, match ); + } + + public bool MatchIs( int offset, string match, LexerMatcher[] ignoring = null ) + { + var next = Get( offset, ignoring ); + + return next.MatchIs( match ); + } + + LexerMatcher[] GetIgnore( LexerMatcher[] ignoring ) + { + ignoring = ignoring != null ? ignoring : _ignore; + ignoring = ignoring != null ? ignoring : []; + + return ignoring; + } + + public LexerEvent Get( int offset, LexerMatcher[] ignoring = null ) + { + return events[ GetIndex( offset, ignoring ) ]; + } + + public LexerEvent GetReverse( int offset, LexerMatcher[] ignoring = null ) + { + return events[ GetIndexReverse( offset, ignoring ) ]; + } + + public int GetIndex( int offset, LexerMatcher[] ignoring = null ) + { + ignoring = GetIgnore( ignoring ); + + for ( int i = offset; i < _events.Count; i++ ) + { + if ( _events[ i ].IsAnyOf( ignoring ) ) + { + continue; + } + + return i; + } + + return -1; + } + + public int GetIndexReverse( int offset, LexerMatcher[] ignoring = null ) + { + ignoring = GetIgnore( ignoring ); + + for ( int i = offset; i >= 0; i-- ) + { + if ( _events[ i ].IsAnyOf( ignoring ) ) + { + continue; + } + + return i; + } + + return -1; + } + + public int FindIndexOfType( int offset, string type ) + { + for ( int i = offset; i < _events.Count; i++ ) + { + if ( _events[ i ].type == type ) + { + return i; + } + } + + return -1; + } + + public int FindIndexOfMatch( int offset, string match ) + { + for ( int i = offset; i < _events.Count; i++ ) + { + if ( _events[ i ].match == match ) + { + return i; + } + } + + return -1; + } public LexerEvent.FindResult Find( int offset, List found, List keepSearching = null, List errors = null ) @@ -139,6 +284,76 @@ namespace Rokojori public List GetBlocks() { return LexerEvent.GetBlocks( _events ); + } + + public void ReplaceBlocks( System.Func blockReplacer ) + { + ReplaceRanges( GetBlocks(), blockReplacer ); + } + + public void ReplaceRanges( List ranges, System.Func blockReplacer ) + { + for ( int i = 0; i < ranges.Count; i++ ) + { + var r = ranges[ ranges.Count - 1 - i ]; + var le = blockReplacer( r ); + _events.ReplaceRange( r.min, r.max - r.min + 1, [ le ] ); + } + } + + public int MoveIndexForward( int start, string[] matches, LexerMatcher[] ignoring = null ) + { + return MoveIndex( start, -1, matches, ignoring ); + } + + public int MoveIndexBackwards( int start, string[] matches, LexerMatcher[] ignoring = null ) + { + return MoveIndex( start, -1, matches, ignoring ); + } + + + public int MoveIndex( int start, int direction, string[] matches, LexerMatcher[] ignoring = null ) + { + ignoring = GetIgnore( ignoring ); + + var tokenIndex = start; + var token = _events[ tokenIndex ]; + var moving = true; + var moveIndex = start; + + while ( moving && token != null && token.IsAnyOf( ignoring ) ) + { + moveIndex = tokenIndex; + + tokenIndex += direction; + token = tokenIndex < 0 || tokenIndex >= _events.Count ? null : events[ tokenIndex ]; + + if ( token != null && token.IsAnyOf( ignoring ) ) + { + continue; + } + + if ( token.MatchIsAny( matches ) ) + { + moveIndex = tokenIndex; + + tokenIndex += direction; + token = tokenIndex < 0 || tokenIndex >= _events.Count ? null : events[ tokenIndex ]; + } + } + + return moveIndex; + } + + + public int Index( LexerEvent lexerEvent, int offset = 0 ) + { + return _events.IndexOf( lexerEvent, offset ); + } + + public RangeI NextBlock( int offset ) + { + return LexerEvent.GetNextBlock( _events, offset ); } public LexerList Range( RangeI range ) @@ -146,22 +361,44 @@ namespace Rokojori return Range( range.min, range.max ); } - public LexerList Range( int start, int end = -1 ) + public string match { - if ( end == -1 ) - { - end = _events.Count; - } - - return Create( _events.Sub( start, end - start + 1 ) ); + get { return _events.Map( e => e.match ).Join( "" ); } } - public static LexerList Create( List lexerEvents ) + public LexerList RangeInside( RangeI range ) + { + return Range( range.min + 1, range.max - 1); + } + + public int size => _events.Count; + + public LexerList Range( int start, int end = -1 ) + { + + if ( end == -1 ) + { + end = _events.Count - 1; + } + + if ( start < 0 || start >= _events.Count || end < 0 || end >= _events.Count ) + { + RJLog.Log( "Range invalid", start, end, "count:", _events.Count ); + return null; + } + + var list = Create( _events.Sub( start, end - start + 1 ), ignore ); + return list; + } + + public static LexerList Create( List lexerEvents, LexerMatcher[] ignore = null ) { var list = new LexerList(); list._events = lexerEvents; + list.ignore = ignore; return list; } + } } \ No newline at end of file diff --git a/Runtime/Tools/Lists.cs b/Runtime/Tools/Lists.cs index 4806777..d116117 100644 --- a/Runtime/Tools/Lists.cs +++ b/Runtime/Tools/Lists.cs @@ -414,6 +414,34 @@ namespace Rokojori return list; } + + public static Dictionary ToMap( this List list, Func mapper ) + { + var d = new Dictionary(); + + list.ForEach( + ( item )=> + { + d[ mapper( item ) ] = item; + } + ); + + return d; + } + + public static void ReplaceRange( this List list, int start, int count, List replacement ) + { + if ( count > 0 ) + { + list.RemoveRange( start, count ); + } + + if ( replacement.Count > 0 ) + { + list.InsertRange( start, replacement ); + } + } + public static List From( params T[] elements ) { return ToList( elements ); @@ -715,6 +743,11 @@ namespace Rokojori public static string Join( this List array, string seperator = ", " ) { + if ( array == null ) + { + return "null"; + } + var sb = new StringBuilder(); for ( var i = 0; i < array.Count; i++ ) diff --git a/Tools/Refactoring/camera.json b/Tools/Refactoring/camera.json new file mode 100644 index 0000000..c16190d --- /dev/null +++ b/Tools/Refactoring/camera.json @@ -0,0 +1,12 @@ +{ + "refactorings": + [ + { + "context": "Renamed Camera Manager", + "from":"res://addons/rokojori_action_library/Runtime/VirtualCameras/VirtualCamera3DManager.cs", + "to":"res://addons/rokojori_action_library/Runtime/Cameras/CameraManager.cs", + "date": null, + "version":"4.5" + } + ] +} \ No newline at end of file diff --git a/Tools/docs/ClassDocEditing/ClassBlock.cs b/Tools/docs/ClassDocEditing/ClassBlock.cs new file mode 100644 index 0000000..c0d8f1e --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassBlock.cs @@ -0,0 +1,30 @@ + +using Godot; + +using Rokojori; +using System.Collections.Generic; +using System; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Linq; + +namespace Rokojori.DocGenerator +{ + public class ClassBlock:LexerEvent + { + public static readonly string LexerType = "ClassBlock"; + public int originalStartIndex = -1; + public int originalEndIndex = -1; + + public ClassBlock( int s, int e, int originalStartIndex, int originalEndIndex ):base( LexerType, s, e ) + { + this.originalEndIndex = originalEndIndex; + this.originalStartIndex = originalStartIndex; + } + + public void SetMatch( string match ) + { + _match = match; + } + } +} \ No newline at end of file diff --git a/Tools/docs/ClassDocEditing/ClassBlock.cs.uid b/Tools/docs/ClassDocEditing/ClassBlock.cs.uid new file mode 100644 index 0000000..81faafc --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassBlock.cs.uid @@ -0,0 +1 @@ +uid://wrytq8ayur0j diff --git a/Tools/docs/ClassDocEditing/ClassDocEditor.cs b/Tools/docs/ClassDocEditing/ClassDocEditor.cs new file mode 100644 index 0000000..aa289be --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocEditor.cs @@ -0,0 +1,154 @@ + +using Godot; + +using Rokojori; +using System.Collections.Generic; +using System; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Linq; +using Rokojori.Tools; + +namespace Rokojori.DocGenerator +{ + public class ClassDocEditor + { + public static readonly bool NO_SIGNATURE_FALLBACK_MODE = true; + + public string source; + public LexerList originalTokens; + + ClassDocParser parser; + + + public void Process( CSharpObjectDefinition definition, OnlineDocJSON onlineDocJSON ) + { + parser = new ClassDocParser(); + parser.orginalTokens = originalTokens; + parser.orginalTokens.ignore = LexerMatcherLibrary.Ignore; + + parser.linesMapper = new TextLinesMapper(); + parser.linesMapper.Map( source ); + parser.Parse( definition ); + + var members = parser.GetMembers(); + + members.ForEach( + ( m )=> + { + var name = parser.innerTokens[ m.name ].match; + var type = parser.innerTokens.Range( m.type ).match; + + var parameters = ""; + + + var isMethod = m.IsMethod( parser.innerTokens ); + + if ( isMethod ) + { + var types = m.GetMethodParameterTypes( parser.innerTokens ); + + parameters = "(" + types.Join( "," ) + ")"; + } + else + { + var next = parser.innerTokens.Get( m.name, LexerMatcherLibrary.Ignore ); + var anchorNext = parser.linesMapper.GetAnchor( next.offset, true ); + var anchorName = parser.linesMapper.GetAnchor( parser.innerTokens[ m.name ].offset, true ); + + // RJLog.Log( anchorName.info, anchorNext.info ); + } + + + + var comment = "/** */"; + + if ( m.comment != -1 ) + { + comment = parser.innerTokens[ m.comment ].match; + } + + var onlineDocEntries = GetOnlineDoc( members, members.IndexOf( m ), onlineDocJSON ); + + // RJLog.Log( "Online docs:", onlineDocEntries == null ? "---" : onlineDocEntries.Count ); + + + if ( onlineDocEntries != null ) + { + var title = onlineDocEntries[ 0 ].content; + var description = onlineDocEntries[ 1 ].content; + + comment = + @$" + /** + + + + {title} + + + + {description} + + + + */ + + ".Indent( "" ); + } + + + RJLog.Log( "[color=#888888]" + comment + "[/color]", "\n" + type, name + parameters ); + } + ); + + } + + List GetOnlineDoc( List members, int index, OnlineDocJSON onlineDoc ) + { + if ( NO_SIGNATURE_FALLBACK_MODE ) + { + return GetOnlineDoc_FALLBACK( members, index, onlineDoc ); + } + + return null; + } + + List GetOnlineDoc_FALLBACK( List members, int index, OnlineDocJSON onlineDoc ) + { + var member = members[ index ]; + + var membersWithSameName = members.Filter( m => m.name == member.name ); + + var name = parser.innerTokens[ member.name ].match; + + var docNames = onlineDoc.content.Map( e => OnlineDocsTarget.From( e.target ).memberName ).Join( "," ); + var docEntries = onlineDoc.content.Filter( e => OnlineDocsTarget.From( e.target ).memberName == name ); + + if ( docEntries == null || docEntries.Count == 0 ) + { + // RJLog.Log( "No doc entries for:", "'" + name + "'", ">>", docNames ); + return null; + } + + if ( membersWithSameName.Count == 1 ) + { + return docEntries; + } + + + var memberIndex = membersWithSameName.IndexOf( member ); + + var docEntryIndex = memberIndex * 2; + + if ( ( docEntryIndex + 1 ) >= docEntries.Count ) + { + return null; + } + + return docEntries.Sub( docEntryIndex, 2 ); + + } + + } +} \ No newline at end of file diff --git a/Tools/docs/ClassDocEditing/ClassDocEditor.cs.uid b/Tools/docs/ClassDocEditing/ClassDocEditor.cs.uid new file mode 100644 index 0000000..3d2b778 --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocEditor.cs.uid @@ -0,0 +1 @@ +uid://crrgiu20gemhx diff --git a/Tools/docs/ClassDocEditing/ClassDocMember.cs b/Tools/docs/ClassDocEditing/ClassDocMember.cs new file mode 100644 index 0000000..2d32213 --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocMember.cs @@ -0,0 +1,62 @@ + +using Godot; + +using Rokojori; +using System.Collections.Generic; +using System; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Linq; + +namespace Rokojori.DocGenerator +{ + public class ClassDocMember + { + public int start; + public RangeI attributes; + public RangeI modifiers; + public RangeI type; + public int name; + public int end; + public int comment; + + public bool IsMethod( LexerList lexerList ) + { + var next = lexerList.Get( name + 1, LexerMatcherLibrary.Ignore ); + + // RJLog.Log( lexerList[ name ].match, ">>", next.match ); + return lexerList.MatchIs( name + 1, "(", LexerMatcherLibrary.Ignore ); + } + + public List GetMethodParameterTypes( LexerList lexerList ) + { + var parameters = lexerList.GetParameters( name ); + + if ( parameters == null || parameters.Count == 0 ) + { + return []; + } + + var list = parameters.Map( + ( r )=> + { + var tokens = lexerList.Range( r ); + tokens = tokens.Filter( t => ! t.IsAnyOf( LexerMatcherLibrary.Ignore ) ); + + var assignmentIndex = tokens.FindIndexOfMatch( 0, "=" ); + + if ( assignmentIndex != -1 ) + { + tokens.events.RemoveRange( assignmentIndex, tokens.events.Count - assignmentIndex ); + } + + tokens.events.RemoveAt( tokens.events.Count - 1 ); + + return tokens.match; + } + ); + + return list; + } + } +} \ No newline at end of file diff --git a/Tools/docs/ClassDocEditing/ClassDocMember.cs.uid b/Tools/docs/ClassDocEditing/ClassDocMember.cs.uid new file mode 100644 index 0000000..449b453 --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocMember.cs.uid @@ -0,0 +1 @@ +uid://dehc4ssbjfrkq diff --git a/Tools/docs/ClassDocEditing/ClassDocParser.cs b/Tools/docs/ClassDocEditing/ClassDocParser.cs new file mode 100644 index 0000000..e7dcd5e --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocParser.cs @@ -0,0 +1,652 @@ + +using Godot; + +using Rokojori; +using System.Collections.Generic; +using System; +using System.Reflection; +using System.Text.RegularExpressions; +using System.Linq; + +namespace Rokojori.DocGenerator +{ + public class ClassDocParser + { + public static readonly string[] ModifierTypes = + [ + // Access modifiers + "public", + "protected", + "internal", + "protected internal", + "private", + "private protected", + + // Type behavior modifiers + "abstract", + "sealed", + "static", + "partial", + + // Type-specific modifiers + "readonly", + "ref", + "unsafe", + "new", + + "override", + "virtual", + + // Modern / contextual + "record", + "record struct" + ]; + + public LexerList orginalTokens; + + public LexerList innerTokens; + + public TextLinesMapper linesMapper; + + public List GetMembers() + { + return members; + } + + public CSharpObjectDefinition definition; + + public int definitionStart = -1; + + public void Parse( CSharpObjectDefinition definition ) + { + this.definition = definition; + + // RJLog.Log( "\n\n PARSING START \n\n" ); + ParseObjectDefinition(); + ParseInnerObject(); + ParseMembers(); + ParseComments(); + // RJLog.Log( "\n\n PARSING DONE \n\n" ); + + } + + protected void ParseObjectDefinition() + { + var typeIndex = orginalTokens.Index( definition.type ) ; + + + var tokenIndex = orginalTokens.MoveIndexBackwards( typeIndex, ModifierTypes ); + + var prevIndex = orginalTokens.GetIndexReverse( tokenIndex ); + + if ( prevIndex == -1 ) + { + definitionStart = tokenIndex; + return; + } + + var prev = prevIndex == -1 ? null : orginalTokens[ prevIndex ]; + + while ( prev != null && prev.MatchIs( "]" ) ) + { + var opening = LexerEvent.ReverseFindOpeningBracket( orginalTokens.events, prevIndex ); + tokenIndex = opening.index; + prevIndex = orginalTokens.GetIndexReverse( tokenIndex ); + prev = prevIndex == -1 ? null : orginalTokens[ prevIndex ]; + } + + definitionStart = tokenIndex; + + } + + protected void ParseInnerObject() + { + var index = orginalTokens.Index( definition.name ); + var block = orginalTokens.NextBlock( index ); + + innerTokens = orginalTokens.RangeInside( block ); + + innerTokens.ReplaceBlocks( + ( r )=> + { + var opener = orginalTokens[ r.min ]; + var closer = orginalTokens[ r.min ]; + var block = new ClassBlock( opener.offset, closer.end, r.min, r.max ); + block.SetMatch( "{ /* - inner block - */ }" ); + return block; + } + ); + + var innerObjects = CSharpLexer.GetAllObjectDefinitions( innerTokens.events ); + + var objectRanges = innerObjects.Map( + ( io )=> + { + var startIndex = innerTokens.Index( io.type ); + var endIndex = innerTokens.Index( io.name, startIndex ); + var end = innerTokens.FindIndexOfType( endIndex, ClassBlock.LexerType ); + var modifierStart = startIndex; + + var searching = true; + + while ( searching ) + { + var result = LexerEvent.ReverseFind( innerTokens.events, modifierStart - 1, + ( le ) => + { + if ( le.MatchIsAny( ModifierTypes ) ) + { + return LexerEvent.FindResultType.Found; + } + + if ( le.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + return LexerEvent.FindResultType.KeepSearching; + } + + return LexerEvent.FindResultType.NotFound; + } + ); + + if ( result.type == LexerEvent.FindResultType.Found ) + { + modifierStart = result.index; + + } + else + { + searching = false; + } + } + + return new RangeI( modifierStart, end ); + + } + ); + + innerTokens.ReplaceRanges( objectRanges, + ( r ) => + { + var start = innerTokens.events[ r.min ]; + var end = innerTokens.events[ r.max ]; + return LexerEvent.WithMatch( LexerMatcherLibrary.MultiLineCommentMatcher.type, start.offset, "/* - inner object - */" ); + } + ); + + } + + enum ParsePhase + { + Attributes, + Modifiers, + Type, + Name, + MemberEnd + } + + List members = new List(); + + void ParseMembers() + { + var phase = ParsePhase.Attributes; + var tokenIndex = 0; + + var memberStart = -1; + RangeI attributes = null; + RangeI modifiers = null; + RangeI type = null; + var name = -1; + + + var checkIndex = -1; + + while ( tokenIndex < innerTokens.size && checkIndex <= tokenIndex ) + { + checkIndex = Mathf.Max( checkIndex, tokenIndex ); + + var token = innerTokens[ tokenIndex ]; + + // RJLog.Log( phase, "index", tokenIndex, "token", token.type, token.match, "line", linesMapper.GetAnchor( token.offset, true ).info ); + + if ( token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + continue; + } + + if ( memberStart == -1 ) + { + memberStart = tokenIndex; + } + + if ( ParsePhase.Attributes == phase ) + { + attributes = null; + var attributesEndIndex = GetAttributesEndIndex( tokenIndex ); + + phase = ParsePhase.Modifiers; + + if ( attributesEndIndex != -1 ) + { + attributes = new RangeI( tokenIndex, attributesEndIndex ); + tokenIndex = attributesEndIndex + 1; + } + + continue; + } + + if ( ParsePhase.Modifiers == phase ) + { + modifiers = null; + var modifiersEndIndex = GetModifiersEndIndex( tokenIndex ); + + phase = ParsePhase.Type; + + if ( modifiersEndIndex != -1 ) + { + tokenIndex = modifiersEndIndex + 1; + } + + continue; + } + + if ( ParsePhase.Type == phase ) + { + if ( token.Is( LexerMatcherLibrary.CFunctionMatcher ) ) + { + type = new RangeI( tokenIndex, tokenIndex ); + name = tokenIndex; + + phase = ParsePhase.MemberEnd; + tokenIndex++; + } + else + { + var typeEndIndex = GetTypeEndIndex( tokenIndex ); + + type = new RangeI( tokenIndex, typeEndIndex ); + tokenIndex = typeEndIndex + 1; + + phase = ParsePhase.Name; + } + + + continue; + } + + if ( ParsePhase.Name == phase ) + { + if ( token.MatchIs( "(") ) + { + name = type.max; + } + else + { + name = tokenIndex; + tokenIndex++; + } + + + phase = ParsePhase.MemberEnd; + + continue; + } + + if ( ParsePhase.MemberEnd == phase ) + { + var memberEndIndex = GetMemberEndIndex( tokenIndex ); + + if ( memberEndIndex == -1 ) + { + if ( tokenIndex != -1 && memberStart != -1 ) + { + var memberEnd = tokenIndex < memberStart ? innerTokens.size - 1 : tokenIndex; + RJLog.Error( tokenIndex, memberStart ); + + RJLog.Error( + "Could not parse", innerTokens.Range( new RangeI( memberStart, memberEnd ) ).match + // "Type:", "'" + innerTokens.Range( type ).match + "'" + ); + } + return; + } + + phase = ParsePhase.Attributes; + + var cdMember = new ClassDocMember(); + cdMember.start = memberStart; + cdMember.attributes = attributes; + cdMember.modifiers = modifiers; + cdMember.type = type; + cdMember.name = name; + cdMember.end = memberEndIndex; + + members.Add( cdMember ); + + // RJLog.Log( + // "-------------\n", + // innerTokens.Range( cdMember.type ).match, innerTokens[ cdMember.name ].match, "\n" + + // "-------------" + // ); + + tokenIndex = memberEndIndex + 1; + + memberStart = -1; + + continue; + } + + } + + if ( checkIndex > tokenIndex ) + { + RJLog.Log( "CheckIndex > TokenIndex", checkIndex, tokenIndex ); + } + } + + int GetAttributesEndIndex( int tokenIndex ) + { + if ( tokenIndex >= innerTokens.size ) + { + return -1; + } + + var token = innerTokens[ tokenIndex ]; + var end = -1; + + while ( token != null && token.MatchIs( "[" ) ) + { + var endResult = innerTokens.FindClosingBracket( tokenIndex ); + + if ( LexerEvent.FindResultType.Found != endResult.type ) + { + return end; + } + + end = endResult.index; + + tokenIndex = endResult.index + 1; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + } + + return end; + } + + int GetModifiersEndIndex( int tokenIndex ) + { + if ( tokenIndex >= innerTokens.size ) + { + return -1; + } + + var token = innerTokens[ tokenIndex ]; + var end = -1; + + while ( token != null && token.MatchIsAny( ModifierTypes ) ) + { + end = tokenIndex; + + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + } + + return end; + } + + int GetTypeEndIndex( int tokenIndex ) + { + if ( tokenIndex >= innerTokens.size ) + { + return -1; + } + + tokenIndex = GetNameEndIndex( tokenIndex ); + tokenIndex = GetGenericsEndIndex( tokenIndex ); + tokenIndex = GetPointerArraysEndIndex( tokenIndex ); + tokenIndex = GetNullableEndIndex( tokenIndex ); + + return tokenIndex; + } + + int GetNameEndIndex( int tokenIndex ) + { + if ( tokenIndex >= innerTokens.size ) + { + return -1; + } + + var token = innerTokens[ tokenIndex ]; + + var end = -1; + + while ( token != null && token.Is( LexerMatcherLibrary.CwordMatcher ) ) + { + end = tokenIndex; + + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + if ( ! token.Is( LexerMatcherLibrary.OperatorMatcher, "." ) ) + { + return end; + } + + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + } + + return end; + } + + int GetGenericsEndIndex( int tokenIndex ) + { + if ( tokenIndex >= innerTokens.size ) + { + return -1; + } + + var orignalIndex = tokenIndex; + + tokenIndex ++; + var token = innerTokens[ tokenIndex ]; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + if ( token.MatchIs( "<" ) ) + { + var end = innerTokens.FindClosingBracket( tokenIndex ).index; + // RJLog.Log( "Has Generics", innerTokens.Range( new RangeI( orignalIndex, end ) ).match ); + return end; + } + else + { + // RJLog.Log( "Has No Generics", token.match ); + } + + return orignalIndex; + } + + int GetPointerArraysEndIndex( int tokenIndex ) + { + if ( tokenIndex < 0 || tokenIndex >= innerTokens.size ) + { + return -1; + } + + var token = innerTokens[ tokenIndex ]; + var lastTokenIndex = tokenIndex; + + tokenIndex ++; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) || token.MatchIs( "*" ) || token.MatchIs( "[" ) ) + { + if ( token.MatchIs( "[" ) ) + { + tokenIndex = innerTokens.FindClosingBracket( tokenIndex ).index; + } + + lastTokenIndex = tokenIndex; + + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + return lastTokenIndex; + } + + int GetNullableEndIndex( int tokenIndex ) + { + if ( tokenIndex < 0 || tokenIndex >= innerTokens.size ) + { + return -1; + } + + var orignalIndex = tokenIndex; + var token = innerTokens[ tokenIndex ]; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + if ( token != null && token.MatchIs( "?" ) ) + { + return tokenIndex; + } + + return orignalIndex; + } + + + int GetMemberEndIndex( int tokenIndex ) + { + if ( tokenIndex < 0 || tokenIndex >= innerTokens.size ) + { + return -1; + } + + var token = innerTokens[ tokenIndex ]; + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + if ( token.MatchIs( ";" ) ) + { + // RJLog.Log( "Member has no assignment" ); + return tokenIndex; + } + + if ( token.MatchIs( "=" ) || token.MatchIs( "=>" ) ) + { + // RJLog.Log( "Member has assignment" ); + return innerTokens.FindIndexOfMatch( tokenIndex, ";" ); + } + + if ( token.MatchIs( "(" ) ) + { + // RJLog.Log( "Member is function" ); + + tokenIndex = innerTokens.FindClosingBracket( tokenIndex ).index + 1; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + while ( token != null && token.IsAnyOf( LexerMatcherLibrary.Ignore ) ) + { + tokenIndex ++; + token = tokenIndex < innerTokens.size ? innerTokens[ tokenIndex ] : null; + } + + if ( token.Is( ClassBlock.LexerType ) ) + { + // RJLog.Log( "Member is function with block" ); + return tokenIndex; + } + + if ( token.MatchIs( "=>" ) ) + { + // RJLog.Log( "Member is function with assigner reference" ); + return innerTokens.FindIndexOfMatch( tokenIndex, ";" ); + } + + RJLog.Log( "Member not found, token", token.match ); + + return -1; + + } + + + void ParseComments() + { + var endIndex = 0; + + for ( int i = 0; i < members.Count; i++ ) + { + members[ i ].comment = GetComment( members[ i ].start, endIndex ); + endIndex = members[ i ].end; + } + } + + int GetComment( int start, int end ) + { + var it = start - 1; + + while ( it > end ) + { + var token = innerTokens[ it ]; + + if ( token.Is( LexerMatcherLibrary.MultiLineCommentMatcher ) ) + { + var comment = token.match; + + var startRegex = @"^\/\*\*(\s|\n|\r)*(\s|\n|\r)*\*\/$"; + + if ( RegexUtility.Matches( comment, startRegex ) && RegexUtility.Matches( comment, endRegex ) ) + { + return it; + } + + return -1; + } + + it --; + } + + return -1; + } + + } +} \ No newline at end of file diff --git a/Tools/docs/ClassDocEditing/ClassDocParser.cs.uid b/Tools/docs/ClassDocEditing/ClassDocParser.cs.uid new file mode 100644 index 0000000..fffc365 --- /dev/null +++ b/Tools/docs/ClassDocEditing/ClassDocParser.cs.uid @@ -0,0 +1 @@ +uid://bry7q2thf5p5k diff --git a/Tools/docs/ClassDocGenerator.cs b/Tools/docs/ClassDocGenerator.cs index fb6db77..56f6e8b 100644 --- a/Tools/docs/ClassDocGenerator.cs +++ b/Tools/docs/ClassDocGenerator.cs @@ -91,6 +91,7 @@ namespace Rokojori.DocGenerator info.modificationTime = FilesSync.GetModificationTimeStamp( filePath ); info.name = typeName; info.csNameSpace = typeNameSpace; + info.isCSOnly = true; info.definitionType = definitionType; info.sourcePath = filePath.SubstringAfterMatching( "addons/rokojori_action_library/"); @@ -140,7 +141,41 @@ namespace Rokojori.DocGenerator info.icon = GetIcon( data, info.name, info.extendingClasses, icons ); - var constructors = Lists.ToList( classType.GetConstructors( allBindings ) ); + + + + fields.ForEach( + ( f )=> + { + if ( f.Name == "value__" ) + { + return; + } + var memberInfo = MemberInfo.CreateField(); + + memberInfo.name = f.Name; + + + memberInfo.csNameSpace = f.FieldType.Namespace; + memberInfo.dataType = GetDocsType.Of( f.FieldType ); + memberInfo.generics = Lists.Map( f.FieldType.GetGenericArguments(), t => t + "" ); + memberInfo.doc = comments.FindDoc( "field", f.Name ); + memberInfo.attributes = GetExports( f ); + + if ( f.IsStatic ) + { + memberInfo.modifiers.Add( "static" ); + } + + memberInfo.modifiers.Add( f.IsPublic ? "public" : "protected" ); + + info.memberInfos.Add( memberInfo ); + + } + ); + + + var constructors = Lists.ToList( classType.GetConstructors( allBindings ) ); constructors = Lists.Filter( constructors, m => ! m.IsPrivate ); constructors.ForEach( @@ -177,39 +212,7 @@ namespace Rokojori.DocGenerator ); - - - fields.ForEach( - ( f )=> - { - if ( f.Name == "value__" ) - { - return; - } - var memberInfo = MemberInfo.CreateField(); - - memberInfo.name = f.Name; - - - memberInfo.csNameSpace = f.FieldType.Namespace; - memberInfo.dataType = GetDocsType.Of( f.FieldType ); - memberInfo.generics = Lists.Map( f.FieldType.GetGenericArguments(), t => t + "" ); - memberInfo.doc = comments.FindDoc( "field", f.Name ); - memberInfo.attributes = GetExports( f ); - - if ( f.IsStatic ) - { - memberInfo.modifiers.Add( "static" ); - } - - memberInfo.modifiers.Add( f.IsPublic ? "public" : "protected" ); - - info.memberInfos.Add( memberInfo ); - - } - ); - - + var methods = Lists.ToList( classType.GetMethods( allBindings ) ); methods = Lists.Filter( methods, m => ! m.IsPrivate ); diff --git a/Tools/docs/ClassDocInfo.cs b/Tools/docs/ClassDocInfo.cs index 788de05..8ed86f6 100644 --- a/Tools/docs/ClassDocInfo.cs +++ b/Tools/docs/ClassDocInfo.cs @@ -25,16 +25,22 @@ namespace Rokojori.DocGenerator public List attributes = new List(); public int lineIndex; public int lineOffset; + public List modifiers = new List(); public List generics; public List parameters = new List(); + public string value; + + // memberType public static readonly string Field = "Field"; public static readonly string Method = "Method"; public static readonly string Constructor = "Constructor"; + public static readonly string Signal = "Signal"; public static readonly string Uniform = "Uniform"; public static readonly string Varying = "Varying"; + public static MemberInfo Create( string memberType ) { @@ -72,8 +78,10 @@ namespace Rokojori.DocGenerator public class ClassDocInfo { public string csNameSpace = ""; + public bool isCSOnly = true; public string name =""; public string doc; + public string docMode; public string icon; public string sourcePath; public string definitionType; diff --git a/Tools/docs/CreateDoc.cs b/Tools/docs/CreateDoc.cs index cde5223..4d83eab 100644 --- a/Tools/docs/CreateDoc.cs +++ b/Tools/docs/CreateDoc.cs @@ -3,27 +3,10 @@ using Godot; using System.Collections.Generic; using System; +using Rokojori.Tools; namespace Rokojori.DocGenerator { - public class SomeArrayClass - { - public int index = 2; - public string value = "Hello World"; - } - - public class SomeClass - { - public float x = 0; - public float GetX() - { - return x * 2; - } - - public List values = new List(); - - } - [GlobalClass][Tool] public partial class CreateDoc : Node { @@ -46,22 +29,9 @@ namespace Rokojori.DocGenerator public int hoursCheckTime = 12; [ExportToolButton( "Create")] - public Callable createButton => Callable.From( ()=>{ Generate(); } ); + public Callable createButton => Callable.From( ()=>{ Create(); } ); - void Test() - { - var obj = new SomeClass(); - var sa = new SomeArrayClass(); - var sb = new SomeArrayClass(); - sb.value = "Huhu"; - obj.values.Add( sa ); - obj.values.Add( sb ); - - var testJSON = JSON.StringifyObject( obj ); - RJLog.Log( testJSON ); - } - - void Generate() + void Create() { var absoluteLibraryPath = ProjectSettings.GlobalizePath( "res://addons/rokojori_action_library/Runtime" ); @@ -82,5 +52,103 @@ namespace Rokojori.DocGenerator var icons = Lists.Map( FilesSync.GetFiles( absoluteIconPath, ( fp => fp.fileExtension == ".svg" ) ), fp => fp.fullFileName ); generator.Generate( absoluteLibraryPath, absoluteOutputPath, icons ); } + + + [Export(PropertyHint.Dir)] + public string externalDocsPath; + + [ExportToolButton( "Intergrate External")] + public Callable integrateExternalButton => Callable.From( ()=>{ IntegrateExtarnel(); } ); + + void IntegrateExtarnel() + { + + var absoluteLibraryPath = ProjectSettings.GlobalizePath( "res://addons/rokojori_action_library/Runtime" ); + var absoluteExternalPath = ProjectSettings.GlobalizePath( externalDocsPath ); + + var libraryFilePath = FilePath.Absolute( absoluteLibraryPath ); + var externalPath = FilePath.Absolute( absoluteExternalPath ); + + var externalDocFiles = FilesSync.GetFilesRecursive( absoluteExternalPath, + + ( fp )=> + { + return fp.HasFileExtension( "json" ); + } + + ); + + var codeFiles = FilesSync.GetFilesRecursive( absoluteLibraryPath, + + ( fp )=> + { + return fp.HasFileExtension( "cs" ); + } + + ); + + var namesMap = codeFiles.ToMap( cf => cf.fullFileName ); + + var missing = new List(); + var mapped = new Dictionary(); + var found = new List(); + var csToDocs = new Dictionary(); + + externalDocFiles.ForEach( + ( docFile )=> + { + var relativeFilePath = externalPath.MakeRelative( docFile ); + var relativePath = docFile.path.ReplaceEnd( ".json" ); + + var libPath = libraryFilePath.MakeRelative( relativePath ); + + if ( ! libPath.Exists() ) + { + var name = libPath.fullFileName; + + if ( namesMap.ContainsKey( name ) ) + { + // this.LogInfo( "Remapping:", relativePath, "using:", namesMap[ name ].path ); + mapped[ docFile ] = namesMap[ name ]; + } + else + { + this.LogInfo( "Could not find:", relativePath ); + missing.Add( docFile ); + } + + } + else + { + found.Add( libPath ); + csToDocs[ libPath ] = docFile; + } + } + ); + + // if ( missing.Count == 0 ) + // { + // this.LogInfo( "All good" ); + // return; + // } + + + if ( found.Count == 0 ) + { + return; + } + + var editor = new ClassDocEditor(); + var source = found[ 0 ].LoadUTF8(); + editor.originalTokens = LexerList.Create( CSharpLexer.Lex( source ), LexerMatcherLibrary.Ignore ); + var objects = CSharpLexer.GetAllObjectDefinitions( editor.originalTokens.events ); + var classObject = objects.Find( obj => obj.type.Is( LexerMatcherLibrary.ClassMatcher ) ); + editor.source = source; + + var doc = csToDocs[ found[ 0 ] ].LoadJSON(); + editor.Process( classObject, doc ); + + // this.LogInfo( editing ); + } } } \ No newline at end of file diff --git a/Tools/docs/DocGenerator.cs b/Tools/docs/DocGenerator.cs index faf5feb..a25f54b 100644 --- a/Tools/docs/DocGenerator.cs +++ b/Tools/docs/DocGenerator.cs @@ -126,8 +126,8 @@ namespace Rokojori.DocGenerator for ( int i = 0; i < definitions.Count; i++ ) { var sequence = definitions[ i ]; - var definitionType = sequence[ 0 ]; - var definitionName = sequence[ 1 ]; + var definitionType = sequence.type; + var definitionName = sequence.name; // RJLog.Log( "Adding definition:", definitionName.match ); AddCSharpsClassType( cf, definitionName.match, definitionType.match, namespaceLabel, assembly ); diff --git a/Tools/docs/OnlineDocJSON.cs b/Tools/docs/OnlineDocJSON.cs new file mode 100644 index 0000000..20b2443 --- /dev/null +++ b/Tools/docs/OnlineDocJSON.cs @@ -0,0 +1,94 @@ +#if TOOLS +using Godot; +using Rokojori; +using System.Diagnostics; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Linq; + + +namespace Rokojori.Tools +{ + public enum OnlineDocsTargetType + { + Member, + Class + } + + public class OnlineDocsTarget + { + public OnlineDocsTargetType type = OnlineDocsTargetType.Member; + public string memberName; + public string memberType = null ; + public List parameters = null; + public string docTarget; + public bool isFunction = false; + public bool hasSignature => memberType != null; + + public static readonly string Delimiter = ":::"; + + public static OnlineDocsTarget From( string target ) + { + var odt = new OnlineDocsTarget(); + + if ( target.IndexOf( Delimiter ) == -1 ) + { + // RJLog.Log( "No delimiter:", target ); + odt.type = OnlineDocsTargetType.Class; + odt.docTarget = target; + return odt; + } + + var splits = target.Split( Delimiter ); + + // RJLog.Log( "Splitting:", target, ">>", "'" + splits.Join( "','" ) + "'" ); + + odt.docTarget = splits[ 1 ]; + + var memberTarget = splits[ 0 ]; + + var typeIndex = memberTarget.IndexOf( ":" ); + + if ( typeIndex != -1 ) + { + odt.memberType = memberTarget.Substring( typeIndex + 1 ); + } + + var bracketIndex = memberTarget.IndexOf( "(" ); + + if ( bracketIndex != -1 ) + { + odt.isFunction = true; + var closingIndex = memberTarget.IndexOf( ")", bracketIndex + 1 ); + odt.parameters = memberTarget.Substring( bracketIndex + 1, closingIndex ).Split( "," ).ToList(); + } + + var nameEndIndex = typeIndex != -1 ? typeIndex : + bracketIndex != -1 ? bracketIndex : memberTarget.Count(); + + odt.memberName = memberTarget.Substring( 0, nameEndIndex ); + + return odt; + } + + } + + public class OnlineDocJSONDocEntry + { + public string content; + public string target; + } + + public class OnlineDocJSON + { + public string key = ""; + public string sourcePath = ""; + + public List content = []; + + public ISOTimeStamp changeDate; + public string version; + } +} + +#endif \ No newline at end of file diff --git a/Tools/docs/OnlineDocJSON.cs.uid b/Tools/docs/OnlineDocJSON.cs.uid new file mode 100644 index 0000000..de83098 --- /dev/null +++ b/Tools/docs/OnlineDocJSON.cs.uid @@ -0,0 +1 @@ +uid://c8t6fm027suvq