diff --git a/.editorconfig b/.editorconfig index 1909f880..97af5d1d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -244,7 +244,7 @@ dotnet_style_qualification_for_method = false:error dotnet_style_qualification_for_property = false:error dotnet_style_readonly_field = true:error -dotnet_style_require_accessibility_modifiers = always:error +dotnet_style_require_accessibility_modifiers = for_non_interface_members:error ############################################################################### # Set dotnet style options to: diff --git a/global.json b/global.json index 61d88a71..ff239fd9 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "10.0.100-preview", "allowPrerelease": true, "rollForward": "latestFeature" } diff --git a/scripts/build.ps1 b/scripts/build.ps1 index 882eba52..51865694 100644 --- a/scripts/build.ps1 +++ b/scripts/build.ps1 @@ -172,7 +172,7 @@ try { $DotNetInstallDirectory = Join-Path -Path $ArtifactsDir -ChildPath "dotnet" Create-Directory -Path $DotNetInstallDirectory - & $DotNetInstallScript -Channel 8.0 -Version latest -InstallDir $DotNetInstallDirectory -Architecture $architecture + & $DotNetInstallScript -Channel 10.0 -Version latest -InstallDir $DotNetInstallDirectory -Architecture $architecture $env:PATH="$DotNetInstallDirectory;$env:PATH" } diff --git a/scripts/build.sh b/scripts/build.sh index c435695f..7429bd46 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -204,7 +204,7 @@ if [[ ! -z "$architecture" ]]; then DotNetInstallDirectory="$ArtifactsDir/dotnet" CreateDirectory "$DotNetInstallDirectory" - . "$DotNetInstallScript" --channel 8.0 --version latest --install-dir "$DotNetInstallDirectory" --architecture "$architecture" + . "$DotNetInstallScript" --channel 10.0 --version latest --install-dir "$DotNetInstallDirectory" --architecture "$architecture" PATH="$DotNetInstallDirectory:$PATH:" fi diff --git a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj index 0e1fe8a1..dd01281b 100644 --- a/sources/ClangSharp.Interop/ClangSharp.Interop.csproj +++ b/sources/ClangSharp.Interop/ClangSharp.Interop.csproj @@ -2,7 +2,7 @@ - net8.0 + net10.0 diff --git a/sources/ClangSharp.Interop/Extensions/CXCursor.cs b/sources/ClangSharp.Interop/Extensions/CXCursor.cs index e767d1e1..0cccb0b3 100644 --- a/sources/ClangSharp.Interop/Extensions/CXCursor.cs +++ b/sources/ClangSharp.Interop/Extensions/CXCursor.cs @@ -37,7 +37,7 @@ public readonly string AttrKindSpelling Debug.Assert(CX_AttrKind_FirstTypeAttr == CX_AttrKind_AddressSpace); Debug.Assert(CX_AttrKind_LastTypeAttr == CX_AttrKind_WebAssemblyFuncref); - Debug.Assert(CX_AttrKind_FirstStmtAttr == CX_AttrKind_CodeAlign); + Debug.Assert(CX_AttrKind_FirstStmtAttr == CX_AttrKind_CXXAssume); Debug.Assert(CX_AttrKind_LastStmtAttr == CX_AttrKind_Unlikely); Debug.Assert(CX_AttrKind_FirstDeclOrStmtAttr == CX_AttrKind_AlwaysInline); @@ -49,14 +49,14 @@ public readonly string AttrKindSpelling Debug.Assert(CX_AttrKind_FirstDeclOrTypeAttr == CX_AttrKind_AArch64SVEPcs); Debug.Assert(CX_AttrKind_LastDeclOrTypeAttr == CX_AttrKind_VectorCall); - Debug.Assert(CX_AttrKind_FirstInheritableParamAttr == CX_AttrKind_SwiftAsyncContext); + Debug.Assert(CX_AttrKind_FirstInheritableParamAttr == CX_AttrKind_Annotate); Debug.Assert(CX_AttrKind_LastInheritableParamAttr == CX_AttrKind_UseHandle); - Debug.Assert(CX_AttrKind_FirstParameterABIAttr == CX_AttrKind_SwiftAsyncContext); + Debug.Assert(CX_AttrKind_FirstParameterABIAttr == CX_AttrKind_HLSLParamModifier); Debug.Assert(CX_AttrKind_LastParameterABIAttr == CX_AttrKind_SwiftIndirectResult); - Debug.Assert(CX_AttrKind_FirstHLSLAnnotationAttr == CX_AttrKind_HLSLSV_DispatchThreadID); - Debug.Assert(CX_AttrKind_LastHLSLAnnotationAttr == CX_AttrKind_HLSLSV_GroupIndex); + Debug.Assert(CX_AttrKind_FirstHLSLAnnotationAttr == CX_AttrKind_HLSLPackOffset); + Debug.Assert(CX_AttrKind_LastHLSLAnnotationAttr == CX_AttrKind_HLSLSV_GroupThreadID); return AttrKind switch { CX_AttrKind_Invalid => "Invalid", @@ -1353,7 +1353,7 @@ public readonly string StmtClassSpelling Debug.Assert(CX_StmtClass_LastSwitchCase == CX_StmtClass_CaseStmt); Debug.Assert(CX_StmtClass_FirstOMPLoopTransformationDirective == CX_StmtClass_OMPUnrollDirective); - Debug.Assert(CX_StmtClass_LastOMPLoopTransformationDirective == CX_StmtClass_OMPTileDirective); + Debug.Assert(CX_StmtClass_LastOMPLoopTransformationDirective == CX_StmtClass_OMPInterchangeDirective); Debug.Assert(CX_StmtClass_FirstOMPLoopDirective == CX_StmtClass_OMPTeamsGenericLoopDirective); Debug.Assert(CX_StmtClass_LastOMPLoopDirective == CX_StmtClass_OMPDistributeDirective); @@ -1362,7 +1362,7 @@ public readonly string StmtClassSpelling Debug.Assert(CX_StmtClass_LastOMPLoopBasedDirective == CX_StmtClass_OMPDistributeDirective); Debug.Assert(CX_StmtClass_FirstOMPExecutableDirective == CX_StmtClass_OMPTeamsDirective); - Debug.Assert(CX_StmtClass_LastOMPExecutableDirective == CX_StmtClass_OMPAtomicDirective); + Debug.Assert(CX_StmtClass_LastOMPExecutableDirective == CX_StmtClass_OMPAssumeDirective); Debug.Assert(CX_StmtClass_FirstAsmStmt == CX_StmtClass_MSAsmStmt); Debug.Assert(CX_StmtClass_LastAsmStmt == CX_StmtClass_GCCAsmStmt); diff --git a/sources/ClangSharp.Interop/Extensions/CXUnsavedFile.cs b/sources/ClangSharp.Interop/Extensions/CXUnsavedFile.cs index 3f61354a..cf2bce27 100644 --- a/sources/ClangSharp.Interop/Extensions/CXUnsavedFile.cs +++ b/sources/ClangSharp.Interop/Extensions/CXUnsavedFile.cs @@ -46,6 +46,41 @@ public static CXUnsavedFile Create(string filename, string contents) }; } + public static CXUnsavedFile Create(string filename, CXTranslationUnit translationUnit, CXFile baseFile, string additionalContents) + { + sbyte* pFilename, pContents; + nuint contentsLength; + + if (string.IsNullOrEmpty(filename)) + { + pFilename = null; + } + else + { + var maxFilenameLength = Encoding.UTF8.GetMaxByteCount(filename.Length); + pFilename = (sbyte*)NativeMemory.Alloc((uint)maxFilenameLength + 1); + var filenameLength = (uint)Encoding.UTF8.GetBytes(filename, new Span(pFilename, maxFilenameLength)); + pFilename[filenameLength] = 0; + } + + var baseFileContents = translationUnit.GetFileContents(baseFile, out _); + var maxContentsLength = baseFileContents.Length + Encoding.UTF8.GetMaxByteCount((additionalContents?.Length).GetValueOrDefault()); + + pContents = (sbyte*)NativeMemory.Alloc((uint)maxContentsLength + 1); + + var contents = new Span(pContents, maxContentsLength); + baseFileContents.CopyTo(contents); + + contentsLength = (uint)(baseFileContents.Length + Encoding.UTF8.GetBytes(additionalContents, contents[baseFileContents.Length..])); + pContents[contentsLength] = 0; + + return new CXUnsavedFile() { + Filename = pFilename, + Contents = pContents, + Length = contentsLength + }; + } + public void Dispose() { if (Filename != null) diff --git a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs index 30b8ccc1..7c6c232d 100644 --- a/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs +++ b/sources/ClangSharp.PInvokeGenerator/CSharp/CSharpOutputBuilder.cs @@ -18,8 +18,8 @@ internal sealed partial class CSharpOutputBuilder(string name, PInvokeGenerator private readonly PInvokeGenerator _generator = generator; private readonly List _contents = []; private readonly StringBuilder _currentLine = new StringBuilder(); - private readonly SortedSet _usingDirectives = []; - private readonly SortedSet _staticUsingDirectives = []; + private readonly SortedSet _usingDirectives = new SortedSet(StringComparer.Ordinal); + private readonly SortedSet _staticUsingDirectives = new SortedSet(StringComparer.Ordinal); private readonly string _indentationString = indentationString; private readonly bool _isTestOutput = isTestOutput; @@ -80,6 +80,8 @@ public void WriteBlockEnd() public void Write(T value) => _ = _currentLine.Append(value); + public void Write(ReadOnlySpan value) => _ = _currentLine.Append(value); + public void WriteIndentation() { WriteNewlineIfNeeded(); diff --git a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj index a8c82d4a..bfdcb5f6 100644 --- a/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj +++ b/sources/ClangSharp.PInvokeGenerator/ClangSharp.PInvokeGenerator.csproj @@ -3,7 +3,7 @@ ClangSharp - net8.0 + net10.0 diff --git a/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs b/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs index 5aa2100f..de4693e7 100644 --- a/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs +++ b/sources/ClangSharp.PInvokeGenerator/OutputBuilderFactory.cs @@ -12,7 +12,7 @@ namespace ClangSharp; internal sealed class OutputBuilderFactory(PInvokeGenerator generator) { private readonly bool _writeSourceLocation = generator.Config.GenerateSourceLocationAttribute; - private readonly Dictionary _outputBuilders = []; + private readonly Dictionary _outputBuilders = new Dictionary(StringComparer.Ordinal); public IEnumerable OutputBuilders => _outputBuilders.Values; diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 1a874965..01532b6c 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -627,7 +627,7 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) } }, CustomAttrGeneratorData = (functionDecl, _outputBuilder, this), - ParameterTypes = overloadCount > 1 ? functionDecl.Parameters.Select(param => GetTargetTypeName(param, out var _)).ToArray() : null, + ParameterTypes = overloadCount > 1 ? [.. functionDecl.Parameters.Select(param => GetTargetTypeName(param, out var _))] : null, }; Debug.Assert(_outputBuilder is not null); @@ -1116,7 +1116,7 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl) if (arraySize == 1) { - if (TryGetRemappedValue(indirectFieldDecl, _config.WithLengths, out var length)) + if (TryGetRemappedValue(indirectFieldDecl, _config._withLengths, out var length)) { code.Write(length); } @@ -1510,7 +1510,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) baseTypeNames = [.. baseTypeNamesBuilder]; } - if (!TryGetRemappedValue(recordDecl, _config.WithPackings, out var pack)) + if (!TryGetRemappedValue(recordDecl, _config._withPackings, out var pack)) { pack = alignment < maxAlignm ? alignment.ToString(CultureInfo.InvariantCulture) : null; } @@ -1558,7 +1558,7 @@ private void VisitRecordDecl(RecordDecl recordDecl) if (!_topLevelClassUsings.TryGetValue(name, out var withUsings)) { - withUsings = []; + withUsings = new HashSet(StringComparer.Ordinal); } if (desc.LayoutAttribute is not null) @@ -3311,7 +3311,7 @@ void ForUnderlyingType(TypedefDecl typedefDecl, Type underlyingType, bool onlyHa { if (!_allValidNameRemappings.TryGetValue(underlyingName, out var allRemappings)) { - allRemappings = []; + allRemappings = new HashSet(QualifiedNameComparer.Default); _allValidNameRemappings[underlyingName] = allRemappings; } _ = allRemappings.Add(typedefName); @@ -3321,7 +3321,7 @@ void ForUnderlyingType(TypedefDecl typedefDecl, Type underlyingType, bool onlyHa { if (!_traversedValidNameRemappings.TryGetValue(underlyingName, out var traversedRemappings)) { - traversedRemappings = []; + traversedRemappings = new HashSet(QualifiedNameComparer.Default); _traversedValidNameRemappings[underlyingName] = traversedRemappings; } _ = traversedRemappings.Add(typedefName); diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index 56f2a0e1..e5334899 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -804,7 +804,7 @@ private void VisitCXXOperatorCallExpr(CXXOperatorCallExpr cxxOperatorCallExpr) { Visit(args[0]); outputBuilder.Write(' '); - outputBuilder.Write(functionDeclName[8..]); + outputBuilder.Write(functionDeclName.AsSpan()[8..]); outputBuilder.Write(' '); Visit(args[1]); StopCSharpCode(); @@ -813,7 +813,7 @@ private void VisitCXXOperatorCallExpr(CXXOperatorCallExpr cxxOperatorCallExpr) case "operator~": { - outputBuilder.Write(functionDeclName[8..]); + outputBuilder.Write(functionDeclName.AsSpan()[8..]); Visit(args[0]); StopCSharpCode(); return; @@ -1161,7 +1161,7 @@ private void VisitFloatingLiteral(FloatingLiteral floatingLiteral) var outputBuilder = StartCSharpCode(); if (floatingLiteral.ValueString.EndsWith(".f", StringComparison.Ordinal)) { - outputBuilder.Write(floatingLiteral.ValueString[0..^1]); + outputBuilder.Write(floatingLiteral.ValueString.AsSpan()[..^1]); outputBuilder.Write("0f"); } else @@ -1954,67 +1954,76 @@ void HandleUnmanagedConstant(CSharpOutputBuilder outputBuilder, InitListExpr ini private void VisitIntegerLiteral(IntegerLiteral integerLiteral) { - var valueString = integerLiteral.ValueString; + var valueString = integerLiteral.ValueString.AsSpan(); + var valueSuffix = ""; if (valueString.EndsWith("ui8", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^3]; + valueString = valueString[..^3]; } else if (valueString.EndsWith("i8", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^2]; + valueString = valueString[..^2]; } else if (valueString.EndsWith("ui16", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^4]; + valueString = valueString[..^4]; } else if (valueString.EndsWith("i16", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^3]; + valueString = valueString[..^3]; } else if (valueString.EndsWith("ui32", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^4] + "U"; + valueString = valueString[..^4]; + valueSuffix = "U"; } else if (valueString.EndsWith("i32", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^3]; + valueString = valueString[..^3]; } else if (valueString.EndsWith("ui64", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^4] + "UL"; + valueString = valueString[..^4]; + valueSuffix = "UL"; } else if (valueString.EndsWith("i64", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^3] + "L"; + valueString = valueString[..^3]; + valueSuffix = "L"; } else if ( valueString.EndsWith("ull", StringComparison.OrdinalIgnoreCase) || valueString.EndsWith("llu", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^3] + "UL"; + valueString = valueString[..^3]; + valueSuffix = "UL"; } else if (valueString.EndsWith("ll", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^2] + "L"; + valueString = valueString[..^2]; + valueSuffix = "L"; } else if ( valueString.EndsWith("ul", StringComparison.OrdinalIgnoreCase) || valueString.EndsWith("lu", StringComparison.OrdinalIgnoreCase)) { - valueString = valueString[0..^2] + "U"; + valueString = valueString[..^2]; + valueSuffix = "U"; } else if (valueString.EndsWith('u') || valueString.EndsWith('U')) { - valueString = valueString[0..^1] + "U"; + valueString = valueString[..^1]; + valueSuffix = "U"; } else if (valueString.EndsWith('l') || valueString.EndsWith('L')) { - valueString = valueString[0..^1]; + valueString = valueString[..^1]; } var outputBuilder = StartCSharpCode(); outputBuilder.Write(valueString); + outputBuilder.Write(valueSuffix); StopCSharpCode(); } @@ -2997,12 +3006,12 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT { if ((parentType.Handle.SizeOf == 8) && IsPrevContextDecl(out var varDecl, out _)) { - var cursorName = GetCursorName(varDecl); + var cursorName = GetCursorName(varDecl).AsSpan(); if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { cursorName = cursorName["ClangSharpMacro_".Length..]; - parentTypeIsVariableSized |= _config.WithTypes.TryGetValue(cursorName, out var remappedTypeName) && (remappedTypeName.Equals("int", StringComparison.Ordinal) || remappedTypeName.Equals("uint", StringComparison.Ordinal)); + parentTypeIsVariableSized |= _config._withTypes.GetAlternateLookup>().TryGetValue(cursorName, out var remappedTypeName) && (remappedTypeName.Equals("int", StringComparison.Ordinal) || remappedTypeName.Equals("uint", StringComparison.Ordinal)); } } diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index ed878237..d81ab249 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -7,6 +7,7 @@ using System.Globalization; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; @@ -15,17 +16,17 @@ using ClangSharp.Interop; using ClangSharp.XML; using static ClangSharp.Interop.CX_AttrKind; -using static ClangSharp.Interop.CXBinaryOperatorKind; using static ClangSharp.Interop.CX_CXXAccessSpecifier; using static ClangSharp.Interop.CX_StmtClass; using static ClangSharp.Interop.CX_UnaryExprOrTypeTrait; -using static ClangSharp.Interop.CXUnaryOperatorKind; +using static ClangSharp.Interop.CXBinaryOperatorKind; using static ClangSharp.Interop.CXCallingConv; using static ClangSharp.Interop.CXDiagnosticSeverity; using static ClangSharp.Interop.CXEvalResultKind; using static ClangSharp.Interop.CXTemplateArgumentKind; using static ClangSharp.Interop.CXTranslationUnit_Flags; using static ClangSharp.Interop.CXTypeKind; +using static ClangSharp.Interop.CXUnaryOperatorKind; namespace ClangSharp; @@ -61,6 +62,7 @@ public sealed partial class PInvokeGenerator : IDisposable private readonly Dictionary _topLevelClassIsUnsafe; private readonly Dictionary> _topLevelClassUsings; private readonly Dictionary> _topLevelClassAttributes; + private readonly Dictionary _fileContents; private readonly HashSet _topLevelClassNames; private readonly HashSet _usedRemappings; private readonly string _placeholderMacroType; @@ -136,30 +138,31 @@ public PInvokeGenerator(PInvokeGeneratorConfiguration config, Func(StringComparer.Ordinal); _diagnostics = []; _context = new LinkedList<(Cursor, object?)>(); - _uuidsToGenerate = []; - _generatedUuids = []; + _uuidsToGenerate = new Dictionary(StringComparer.Ordinal); + _generatedUuids = new HashSet(StringComparer.Ordinal); _cursorNames = []; _cursorQualifiedNames = []; _typeNames = []; - _allValidNameRemappings = new Dictionary>() { + _allValidNameRemappings = new Dictionary>(QualifiedNameComparer.Default) { ["intptr_t"] = ["IntPtr", "nint"], ["ptrdiff_t"] = ["IntPtr", "nint"], ["size_t"] = ["UIntPtr", "nuint"], ["uintptr_t"] = ["UIntPtr", "nuint"], ["_GUID"] = ["Guid"], }; - _traversedValidNameRemappings = []; + _traversedValidNameRemappings = new Dictionary>(StringComparer.Ordinal); _overloadIndices = []; _isExcluded = []; - _topLevelClassHasGuidMember = []; - _topLevelClassIsUnsafe = []; - _topLevelClassNames = []; - _topLevelClassAttributes = []; - _topLevelClassUsings = []; - _usedRemappings = []; + _topLevelClassHasGuidMember = new Dictionary(StringComparer.Ordinal); + _topLevelClassIsUnsafe = new Dictionary(StringComparer.Ordinal); + _topLevelClassNames = new HashSet(StringComparer.Ordinal); + _topLevelClassAttributes = new Dictionary>(StringComparer.Ordinal); + _fileContents = []; + _topLevelClassUsings = new Dictionary>(StringComparer.Ordinal); + _usedRemappings = new HashSet(StringComparer.Ordinal); _filePath = ""; _clangCommandLineArgs = []; _placeholderMacroType = GetPlaceholderMacroType(); @@ -212,8 +215,8 @@ public void Close() Stream? stream = null; Stream? testStream = null; - var methodClassOutputBuilders = new Dictionary(); - var methodClassTestOutputBuilders = new Dictionary(); + var methodClassOutputBuilders = new Dictionary(StringComparer.Ordinal); + var methodClassTestOutputBuilders = new Dictionary(StringComparer.Ordinal); var emitNamespaceDeclaration = true; var leaveStreamOpen = false; @@ -1697,14 +1700,8 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s { if (_config.GenerateMacroBindings) { - var translationUnitHandle = translationUnit.Handle; - - var file = translationUnitHandle.GetFile(_filePath); - var fileContents = translationUnitHandle.GetFileContents(file, out var size); var fileContentsBuilder = _fileContentsBuilder; - _ = fileContentsBuilder.Append(Encoding.UTF8.GetString(fileContents)); - foreach (var cursor in translationUnit.TranslationUnitDecl.CursorChildren) { if (cursor is PreprocessedEntity preprocessedEntity) @@ -1716,7 +1713,10 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s var unsavedFileContents = fileContentsBuilder.ToString(); _ = fileContentsBuilder.Clear(); - using var unsavedFile = CXUnsavedFile.Create(_filePath, unsavedFileContents); + var translationUnitHandle = translationUnit.Handle; + var file = translationUnitHandle.GetFile(_filePath); + + using var unsavedFile = CXUnsavedFile.Create(_filePath, translationUnitHandle, file, unsavedFileContents); var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; translationFlags = _translationFlags & ~CXTranslationUnit_DetailedPreprocessingRecord; @@ -1734,53 +1734,61 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s { foreach (var kvp in _traversedValidNameRemappings) { - var name = kvp.Key; + var name = kvp.Key.AsSpan(); var remappings = kvp.Value; - if (name.Contains('<', StringComparison.OrdinalIgnoreCase)) + if (name.Contains('<')) { var parts = name.Split('<'); - if (parts.Length >= 2) + if (parts.MoveNext()) { - name = parts[0]; + var part = parts.Current; + + if (parts.MoveNext()) + { + name = name[part]; + } } } - if (!_config.RemappedNames.TryGetValue(name, out _)) + var remappedNamesLookup = _config._remappedNames.GetAlternateLookup>(); + + if (!remappedNamesLookup.TryGetValue(name, out _)) { - var addDiag = false; + var addDiag = true; - var altName = name; var smlName = name; + var lastSeparatorIndex = smlName.LastIndexOf("::", StringComparison.Ordinal); - if (name.Contains("::", StringComparison.Ordinal)) + if (lastSeparatorIndex != -1) { - altName = name.Replace("::", ".", StringComparison.Ordinal); - smlName = altName.Split('.')[^1]; + smlName = smlName[(lastSeparatorIndex + 2)..]; + addDiag = false; } - else if (name.Contains('.', StringComparison.Ordinal)) + + lastSeparatorIndex = smlName.LastIndexOf('.'); + + if (lastSeparatorIndex != -1) { - altName = name.Replace(".", "::", StringComparison.Ordinal); - smlName = altName.Split("::")[^1]; + smlName = smlName[(lastSeparatorIndex + 1)..]; + addDiag = false; } - else + + if (!addDiag && !remappedNamesLookup.TryGetValue(smlName, out _)) { addDiag = true; } - if (!addDiag && !_config.RemappedNames.TryGetValue(altName, out _)) + if (addDiag) { - if (!_config.RemappedNames.TryGetValue(smlName, out _)) + var remappingsLookup = remappings.GetAlternateLookup>(); + + if (!remappingsLookup.Contains(name) && !remappingsLookup.Contains(smlName)) { - addDiag = true; + AddDiagnostic(DiagnosticLevel.Info, $"Potential missing remapping '{name}'. {GetFoundRemappingString(name, remappings)}"); } } - - if (addDiag && !remappings.Contains(altName) && !remappings.Contains(smlName)) - { - AddDiagnostic(DiagnosticLevel.Info, $"Potential missing remapping '{name}'. {GetFoundRemappingString(name, remappings)}"); - } } } @@ -1789,34 +1797,32 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s var name = kvp.Key; var remappings = kvp.Value; - if (_config.RemappedNames.TryGetValue(name, out var remappedName) && !remappings.Contains(remappedName) && (name != remappedName) && !_config.ForceRemappedNames.Contains(name)) + var remappedNamesLookup = _config._remappedNames.GetAlternateLookup>(); + + if (remappedNamesLookup.TryGetValue(name, out var remappedName) && !remappings.Contains(remappedName) && (name != remappedName) && !_config.ForceRemappedNames.Contains(name)) { - var addDiag = false; + var addDiag = true; - var altName = name; var smlName = name; + var lastSeparatorIndex = smlName.LastIndexOf("::", StringComparison.Ordinal); - if (name.Contains("::", StringComparison.Ordinal)) - { - altName = name.Replace("::", ".", StringComparison.Ordinal); - smlName = altName.Split('.')[^1]; - } - else if (name.Contains('.', StringComparison.Ordinal)) + if (lastSeparatorIndex != -1) { - altName = name.Replace(".", "::", StringComparison.Ordinal); - smlName = altName.Split("::")[^1]; + smlName = smlName[(lastSeparatorIndex + 2)..]; + addDiag = false; } - else + + lastSeparatorIndex = smlName.LastIndexOf('.'); + + if (lastSeparatorIndex != -1) { - addDiag = true; + smlName = smlName[(lastSeparatorIndex + 1)..]; + addDiag = false; } - if (!addDiag && _config.RemappedNames.TryGetValue(altName, out remappedName) && !remappings.Contains(remappedName) && (altName != remappedName) && !_config.ForceRemappedNames.Contains(altName)) + if (!addDiag && remappedNamesLookup.TryGetValue(smlName, out remappedName) && !remappings.Contains(remappedName) && (smlName != remappedName) && !_config.ForceRemappedNames.Contains(smlName)) { - if (_config.RemappedNames.TryGetValue(smlName, out remappedName) && !remappings.Contains(remappedName) && (smlName != remappedName) && !_config.ForceRemappedNames.Contains(smlName)) - { - addDiag = true; - } + addDiag = true; } if (addDiag) @@ -1830,34 +1836,32 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s { var remappedName = _config.RemappedNames[name]; - if (!_allValidNameRemappings.ContainsKey(name) && (name != remappedName) && !_config.ForceRemappedNames.Contains(name)) + var allValidNameRemappingsLookup = _allValidNameRemappings.GetAlternateLookup>(); + + if (!allValidNameRemappingsLookup.ContainsKey(name) && (name != remappedName) && !_config.ForceRemappedNames.Contains(name)) { - var addDiag = false; + var addDiag = true; - var altName = name; var smlName = name; + var lastSeparatorIndex = smlName.LastIndexOf("::", StringComparison.Ordinal); - if (name.Contains("::", StringComparison.Ordinal)) - { - altName = name.Replace("::", ".", StringComparison.Ordinal); - smlName = altName.Split('.')[^1]; - } - else if (name.Contains('.', StringComparison.Ordinal)) + if (lastSeparatorIndex != -1) { - altName = name.Replace(".", "::", StringComparison.Ordinal); - smlName = altName.Split("::")[^1]; + smlName = smlName[(lastSeparatorIndex + 2)..]; + addDiag = false; } - else + + lastSeparatorIndex = smlName.LastIndexOf('.'); + + if (lastSeparatorIndex != -1) { - addDiag = true; + smlName = smlName[(lastSeparatorIndex + 1)..]; + addDiag = false; } - if (!addDiag && !_allValidNameRemappings.ContainsKey(altName) && (altName != remappedName) && !_config.ForceRemappedNames.Contains(altName)) + if (!addDiag && !allValidNameRemappingsLookup.ContainsKey(smlName) && (smlName != remappedName) && !_config.ForceRemappedNames.Contains(smlName)) { - if (!_allValidNameRemappings.ContainsKey(smlName) && (smlName != remappedName) && !_config.ForceRemappedNames.Contains(smlName)) - { - addDiag = true; - } + addDiag = true; } if (addDiag) @@ -1867,62 +1871,71 @@ public void GenerateBindings(TranslationUnit translationUnit, string filePath, s } } - static string GetFoundRemappingString(string name, HashSet remappings) + static ReadOnlySpan GetFoundRemappingString(ReadOnlySpan name, HashSet remappings) { - var recommendedRemapping = ""; + var recommendedRemappingString = ""; + var recommendedRemapping = recommendedRemappingString.AsSpan(); if (remappings.Count == 1) { - recommendedRemapping = remappings.Single(); + recommendedRemappingString = remappings.Single(); + recommendedRemapping = recommendedRemappingString; } - if (string.IsNullOrEmpty(recommendedRemapping) && name.StartsWith('_')) + var remappingsLookup = remappings.GetAlternateLookup>(); + + if (recommendedRemapping.IsWhiteSpace() && name.StartsWith('_')) { var remapping = name[1..]; - if (remappings.Contains(remapping)) + if (remappingsLookup.Contains(remapping)) { recommendedRemapping = remapping; + recommendedRemappingString = null; } } - if (string.IsNullOrEmpty(recommendedRemapping) && name.StartsWith("tag", StringComparison.Ordinal)) + if (recommendedRemapping.IsWhiteSpace() && name.StartsWith("tag", StringComparison.Ordinal)) { var remapping = name[3..]; - if (remappings.Contains(remapping)) + if (remappingsLookup.Contains(remapping)) { recommendedRemapping = remapping; + recommendedRemappingString = null; } } - if (string.IsNullOrEmpty(recommendedRemapping) && name.EndsWith('_')) + if (recommendedRemapping.IsWhiteSpace() && name.EndsWith('_')) { - var remapping = name[0..^1]; + var remapping = name[..^1]; - if (remappings.Contains(remapping)) + if (remappingsLookup.Contains(remapping)) { recommendedRemapping = remapping; + recommendedRemappingString = null; } } - if (string.IsNullOrEmpty(recommendedRemapping) && name.EndsWith("tag", StringComparison.Ordinal)) + if (recommendedRemapping.IsWhiteSpace() && name.EndsWith("tag", StringComparison.Ordinal)) { - var remapping = name[0..^3]; + var remapping = name[..^3]; - if (remappings.Contains(remapping)) + if (remappingsLookup.Contains(remapping)) { recommendedRemapping = remapping; + recommendedRemappingString = null; } } - if (string.IsNullOrEmpty(recommendedRemapping)) + if (recommendedRemapping.IsWhiteSpace()) { - var remapping = name.ToUpperInvariant(); + var remapping = name.ToString().ToUpperInvariant(); - if (remappings.Contains(remapping)) + if (remappingsLookup.Contains(remapping)) { - recommendedRemapping = remapping; + recommendedRemappingString = remapping; + recommendedRemapping = recommendedRemappingString; } } @@ -1930,7 +1943,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) var remainingRemappings = (IEnumerable)remappings; var remainingString = "Found"; - if (!string.IsNullOrEmpty(recommendedRemapping)) + if (!recommendedRemapping.IsWhiteSpace()) { result += $"Recommended remapping: '{name}={recommendedRemapping}'."; @@ -1941,7 +1954,7 @@ static string GetFoundRemappingString(string name, HashSet remappings) else { result += ' '; - remainingRemappings = remappings.Except([recommendedRemapping]); + remainingRemappings = remappings.Except([recommendedRemappingString ?? recommendedRemapping.ToString()]); remainingString = "Other"; } } @@ -2036,9 +2049,9 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo if (isMethodClass) { - var nonTestName = outputBuilder.IsTestOutput ? outputBuilder.Name[0..^5] : outputBuilder.Name; + var nonTestName = outputBuilder.IsTestOutput ? outputBuilder.Name.AsSpan()[..^5] : outputBuilder.Name; - if (_topLevelClassUsings.TryGetValue(nonTestName, out var withUsings)) + if (_topLevelClassUsings.GetAlternateLookup>().TryGetValue(nonTestName, out var withUsings)) { foreach (var withUsing in withUsings) { @@ -2101,17 +2114,17 @@ private void CloseOutputBuilder(Stream stream, IOutputBuilder outputBuilder, boo } } - void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) + void ForCSharp(CSharpOutputBuilder outputBuilder) { - var indentationString = csharpOutputBuilder.IndentationString; - var nonTestName = outputBuilder.IsTestOutput ? outputBuilder.Name[0..^5] : outputBuilder.Name; + var indentationString = outputBuilder.IndentationString; + var nonTestName = outputBuilder.IsTestOutput ? outputBuilder.Name.AsSpan()[..^5] : outputBuilder.Name; if (emitNamespaceDeclaration) { sw.Write("namespace "); sw.Write(GetNamespace(nonTestName)); - if (csharpOutputBuilder.IsTestOutput) + if (outputBuilder.IsTestOutput) { sw.Write(".UnitTests"); } @@ -2135,7 +2148,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) if (isMethodClass) { - var isTopLevelStruct = _config.WithTypes.TryGetValue(nonTestName, out var withType) && withType.Equals("struct", StringComparison.Ordinal); + var isTopLevelStruct = _config._withTypes.GetAlternateLookup>().TryGetValue(nonTestName, out var withType) && withType.Equals("struct", StringComparison.Ordinal); if (outputBuilder.IsTestOutput) { @@ -2156,7 +2169,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) sw.WriteLine("."); } - if (_topLevelClassAttributes.TryGetValue(nonTestName, out var withAttributes)) + if (_topLevelClassAttributes.GetAlternateLookup>().TryGetValue(nonTestName, out var withAttributes)) { if (withAttributes.Count != 0) { @@ -2184,7 +2197,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) sw.Write("static "); } - if ((_topLevelClassIsUnsafe.TryGetValue(nonTestName, out var isUnsafe) && isUnsafe) || (outputBuilder.IsTestOutput && isTopLevelStruct)) + if ((_topLevelClassIsUnsafe.GetAlternateLookup>().TryGetValue(nonTestName, out var isUnsafe) && isUnsafe) || (outputBuilder.IsTestOutput && isTopLevelStruct)) { sw.Write("unsafe "); } @@ -2211,15 +2224,15 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) sw.Write(indentationString); sw.Write('{'); - if ((!outputBuilder.IsTestOutput && !isTopLevelStruct) || !string.IsNullOrEmpty(csharpOutputBuilder.Contents.First())) + if ((!outputBuilder.IsTestOutput && !isTopLevelStruct) || !string.IsNullOrEmpty(outputBuilder.Contents.First())) { sw.WriteLine(); } - indentationString += csharpOutputBuilder.IndentationString; + indentationString += outputBuilder.IndentationString; } - foreach (var line in csharpOutputBuilder.Contents) + foreach (var line in outputBuilder.Contents) { if (string.IsNullOrWhiteSpace(line)) { @@ -2234,7 +2247,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) if (isMethodClass) { - indentationString = indentationString[..^csharpOutputBuilder.IndentationString.Length]; + indentationString = indentationString[..^outputBuilder.IndentationString.Length]; sw.Write(indentationString); sw.WriteLine('}'); @@ -2246,7 +2259,7 @@ void ForCSharp(CSharpOutputBuilder csharpOutputBuilder) } } - void ForXml(XmlOutputBuilder xmlOutputBuilder) + void ForXml(XmlOutputBuilder outputBuilder) { const string Indent = " "; var indentationString = Indent; @@ -2255,7 +2268,7 @@ void ForXml(XmlOutputBuilder xmlOutputBuilder) { sw.Write(indentationString); sw.Write(""); } @@ -2265,10 +2278,10 @@ void ForXml(XmlOutputBuilder xmlOutputBuilder) { sw.Write(indentationString); sw.Write(" value.Replace(@"\0", "\0", private AccessSpecifier GetAccessSpecifier(NamedDecl namedDecl, bool matchStar) { - if (!TryGetRemappedValue(namedDecl, _config.WithAccessSpecifiers, out var accessSpecifier, matchStar) || (accessSpecifier == AccessSpecifier.None)) + if (!TryGetRemappedValue(namedDecl, _config._withAccessSpecifiers, out var accessSpecifier, matchStar) || (accessSpecifier == AccessSpecifier.None)) { switch (namedDecl.Access) { @@ -2629,7 +2642,7 @@ private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type if (cursor is NamedDecl namedDecl) { - if (TryGetRemappedValue(namedDecl, _config.WithCallConvs, out var callConv, matchStar: true)) + if (TryGetRemappedValue(namedDecl, _config._withCallConvs, out var callConv, matchStar: true)) { if (Enum.TryParse(callConv, true, out var remappedCallingConvention)) { @@ -2773,22 +2786,26 @@ private CallConv GetCallingConvention(Cursor? cursor, Cursor? context, Type type private string GetCursorName(NamedDecl namedDecl) { - if (!_cursorNames.TryGetValue(namedDecl, out var name)) + if (!_cursorNames.TryGetValue(namedDecl, out var nameString)) { - name = namedDecl.Name.NormalizePath(); + nameString = namedDecl.Name.NormalizePath(); + var name = nameString.AsSpan(); // strip the prefix if (name.StartsWith("enum ", StringComparison.Ordinal)) { name = name[5..]; + nameString = null; } else if (name.StartsWith("struct ", StringComparison.Ordinal)) { name = name[7..]; + nameString = null; } else if (name.StartsWith("union ", StringComparison.Ordinal)) { name = name[6..]; + nameString = null; } var anonymousNameStartIndex = name.IndexOf("::(", StringComparison.Ordinal); @@ -2797,21 +2814,26 @@ private string GetCursorName(NamedDecl namedDecl) { anonymousNameStartIndex += 2; name = name[anonymousNameStartIndex..]; + nameString = null; } if (namedDecl is CXXConstructorDecl cxxConstructorDecl) { var parent = cxxConstructorDecl.Parent; Debug.Assert(parent is not null); - name = GetCursorName(parent); + + nameString = GetCursorName(parent); + name = nameString; } else if (namedDecl is CXXDestructorDecl cxxDestructorDecl) { var parent = cxxDestructorDecl.Parent; Debug.Assert(parent is not null); - name = $"~{GetCursorName(parent)}"; + + nameString = $"~{GetCursorName(parent)}"; + name = nameString; } - else if (string.IsNullOrWhiteSpace(name) || name.StartsWith('(')) + else if (name.IsWhiteSpace() || name.StartsWith('(')) { #if DEBUG if (name.StartsWith('(')) @@ -2829,17 +2851,20 @@ private string GetCursorName(NamedDecl namedDecl) if (namedDecl is TypeDecl typeDecl) { - name = (typeDecl is TagDecl tagDecl) && tagDecl.Handle.IsAnonymous - ? GetAnonymousName(tagDecl, tagDecl.TypeForDecl.KindSpelling) - : GetTypeName(namedDecl, context: null, type: typeDecl.TypeForDecl, ignoreTransparentStructsWhereRequired: false, isTemplate: false, nativeTypeName: out _); + nameString = (typeDecl is TagDecl tagDecl) && tagDecl.Handle.IsAnonymous + ? GetAnonymousName(tagDecl, tagDecl.TypeForDecl.KindSpelling) + : GetTypeName(namedDecl, context: null, type: typeDecl.TypeForDecl, ignoreTransparentStructsWhereRequired: false, isTemplate: false, nativeTypeName: out _); + name = nameString; } else if (namedDecl is ParmVarDecl) { - name = "param"; + nameString = "param"; + name = nameString; } else if (namedDecl is FieldDecl fieldDecl) { - name = GetAnonymousName(fieldDecl, fieldDecl.CursorKindSpelling); + nameString = GetAnonymousName(fieldDecl, fieldDecl.CursorKindSpelling); + name = nameString; } else { @@ -2847,11 +2872,12 @@ private string GetCursorName(NamedDecl namedDecl) } } - _cursorNames[namedDecl] = name; + nameString ??= name.ToString(); + _cursorNames[namedDecl] = nameString; } - Debug.Assert(!string.IsNullOrWhiteSpace(name)); - return name; + Debug.Assert(!string.IsNullOrWhiteSpace(nameString)); + return nameString; } private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateParameters = false) @@ -3156,15 +3182,6 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - name = name.Replace("::", ".", StringComparison.Ordinal); - remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); - - if (wasRemapped) - { - return remappedName; - } - - name = GetCursorQualifiedName(namedDecl, truncateParameters: true); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); @@ -3173,14 +3190,6 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - name = name.Replace("::", ".", StringComparison.Ordinal); - remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); - - if (wasRemapped) - { - return remappedName; - } - name = GetCursorName(namedDecl); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); @@ -3290,7 +3299,9 @@ private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperato private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperatorName, out bool wasRemapped, bool skipUsing, bool skipUsingIfNotRemapped) { - if (_config.RemappedNames.TryGetValue(name, out var remappedName)) + var remappedNamesLookup = _config._remappedNames.GetAlternateLookup>(); + + if (remappedNamesLookup.TryGetValue(name, out var remappedName)) { wasRemapped = true; _ = _usedRemappings.Add(name); @@ -3299,13 +3310,13 @@ private string GetRemappedName(string name, Cursor? cursor, bool tryRemapOperato if (name.StartsWith("const ", StringComparison.Ordinal)) { - var tmpName = name[6..]; + var tmpName = name.AsSpan()[6..]; - if (_config.RemappedNames.TryGetValue(tmpName, out remappedName)) + if (remappedNamesLookup.TryGetValue(tmpName, out remappedName)) { wasRemapped = true; - _ = _usedRemappings.Add(tmpName); + _ = _usedRemappings.Add(tmpName.ToString()); return AddUsingDirectiveIfNeeded(_outputBuilder, remappedName, skipUsing); } } @@ -3363,38 +3374,32 @@ private string GetRemappedTypeName(Cursor? cursor, Cursor? context, Type type, o if (!wasRemapped) { - nameToCheck = nameToCheck.Replace("::", ".", StringComparison.Ordinal); - remappedName = GetRemappedName(nameToCheck, cursor, tryRemapOperatorName: false, out wasRemapped, skipUsing, skipUsingIfNotRemapped: true); + nameToCheck = name; + remappedName = GetRemappedName(nameToCheck, cursor, tryRemapOperatorName: false, out wasRemapped, skipUsing); if (!wasRemapped) { - nameToCheck = name; - remappedName = GetRemappedName(nameToCheck, cursor, tryRemapOperatorName: false, out wasRemapped, skipUsing); - - if (!wasRemapped) + if (IsTypeConstantOrIncompleteArray(cursor, type, out var arrayType) && IsType(cursor, arrayType.ElementType)) { - if (IsTypeConstantOrIncompleteArray(cursor, type, out var arrayType) && IsType(cursor, arrayType.ElementType)) - { - type = arrayType.ElementType; - } + type = arrayType.ElementType; + } - if (IsType(cursor, type, out var recordType) && remappedName.StartsWith("__AnonymousRecord_", StringComparison.Ordinal)) - { - var recordDecl = recordType.Decl; - remappedName = GetRemappedNameForAnonymousRecord(recordDecl); - } - else if (IsType(cursor, type, out var enumType) && remappedName.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) - { - remappedName = GetRemappedTypeName(enumType.Decl, context: null, enumType.Decl.IntegerType, out _, skipUsing); - } - else if (cursor is EnumDecl enumDecl) - { - // Even though some types have entries with names like *_FORCE_DWORD or *_FORCE_UINT - // MSVC and Clang both still treat this as "signed" values and thus we don't want - // to specially handle it as uint, as that can break ABI handling on some platforms. + if (IsType(cursor, type, out var recordType) && remappedName.StartsWith("__AnonymousRecord_", StringComparison.Ordinal)) + { + var recordDecl = recordType.Decl; + remappedName = GetRemappedNameForAnonymousRecord(recordDecl); + } + else if (IsType(cursor, type, out var enumType) && remappedName.StartsWith("__AnonymousEnum_", StringComparison.Ordinal)) + { + remappedName = GetRemappedTypeName(enumType.Decl, context: null, enumType.Decl.IntegerType, out _, skipUsing); + } + else if (cursor is EnumDecl enumDecl) + { + // Even though some types have entries with names like *_FORCE_DWORD or *_FORCE_UINT + // MSVC and Clang both still treat this as "signed" values and thus we don't want + // to specially handle it as uint, as that can break ABI handling on some platforms. - WithType(enumDecl, ref remappedName, ref nativeTypeName); - } + WithType(enumDecl, ref remappedName, ref nativeTypeName); } } } @@ -3418,7 +3423,19 @@ private string GetRemappedTypeName(Cursor? cursor, Cursor? context, Type type, o return remappedName; } - private static string GetSourceRangeContents(CXTranslationUnit translationUnit, CXSourceRange sourceRange) + private unsafe ReadOnlySpan GetFileContents(CXTranslationUnit translationUnit, CXFile file) + { + if (!_fileContents.TryGetValue(file, out var fileContentsMetadata)) + { + var fileContents = translationUnit.GetFileContents(file, out _); + fileContentsMetadata = ((nuint)Unsafe.AsPointer(ref MemoryMarshal.GetReference(fileContents)), (uint)fileContents.Length); + _fileContents.Add(file, fileContentsMetadata); + } + + return new ReadOnlySpan((byte*)fileContentsMetadata.Address, (int)fileContentsMetadata.Length); + } + + private string GetSourceRangeContents(CXTranslationUnit translationUnit, CXSourceRange sourceRange) { sourceRange.Start.GetFileLocation(out var startFile, out _, out _, out var startOffset); sourceRange.End.GetFileLocation(out var endFile, out _, out _, out var endOffset); @@ -3428,9 +3445,9 @@ private static string GetSourceRangeContents(CXTranslationUnit translationUnit, return string.Empty; } - var fileContents = translationUnit.GetFileContents(startFile, out _); - fileContents = fileContents.Slice(unchecked((int)startOffset), unchecked((int)(endOffset - startOffset))); - return Encoding.UTF8.GetString(fileContents); + var contents = GetFileContents(translationUnit, startFile); + contents = contents.Slice(unchecked((int)startOffset), unchecked((int)(endOffset - startOffset))); + return Encoding.UTF8.GetString(contents); } private string GetTargetTypeName(Cursor cursor, out string nativeTypeName) @@ -3466,13 +3483,13 @@ private string GetTargetTypeName(Cursor cursor, out string nativeTypeName) else { var type = varDecl.Type; - var cursorName = GetCursorName(varDecl); + var cursorName = GetCursorName(varDecl).AsSpan(); if (cursorName.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { cursorName = cursorName["ClangSharpMacro_".Length..]; - if (_config.WithTypes.TryGetValue(cursorName, out targetTypeName)) + if (_config._withTypes.GetAlternateLookup>().TryGetValue(cursorName, out targetTypeName)) { return targetTypeName; } @@ -4586,7 +4603,7 @@ private void GetTypeSize(Cursor cursor, Type type, ref long alignment32, ref lon } private bool HasSuppressGCTransition(Cursor? cursor) - => (cursor is NamedDecl namedDecl) && HasRemapping(namedDecl, _config.WithSuppressGCTransitions); + => (cursor is NamedDecl namedDecl) && HasRemapping(namedDecl, _config._withSuppressGCTransitions); private bool HasBaseField(CXXRecordDecl cxxRecordDecl) { @@ -4865,9 +4882,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) } } - var dottedQualifiedName = qualifiedName.Replace("::", ".", StringComparison.Ordinal); - - if (_config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(dottedQualifiedName)) + if (_config.ExcludedNames.Contains(qualifiedName)) { if (_config.LogExclusions) { @@ -4887,9 +4902,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) return true; } - var dottedQualifiedNameWithoutParameters = qualifiedNameWithoutParameters.Replace("::", ".", StringComparison.Ordinal); - - if (_config.ExcludedNames.Contains(qualifiedNameWithoutParameters) || _config.ExcludedNames.Contains(dottedQualifiedNameWithoutParameters) || _config.ExcludedNames.Contains(name)) + if (_config.ExcludedNames.Contains(qualifiedNameWithoutParameters) || _config.ExcludedNames.Contains(name)) { if (_config.LogExclusions) { @@ -4919,9 +4932,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) } if (_config.IncludedNames.Count != 0 && !_config.IncludedNames.Contains(qualifiedName) - && !_config.IncludedNames.Contains(dottedQualifiedName) && !_config.IncludedNames.Contains(qualifiedNameWithoutParameters) - && !_config.IncludedNames.Contains(dottedQualifiedNameWithoutParameters) && !_config.IncludedNames.Contains(name)) { var semanticParentCursor = cursor.SemanticParentCursor; @@ -5210,9 +5221,7 @@ private bool IsBaseExcluded(CXXRecordDecl cxxRecordDecl, CXXRecordDecl baseCxxRe baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out _, skipUsing: true); var qualifiedName = $"{GetCursorQualifiedName(cxxRecordDecl)}::{baseFieldName}"; - var dottedQualifiedName = qualifiedName.Replace("::", ".", StringComparison.Ordinal); - - return _config.ExcludedNames.Contains(qualifiedName) || _config.ExcludedNames.Contains(dottedQualifiedName); + return _config.ExcludedNames.Contains(qualifiedName); } private bool IsFixedSize(Cursor cursor, Type type) @@ -6473,7 +6482,7 @@ private void StopUsingOutputBuilder() private bool TryGetUuid(RecordDecl recordDecl, out Guid uuid) { - if (TryGetRemappedValue(recordDecl, _config.WithGuids, out var guid)) + if (TryGetRemappedValue(recordDecl, _config._withGuids, out var guid)) { uuid = guid; return true; @@ -6807,7 +6816,7 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform = var outputBuilder = isTestOutput ? _testOutputBuilder : _outputBuilder; Debug.Assert(outputBuilder is not null); - if (TryGetRemappedValue(namedDecl, _config.WithAttributes, out var attributes, matchStar: true)) + if (TryGetRemappedValue(namedDecl, _config._withAttributes, out var attributes, matchStar: true)) { foreach (var attribute in attributes.Where((a) => !onlySupportedOSPlatform || a.StartsWith("SupportedOSPlatform(", StringComparison.Ordinal))) { @@ -6907,16 +6916,16 @@ private string GetClass(string remappedName, bool disallowPrefixMatch = false) return className; } - private bool TryGetClass(string remappedName, [MaybeNullWhen(false)] out string className, bool disallowPrefixMatch = false) + private bool TryGetClass(ReadOnlySpan remappedName, [MaybeNullWhen(false)] out string className, bool disallowPrefixMatch = false) { - var index = remappedName.IndexOf('*', StringComparison.Ordinal); + var index = remappedName.IndexOf('*'); if (index != -1) { remappedName = remappedName[..index]; } - if (_config.WithClasses.TryGetValue(remappedName, out className)) + if (_config._withClasses.GetAlternateLookup>().TryGetValue(remappedName, out className)) { _ = _topLevelClassNames.Add(className); _ = _topLevelClassNames.Add($"{className}Tests"); @@ -6928,14 +6937,14 @@ private bool TryGetClass(string remappedName, [MaybeNullWhen(false)] out string return false; } - foreach (var withClass in _config.WithClasses) + foreach (var withClass in _config._withClasses) { if (!withClass.Key.EndsWith('*')) { continue; } - var prefix = withClass.Key[0..^1]; + var prefix = withClass.Key.AsSpan()[..^1]; if (remappedName.StartsWith(prefix, StringComparison.Ordinal)) { @@ -6948,7 +6957,7 @@ private bool TryGetClass(string remappedName, [MaybeNullWhen(false)] out string return false; } - private string GetNamespace(string remappedName, NamedDecl? namedDecl = null) + private string GetNamespace(ReadOnlySpan remappedName, NamedDecl? namedDecl = null) { if (!TryGetNamespace(remappedName, out var namespaceName)) { @@ -6965,37 +6974,32 @@ private string GetNamespace(string remappedName, NamedDecl? namedDecl = null) return namespaceName; } - private bool TryGetNamespace(string remappedName, [MaybeNullWhen(false)] out string namespaceName) + private bool TryGetNamespace(ReadOnlySpan remappedName, [MaybeNullWhen(false)] out string namespaceName) { - var index = remappedName.IndexOf('*', StringComparison.Ordinal); + var index = remappedName.IndexOf('*'); if (index != -1) { remappedName = remappedName[..index]; } - return _config.WithNamespaces.TryGetValue(remappedName, out namespaceName); + return _config._withNamespaces.GetAlternateLookup>().TryGetValue(remappedName, out namespaceName); } - private bool GetSetLastError(NamedDecl namedDecl) => HasRemapping(namedDecl, _config.WithSetLastErrors, matchStar: true); + private bool GetSetLastError(NamedDecl namedDecl) => HasRemapping(namedDecl, _config._withSetLastErrors, matchStar: true); - private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entries, bool matchStar = false) + private bool HasRemapping(NamedDecl namedDecl, HashSet entries, bool matchStar = false) { - var name = GetCursorQualifiedName(namedDecl); + var name = GetCursorQualifiedName(namedDecl).AsSpan(); if (name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { name = name["ClangSharpMacro_".Length..]; } - if (entries.Contains(name)) - { - return true; - } - - name = name.Replace("::", ".", StringComparison.Ordinal); + var entriesLookup = entries.GetAlternateLookup>(); - if (entries.Contains(name)) + if (entriesLookup.Contains(name)) { return true; } @@ -7007,14 +7011,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri name = name["ClangSharpMacro_".Length..]; } - if (entries.Contains(name)) - { - return true; - } - - name = name.Replace("::", ".", StringComparison.Ordinal); - - if (entries.Contains(name)) + if (entriesLookup.Contains(name)) { return true; } @@ -7026,26 +7023,21 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri name = name["ClangSharpMacro_".Length..]; } - return entries.Contains(name) || (matchStar && entries.Contains("*")); + return entriesLookup.Contains(name) || (matchStar && entriesLookup.Contains("*")); } - private bool TryGetRemappedValue(NamedDecl namedDecl, IReadOnlyDictionary remappings, [MaybeNullWhen(false)] out T value, bool matchStar = false) + private bool TryGetRemappedValue(NamedDecl namedDecl, Dictionary remappings, [MaybeNullWhen(false)] out T value, bool matchStar = false) { - var name = GetCursorQualifiedName(namedDecl); + var name = GetCursorQualifiedName(namedDecl).AsSpan(); if (name.StartsWith("ClangSharpMacro_", StringComparison.Ordinal)) { name = name["ClangSharpMacro_".Length..]; } - if (remappings.TryGetValue(name, out value)) - { - return true; - } + var remappingsLookup = remappings.GetAlternateLookup>(); - name = name.Replace("::", ".", StringComparison.Ordinal); - - if (remappings.TryGetValue(name, out value)) + if (remappingsLookup.TryGetValue(name, out value)) { return true; } @@ -7057,14 +7049,7 @@ private bool TryGetRemappedValue(NamedDecl namedDecl, IReadOnlyDictionary(NamedDecl namedDecl, IReadOnlyDictionary _excludedNames; - private readonly SortedSet _forceRemappedNames; - private readonly SortedSet _includedNames; - private readonly SortedSet _nativeTypeNamesToStrip; - private readonly SortedSet _withManualImports; - private readonly SortedSet _traversalNames; - private readonly SortedSet _withSetLastErrors; - private readonly SortedSet _withSuppressGCTransitions; - - private readonly SortedDictionary _remappedNames; - private readonly SortedDictionary _withAccessSpecifiers; - private readonly SortedDictionary> _withAttributes; - private readonly SortedDictionary _withCallConvs; - private readonly SortedDictionary _withClasses; - private readonly SortedDictionary _withGuids; - private readonly SortedDictionary _withLengths; - private readonly SortedDictionary _withLibraryPaths; - private readonly SortedDictionary _withNamespaces; - private readonly SortedDictionary _withTransparentStructs; - private readonly SortedDictionary _withTypes; - private readonly SortedDictionary> _withUsings; - private readonly SortedDictionary _withPackings; + internal readonly HashSet _excludedNames; + private readonly HashSet _forceRemappedNames; + private readonly HashSet _includedNames; + private readonly HashSet _nativeTypeNamesToStrip; + private readonly HashSet _withManualImports; + private readonly HashSet _traversalNames; + internal readonly HashSet _withSetLastErrors; + internal readonly HashSet _withSuppressGCTransitions; + + internal readonly Dictionary _remappedNames; + internal readonly Dictionary _withAccessSpecifiers; + internal readonly Dictionary> _withAttributes; + internal readonly Dictionary _withCallConvs; + internal readonly Dictionary _withClasses; + internal readonly Dictionary _withGuids; + internal readonly Dictionary _withLengths; + private readonly Dictionary _withLibraryPaths; + internal readonly Dictionary _withNamespaces; + private readonly Dictionary _withTransparentStructs; + internal readonly Dictionary _withTypes; + internal readonly Dictionary> _withUsings; + internal readonly Dictionary _withPackings; private PInvokeGeneratorConfigurationOptions _options; @@ -81,28 +81,28 @@ public PInvokeGeneratorConfiguration(string language, string languageStandard, s _methodPrefixToStrip = DefaultMethodPrefixToStripValue; _testOutputLocation = DefaultTestOutputLocationValue; - _excludedNames = []; - _forceRemappedNames = []; - _includedNames = []; - _nativeTypeNamesToStrip = []; - _withManualImports = []; - _traversalNames = []; - _withSetLastErrors = []; - _withSuppressGCTransitions = []; - - _remappedNames = []; - _withAccessSpecifiers = []; - _withAttributes = []; - _withCallConvs = []; - _withClasses = []; - _withGuids = []; - _withLengths = []; - _withLibraryPaths = []; - _withNamespaces = []; - _withTransparentStructs = []; - _withTypes = []; - _withUsings = []; - _withPackings = []; + _excludedNames = new HashSet(QualifiedNameComparer.Default); + _forceRemappedNames = new HashSet(QualifiedNameComparer.Default); + _includedNames = new HashSet(QualifiedNameComparer.Default); + _nativeTypeNamesToStrip = new HashSet(StringComparer.Ordinal); + _withManualImports = new HashSet(StringComparer.Ordinal); + _traversalNames = new HashSet(StringComparer.Ordinal); + _withSetLastErrors = new HashSet(QualifiedNameComparer.Default); + _withSuppressGCTransitions = new HashSet(QualifiedNameComparer.Default); + + _remappedNames = new Dictionary(QualifiedNameComparer.Default); + _withAccessSpecifiers = new Dictionary(QualifiedNameComparer.Default); + _withAttributes = new Dictionary>(QualifiedNameComparer.Default); + _withCallConvs = new Dictionary(QualifiedNameComparer.Default); + _withClasses = new Dictionary(StringComparer.Ordinal); + _withGuids = new Dictionary(QualifiedNameComparer.Default); + _withLengths = new Dictionary(QualifiedNameComparer.Default); + _withLibraryPaths = new Dictionary(StringComparer.Ordinal); + _withNamespaces = new Dictionary(StringComparer.Ordinal); + _withTransparentStructs = new Dictionary(StringComparer.Ordinal); + _withTypes = new Dictionary(QualifiedNameComparer.Default); + _withUsings = new Dictionary>(QualifiedNameComparer.Default); + _withPackings = new Dictionary(QualifiedNameComparer.Default); if ((outputMode == PInvokeGeneratorOutputMode.Xml) && !options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateMultipleFiles) && (options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsNUnit) || options.HasFlag(PInvokeGeneratorConfigurationOptions.GenerateTestsXUnit))) { @@ -612,7 +612,7 @@ public static AccessSpecifier ConvertStringToAccessSpecifier(string input) : input.Equals("public", StringComparison.OrdinalIgnoreCase) ? AccessSpecifier.Public : AccessSpecifier.None; } - private static void AddRange(SortedDictionary dictionary, IEnumerable>? keyValuePairs) + private static void AddRange(Dictionary dictionary, IEnumerable>? keyValuePairs) { if (keyValuePairs != null) { @@ -625,7 +625,7 @@ private static void AddRange(SortedDictionary dictionary } } - private static void AddRange(SortedDictionary dictionary, IEnumerable>? keyValuePairs, Func convert) + private static void AddRange(Dictionary dictionary, IEnumerable>? keyValuePairs, Func convert) { if (keyValuePairs != null) { @@ -638,7 +638,7 @@ private static void AddRange(SortedDictionary di } } - private static void AddRange(SortedSet hashSet, IEnumerable? keys) + private static void AddRange(HashSet hashSet, IEnumerable? keys) { if (keys != null) { @@ -649,7 +649,7 @@ private static void AddRange(SortedSet hashSet, IEnumerable(SortedSet hashSet, IEnumerable? keys, Func convert) + private static void AddRange(HashSet hashSet, IEnumerable? keys, Func convert) { if (keys != null) { @@ -660,7 +660,7 @@ private static void AddRange(SortedSet hashSet, IEnumera } } - private static void AddRange(SortedSet hashSet, IEnumerable>? keyValuePairs, Func shouldAdd) + private static void AddRange(HashSet hashSet, IEnumerable>? keyValuePairs, Func shouldAdd) { if (keyValuePairs != null) { diff --git a/sources/ClangSharp.PInvokeGenerator/QualifiedNameComparer.cs b/sources/ClangSharp.PInvokeGenerator/QualifiedNameComparer.cs new file mode 100644 index 00000000..820522ac --- /dev/null +++ b/sources/ClangSharp.PInvokeGenerator/QualifiedNameComparer.cs @@ -0,0 +1,105 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace ClangSharp; + +internal class QualifiedNameComparer : IEqualityComparer, IAlternateEqualityComparer, string> +{ + public static readonly QualifiedNameComparer Default = new QualifiedNameComparer(); + + public string Create(ReadOnlySpan alternate) => alternate.ToString(); + + public bool Equals(ReadOnlySpan alternate, string other) => Equals(alternate, other.AsSpan()); + + public static bool Equals(ReadOnlySpan alternate, ReadOnlySpan other) + { + while ((alternate.Length != 0) && (other.Length != 0)) + { + if (alternate.StartsWith("::", StringComparison.Ordinal)) + { + if (other.StartsWith('.')) + { + alternate = alternate[2..]; + other = other[1..]; + } + else + { + return false; + } + } + else if (alternate.StartsWith('.')) + { + if (other.StartsWith("::", StringComparison.Ordinal)) + { + alternate = alternate[1..]; + other = other[2..]; + } + else + { + return false; + } + } + + var prefixLength = alternate.CommonPrefixLength(other); + + if (prefixLength == 0) + { + break; + } + + alternate = alternate[prefixLength..]; + other = other[prefixLength..]; + } + + return (alternate.Length == 0) && (other.Length == 0); + } + + public bool Equals(string? x, string? y) => Equals(x.AsSpan(), y.AsSpan()); + + public int GetHashCode(ReadOnlySpan alternate) + { + var hashCode = new HashCode(); + + while (alternate.Length != 0) + { + var part = alternate; + var separatorLength = 0; + + var colonSeparatorIndex = part.IndexOf("::", StringComparison.Ordinal); + + if (colonSeparatorIndex != -1) + { + part = part[..colonSeparatorIndex]; + separatorLength = 2; + } + + var dotSeparatorIndex = part.IndexOf('.'); + + if (dotSeparatorIndex != -1) + { + part = part[..dotSeparatorIndex]; + separatorLength = 1; + } + + hashCode.Add(string.GetHashCode(part, StringComparison.Ordinal)); + + if (separatorLength != 0) + { + hashCode.Add('.'); + alternate = alternate[(part.Length + separatorLength)..]; + } + else + { + alternate = alternate[part.Length..]; + } + } + + return hashCode.ToHashCode(); + } + + public int GetHashCode([DisallowNull] string obj) => GetHashCode(obj.AsSpan()); +} diff --git a/sources/ClangSharp/ClangSharp.csproj b/sources/ClangSharp/ClangSharp.csproj index d5fee39f..919628d5 100644 --- a/sources/ClangSharp/ClangSharp.csproj +++ b/sources/ClangSharp/ClangSharp.csproj @@ -2,14 +2,15 @@ - net8.0 + net10.0 - $(NoWarn);CA1034;CA1040;CA1720 + + $(NoWarn);CA1034;CA1040;CA1720;IDE0130 diff --git a/sources/ClangSharp/Cursors/Cursor.cs b/sources/ClangSharp/Cursors/Cursor.cs index 95783bcb..4a60a899 100644 --- a/sources/ClangSharp/Cursors/Cursor.cs +++ b/sources/ClangSharp/Cursors/Cursor.cs @@ -13,11 +13,11 @@ namespace ClangSharp; [DebuggerDisplay("{Handle.DebuggerDisplayString,nq}")] public unsafe class Cursor : IEquatable { - private readonly Lazy _kindSpelling; - private readonly Lazy _lexicalParentCursor; - private readonly Lazy _semanticParentCursor; - private readonly Lazy _spelling; - private readonly Lazy _translationUnit; + private readonly ValueLazy _kindSpelling; + private readonly ValueLazy _lexicalParentCursor; + private readonly ValueLazy _semanticParentCursor; + private readonly ValueLazy _spelling; + private readonly ValueLazy _translationUnit; private List? _cursorChildren; private protected Cursor(CXCursor handle, CXCursorKind expectedCursorKind) @@ -28,11 +28,11 @@ private protected Cursor(CXCursor handle, CXCursorKind expectedCursorKind) } Handle = handle; - _kindSpelling = new Lazy(Handle.KindSpelling.ToString); - _lexicalParentCursor = new Lazy(() => !Handle.LexicalParent.IsNull ? TranslationUnit.GetOrCreate(Handle.LexicalParent) : null); - _semanticParentCursor = new Lazy(() => !Handle.SemanticParent.IsNull ? TranslationUnit.GetOrCreate(Handle.SemanticParent) : null); - _spelling = new Lazy(Handle.Spelling.ToString); - _translationUnit = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TranslationUnit)); + _kindSpelling = new ValueLazy(Handle.KindSpelling.ToString); + _lexicalParentCursor = new ValueLazy(() => !Handle.LexicalParent.IsNull ? TranslationUnit.GetOrCreate(Handle.LexicalParent) : null); + _semanticParentCursor = new ValueLazy(() => !Handle.SemanticParent.IsNull ? TranslationUnit.GetOrCreate(Handle.SemanticParent) : null); + _spelling = new ValueLazy(Handle.Spelling.ToString); + _translationUnit = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TranslationUnit)); } public IReadOnlyList CursorChildren diff --git a/sources/ClangSharp/Cursors/Decls/BindingDecl.cs b/sources/ClangSharp/Cursors/Decls/BindingDecl.cs index 512aacbd..21c7a630 100644 --- a/sources/ClangSharp/Cursors/Decls/BindingDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/BindingDecl.cs @@ -9,15 +9,15 @@ namespace ClangSharp; public sealed class BindingDecl : ValueDecl { - private readonly Lazy _binding; - private readonly Lazy _decomposedDecl; - private readonly Lazy _holdingVar; + private readonly ValueLazy _binding; + private readonly ValueLazy _decomposedDecl; + private readonly ValueLazy _holdingVar; internal BindingDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_Binding) { - _binding = new Lazy(() => TranslationUnit.GetOrCreate(Handle.BindingExpr)); - _decomposedDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DecomposedDecl)); - _holdingVar = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _binding = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.BindingExpr)); + _decomposedDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DecomposedDecl)); + _holdingVar = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); } public Expr Binding => _binding.Value; diff --git a/sources/ClangSharp/Cursors/Decls/BlockDecl.Capture.cs b/sources/ClangSharp/Cursors/Decls/BlockDecl.Capture.cs index 6394f7ee..d56eb53f 100644 --- a/sources/ClangSharp/Cursors/Decls/BlockDecl.Capture.cs +++ b/sources/ClangSharp/Cursors/Decls/BlockDecl.Capture.cs @@ -10,16 +10,16 @@ public sealed class Capture { private readonly Decl _parentDecl; private readonly uint _index; - private readonly Lazy _copyExpr; - private readonly Lazy _variable; + private readonly ValueLazy _copyExpr; + private readonly ValueLazy _variable; internal Capture(Decl parentDecl, uint index) { _parentDecl = parentDecl; _index = index; - _copyExpr = new Lazy(() => _parentDecl.TranslationUnit.GetOrCreate(_parentDecl.Handle.GetCaptureCopyExpr(_index))); - _variable = new Lazy(() => _parentDecl.TranslationUnit.GetOrCreate(_parentDecl.Handle.GetCaptureVariable(_index))); + _copyExpr = new ValueLazy(() => _parentDecl.TranslationUnit.GetOrCreate(_parentDecl.Handle.GetCaptureCopyExpr(_index))); + _variable = new ValueLazy(() => _parentDecl.TranslationUnit.GetOrCreate(_parentDecl.Handle.GetCaptureVariable(_index))); } public Expr CopyExpr => _copyExpr.Value; diff --git a/sources/ClangSharp/Cursors/Decls/BlockDecl.cs b/sources/ClangSharp/Cursors/Decls/BlockDecl.cs index b52ad9a1..25d59bc8 100644 --- a/sources/ClangSharp/Cursors/Decls/BlockDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/BlockDecl.cs @@ -1,46 +1,24 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; -using static ClangSharp.Interop.CX_DeclKind; using System; using System.Collections.Generic; +using ClangSharp.Interop; +using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed partial class BlockDecl : Decl, IDeclContext { - private readonly Lazy _blockManglingContextDecl; - private readonly Lazy> _captures; - private readonly Lazy> _parameters; + private readonly ValueLazy _blockManglingContextDecl; + private readonly LazyList _captures; + private readonly LazyList _parameters; internal BlockDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_Block) { - _blockManglingContextDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.BlockManglingContextDecl)); - _captures = new Lazy>(() => { - var captureCount = Handle.NumCaptures; - var captures = new List(captureCount); - - for (var i = 0; i < captureCount; i++) - { - var capture = new Capture(this, unchecked((uint)i)); - captures.Add(capture); - } - - return captures; - }); - _parameters = new Lazy>(() => { - var parameterCount = Handle.NumArguments; - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); + _blockManglingContextDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.BlockManglingContextDecl)); + _captures = LazyList.Create(Handle.NumCaptures, (i) => new Capture(this, unchecked((uint)i))); + _parameters = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); } public Decl BlockManglingContextDecl => _blockManglingContextDecl.Value; @@ -49,7 +27,7 @@ internal BlockDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_De public bool BlockMissingReturnType => Handle.BlockMissingReturnType; - public IReadOnlyList Captures => _captures.Value; + public IReadOnlyList Captures => _captures; public bool CanAvoidCopyToHeap() => Handle.CanAvoidCopyToHeap; @@ -69,7 +47,7 @@ internal BlockDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_De public uint NumParams => unchecked((uint)Handle.NumArguments); - public IReadOnlyList Parameters => _parameters.Value; + public IReadOnlyList Parameters => _parameters; public bool ParamEmpty => ParamSize == 0; diff --git a/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs index 6781c882..6dd894fa 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXConstructorDecl.cs @@ -3,38 +3,27 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class CXXConstructorDecl : CXXMethodDecl { - private readonly Lazy _inheritedConstructor; - private readonly Lazy> _initExprs; + private readonly ValueLazy _inheritedConstructor; + private readonly LazyList _initExprs; internal CXXConstructorDecl(CXCursor handle) : base(handle, CXCursor_Constructor, CX_DeclKind_CXXConstructor) { - _inheritedConstructor = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InheritedConstructor)); - _initExprs = new Lazy>(() => { - var numInitExprs = Handle.NumExprs; - var initExprs = new List(numInitExprs); - - for (var i = 0; i < numInitExprs; i++) - { - var initExpr = TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i))); - initExprs.Add(initExpr); - } - - return initExprs; - }); + _inheritedConstructor = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InheritedConstructor)); + _initExprs = LazyList.Create(Handle.NumExprs , (i) => TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i)))); } public new CXXConstructorDecl CanonicalDecl => (CXXConstructorDecl)base.CanonicalDecl; public CXXConstructorDecl InheritedConstructor => _inheritedConstructor.Value; - public IReadOnlyList InitExprs => _initExprs.Value; + public IReadOnlyList InitExprs => _initExprs; public bool IsConvertingConstructor => Handle.CXXConstructor_IsConvertingConstructor; diff --git a/sources/ClangSharp/Cursors/Decls/CXXConversionDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXConversionDecl.cs index 096f4cef..8c76cc36 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXConversionDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXConversionDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class CXXConversionDecl : CXXMethodDecl { - private readonly Lazy _conversionType; + private readonly ValueLazy _conversionType; internal CXXConversionDecl(CXCursor handle) : base(handle, CXCursor_ConversionFunction, CX_DeclKind_CXXConversion) { - _conversionType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _conversionType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public new CXXConversionDecl CanonicalDecl => (CXXConversionDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/CXXDeductionGuideDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXDeductionGuideDecl.cs index 2c4850b5..92243736 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXDeductionGuideDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXDeductionGuideDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class CXXDeductionGuideDecl : FunctionDecl { - private readonly Lazy _deducedTemplate; + private readonly ValueLazy _deducedTemplate; internal CXXDeductionGuideDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_CXXDeductionGuide) { - _deducedTemplate = new Lazy(() => TranslationUnit.GetOrCreate(handle.TemplatedDecl)); + _deducedTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.TemplatedDecl)); } public bool IsExplicit => !Handle.IsImplicit; diff --git a/sources/ClangSharp/Cursors/Decls/CXXDestructorDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXDestructorDecl.cs index e90b4dca..f47ee3b2 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXDestructorDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXDestructorDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class CXXDestructorDecl : CXXMethodDecl { - private readonly Lazy _operatorDelete; - private readonly Lazy _operatorDeleteThisArg; + private readonly ValueLazy _operatorDelete; + private readonly ValueLazy _operatorDeleteThisArg; internal CXXDestructorDecl(CXCursor handle) : base(handle, CXCursor_Destructor, CX_DeclKind_CXXDestructor) { - _operatorDelete = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _operatorDeleteThisArg = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _operatorDelete = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _operatorDeleteThisArg = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); } public new CXXDestructorDecl CanonicalDecl => (CXXDestructorDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs index 05f669a4..204a22cc 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXMethodDecl.cs @@ -3,16 +3,16 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public class CXXMethodDecl : FunctionDecl { - private readonly Lazy> _overriddenMethods; - private readonly Lazy _thisType; - private readonly Lazy _thisObjectType; + private readonly LazyList _overriddenMethods; + private readonly ValueLazy _thisType; + private readonly ValueLazy _thisObjectType; internal CXXMethodDecl(CXCursor handle) : this(handle, CXCursor_CXXMethod, CX_DeclKind_CXXMethod) { @@ -25,21 +25,9 @@ private protected CXXMethodDecl(CXCursor handle, CXCursorKind expectedCursorKind throw new ArgumentOutOfRangeException(nameof(handle)); } - _overriddenMethods = new Lazy>(() => { - var numOverriddenMethods = Handle.NumMethods; - var overriddenMethods = new List(numOverriddenMethods); - - for (var i = 0; i < numOverriddenMethods; i++) - { - var overriddenMethod = TranslationUnit.GetOrCreate(Handle.GetMethod(unchecked((uint)i))); - overriddenMethods.Add(overriddenMethod); - } - - return overriddenMethods; - }); - - _thisType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ThisType)); - _thisObjectType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ThisObjectType)); + _overriddenMethods = LazyList.Create(Handle.NumMethods, (i) => TranslationUnit.GetOrCreate(Handle.GetMethod(unchecked((uint)i)))); + _thisType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ThisType)); + _thisObjectType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ThisObjectType)); } public new CXXMethodDecl CanonicalDecl => (CXXMethodDecl)base.CanonicalDecl; @@ -54,7 +42,7 @@ private protected CXXMethodDecl(CXCursor handle, CXCursorKind expectedCursorKind public new CXXMethodDecl MostRecentDecl => (CXXMethodDecl)base.MostRecentDecl; - public IReadOnlyList OverriddenMethods => _overriddenMethods.Value; + public IReadOnlyList OverriddenMethods => _overriddenMethods; public new CXXRecordDecl? Parent => (CXXRecordDecl?)(base.Parent ?? ThisObjectType.AsCXXRecordDecl); diff --git a/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs b/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs index a508f38a..b4c5bce3 100644 --- a/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CXXRecordDecl.cs @@ -10,19 +10,19 @@ namespace ClangSharp; public class CXXRecordDecl : RecordDecl { - private readonly Lazy> _bases; - private readonly Lazy> _ctors; - private readonly Lazy _dependentLambdaCallOperator; - private readonly Lazy _describedClassTemplate; - private readonly Lazy _destructor; - private readonly Lazy> _friends; - private readonly Lazy _instantiatedFromMemberClass; - private readonly Lazy _lambdaCallOperator; - private readonly Lazy _lambdaContextDecl; - private readonly Lazy _lambdaStaticInvoker; - private readonly Lazy> _methods; - private readonly Lazy _templateInstantiationPattern; - private readonly Lazy> _vbases; + private readonly LazyList _bases; + private readonly LazyList _ctors; + private readonly ValueLazy _dependentLambdaCallOperator; + private readonly ValueLazy _describedClassTemplate; + private readonly ValueLazy _destructor; + private readonly LazyList _friends; + private readonly ValueLazy _instantiatedFromMemberClass; + private readonly ValueLazy _lambdaCallOperator; + private readonly ValueLazy _lambdaContextDecl; + private readonly ValueLazy _lambdaStaticInvoker; + private readonly LazyList _methods; + private readonly ValueLazy _templateInstantiationPattern; + private readonly LazyList _vbases; internal CXXRecordDecl(CXCursor handle) : this(handle, handle.Kind, CX_DeclKind_CXXRecord) { @@ -35,93 +35,31 @@ private protected CXXRecordDecl(CXCursor handle, CXCursorKind expectedCursorKind throw new ArgumentOutOfRangeException(nameof(handle)); } - _bases = new Lazy>(() => { - var numBases = Handle.NumBases; - var bases = new List(numBases); - - for (var i = 0; i < numBases; i++) - { - var @base = TranslationUnit.GetOrCreate(Handle.GetBase(unchecked((uint)i))); - bases.Add(@base); - } - - return bases; - }); - - _ctors = new Lazy>(() => { - var numCtors = Handle.NumCtors; - var ctors = new List(numCtors); - - for (var i = 0; i < numCtors; i++) - { - var ctor = TranslationUnit.GetOrCreate(Handle.GetCtor(unchecked((uint)i))); - ctors.Add(ctor); - } - - return ctors; - }); - - _dependentLambdaCallOperator = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DependentLambdaCallOperator)); - _describedClassTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DescribedCursorTemplate)); - _destructor = new Lazy(() => { + _bases = LazyList.Create(Handle.NumBases, (i) => TranslationUnit.GetOrCreate(Handle.GetBase(unchecked((uint)i)))); + _ctors = LazyList.Create(Handle.NumCtors, (i) => TranslationUnit.GetOrCreate(Handle.GetCtor(unchecked((uint)i)))); + _dependentLambdaCallOperator = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DependentLambdaCallOperator)); + _describedClassTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DescribedCursorTemplate)); + _destructor = new ValueLazy(() => { var destructor = Handle.Destructor; return destructor.IsNull ? null : TranslationUnit.GetOrCreate(Handle.Destructor); }); - - _friends = new Lazy>(() => { - var numFriends = Handle.NumFriends; - var friends = new List(numFriends); - - for (var i = 0; i < numFriends; i++) - { - var friend = TranslationUnit.GetOrCreate(Handle.GetFriend(unchecked((uint)i))); - friends.Add(friend); - } - - return friends; - }); - - _instantiatedFromMemberClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); - _lambdaCallOperator = new Lazy(() => TranslationUnit.GetOrCreate(Handle.LambdaCallOperator)); - _lambdaContextDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.LambdaContextDecl)); - _lambdaStaticInvoker = new Lazy(() => TranslationUnit.GetOrCreate(Handle.LambdaStaticInvoker)); - - _methods = new Lazy>(() => { - var numMethods = Handle.NumMethods; - var methods = new List(numMethods); - - for (var i = 0; i < numMethods; i++) - { - var method = TranslationUnit.GetOrCreate(Handle.GetMethod(unchecked((uint)i))); - methods.Add(method); - } - - return methods; - }); - - _templateInstantiationPattern = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); - - _vbases = new Lazy>(() => { - var numVBases = Handle.NumVBases; - var vbases = new List(numVBases); - - for (var i = 0; i < numVBases; i++) - { - var vbase = TranslationUnit.GetOrCreate(Handle.GetVBase(unchecked((uint)i))); - vbases.Add(vbase); - } - - return vbases; - }); + _friends = LazyList.Create(Handle.NumFriends, (i) => TranslationUnit.GetOrCreate(Handle.GetFriend(unchecked((uint)i)))); + _instantiatedFromMemberClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _lambdaCallOperator = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.LambdaCallOperator)); + _lambdaContextDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.LambdaContextDecl)); + _lambdaStaticInvoker = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.LambdaStaticInvoker)); + _methods = LazyList.Create(Handle.NumMethods, (i) => TranslationUnit.GetOrCreate(Handle.GetMethod(unchecked((uint)i)))); + _templateInstantiationPattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); + _vbases = LazyList.Create(Handle.NumVBases, (i) => TranslationUnit.GetOrCreate(Handle.GetVBase(unchecked((uint)i)))); } public bool IsAbstract => Handle.CXXRecord_IsAbstract; - public IReadOnlyList Bases => _bases.Value; + public IReadOnlyList Bases => _bases; public new CXXRecordDecl CanonicalDecl => (CXXRecordDecl)base.CanonicalDecl; - public IReadOnlyList Ctors => _ctors.Value; + public IReadOnlyList Ctors => _ctors; public new CXXRecordDecl? Definition => (CXXRecordDecl?)base.Definition; @@ -131,7 +69,7 @@ private protected CXXRecordDecl(CXCursor handle, CXCursorKind expectedCursorKind public CXXDestructorDecl? Destructor => _destructor.Value; - public IReadOnlyList Friends => _friends.Value; + public IReadOnlyList Friends => _friends; public bool HasDefinition => Definition is not null; @@ -159,7 +97,7 @@ private protected CXXRecordDecl(CXCursor handle, CXCursorKind expectedCursorKind public CXXMethodDecl LambdaStaticInvoker => _lambdaStaticInvoker.Value; - public IReadOnlyList Methods => _methods.Value; + public IReadOnlyList Methods => _methods; public new CXXRecordDecl MostRecentDecl => (CXXRecordDecl)base.MostRecentDecl; @@ -189,5 +127,5 @@ public CXXRecordDecl MostRecentNonInjectedDecl public CXXRecordDecl TemplateInstantiationPattern => _templateInstantiationPattern.Value; - public IReadOnlyList VBases => _vbases.Value; + public IReadOnlyList VBases => _vbases; } diff --git a/sources/ClangSharp/Cursors/Decls/CapturedDecl.cs b/sources/ClangSharp/Cursors/Decls/CapturedDecl.cs index 299793a7..29a077dd 100644 --- a/sources/ClangSharp/Cursors/Decls/CapturedDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/CapturedDecl.cs @@ -1,33 +1,22 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; -using static ClangSharp.Interop.CX_DeclKind; using System; using System.Collections.Generic; +using ClangSharp.Interop; +using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class CapturedDecl : Decl, IDeclContext { - private readonly Lazy _contextParam; - private readonly Lazy> _parameters; + private readonly ValueLazy _contextParam; + private readonly LazyList _parameters; internal CapturedDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_Captured) { - _contextParam = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ContextParam)); - _parameters = new Lazy>(() => { - var parameterCount = Handle.NumArguments; - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); + _contextParam = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ContextParam)); + _parameters = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); } public ImplicitParamDecl ContextParam => _contextParam.Value; @@ -38,5 +27,5 @@ internal CapturedDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX public uint NumParams => unchecked((uint)Handle.NumArguments); - public IReadOnlyList Parameters => _parameters.Value; + public IReadOnlyList Parameters => _parameters; } diff --git a/sources/ClangSharp/Cursors/Decls/ClassTemplateDecl.cs b/sources/ClangSharp/Cursors/Decls/ClassTemplateDecl.cs index e6233e9c..8fa808c8 100644 --- a/sources/ClangSharp/Cursors/Decls/ClassTemplateDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ClassTemplateDecl.cs @@ -3,32 +3,20 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ClassTemplateDecl : RedeclarableTemplateDecl { - private readonly Lazy _injectedClassNameSpecialization; - private readonly Lazy> _specializations; + private readonly ValueLazy _injectedClassNameSpecialization; + private readonly LazyList _specializations; internal ClassTemplateDecl(CXCursor handle) : base(handle, CXCursor_ClassTemplate, CX_DeclKind_ClassTemplate) { - _injectedClassNameSpecialization = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); - - _specializations = new Lazy>(() => { - var numSpecializations = Handle.NumSpecializations; - var specializations = new List(numSpecializations); - - for (var i = 0; i (Handle.GetSpecialization(unchecked((uint)i))); - specializations.Add(specialization); - } - - return specializations; - }); + _injectedClassNameSpecialization = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); + _specializations = LazyList.Create(Handle.NumSpecializations, (i) => TranslationUnit.GetOrCreate(Handle.GetSpecialization(unchecked((uint)i)))); } public new ClassTemplateDecl CanonicalDecl => (ClassTemplateDecl)base.CanonicalDecl; @@ -43,7 +31,7 @@ internal ClassTemplateDecl(CXCursor handle) : base(handle, CXCursor_ClassTemplat public new ClassTemplateDecl PreviousDecl => (ClassTemplateDecl)base.PreviousDecl; - public IReadOnlyList Specializations => _specializations.Value; + public IReadOnlyList Specializations => _specializations; public new CXXRecordDecl TemplatedDecl => (CXXRecordDecl)base.TemplatedDecl; } diff --git a/sources/ClangSharp/Cursors/Decls/ClassTemplatePartialSpecializationDecl.cs b/sources/ClangSharp/Cursors/Decls/ClassTemplatePartialSpecializationDecl.cs index 51062f2f..fd3dfc98 100644 --- a/sources/ClangSharp/Cursors/Decls/ClassTemplatePartialSpecializationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ClassTemplatePartialSpecializationDecl.cs @@ -10,44 +10,20 @@ namespace ClangSharp; public sealed class ClassTemplatePartialSpecializationDecl : ClassTemplateSpecializationDecl { - private readonly Lazy> _associatedConstraints; - private readonly Lazy _injectedSpecializationType; - private readonly Lazy _instantiatedFromMember; - private readonly Lazy> _templateParameters; + private readonly LazyList _associatedConstraints; + private readonly ValueLazy _injectedSpecializationType; + private readonly ValueLazy _instantiatedFromMember; + private readonly LazyList _templateParameters; internal ClassTemplatePartialSpecializationDecl(CXCursor handle) : base(handle, CXCursor_ClassTemplatePartialSpecialization, CX_DeclKind_ClassTemplatePartialSpecialization) { - _associatedConstraints = new Lazy>(() => { - var associatedConstraintCount = Handle.NumAssociatedConstraints; - var associatedConstraints = new List(associatedConstraintCount); - - for (var i = 0; i < associatedConstraintCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i))); - associatedConstraints.Add(parameter); - } - - return associatedConstraints; - }); - - _injectedSpecializationType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); - _instantiatedFromMember = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); - - _templateParameters = new Lazy>(() => { - var parameterCount = Handle.GetNumTemplateParameters(0); - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); + _associatedConstraints = LazyList.Create(Handle.NumAssociatedConstraints, (i) => TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i)))); + _injectedSpecializationType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); + _instantiatedFromMember = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _templateParameters = LazyList.Create(Handle.GetNumTemplateParameters(0), (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i)))); } - public IReadOnlyList AssociatedConstraints => _associatedConstraints.Value; + public IReadOnlyList AssociatedConstraints => _associatedConstraints; public bool HasAssociatedConstraints => Handle.NumAssociatedConstraints != 0; @@ -61,5 +37,5 @@ internal ClassTemplatePartialSpecializationDecl(CXCursor handle) : base(handle, public new ClassTemplatePartialSpecializationDecl MostRecentDecl => (ClassTemplatePartialSpecializationDecl)base.MostRecentDecl; - public IReadOnlyList TemplateParameters => _templateParameters.Value; + public IReadOnlyList TemplateParameters => _templateParameters; } diff --git a/sources/ClangSharp/Cursors/Decls/ClassTemplateSpecializationDecl.cs b/sources/ClangSharp/Cursors/Decls/ClassTemplateSpecializationDecl.cs index b3ae1ced..f666ad59 100644 --- a/sources/ClangSharp/Cursors/Decls/ClassTemplateSpecializationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ClassTemplateSpecializationDecl.cs @@ -11,24 +11,13 @@ namespace ClangSharp; public class ClassTemplateSpecializationDecl : CXXRecordDecl { - private readonly Lazy _specializedTemplate; - private readonly Lazy> _templateArgs; + private readonly ValueLazy _specializedTemplate; + private readonly LazyList _templateArgs; internal ClassTemplateSpecializationDecl(CXCursor handle) : this(handle, handle.Kind, CX_DeclKind_ClassTemplateSpecialization) { - _specializedTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _specializedTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } private protected ClassTemplateSpecializationDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) @@ -38,19 +27,8 @@ private protected ClassTemplateSpecializationDecl(CXCursor handle, CXCursorKind throw new ArgumentOutOfRangeException(nameof(handle)); } - _specializedTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _specializedTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } public bool IsClassScopeExplicitSpecialization => IsExplicitSpecialization && (LexicalDeclContext is CXXRecordDecl); @@ -88,5 +66,5 @@ public bool IsExplicitInstantiationOrSpecialization public ClassTemplateDecl SpecializedTemplate => _specializedTemplate.Value; - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Decls/ConceptDecl.cs b/sources/ClangSharp/Cursors/Decls/ConceptDecl.cs index 13b106eb..90007682 100644 --- a/sources/ClangSharp/Cursors/Decls/ConceptDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ConceptDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ConceptDecl : TemplateDecl, IMergeable { - private readonly Lazy _constraintExpr; + private readonly ValueLazy _constraintExpr; internal ConceptDecl(CXCursor handle) : base(handle, CXCursor_ConceptDecl, CX_DeclKind_Concept) { - _constraintExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ConstraintExpr)); + _constraintExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ConstraintExpr)); } public new ConceptDecl CanonicalDecl => (ConceptDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/ConstructorUsingShadowDecl.cs b/sources/ClangSharp/Cursors/Decls/ConstructorUsingShadowDecl.cs index 2a66c1b8..e3020162 100644 --- a/sources/ClangSharp/Cursors/Decls/ConstructorUsingShadowDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ConstructorUsingShadowDecl.cs @@ -9,17 +9,17 @@ namespace ClangSharp; public sealed class ConstructorUsingShadowDecl : UsingShadowDecl { - private readonly Lazy _constructedBaseClass; - private readonly Lazy _constructedBaseClassShadowDecl; - private readonly Lazy _nominatedBaseClass; - private readonly Lazy _nominatedBaseClassShadowDecl; + private readonly ValueLazy _constructedBaseClass; + private readonly ValueLazy _constructedBaseClassShadowDecl; + private readonly ValueLazy _nominatedBaseClass; + private readonly ValueLazy _nominatedBaseClassShadowDecl; internal ConstructorUsingShadowDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_ConstructorUsingShadow) { - _constructedBaseClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ConstructedBaseClass)); - _constructedBaseClassShadowDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ConstructedBaseClassShadowDecl)); - _nominatedBaseClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NominatedBaseClass)); - _nominatedBaseClassShadowDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NominatedBaseClassShadowDecl)); + _constructedBaseClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ConstructedBaseClass)); + _constructedBaseClassShadowDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ConstructedBaseClassShadowDecl)); + _nominatedBaseClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NominatedBaseClass)); + _nominatedBaseClassShadowDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NominatedBaseClassShadowDecl)); } public CXXRecordDecl ConstructedBaseClass => _constructedBaseClass.Value; diff --git a/sources/ClangSharp/Cursors/Decls/Decl.cs b/sources/ClangSharp/Cursors/Decls/Decl.cs index 741afb59..cc9b1429 100644 --- a/sources/ClangSharp/Cursors/Decls/Decl.cs +++ b/sources/ClangSharp/Cursors/Decls/Decl.cs @@ -10,19 +10,19 @@ namespace ClangSharp; public class Decl : Cursor { - private readonly Lazy _asFunction; - private readonly Lazy> _attrs; - private readonly Lazy _body; - private readonly Lazy _canonicalDecl; - private readonly Lazy> _decls; - private readonly Lazy _describedTemplate; - private readonly Lazy _mostRecentDecl; - private readonly Lazy _nextDeclInContext; - private readonly Lazy _nonClosureContext; - private readonly Lazy _parentFunctionOrMethod; - private readonly Lazy _previousDecl; - private readonly Lazy _redeclContext; - private readonly Lazy _translationUnitDecl; + private readonly ValueLazy _asFunction; + private readonly LazyList _attrs; + private readonly ValueLazy _body; + private readonly ValueLazy _canonicalDecl; + private readonly LazyList _decls; + private readonly ValueLazy _describedTemplate; + private readonly ValueLazy _mostRecentDecl; + private readonly ValueLazy _nextDeclInContext; + private readonly ValueLazy _nonClosureContext; + private readonly ValueLazy _parentFunctionOrMethod; + private readonly ValueLazy _previousDecl; + private readonly ValueLazy _redeclContext; + private readonly ValueLazy _translationUnitDecl; private protected Decl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind) { @@ -31,56 +31,29 @@ private protected Decl(CXCursor handle, CXCursorKind expectedCursorKind, CX_Decl throw new ArgumentOutOfRangeException(nameof(handle)); } - _asFunction = new Lazy(() => TranslationUnit.GetOrCreate(Handle.AsFunction)); - - _attrs = new Lazy>(() => { - var attrCount = Handle.NumAttrs; - var attrs = new List(attrCount); - - for (var i = 0; i < attrCount; i++) - { - var attr = TranslationUnit.GetOrCreate(Handle.GetAttr(unchecked((uint)i))); - attrs.Add(attr); - } - - return attrs; - }); - - _body = new Lazy(() => !Handle.Body.IsNull ? TranslationUnit.GetOrCreate(Handle.Body) : null); - _canonicalDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CanonicalCursor)); - - _decls = new Lazy>(() => { - var declCount = Handle.NumDecls; - var decls = new List(declCount); - - for (var i = 0; i < declCount; i++) - { - var decl = TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i))); - decls.Add(decl); - } - - return decls; - }); -; - _describedTemplate = new Lazy(() => - { - CXCursor describedTemplate = Handle.DescribedTemplate; + _asFunction = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsFunction)); + _attrs = LazyList.Create(Handle.NumAttrs, (i) => TranslationUnit.GetOrCreate(Handle.GetAttr(unchecked((uint)i)))); + _body = new ValueLazy(() => !Handle.Body.IsNull ? TranslationUnit.GetOrCreate(Handle.Body) : null); + _canonicalDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CanonicalCursor)); + _decls = LazyList.Create(Handle.NumDecls, (i) => TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i)))); + _describedTemplate = new ValueLazy(() => { + var describedTemplate = Handle.DescribedTemplate; return describedTemplate.IsNull ? null : TranslationUnit.GetOrCreate(describedTemplate); }); - _mostRecentDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.MostRecentDecl)); - _nextDeclInContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NextDeclInContext)); - _nonClosureContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NonClosureContext)); - _parentFunctionOrMethod = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ParentFunctionOrMethod) as IDeclContext); - _previousDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.PreviousDecl)); - _redeclContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.RedeclContext) as IDeclContext); - _translationUnitDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TranslationUnit.Cursor)); + _mostRecentDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.MostRecentDecl)); + _nextDeclInContext = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NextDeclInContext)); + _nonClosureContext = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NonClosureContext)); + _parentFunctionOrMethod = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ParentFunctionOrMethod) as IDeclContext); + _previousDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.PreviousDecl)); + _redeclContext = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.RedeclContext) as IDeclContext); + _translationUnitDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TranslationUnit.Cursor)); } public CX_CXXAccessSpecifier Access => Handle.CXXAccessSpecifier; public FunctionDecl AsFunction => _asFunction.Value; - public IReadOnlyList Attrs => _attrs.Value; + public IReadOnlyList Attrs => _attrs; public CXAvailabilityKind Availability => Handle.Availability; @@ -92,7 +65,7 @@ private protected Decl(CXCursor handle, CXCursorKind expectedCursorKind, CX_Decl public string DeclKindName => Handle.DeclKindSpelling; - public IReadOnlyList Decls => _decls.Value; + public IReadOnlyList Decls => _decls; /// /// Per clang documentation: This returns null for partial specializations, because they are not modeled as TemplateDecls. diff --git a/sources/ClangSharp/Cursors/Decls/DeclaratorDecl.cs b/sources/ClangSharp/Cursors/Decls/DeclaratorDecl.cs index a73b80f5..d45b5969 100644 --- a/sources/ClangSharp/Cursors/Decls/DeclaratorDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/DeclaratorDecl.cs @@ -9,8 +9,8 @@ namespace ClangSharp; public class DeclaratorDecl : ValueDecl { - private readonly Lazy>> _templateParameterLists; - private readonly Lazy _trailingRequiresClause; + private readonly LazyList> _templateParameterLists; + private readonly ValueLazy _trailingRequiresClause; private protected DeclaratorDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -19,33 +19,16 @@ private protected DeclaratorDecl(CXCursor handle, CXCursorKind expectedCursorKin throw new ArgumentOutOfRangeException(nameof(handle)); } - _templateParameterLists = new Lazy>>(() => { - var numTemplateParameterLists = Handle.NumTemplateParameterLists; - var templateParameterLists = new List>(numTemplateParameterLists); - - for (var listIndex = 0; listIndex < numTemplateParameterLists; listIndex++) - { - var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); - var templateParameterList = new List(numTemplateParameters); - - for (var parameterIndex = 0; parameterIndex < numTemplateParameters; parameterIndex++) - { - var templateParameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex))); - templateParameterList.Add(templateParameter); - } - - templateParameterLists.Add(templateParameterList); - } - - return templateParameterLists; + _templateParameterLists = LazyList.Create>(Handle.NumTemplateParameterLists, (listIndex) => { + var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); + return LazyList.Create(numTemplateParameters, (parameterIndex) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex)))); }); - - _trailingRequiresClause = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TrailingRequiresClause)); + _trailingRequiresClause = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TrailingRequiresClause)); } public uint NumTemplateParameterLists => unchecked((uint)Handle.NumTemplateParameterLists); - public IReadOnlyList> TemplateParameterLists => _templateParameterLists.Value; + public IReadOnlyList> TemplateParameterLists => _templateParameterLists; public Expr TrailingRequiresClause => _trailingRequiresClause.Value; } diff --git a/sources/ClangSharp/Cursors/Decls/DecompositionDecl.cs b/sources/ClangSharp/Cursors/Decls/DecompositionDecl.cs index ba7d97c7..7259760f 100644 --- a/sources/ClangSharp/Cursors/Decls/DecompositionDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/DecompositionDecl.cs @@ -1,32 +1,20 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class DecompositionDecl : VarDecl { - private readonly Lazy> _bindings; + private readonly LazyList _bindings; internal DecompositionDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_Decomposition) { - _bindings = new Lazy>(() => { - var numBindings = Handle.NumBindings; - var bindings = new List(numBindings); - - for (var i = 0; i < numBindings; i++) - { - var binding = TranslationUnit.GetOrCreate(Handle.GetBindingDecl(unchecked((uint)i))); - bindings.Add(binding); - } - - return bindings; - }); + _bindings = LazyList.Create(Handle.NumBindings, (i) => TranslationUnit.GetOrCreate(Handle.GetBindingDecl(unchecked((uint)i)))); } - public IReadOnlyList Bindings => _bindings.Value; + public IReadOnlyList Bindings => _bindings; } diff --git a/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs b/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs index 6f19ce36..9a6e7188 100644 --- a/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/EnumConstantDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class EnumConstantDecl : ValueDecl, IMergeable { - private readonly Lazy _initExpr; + private readonly ValueLazy _initExpr; internal EnumConstantDecl(CXCursor handle) : base(handle, CXCursor_EnumConstantDecl, CX_DeclKind_EnumConstant) { - _initExpr = new Lazy(() => !Handle.InitExpr.IsNull ? TranslationUnit.GetOrCreate(Handle.InitExpr) : null); + _initExpr = new ValueLazy(() => !Handle.InitExpr.IsNull ? TranslationUnit.GetOrCreate(Handle.InitExpr) : null); } public new EnumConstantDecl CanonicalDecl => (EnumConstantDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/EnumDecl.cs b/sources/ClangSharp/Cursors/Decls/EnumDecl.cs index 707e9f5f..49442166 100644 --- a/sources/ClangSharp/Cursors/Decls/EnumDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/EnumDecl.cs @@ -10,38 +10,26 @@ namespace ClangSharp; public sealed class EnumDecl : TagDecl { - private readonly Lazy> _enumerators; - private readonly Lazy _instantiatedFromMemberEnum; - private readonly Lazy _integerType; - private readonly Lazy _promotionType; - private readonly Lazy _templateInstantiationPattern; + private readonly LazyList _enumerators; + private readonly ValueLazy _instantiatedFromMemberEnum; + private readonly ValueLazy _integerType; + private readonly ValueLazy _promotionType; + private readonly ValueLazy _templateInstantiationPattern; internal EnumDecl(CXCursor handle) : base(handle, CXCursor_EnumDecl, CX_DeclKind_Enum) { - _enumerators = new Lazy>(() => { - var numEnumerators = Handle.NumEnumerators; - var enumerators = new List(numEnumerators); - - for (var i = 0; i < numEnumerators; i++) - { - var enumerator = TranslationUnit.GetOrCreate(Handle.GetEnumerator(unchecked((uint)i))); - enumerators.Add(enumerator); - } - - return enumerators; - }); - - _instantiatedFromMemberEnum = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); - _integerType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.EnumDecl_IntegerType)); - _promotionType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.EnumDecl_PromotionType)); - _templateInstantiationPattern = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); + _enumerators = LazyList.Create(Handle.NumEnumerators, (i) => TranslationUnit.GetOrCreate(Handle.GetEnumerator(unchecked((uint)i)))); + _instantiatedFromMemberEnum = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _integerType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.EnumDecl_IntegerType)); + _promotionType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.EnumDecl_PromotionType)); + _templateInstantiationPattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); } public new EnumDecl CanonicalDecl => (EnumDecl)base.CanonicalDecl; public new EnumDecl? Definition => (EnumDecl?)base.Definition; - public IReadOnlyList Enumerators => _enumerators.Value; + public IReadOnlyList Enumerators => _enumerators; public EnumDecl InstantiatedFromMemberEnum => _instantiatedFromMemberEnum.Value; diff --git a/sources/ClangSharp/Cursors/Decls/FieldDecl.cs b/sources/ClangSharp/Cursors/Decls/FieldDecl.cs index 35448425..0d2f5592 100644 --- a/sources/ClangSharp/Cursors/Decls/FieldDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/FieldDecl.cs @@ -10,9 +10,9 @@ namespace ClangSharp; public class FieldDecl : DeclaratorDecl, IMergeable { - private readonly Lazy _bitWidth; - private readonly Lazy _inClassInitializer; - private readonly Lazy _isAnonymousField; + private readonly ValueLazy _bitWidth; + private readonly ValueLazy _inClassInitializer; + private readonly ValueLazy _isAnonymousField; internal FieldDecl(CXCursor handle) : this(handle, CXCursor_FieldDecl, CX_DeclKind_Field) { @@ -25,12 +25,12 @@ private protected FieldDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX throw new ArgumentOutOfRangeException(nameof(handle)); } - _bitWidth = new Lazy(() => TranslationUnit.GetOrCreate(Handle.BitWidth)); - _inClassInitializer = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InClassInitializer)); - _isAnonymousField = new Lazy(() => { - var name = Name; + _bitWidth = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.BitWidth)); + _inClassInitializer = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InClassInitializer)); + _isAnonymousField = new ValueLazy(() => { + var name = Name.AsSpan(); - if (string.IsNullOrWhiteSpace(name)) + if (name.IsWhiteSpace()) { return true; } diff --git a/sources/ClangSharp/Cursors/Decls/FriendDecl.cs b/sources/ClangSharp/Cursors/Decls/FriendDecl.cs index c19be2a2..45c4aadc 100644 --- a/sources/ClangSharp/Cursors/Decls/FriendDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/FriendDecl.cs @@ -10,32 +10,15 @@ namespace ClangSharp; public sealed class FriendDecl : Decl { - private readonly Lazy _friendNamedDecl; - private readonly Lazy>> _friendTypeTemplateParameterLists; + private readonly ValueLazy _friendNamedDecl; + private readonly LazyList> _friendTypeTemplateParameterLists; internal FriendDecl(CXCursor handle) : base(handle, CXCursor_FriendDecl, CX_DeclKind_Friend) { - _friendNamedDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.FriendDecl)); - - _friendTypeTemplateParameterLists = new Lazy>>(() => { - var numTemplateParameterLists = Handle.NumTemplateParameterLists; - var templateParameterLists = new List>(numTemplateParameterLists); - - for (var listIndex = 0; listIndex < numTemplateParameterLists; listIndex++) - { - var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); - var templateParameterList = new List(numTemplateParameters); - - for (var parameterIndex = 0; parameterIndex < numTemplateParameters; parameterIndex++) - { - var templateParameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex))); - templateParameterList.Add(templateParameter); - } - - templateParameterLists.Add(templateParameterList); - } - - return templateParameterLists; + _friendNamedDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.FriendDecl)); + _friendTypeTemplateParameterLists = LazyList.Create>(Handle.NumTemplateParameterLists, (listIndex) => { + var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); + return LazyList.Create(numTemplateParameters, (parameterIndex) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex)))); }); } @@ -45,5 +28,5 @@ internal FriendDecl(CXCursor handle) : base(handle, CXCursor_FriendDecl, CX_Decl public uint FriendTypeNumTemplateParameterLists => unchecked((uint)Handle.NumTemplateParameterLists); - public IReadOnlyList> FriendTypeTemplateParameterLists => _friendTypeTemplateParameterLists.Value; + public IReadOnlyList> FriendTypeTemplateParameterLists => _friendTypeTemplateParameterLists; } diff --git a/sources/ClangSharp/Cursors/Decls/FriendTemplateDecl.cs b/sources/ClangSharp/Cursors/Decls/FriendTemplateDecl.cs index 7da60792..ae486c38 100644 --- a/sources/ClangSharp/Cursors/Decls/FriendTemplateDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/FriendTemplateDecl.cs @@ -3,41 +3,24 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class FriendTemplateDecl : Decl { - private readonly Lazy _friendDecl; - private readonly Lazy _friendType; - private readonly Lazy>> _templateParameterLists; + private readonly ValueLazy _friendDecl; + private readonly ValueLazy _friendType; + private readonly LazyList> _templateParameterLists; internal FriendTemplateDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_FriendTemplate) { - _friendDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.FriendDecl)); - _friendType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - - _templateParameterLists = new Lazy>>(() => { - var numTemplateParameterLists = Handle.NumTemplateParameterLists; - var templateParameterLists = new List>(numTemplateParameterLists); - - for (var listIndex = 0; listIndex < numTemplateParameterLists; listIndex++) - { - var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); - var templateParameterList = new List(numTemplateParameters); - - for (var parameterIndex = 0; parameterIndex < numTemplateParameters; parameterIndex++) - { - var templateParameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex))); - templateParameterList.Add(templateParameter); - } - - templateParameterLists.Add(templateParameterList); - } - - return templateParameterLists; + _friendDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.FriendDecl)); + _friendType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _templateParameterLists = LazyList.Create>(Handle.NumTemplateParameterLists, (listIndex) => { + var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); + return LazyList.Create(numTemplateParameters, (parameterIndex) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex)))); }); } @@ -47,5 +30,5 @@ internal FriendTemplateDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDe public uint NumTemplateParameterLists => unchecked((uint)Handle.NumTemplateParameterLists); - public IReadOnlyList> TemplateParameterLists => _templateParameterLists.Value; + public IReadOnlyList> TemplateParameterLists => _templateParameterLists; } diff --git a/sources/ClangSharp/Cursors/Decls/FunctionDecl.cs b/sources/ClangSharp/Cursors/Decls/FunctionDecl.cs index c1054c26..2e1aaca7 100644 --- a/sources/ClangSharp/Cursors/Decls/FunctionDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/FunctionDecl.cs @@ -3,23 +3,23 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public class FunctionDecl : DeclaratorDecl, IDeclContext, IRedeclarable { - private readonly Lazy _callResultType; - private readonly Lazy _declaredReturnType; - private readonly Lazy _definition; - private readonly Lazy _describedFunctionDecl; - private readonly Lazy _instantiatedFromMemberFunction; - private readonly Lazy> _parameters; - private readonly Lazy _primaryTemplate; - private readonly Lazy _returnType; - private readonly Lazy _templateInstantiationPattern; - private readonly Lazy> _templateSpecializationArgs; + private readonly ValueLazy _callResultType; + private readonly ValueLazy _declaredReturnType; + private readonly ValueLazy _definition; + private readonly ValueLazy _describedFunctionDecl; + private readonly ValueLazy _instantiatedFromMemberFunction; + private readonly LazyList _parameters; + private readonly ValueLazy _primaryTemplate; + private readonly ValueLazy _returnType; + private readonly ValueLazy _templateInstantiationPattern; + private readonly LazyList _templateSpecializationArgs; internal FunctionDecl(CXCursor handle) : this(handle, CXCursor_FunctionDecl, CX_DeclKind_Function) { @@ -32,41 +32,16 @@ private protected FunctionDecl(CXCursor handle, CXCursorKind expectedCursorKind, throw new ArgumentOutOfRangeException(nameof(handle)); } - _callResultType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CallResultType)); - _declaredReturnType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DeclaredReturnType)); - _definition = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); - _describedFunctionDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DescribedCursorTemplate)); - _instantiatedFromMemberFunction = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); - - _parameters = new Lazy>(() => { - var parameterCount = Handle.NumArguments; - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); - - _primaryTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.PrimaryTemplate)); - _returnType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); - _templateInstantiationPattern = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); - - _templateSpecializationArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _callResultType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CallResultType)); + _declaredReturnType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DeclaredReturnType)); + _definition = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); + _describedFunctionDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DescribedCursorTemplate)); + _instantiatedFromMemberFunction = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _parameters = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); + _primaryTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.PrimaryTemplate)); + _returnType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); + _templateInstantiationPattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateInstantiationPattern)); + _templateSpecializationArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } public Type CallResultType => _callResultType.Value; @@ -123,7 +98,7 @@ private protected FunctionDecl(CXCursor handle, CXCursorKind expectedCursorKind, public CX_OverloadedOperatorKind OverloadedOperator => Handle.OverloadedOperatorKind; - public IReadOnlyList Parameters => _parameters.Value; + public IReadOnlyList Parameters => _parameters; public FunctionTemplateDecl PrimaryTemplate => _primaryTemplate.Value; @@ -133,7 +108,7 @@ private protected FunctionDecl(CXCursor handle, CXCursorKind expectedCursorKind, public FunctionDecl TemplateInstantiationPattern => _templateInstantiationPattern.Value; - public IReadOnlyList TemplateSpecializationArgs => _templateSpecializationArgs.Value; + public IReadOnlyList TemplateSpecializationArgs => _templateSpecializationArgs; public CX_TemplateSpecializationKind TemplateSpecializationKind => Handle.TemplateSpecializationKind; } diff --git a/sources/ClangSharp/Cursors/Decls/FunctionTemplateDecl.cs b/sources/ClangSharp/Cursors/Decls/FunctionTemplateDecl.cs index 7077354e..3bcac8d5 100644 --- a/sources/ClangSharp/Cursors/Decls/FunctionTemplateDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/FunctionTemplateDecl.cs @@ -1,6 +1,5 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; @@ -10,41 +9,18 @@ namespace ClangSharp; public sealed class FunctionTemplateDecl : RedeclarableTemplateDecl { - private readonly Lazy> _injectedTemplateArgs; - private readonly Lazy> _specializations; + private readonly LazyList _injectedTemplateArgs; + private readonly LazyList _specializations; internal FunctionTemplateDecl(CXCursor handle) : base(handle, CXCursor_FunctionTemplate, CX_DeclKind_FunctionTemplate) { - _injectedTemplateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); - - _specializations = new Lazy>(() => { - var numSpecializations = Handle.NumSpecializations; - var specializations = new List(numSpecializations); - - for (var i = 0; i < numSpecializations; i++) - { - var specialization = TranslationUnit.GetOrCreate(Handle.GetSpecialization(unchecked((uint)i))); - specializations.Add(specialization); - } - - return specializations; - }); + _injectedTemplateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); + _specializations = LazyList.Create(Handle.NumSpecializations, (i) => TranslationUnit.GetOrCreate(Handle.GetSpecialization(unchecked((uint)i)))); } public new FunctionTemplateDecl CanonicalDecl => (FunctionTemplateDecl)base.CanonicalDecl; - public IReadOnlyList InjectedTemplateArgs => _injectedTemplateArgs.Value; + public IReadOnlyList InjectedTemplateArgs => _injectedTemplateArgs; public new FunctionTemplateDecl InstantiatedFromMemberTemplate => (FunctionTemplateDecl)base.InstantiatedFromMemberTemplate; @@ -54,7 +30,7 @@ internal FunctionTemplateDecl(CXCursor handle) : base(handle, CXCursor_FunctionT public new FunctionTemplateDecl PreviousDecl => (FunctionTemplateDecl)base.PreviousDecl; - public IReadOnlyList Specializations => _specializations.Value; + public IReadOnlyList Specializations => _specializations; public new FunctionDecl TemplatedDecl => (FunctionDecl)base.TemplatedDecl; } diff --git a/sources/ClangSharp/Cursors/Decls/ImplicitConceptSpecializationDecl.cs b/sources/ClangSharp/Cursors/Decls/ImplicitConceptSpecializationDecl.cs index 0b65981c..9d6fe8b7 100644 --- a/sources/ClangSharp/Cursors/Decls/ImplicitConceptSpecializationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ImplicitConceptSpecializationDecl.cs @@ -1,6 +1,5 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; using static ClangSharp.Interop.CX_DeclKind; @@ -10,25 +9,14 @@ namespace ClangSharp; public sealed class ImplicitConceptSpecializationDecl : Decl { - private readonly Lazy> _templateArgs; + private readonly LazyList _templateArgs; internal ImplicitConceptSpecializationDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_ImplicitConceptSpecialization) { - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } public uint NumTemplateArgs => unchecked((uint)Handle.NumTemplateArguments); - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Decls/IndirectFieldDecl.cs b/sources/ClangSharp/Cursors/Decls/IndirectFieldDecl.cs index 43102770..0908a98b 100644 --- a/sources/ClangSharp/Cursors/Decls/IndirectFieldDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/IndirectFieldDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class IndirectFieldDecl : ValueDecl, IMergeable { - private readonly Lazy _anonField; - private readonly Lazy _varDecl; + private readonly ValueLazy _anonField; + private readonly ValueLazy _varDecl; internal IndirectFieldDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_IndirectField) { - _anonField = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _varDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _anonField = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _varDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } public FieldDecl AnonField => _anonField.Value; diff --git a/sources/ClangSharp/Cursors/Decls/LabelDecl.cs b/sources/ClangSharp/Cursors/Decls/LabelDecl.cs index 6156f766..7ccbfb16 100644 --- a/sources/ClangSharp/Cursors/Decls/LabelDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/LabelDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class LabelDecl : NamedDecl { - private readonly Lazy _stmt; + private readonly ValueLazy _stmt; internal LabelDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_Label) { - _stmt = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _stmt = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); } public LabelStmt Stmt => _stmt.Value; diff --git a/sources/ClangSharp/Cursors/Decls/LifetimeExtendedTemporaryDecl.cs b/sources/ClangSharp/Cursors/Decls/LifetimeExtendedTemporaryDecl.cs index d2c24a95..4a9bb1f0 100644 --- a/sources/ClangSharp/Cursors/Decls/LifetimeExtendedTemporaryDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/LifetimeExtendedTemporaryDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class LifetimeExtendedTemporaryDecl : Decl, IMergeable { - private readonly Lazy _extendingDecl; - private readonly Lazy _temporaryExpr; + private readonly ValueLazy _extendingDecl; + private readonly ValueLazy _temporaryExpr; internal LifetimeExtendedTemporaryDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_LifetimeExtendedTemporary) { - _extendingDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - _temporaryExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _extendingDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _temporaryExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); } public ValueDecl ExtendingDecl => _extendingDecl.Value; diff --git a/sources/ClangSharp/Cursors/Decls/NamedDecl.cs b/sources/ClangSharp/Cursors/Decls/NamedDecl.cs index d28aff21..dc78fe78 100644 --- a/sources/ClangSharp/Cursors/Decls/NamedDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/NamedDecl.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class NamedDecl : Decl { - private readonly Lazy _underlyingDecl; + private readonly ValueLazy _underlyingDecl; private protected NamedDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -17,7 +17,7 @@ private protected NamedDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX throw new ArgumentOutOfRangeException(nameof(handle)); } - _underlyingDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingDecl)); + _underlyingDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingDecl)); } public CXLinkageKind LinkageInternal => Handle.Linkage; diff --git a/sources/ClangSharp/Cursors/Decls/NamespaceAliasDecl.cs b/sources/ClangSharp/Cursors/Decls/NamespaceAliasDecl.cs index fbff0e97..7bd52219 100644 --- a/sources/ClangSharp/Cursors/Decls/NamespaceAliasDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/NamespaceAliasDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class NamespaceAliasDecl : NamedDecl, IRedeclarable { - private readonly Lazy _aliasedNamespace; - private readonly Lazy _namespace; + private readonly ValueLazy _aliasedNamespace; + private readonly ValueLazy _namespace; internal NamespaceAliasDecl(CXCursor handle) : base(handle, CXCursor_NamespaceAlias, CX_DeclKind_NamespaceAlias) { - _aliasedNamespace = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _namespace = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _aliasedNamespace = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _namespace = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } public NamedDecl AliasedNamespace => _aliasedNamespace.Value; diff --git a/sources/ClangSharp/Cursors/Decls/NamespaceDecl.cs b/sources/ClangSharp/Cursors/Decls/NamespaceDecl.cs index 65b7c6f3..dc6536f6 100644 --- a/sources/ClangSharp/Cursors/Decls/NamespaceDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/NamespaceDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class NamespaceDecl : NamedDecl, IDeclContext, IRedeclarable { - private readonly Lazy _anonymousNamespace; - private readonly Lazy _originalNamespace; + private readonly ValueLazy _anonymousNamespace; + private readonly ValueLazy _originalNamespace; internal NamespaceDecl(CXCursor handle) : base(handle, CXCursor_Namespace, CX_DeclKind_Namespace) { - _anonymousNamespace = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _originalNamespace = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _anonymousNamespace = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _originalNamespace = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } public NamespaceDecl AnonymousNamespace => _anonymousNamespace.Value; diff --git a/sources/ClangSharp/Cursors/Decls/NonTypeTemplateParmDecl.cs b/sources/ClangSharp/Cursors/Decls/NonTypeTemplateParmDecl.cs index d188b482..f49e3425 100644 --- a/sources/ClangSharp/Cursors/Decls/NonTypeTemplateParmDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/NonTypeTemplateParmDecl.cs @@ -3,52 +3,27 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class NonTypeTemplateParmDecl : DeclaratorDecl, ITemplateParmPosition { - private readonly Lazy> _associatedConstraints; - private readonly Lazy _defaultArgument; - private readonly Lazy> _expansionTypes; - private readonly Lazy _placeholderTypeConstraint; + private readonly LazyList _associatedConstraints; + private readonly ValueLazy _defaultArgument; + private readonly LazyList _expansionTypes; + private readonly ValueLazy _placeholderTypeConstraint; internal NonTypeTemplateParmDecl(CXCursor handle) : base(handle, CXCursor_NonTypeTemplateParameter, CX_DeclKind_NonTypeTemplateParm) { - _associatedConstraints = new Lazy>(() => { - var associatedConstraintCount = Handle.NumAssociatedConstraints; - var associatedConstraints = new List(associatedConstraintCount); - - for (var i = 0; i < associatedConstraintCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i))); - associatedConstraints.Add(parameter); - } - - return associatedConstraints; - }); - - _defaultArgument = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DefaultArg)); - - _expansionTypes = new Lazy>(() => { - var numExpansionTypes = Handle.NumExpansionTypes; - var expansionTypes = new List(numExpansionTypes); - - for (var i = 0; i < numExpansionTypes; i++) - { - var expansionType = TranslationUnit.GetOrCreate(Handle.GetExpansionType(unchecked((uint)i))); - expansionTypes.Add(expansionType); - } - - return expansionTypes; - }); - - _placeholderTypeConstraint = new Lazy(() => TranslationUnit.GetOrCreate(Handle.PlaceholderTypeConstraint)); + _associatedConstraints = LazyList.Create(Handle.NumAssociatedConstraints, (i) => TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i)))); + _defaultArgument = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DefaultArg)); + _expansionTypes = LazyList.Create(Handle.NumExpansionTypes, (i) => TranslationUnit.GetOrCreate(Handle.GetExpansionType(unchecked((uint)i)))); + _placeholderTypeConstraint = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.PlaceholderTypeConstraint)); } - public IReadOnlyList AssociatedConstraints => _associatedConstraints.Value; + public IReadOnlyList AssociatedConstraints => _associatedConstraints; public Expr DefaultArgument => _defaultArgument.Value; @@ -56,7 +31,7 @@ internal NonTypeTemplateParmDecl(CXCursor handle) : base(handle, CXCursor_NonTyp public uint Depth => unchecked((uint)Handle.TemplateTypeParmDepth); - public IReadOnlyList ExpansionTypes => _expansionTypes.Value; + public IReadOnlyList ExpansionTypes => _expansionTypes; public bool HasDefaultArgument => Handle.HasDefaultArg; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCCategoryDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCCategoryDecl.cs index 5f3535ba..4c8abea5 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCCategoryDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCCategoryDecl.cs @@ -4,54 +4,30 @@ using System.Collections.Generic; using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCCategoryDecl : ObjCContainerDecl { - private readonly Lazy _classInterface; - private readonly Lazy _implementation; - private readonly Lazy> _ivars; - private readonly Lazy _nextClassCategory; - private readonly Lazy _nextClassCategoryRaw; - private readonly Lazy> _protocols; - private readonly Lazy> _typeParamList; + private readonly ValueLazy _classInterface; + private readonly ValueLazy _implementation; + private readonly ValueLazy> _ivars; + private readonly ValueLazy _nextClassCategory; + private readonly ValueLazy _nextClassCategoryRaw; + private readonly LazyList _protocols; + private readonly LazyList _typeParamList; internal ObjCCategoryDecl(CXCursor handle) : base(handle, CXCursor_ObjCCategoryDecl, CX_DeclKind_ObjCCategory) { - _classInterface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _implementation = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - _ivars = new Lazy>(() => Decls.OfType().ToList()); - _nextClassCategory = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); - _nextClassCategoryRaw = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(3))); - - _protocols = new Lazy>(() => { - var numProtocols = Handle.NumProtocols; - var protocols = new List(numProtocols); - - for (var i = 0; i < numProtocols; i++) - { - var protocol = TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i))); - protocols.Add(protocol); - } - - return protocols; - }); - - _typeParamList = new Lazy>(() => { - var numTypeParams = Handle.NumArguments; - var typeParams = new List(numTypeParams); - - for (var i = 0; i < numTypeParams; i++) - { - var typeParam = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - typeParams.Add(typeParam); - } - - return typeParams; - }); + _classInterface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _implementation = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _ivars = new ValueLazy>(() => [.. Decls.OfType()]); + _nextClassCategory = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); + _nextClassCategoryRaw = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(3))); + _protocols = LazyList.Create(Handle.NumProtocols, (i) => TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i)))); + _typeParamList = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); } public ObjCInterfaceDecl ClassInterface => _classInterface.Value; @@ -66,9 +42,9 @@ internal ObjCCategoryDecl(CXCursor handle) : base(handle, CXCursor_ObjCCategoryD public ObjCCategoryDecl NextClassCategoryRaw => _nextClassCategoryRaw.Value; - public IReadOnlyList Protocols => _protocols.Value; + public IReadOnlyList Protocols => _protocols; public IReadOnlyList ReferencedProtocols => Protocols; - public IReadOnlyList TypeParamList => _typeParamList.Value; + public IReadOnlyList TypeParamList => _typeParamList; } diff --git a/sources/ClangSharp/Cursors/Decls/ObjCCategoryImplDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCCategoryImplDecl.cs index 56f93db9..3c13b54a 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCCategoryImplDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCCategoryImplDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ObjCCategoryImplDecl : ObjCImplDecl { - private readonly Lazy _categoryDecl; + private readonly ValueLazy _categoryDecl; internal ObjCCategoryImplDecl(CXCursor handle) : base(handle, CXCursor_ObjCCategoryImplDecl, CX_DeclKind_ObjCCategoryImpl) { - _categoryDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _categoryDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } public ObjCCategoryDecl CategoryDecl => _categoryDecl.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCCompatibleAliasDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCCompatibleAliasDecl.cs index 246c93df..9c146939 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCCompatibleAliasDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCCompatibleAliasDecl.cs @@ -9,12 +9,12 @@ namespace ClangSharp; public sealed class ObjCCompatibleAliasDecl : NamedDecl { - private readonly Lazy _classInterface; + private readonly ValueLazy _classInterface; internal ObjCCompatibleAliasDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_ObjCCompatibleAlias) { - _classInterface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _classInterface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); } public ObjCInterfaceDecl ClassInterface => _classInterface.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCContainerDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCContainerDecl.cs index fe510167..798d159c 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCContainerDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCContainerDecl.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public class ObjCContainerDecl : NamedDecl, IDeclContext { - private readonly Lazy> _classMethods; - private readonly Lazy> _classProperties; - private readonly Lazy> _instanceMethods; - private readonly Lazy> _instanceProperties; - private readonly Lazy> _methods; - private readonly Lazy> _properties; + private readonly ValueLazy> _classMethods; + private readonly ValueLazy> _classProperties; + private readonly ValueLazy> _instanceMethods; + private readonly ValueLazy> _instanceProperties; + private readonly ValueLazy> _methods; + private readonly ValueLazy> _properties; private protected ObjCContainerDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -24,12 +24,12 @@ private protected ObjCContainerDecl(CXCursor handle, CXCursorKind expectedCursor throw new ArgumentOutOfRangeException(nameof(handle)); } - _classMethods = new Lazy>(() => Methods.Where((method) => method.IsClassMethod).ToList()); - _classProperties = new Lazy>(() => Properties.Where((property) => property.IsClassProperty).ToList()); - _instanceMethods = new Lazy>(() => Methods.Where((method) => method.IsInstanceMethod).ToList()); - _instanceProperties = new Lazy>(() => Properties.Where((property) => property.IsInstanceProperty).ToList()); - _methods = new Lazy>(() => Decls.OfType().ToList()); - _properties = new Lazy>(() => Decls.OfType().ToList()); + _classMethods = new ValueLazy>(() => [.. Methods.Where((method) => method.IsClassMethod)]); + _classProperties = new ValueLazy>(() => [.. Properties.Where((property) => property.IsClassProperty)]); + _instanceMethods = new ValueLazy>(() => [.. Methods.Where((method) => method.IsInstanceMethod)]); + _instanceProperties = new ValueLazy>(() => [.. Properties.Where((property) => property.IsInstanceProperty)]); + _methods = new ValueLazy>(() => [.. Decls.OfType()]); + _properties = new ValueLazy>(() => [.. Decls.OfType()]); } public IReadOnlyList ClassMethods => _classMethods.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCImplDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCImplDecl.cs index 4bd00393..8e2cb00f 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCImplDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCImplDecl.cs @@ -10,8 +10,8 @@ namespace ClangSharp; public class ObjCImplDecl : ObjCContainerDecl { - private readonly Lazy _classInterface; - private readonly Lazy> _propertyImpls; + private readonly ValueLazy _classInterface; + private readonly ValueLazy> _propertyImpls; private protected ObjCImplDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -20,8 +20,8 @@ private protected ObjCImplDecl(CXCursor handle, CXCursorKind expectedCursorKind, throw new ArgumentOutOfRangeException(nameof(handle)); } - _classInterface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _propertyImpls = new Lazy>(() => Decls.OfType().ToList()); + _classInterface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _propertyImpls = new ValueLazy>(() => [.. Decls.OfType()]); } public ObjCInterfaceDecl ClassInterface => _classInterface.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCImplementationDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCImplementationDecl.cs index 6fb29d0f..209ea33f 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCImplementationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCImplementationDecl.cs @@ -1,40 +1,28 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System.Collections.Generic; using System; +using System.Collections.Generic; +using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; -using System.Linq; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCImplementationDecl : ObjCImplDecl { - private readonly Lazy> _initExprs; - private readonly Lazy> _ivars; - private readonly Lazy _superClass; + private readonly LazyList _initExprs; + private readonly ValueLazy> _ivars; + private readonly ValueLazy _superClass; internal ObjCImplementationDecl(CXCursor handle) : base(handle, CXCursor_ObjCImplementationDecl, CX_DeclKind_ObjCImplementation) { - _initExprs = new Lazy>(() => { - var numInitExprs = Handle.NumExprs; - var initExprs = new List(numInitExprs); - - for (var i = 0; i < numInitExprs; i++) - { - var initExpr = TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i))); - initExprs.Add(initExpr); - } - - return initExprs; - }); - - _ivars = new Lazy>(() => Decls.OfType().ToList()); - _superClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _initExprs = LazyList.Create(Handle.NumExprs, (i) => TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i)))); + _ivars = new ValueLazy>(() => [.. Decls.OfType()]); + _superClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } - public IReadOnlyList InitExprs => _initExprs.Value; + public IReadOnlyList InitExprs => _initExprs; public IReadOnlyList Ivars => _ivars.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCInterfaceDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCInterfaceDecl.cs index c76f8c3e..270fe3fe 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCInterfaceDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCInterfaceDecl.cs @@ -1,32 +1,32 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System.Collections.Generic; using System; +using System.Collections.Generic; +using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; -using System.Linq; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCInterfaceDecl : ObjCContainerDecl, IRedeclarable { - private readonly Lazy> _categoryList; - private readonly Lazy _definition; - private readonly Lazy _implementation; - private readonly Lazy> _ivars; - private readonly Lazy> _knownExtensions; - private readonly Lazy> _protocols; - private readonly Lazy _superClass; - private readonly Lazy _superClassType; - private readonly Lazy _typeForDecl; - private readonly Lazy> _typeParamList; - private readonly Lazy> _visibleCategories; - private readonly Lazy> _visibleExtensions; + private readonly ValueLazy> _categoryList; + private readonly ValueLazy _definition; + private readonly ValueLazy _implementation; + private readonly ValueLazy> _ivars; + private readonly ValueLazy> _knownExtensions; + private readonly LazyList _protocols; + private readonly ValueLazy _superClass; + private readonly ValueLazy _superClassType; + private readonly ValueLazy _typeForDecl; + private readonly LazyList _typeParamList; + private readonly ValueLazy> _visibleCategories; + private readonly ValueLazy> _visibleExtensions; internal ObjCInterfaceDecl(CXCursor handle) : base(handle, CXCursor_ObjCInterfaceDecl, CX_DeclKind_ObjCInterface) { - _categoryList = new Lazy>(() => { + _categoryList = new ValueLazy>(() => { var categories = new List(); var category = TranslationUnit.GetOrCreate(handle.GetSubDecl(0)); @@ -40,43 +40,17 @@ internal ObjCInterfaceDecl(CXCursor handle) : base(handle, CXCursor_ObjCInterfac return categories; }); - _definition = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); - _implementation = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - _ivars = new Lazy>(() => Decls.OfType().ToList()); - _knownExtensions = new Lazy>(() => CategoryList.Where((category) => category.IsClassExtension).ToList()); - - _protocols = new Lazy>(() => { - var numProtocols = Handle.NumProtocols; - var protocols = new List(numProtocols); - - for (var i = 0; i < numProtocols; i++) - { - var protocol = TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i))); - protocols.Add(protocol); - } - - return protocols; - }); - - _superClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); - _superClassType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _typeForDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ThisType)); - - _typeParamList = new Lazy>(() => { - var numTypeParams = Handle.NumArguments; - var typeParams = new List(numTypeParams); - - for (var i = 0; i < numTypeParams; i++) - { - var typeParam = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - typeParams.Add(typeParam); - } - - return typeParams; - }); - - _visibleCategories = new Lazy>(() => CategoryList.Where((category) => category.IsUnconditionallyVisible).ToList()); - _visibleExtensions = new Lazy>(() => CategoryList.Where((category) => category.IsClassExtension && category.IsUnconditionallyVisible).ToList()); + _definition = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); + _implementation = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _ivars = new ValueLazy>(() => [.. Decls.OfType()]); + _knownExtensions = new ValueLazy>(() => [.. CategoryList.Where((category) => category.IsClassExtension)]); + _protocols = LazyList.Create(Handle.NumProtocols, (i) => TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i)))); + _superClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); + _superClassType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _typeForDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ThisType)); + _typeParamList = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); + _visibleCategories = new ValueLazy>(() => [.. CategoryList.Where((category) => category.IsUnconditionallyVisible)]); + _visibleExtensions = new ValueLazy>(() => [.. CategoryList.Where((category) => category.IsClassExtension && category.IsUnconditionallyVisible)]); } public new ObjCInterfaceDecl CanonicalDecl => (ObjCInterfaceDecl)base.CanonicalDecl; @@ -99,11 +73,11 @@ internal ObjCInterfaceDecl(CXCursor handle) : base(handle, CXCursor_ObjCInterfac public ObjCObjectType SuperClassType => _superClassType.Value; - public IReadOnlyList Protocols => _protocols.Value; + public IReadOnlyList Protocols => _protocols; public IReadOnlyList ReferencedProtocols => Protocols; - public IReadOnlyList TypeParamList => _typeParamList.Value; + public IReadOnlyList TypeParamList => _typeParamList; public Type TypeForDecl => _typeForDecl.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCIvarDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCIvarDecl.cs index b4b90c20..0b05a131 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCIvarDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCIvarDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class ObjCIvarDecl : FieldDecl { - private readonly Lazy _containingInterface; - private readonly Lazy _nextIvar; + private readonly ValueLazy _containingInterface; + private readonly ValueLazy _nextIvar; internal ObjCIvarDecl(CXCursor handle) : base(handle, CXCursor_ObjCIvarDecl, CX_DeclKind_ObjCIvar) { - _containingInterface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _nextIvar = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _containingInterface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _nextIvar = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); } public ObjCInterfaceDecl ContainingInterface => _containingInterface.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCMethodDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCMethodDecl.cs index c60de569..4bc028f7 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCMethodDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCMethodDecl.cs @@ -3,19 +3,19 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCMethodDecl : NamedDecl, IDeclContext { - private readonly Lazy _classInterface; - private readonly Lazy _cmdDecl; - private readonly Lazy> _parameters; - private readonly Lazy _returnType; - private readonly Lazy _selfDecl; - private readonly Lazy _sendResultType; + private readonly ValueLazy _classInterface; + private readonly ValueLazy _cmdDecl; + private readonly LazyList _parameters; + private readonly ValueLazy _returnType; + private readonly ValueLazy _selfDecl; + private readonly ValueLazy _sendResultType; internal ObjCMethodDecl(CXCursor handle) : base(handle, handle.Kind, CX_DeclKind_ObjCMethod) { @@ -24,25 +24,12 @@ internal ObjCMethodDecl(CXCursor handle) : base(handle, handle.Kind, CX_DeclKind throw new ArgumentOutOfRangeException(nameof(handle)); } - _classInterface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _cmdDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - - _parameters = new Lazy>(() => { - var parameterCount = Handle.NumArguments; - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); - - _selfDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); - _returnType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); - _sendResultType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _classInterface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _cmdDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _parameters = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); + _selfDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); + _returnType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); + _sendResultType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public new ObjCMethodDecl CanonicalDecl => (ObjCMethodDecl)base.CanonicalDecl; @@ -59,7 +46,7 @@ internal ObjCMethodDecl(CXCursor handle) : base(handle, handle.Kind, CX_DeclKind public CXObjCDeclQualifierKind ObjCDeclQualifier => Handle.ObjCDeclQualifiers; - public IReadOnlyList Parameters => _parameters.Value; + public IReadOnlyList Parameters => _parameters; public Type ReturnType => _returnType.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCPropertyDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCPropertyDecl.cs index c36a93b9..faec7053 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCPropertyDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCPropertyDecl.cs @@ -9,17 +9,17 @@ namespace ClangSharp; public sealed class ObjCPropertyDecl : NamedDecl { - private readonly Lazy _getterMethodDecl; - private readonly Lazy _propertyIvarDecl; - private readonly Lazy _setterMethodDecl; - private readonly Lazy _type; + private readonly ValueLazy _getterMethodDecl; + private readonly ValueLazy _propertyIvarDecl; + private readonly ValueLazy _setterMethodDecl; + private readonly ValueLazy _type; internal ObjCPropertyDecl(CXCursor handle) : base(handle, CXCursor_ObjCPropertyDecl, CX_DeclKind_ObjCProperty) { - _getterMethodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _propertyIvarDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - _setterMethodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); - _type = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); + _getterMethodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _propertyIvarDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _setterMethodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); + _type = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ReturnType)); } public ObjCMethodDecl GetterMethodDecl => _getterMethodDecl.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCPropertyImplDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCPropertyImplDecl.cs index 4beab8d3..c52502bf 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCPropertyImplDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCPropertyImplDecl.cs @@ -9,12 +9,12 @@ namespace ClangSharp; public sealed class ObjCPropertyImplDecl : Decl { - private readonly Lazy _getterCXXConstructor; - private readonly Lazy _getterMethodDecl; - private readonly Lazy _propertyDecl; - private readonly Lazy _propertyIvarDecl; - private readonly Lazy _setterMethodDecl; - private readonly Lazy _setterCXXAssignment; + private readonly ValueLazy _getterCXXConstructor; + private readonly ValueLazy _getterMethodDecl; + private readonly ValueLazy _propertyDecl; + private readonly ValueLazy _propertyIvarDecl; + private readonly ValueLazy _setterMethodDecl; + private readonly ValueLazy _setterCXXAssignment; internal ObjCPropertyImplDecl(CXCursor handle) : base(handle, handle.Kind, CX_DeclKind_ObjCPropertyImpl) { @@ -23,12 +23,12 @@ internal ObjCPropertyImplDecl(CXCursor handle) : base(handle, handle.Kind, CX_De throw new ArgumentOutOfRangeException(nameof(handle)); } - _getterCXXConstructor = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); - _getterMethodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); - _propertyDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); - _propertyIvarDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); - _setterMethodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(3))); - _setterCXXAssignment = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(1))); + _getterCXXConstructor = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _getterMethodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(0))); + _propertyDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(1))); + _propertyIvarDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(2))); + _setterMethodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetSubDecl(3))); + _setterCXXAssignment = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(1))); } public Expr GetterCXXConstructor => _getterCXXConstructor.Value; diff --git a/sources/ClangSharp/Cursors/Decls/ObjCProtocolDecl.cs b/sources/ClangSharp/Cursors/Decls/ObjCProtocolDecl.cs index f06e6fee..790f5992 100644 --- a/sources/ClangSharp/Cursors/Decls/ObjCProtocolDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ObjCProtocolDecl.cs @@ -3,32 +3,20 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCProtocolDecl : ObjCContainerDecl, IRedeclarable { - private readonly Lazy _definition; - private readonly Lazy> _protocols; + private readonly ValueLazy _definition; + private readonly LazyList _protocols; internal ObjCProtocolDecl(CXCursor handle) : base(handle, CXCursor_ObjCProtocolDecl, CX_DeclKind_ObjCProtocol) { - _definition = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); - - _protocols = new Lazy>(() => { - var numProtocols = Handle.NumProtocols; - var protocols = new List(numProtocols); - - for (var i = 0; i < numProtocols; i++) - { - var protocol = TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i))); - protocols.Add(protocol); - } - - return protocols; - }); + _definition = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); + _protocols = LazyList.Create(Handle.NumProtocols, (i) => TranslationUnit.GetOrCreate(Handle.GetProtocol(unchecked((uint)i)))); } public new ObjCProtocolDecl CanonicalDecl => (ObjCProtocolDecl)base.CanonicalDecl; @@ -39,7 +27,7 @@ internal ObjCProtocolDecl(CXCursor handle) : base(handle, CXCursor_ObjCProtocolD public string ObjCRuntimeNameAsString => Handle.Name.CString; - public IReadOnlyList Protocols => _protocols.Value; + public IReadOnlyList Protocols => _protocols; public uint ProtocolSize => unchecked((uint)Handle.NumProtocols); diff --git a/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs b/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs index d8d64f90..9064be5e 100644 --- a/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ParmVarDecl.cs @@ -9,15 +9,15 @@ namespace ClangSharp; public sealed class ParmVarDecl : VarDecl { - private readonly Lazy _defaultArg; - private readonly Lazy _originalType; - private readonly Lazy _uninstantiatedDefaultArg; + private readonly ValueLazy _defaultArg; + private readonly ValueLazy _originalType; + private readonly ValueLazy _uninstantiatedDefaultArg; internal ParmVarDecl(CXCursor handle) : base(handle, CXCursor_ParmDecl, CX_DeclKind_ParmVar) { - _defaultArg = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DefaultArg)); - _originalType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); - _uninstantiatedDefaultArg = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UninstantiatedDefaultArg)); + _defaultArg = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DefaultArg)); + _originalType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _uninstantiatedDefaultArg = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UninstantiatedDefaultArg)); } public Expr DefaultArg => _defaultArg.Value; diff --git a/sources/ClangSharp/Cursors/Decls/RecordDecl.cs b/sources/ClangSharp/Cursors/Decls/RecordDecl.cs index 3ad5689a..43edca79 100644 --- a/sources/ClangSharp/Cursors/Decls/RecordDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/RecordDecl.cs @@ -4,18 +4,18 @@ using System.Collections.Generic; using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public class RecordDecl : TagDecl { - private readonly Lazy> _anonymousFields; - private readonly Lazy> _anonymousRecords; - private readonly Lazy> _fields; - private readonly Lazy> _indirectFields; - private readonly Lazy _injectedClassName; + private readonly ValueLazy> _anonymousFields; + private readonly ValueLazy> _anonymousRecords; + private readonly LazyList _fields; + private readonly ValueLazy> _indirectFields; + private readonly ValueLazy _injectedClassName; internal RecordDecl(CXCursor handle) : this(handle, handle.Kind, CX_DeclKind_Record) @@ -34,23 +34,11 @@ private protected RecordDecl(CXCursor handle, CXCursorKind expectedCursorKind, C throw new ArgumentOutOfRangeException(nameof(handle)); } - _fields = new Lazy>(() => { - var numFields = Handle.NumFields; - var fields = new List(numFields); - - for (var i = 0; i < numFields; i++) - { - var field = TranslationUnit.GetOrCreate(Handle.GetField(unchecked((uint)i))); - fields.Add(field); - } - - return fields; - }); - - _anonymousFields = new Lazy>(() => Decls.OfType().Where(decl => decl.IsAnonymousField).ToList()); - _anonymousRecords = new Lazy>(() => Decls.OfType().Where(decl => decl.IsAnonymous && !decl.IsInjectedClassName).ToList()); - _indirectFields = new Lazy>(() => Decls.OfType().ToList()); - _injectedClassName = new Lazy(() => Decls.OfType().Where(decl => decl.IsInjectedClassName).SingleOrDefault()); + _fields = LazyList.Create(Handle.NumFields, (i) => TranslationUnit.GetOrCreate(Handle.GetField(unchecked((uint)i)))); + _anonymousFields = new ValueLazy>(() => [.. Decls.OfType().Where(decl => decl.IsAnonymousField)]); + _anonymousRecords = new ValueLazy>(() => [.. Decls.OfType().Where(decl => decl.IsAnonymous && !decl.IsInjectedClassName)]); + _indirectFields = new ValueLazy>(() => [.. Decls.OfType()]); + _injectedClassName = new ValueLazy(() => Decls.OfType().Where(decl => decl.IsInjectedClassName).SingleOrDefault()); } public bool IsAnonymous => Handle.IsAnonymous; @@ -61,7 +49,7 @@ private protected RecordDecl(CXCursor handle, CXCursorKind expectedCursorKind, C public new RecordDecl? Definition => (RecordDecl?)base.Definition; - public IReadOnlyList Fields => _fields.Value; + public IReadOnlyList Fields => _fields; public IReadOnlyList IndirectFields => _indirectFields.Value; diff --git a/sources/ClangSharp/Cursors/Decls/RedeclarableTemplateDecl.cs b/sources/ClangSharp/Cursors/Decls/RedeclarableTemplateDecl.cs index 76b6eda4..8e209db1 100644 --- a/sources/ClangSharp/Cursors/Decls/RedeclarableTemplateDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/RedeclarableTemplateDecl.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class RedeclarableTemplateDecl : TemplateDecl, IRedeclarable { - private readonly Lazy _instantiatedFromMemberTemplate; + private readonly ValueLazy _instantiatedFromMemberTemplate; private protected RedeclarableTemplateDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -17,7 +17,7 @@ private protected RedeclarableTemplateDecl(CXCursor handle, CXCursorKind expecte throw new ArgumentOutOfRangeException(nameof(handle)); } - _instantiatedFromMemberTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); + _instantiatedFromMemberTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); } public new RedeclarableTemplateDecl CanonicalDecl => (RedeclarableTemplateDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/StaticAssertDecl.cs b/sources/ClangSharp/Cursors/Decls/StaticAssertDecl.cs index d0ab0657..7d6b8c0b 100644 --- a/sources/ClangSharp/Cursors/Decls/StaticAssertDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/StaticAssertDecl.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class StaticAssertDecl : Decl { - private readonly Lazy _assertExpr; - private readonly Lazy _message; + private readonly ValueLazy _assertExpr; + private readonly ValueLazy _message; internal StaticAssertDecl(CXCursor handle) : base(handle, CXCursor_StaticAssert, CX_DeclKind_StaticAssert) { - _assertExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); - _message = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(1))); + _assertExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _message = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(1))); } public Expr AssertExpr => _assertExpr.Value; diff --git a/sources/ClangSharp/Cursors/Decls/TagDecl.cs b/sources/ClangSharp/Cursors/Decls/TagDecl.cs index 85fa287a..fd19d049 100644 --- a/sources/ClangSharp/Cursors/Decls/TagDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TagDecl.cs @@ -3,16 +3,16 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public unsafe class TagDecl : TypeDecl, IDeclContext, IRedeclarable { - private readonly Lazy _definition; - private readonly Lazy>> _templateParameterLists; - private readonly Lazy _typedefNameForAnonDecl; + private readonly ValueLazy _definition; + private readonly LazyList> _templateParameterLists; + private readonly ValueLazy _typedefNameForAnonDecl; private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -21,30 +21,12 @@ private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_D throw new ArgumentOutOfRangeException(nameof(handle)); } - _definition = new Lazy(() => !Handle.Definition.IsNull ? TranslationUnit.GetOrCreate(Handle.Definition) : null); - - _templateParameterLists = new Lazy>>(() => { - var numTemplateParameterLists = Handle.NumTemplateParameterLists; - var templateParameterLists = new List>(numTemplateParameterLists); - - for (var listIndex = 0; listIndex < numTemplateParameterLists; listIndex++) - { - var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); - var templateParameterList = new List(numTemplateParameters); - - for (var parameterIndex = 0; parameterIndex < numTemplateParameters; parameterIndex++) - { - var templateParameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex))); - templateParameterList.Add(templateParameter); - } - - templateParameterLists.Add(templateParameterList); - } - - return templateParameterLists; + _definition = new ValueLazy(() => !Handle.Definition.IsNull ? TranslationUnit.GetOrCreate(Handle.Definition) : null); + _templateParameterLists = LazyList.Create>(Handle.NumTemplateParameterLists, (listIndex) => { + var numTemplateParameters = Handle.GetNumTemplateParameters(unchecked((uint)listIndex)); + return LazyList.Create(numTemplateParameters, (parameterIndex) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(unchecked((uint)listIndex), unchecked((uint)parameterIndex)))); }); - - _typedefNameForAnonDecl = new Lazy(() => !Handle.TypedefNameForAnonDecl.IsNull ? TranslationUnit.GetOrCreate(Handle.TypedefNameForAnonDecl) : null); + _typedefNameForAnonDecl = new ValueLazy(() => !Handle.TypedefNameForAnonDecl.IsNull ? TranslationUnit.GetOrCreate(Handle.TypedefNameForAnonDecl) : null); } public new TagDecl CanonicalDecl => (TagDecl)base.CanonicalDecl; @@ -65,7 +47,7 @@ private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_D public uint NumTemplateParameterLists => unchecked((uint)Handle.NumTemplateParameterLists); - public IReadOnlyList> TemplateParameterLists => _templateParameterLists.Value; + public IReadOnlyList> TemplateParameterLists => _templateParameterLists; public TypedefNameDecl? TypedefNameForAnonDecl => _typedefNameForAnonDecl.Value; } diff --git a/sources/ClangSharp/Cursors/Decls/TemplateDecl.cs b/sources/ClangSharp/Cursors/Decls/TemplateDecl.cs index 706d1ebb..6e146b16 100644 --- a/sources/ClangSharp/Cursors/Decls/TemplateDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TemplateDecl.cs @@ -1,17 +1,17 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using ClangSharp.Interop; -using static ClangSharp.Interop.CX_DeclKind; using System; using System.Collections.Generic; +using ClangSharp.Interop; +using static ClangSharp.Interop.CX_DeclKind; namespace ClangSharp; public class TemplateDecl : NamedDecl { - private readonly Lazy> _associatedConstraints; - private readonly Lazy _templatedDecl; - private readonly Lazy> _templateParameters; + private readonly LazyList _associatedConstraints; + private readonly ValueLazy _templatedDecl; + private readonly LazyList _templateParameters; private protected TemplateDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -20,38 +20,16 @@ private protected TemplateDecl(CXCursor handle, CXCursorKind expectedCursorKind, throw new ArgumentOutOfRangeException(nameof(handle)); } - _associatedConstraints = new Lazy>(() => { - var associatedConstraintCount = Handle.NumAssociatedConstraints; - var associatedConstraints = new List(associatedConstraintCount); - - for (var i = 0; i < associatedConstraintCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i))); - associatedConstraints.Add(parameter); - } - - return associatedConstraints; - }); - _templatedDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplatedDecl)); - _templateParameters = new Lazy>(() => { - var parameterCount = Handle.GetNumTemplateParameters(0); - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); + _associatedConstraints = LazyList.Create(Handle.NumAssociatedConstraints, (i) => TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i)))); + _templatedDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplatedDecl)); + _templateParameters = LazyList.Create(Handle.GetNumTemplateParameters(0), (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i)))); } - public IReadOnlyList AssociatedConstraints => _associatedConstraints.Value; + public IReadOnlyList AssociatedConstraints => _associatedConstraints; public bool HasAssociatedConstraints => AssociatedConstraints.Count != 0; public NamedDecl TemplatedDecl => _templatedDecl.Value; - public IReadOnlyList TemplateParameters => _templateParameters.Value; + public IReadOnlyList TemplateParameters => _templateParameters; } diff --git a/sources/ClangSharp/Cursors/Decls/TemplateTemplateParmDecl.cs b/sources/ClangSharp/Cursors/Decls/TemplateTemplateParmDecl.cs index 5a8bd14b..f308d79a 100644 --- a/sources/ClangSharp/Cursors/Decls/TemplateTemplateParmDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TemplateTemplateParmDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TemplateTemplateParmDecl : TemplateDecl, ITemplateParmPosition { - private readonly Lazy _defaultArgument; + private readonly ValueLazy _defaultArgument; internal TemplateTemplateParmDecl(CXCursor handle) : base(handle, CXCursor_TemplateTemplateParameter, CX_DeclKind_TemplateTemplateParm) { - _defaultArgument = new Lazy(() => TranslationUnit.GetOrCreate(handle.GetTemplateArgumentLoc(0))); + _defaultArgument = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.GetTemplateArgumentLoc(0))); } public TemplateArgumentLoc DefaultArgument => _defaultArgument.Value; diff --git a/sources/ClangSharp/Cursors/Decls/TemplateTypeParmDecl.cs b/sources/ClangSharp/Cursors/Decls/TemplateTypeParmDecl.cs index ca0f4b1f..a118b9bc 100644 --- a/sources/ClangSharp/Cursors/Decls/TemplateTypeParmDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TemplateTypeParmDecl.cs @@ -3,38 +3,27 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed class TemplateTypeParmDecl : TypeDecl { - private readonly Lazy> _associatedConstraints; - private readonly Lazy _defaultArgument; + private readonly LazyList _associatedConstraints; + private readonly ValueLazy _defaultArgument; internal TemplateTypeParmDecl(CXCursor handle) : base(handle, CXCursor_TemplateTypeParameter, CX_DeclKind_TemplateTypeParm) { - _associatedConstraints = new Lazy>(() => { - var associatedConstraintCount = Handle.NumAssociatedConstraints; - var associatedConstraints = new List(associatedConstraintCount); - - for (var i = 0; i < associatedConstraintCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i))); - associatedConstraints.Add(parameter); - } - - return associatedConstraints; - }); - _defaultArgument = new Lazy(() => { - CXType defaultArgType = Handle.DefaultArgType; + _associatedConstraints = LazyList.Create(Handle.NumAssociatedConstraints, (i) => TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i)))); + _defaultArgument = new ValueLazy(() => { + var defaultArgType = Handle.DefaultArgType; return defaultArgType.kind == CXType_Invalid ? null : TranslationUnit.GetOrCreate(defaultArgType); }); } - public IReadOnlyList AssociatedConstraints => _associatedConstraints.Value; + public IReadOnlyList AssociatedConstraints => _associatedConstraints; public Type? DefaultArgument => _defaultArgument.Value; diff --git a/sources/ClangSharp/Cursors/Decls/TopLevelStmtDecl.cs b/sources/ClangSharp/Cursors/Decls/TopLevelStmtDecl.cs index a171987d..fd455390 100644 --- a/sources/ClangSharp/Cursors/Decls/TopLevelStmtDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TopLevelStmtDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TopLevelStmtDecl : Decl { - private readonly Lazy _stmt; + private readonly ValueLazy _stmt; internal TopLevelStmtDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_TopLevelStmt) { - _stmt = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _stmt = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); } public LabelStmt Stmt => _stmt.Value; diff --git a/sources/ClangSharp/Cursors/Decls/TypeDecl.cs b/sources/ClangSharp/Cursors/Decls/TypeDecl.cs index a282ec7f..b6044083 100644 --- a/sources/ClangSharp/Cursors/Decls/TypeDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TypeDecl.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class TypeDecl : NamedDecl { - private readonly Lazy _typeForDecl; + private readonly ValueLazy _typeForDecl; private protected TypeDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -17,7 +17,7 @@ private protected TypeDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_ throw new ArgumentOutOfRangeException(nameof(handle)); } - _typeForDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Type)); + _typeForDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Type)); } public Type TypeForDecl => _typeForDecl.Value; diff --git a/sources/ClangSharp/Cursors/Decls/TypedefNameDecl.cs b/sources/ClangSharp/Cursors/Decls/TypedefNameDecl.cs index 4c43d75e..540e541e 100644 --- a/sources/ClangSharp/Cursors/Decls/TypedefNameDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/TypedefNameDecl.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class TypedefNameDecl : TypeDecl, IRedeclarable { - private readonly Lazy _underlyingType; + private readonly ValueLazy _underlyingType; private protected TypedefNameDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -17,7 +17,7 @@ private protected TypedefNameDecl(CXCursor handle, CXCursorKind expectedCursorKi throw new ArgumentOutOfRangeException(nameof(handle)); } - _underlyingType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypedefDeclUnderlyingType)); + _underlyingType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypedefDeclUnderlyingType)); } public new TypedefNameDecl CanonicalDecl => (TypedefNameDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/UsingEnumDecl.cs b/sources/ClangSharp/Cursors/Decls/UsingEnumDecl.cs index 5888d423..42c7d757 100644 --- a/sources/ClangSharp/Cursors/Decls/UsingEnumDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/UsingEnumDecl.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class UsingEnumDecl : BaseUsingDecl, IMergeable { - private readonly Lazy _enumDecl; + private readonly ValueLazy _enumDecl; internal UsingEnumDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_UsingEnum) { - _enumDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); + _enumDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); } public new UsingEnumDecl CanonicalDecl => (UsingEnumDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/ValueDecl.cs b/sources/ClangSharp/Cursors/Decls/ValueDecl.cs index 13b97501..60729590 100644 --- a/sources/ClangSharp/Cursors/Decls/ValueDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/ValueDecl.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class ValueDecl : NamedDecl { - private readonly Lazy _type; + private readonly ValueLazy _type; private protected ValueDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind) { @@ -17,7 +17,7 @@ private protected ValueDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX throw new ArgumentOutOfRangeException(nameof(handle)); } - _type = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Type)); + _type = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Type)); } public Type Type => _type.Value; diff --git a/sources/ClangSharp/Cursors/Decls/VarDecl.cs b/sources/ClangSharp/Cursors/Decls/VarDecl.cs index b68067b7..d406867b 100644 --- a/sources/ClangSharp/Cursors/Decls/VarDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/VarDecl.cs @@ -9,9 +9,9 @@ namespace ClangSharp; public class VarDecl : DeclaratorDecl, IRedeclarable { - private readonly Lazy _definition; - private readonly Lazy _init; - private readonly Lazy _instantiatedFromStaticDataMember; + private readonly ValueLazy _definition; + private readonly ValueLazy _init; + private readonly ValueLazy _instantiatedFromStaticDataMember; internal VarDecl(CXCursor handle) : this(handle, CXCursor_VarDecl, CX_DeclKind_Var) { @@ -24,9 +24,9 @@ private protected VarDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_D throw new ArgumentOutOfRangeException(nameof(handle)); } - _definition = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); - _init = new Lazy(() => TranslationUnit.GetOrCreate(handle.InitExpr)); - _instantiatedFromStaticDataMember = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _definition = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Definition)); + _init = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.InitExpr)); + _instantiatedFromStaticDataMember = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); } public new VarDecl CanonicalDecl => (VarDecl)base.CanonicalDecl; diff --git a/sources/ClangSharp/Cursors/Decls/VarTemplatePartialSpecializationDecl.cs b/sources/ClangSharp/Cursors/Decls/VarTemplatePartialSpecializationDecl.cs index d44d7087..37f3da16 100644 --- a/sources/ClangSharp/Cursors/Decls/VarTemplatePartialSpecializationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/VarTemplatePartialSpecializationDecl.cs @@ -3,51 +3,29 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public class VarTemplatePartialSpecializationDecl : VarDecl { - private readonly Lazy> _associatedConstraints; - private readonly Lazy _instantiatedFromMember; - private readonly Lazy> _templateParameters; + private readonly LazyList _associatedConstraints; + private readonly ValueLazy _instantiatedFromMember; + private readonly LazyList _templateParameters; internal VarTemplatePartialSpecializationDecl(CXCursor handle) : base(handle, CXCursor_UnexposedDecl, CX_DeclKind_VarTemplatePartialSpecialization) { - _associatedConstraints = new Lazy>(() => { - var associatedConstraintCount = Handle.NumAssociatedConstraints; - var associatedConstraints = new List(associatedConstraintCount); - - for (var i = 0; i < associatedConstraintCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i))); - associatedConstraints.Add(parameter); - } - - return associatedConstraints; - }); - _instantiatedFromMember = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); - _templateParameters = new Lazy>(() => { - var parameterCount = Handle.GetNumTemplateParameters(0); - var parameters = new List(parameterCount); - - for (var i = 0; i < parameterCount; i++) - { - var parameter = TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i))); - parameters.Add(parameter); - } - - return parameters; - }); + _associatedConstraints = LazyList.Create(Handle.NumAssociatedConstraints, (i) => TranslationUnit.GetOrCreate(Handle.GetAssociatedConstraint(unchecked((uint)i)))); + _instantiatedFromMember = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InstantiatedFromMember)); + _templateParameters = LazyList.Create(Handle.GetNumTemplateParameters(0), (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateParameter(0, unchecked((uint)i)))); } - public IReadOnlyList AssociatedConstraints => _associatedConstraints.Value; + public IReadOnlyList AssociatedConstraints => _associatedConstraints; public VarTemplatePartialSpecializationDecl InstantiatedFromMember => _instantiatedFromMember.Value; public new VarTemplatePartialSpecializationDecl MostRecentDecl => (VarTemplatePartialSpecializationDecl)base.MostRecentDecl; - public IReadOnlyList TemplateParameters => _templateParameters.Value; + public IReadOnlyList TemplateParameters => _templateParameters; } diff --git a/sources/ClangSharp/Cursors/Decls/VarTemplateSpecializationDecl.cs b/sources/ClangSharp/Cursors/Decls/VarTemplateSpecializationDecl.cs index 9aed8a7f..2544dab8 100644 --- a/sources/ClangSharp/Cursors/Decls/VarTemplateSpecializationDecl.cs +++ b/sources/ClangSharp/Cursors/Decls/VarTemplateSpecializationDecl.cs @@ -3,15 +3,15 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_DeclKind; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public class VarTemplateSpecializationDecl : VarDecl { - private readonly Lazy _specializedTemplate; - private readonly Lazy> _templateArgs; + private readonly ValueLazy _specializedTemplate; + private readonly LazyList _templateArgs; internal VarTemplateSpecializationDecl(CXCursor handle) : this(handle, CXCursor_UnexposedDecl, CX_DeclKind_VarTemplateSpecialization) { @@ -24,24 +24,13 @@ private protected VarTemplateSpecializationDecl(CXCursor handle, CXCursorKind ex throw new ArgumentOutOfRangeException(nameof(handle)); } - _specializedTemplate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _specializedTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SpecializedCursorTemplate)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } public new VarTemplateSpecializationDecl MostRecentDecl => (VarTemplateSpecializationDecl)base.MostRecentDecl; public VarTemplateDecl SpecializedTemplate => _specializedTemplate.Value; - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/AddrLabelExpr.cs b/sources/ClangSharp/Cursors/Exprs/AddrLabelExpr.cs index 9f81c1ed..6e282a8a 100644 --- a/sources/ClangSharp/Cursors/Exprs/AddrLabelExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/AddrLabelExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class AddrLabelExpr : Expr { - private readonly Lazy _label; + private readonly ValueLazy _label; internal AddrLabelExpr(CXCursor handle) : base(handle, CXCursor_AddrLabelExpr, CX_StmtClass_AddrLabelExpr) { Debug.Assert(NumChildren is 0); - _label = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _label = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public LabelDecl Label => _label.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/AtomicExpr.cs b/sources/ClangSharp/Cursors/Exprs/AtomicExpr.cs index b636751e..1220a135 100644 --- a/sources/ClangSharp/Cursors/Exprs/AtomicExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/AtomicExpr.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_AtomicOperatorKind; @@ -12,13 +11,13 @@ namespace ClangSharp; public sealed class AtomicExpr : Expr { - private readonly Lazy> _subExprs; - private readonly Lazy _valueType; + private readonly LazyList _subExprs; + private readonly ValueLazy _valueType; internal AtomicExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_AtomicExpr) { - _subExprs = new Lazy>(() => Children.Cast().ToList()); - _valueType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _subExprs = LazyList.Create(_children); + _valueType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public CX_AtomicOperatorKind Op => Handle.AtomicOperatorKind; @@ -35,7 +34,7 @@ internal AtomicExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_S or (>= CX_AO__hip_atomic_compare_exchange_strong and <= CX_AO__hip_atomic_store) or (>= CX_AO__scoped_atomic_add_fetch and <= CX_AO__scoped_atomic_xor_fetch)) ? SubExprs[(int)(NumSubExprs - 1)] : null; - public IReadOnlyList SubExprs => _subExprs.Value; + public IReadOnlyList SubExprs => _subExprs; public Expr? Val1 { diff --git a/sources/ClangSharp/Cursors/Exprs/BinaryConditionalOperator.cs b/sources/ClangSharp/Cursors/Exprs/BinaryConditionalOperator.cs index 3de99d52..64ae75bc 100644 --- a/sources/ClangSharp/Cursors/Exprs/BinaryConditionalOperator.cs +++ b/sources/ClangSharp/Cursors/Exprs/BinaryConditionalOperator.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class BinaryConditionalOperator : AbstractConditionalOperator { - private readonly Lazy _opaqueValue; + private readonly ValueLazy _opaqueValue; internal BinaryConditionalOperator(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_BinaryConditionalOperator) { Debug.Assert(NumChildren is 4); - _opaqueValue = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OpaqueValue)); + _opaqueValue = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OpaqueValue)); } public Expr Common => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/BlockExpr.cs b/sources/ClangSharp/Cursors/Exprs/BlockExpr.cs index c1ed5c95..4346a97e 100644 --- a/sources/ClangSharp/Cursors/Exprs/BlockExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/BlockExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class BlockExpr : Expr { - private readonly Lazy _blockDecl; + private readonly ValueLazy _blockDecl; internal BlockExpr(CXCursor handle) : base(handle, CXCursor_BlockExpr, CX_StmtClass_BlockExpr) { Debug.Assert(NumChildren is 0); - _blockDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _blockDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public BlockDecl BlockDecl => _blockDecl.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXBoolLiteralExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXBoolLiteralExpr.cs index 108c5d1a..e706c6fd 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXBoolLiteralExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXBoolLiteralExpr.cs @@ -11,13 +11,13 @@ namespace ClangSharp; public sealed class CXXBoolLiteralExpr : Expr { - private readonly Lazy _valueString; + private readonly ValueLazy _valueString; internal CXXBoolLiteralExpr(CXCursor handle) : base(handle, CXCursor_CXXBoolLiteralExpr, CX_StmtClass_CXXBoolLiteralExpr) { Debug.Assert(NumChildren is 0); - _valueString = new Lazy(() => { + _valueString = new ValueLazy(() => { var tokens = Handle.TranslationUnit.Tokenize(Handle.SourceRange); if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Keyword and not CXToken_Identifier)) diff --git a/sources/ClangSharp/Cursors/Exprs/CXXConstructExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXConstructExpr.cs index b24c706f..03c749e7 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXConstructExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXConstructExpr.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -12,8 +11,8 @@ namespace ClangSharp; public class CXXConstructExpr : Expr { - private readonly Lazy> _args; - private readonly Lazy _constructor; + private readonly LazyList _args; + private readonly ValueLazy _constructor; internal CXXConstructExpr(CXCursor handle) : this(handle, CXCursor_CallExpr, CX_StmtClass_CXXConstructExpr) { @@ -27,11 +26,11 @@ private protected CXXConstructExpr(CXCursor handle, CXCursorKind expectedCursorK } Debug.Assert(NumChildren == NumArgs); - _args = new Lazy>(() => Children.Cast().ToList()); - _constructor = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _args = LazyList.Create(_children); + _constructor = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } - public IReadOnlyList Args => _args.Value; + public IReadOnlyList Args => _args; public CXXConstructorDecl Constructor => _constructor.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs index c4180a7d..b3b48670 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXDefaultArgExpr.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class CXXDefaultArgExpr : Expr { - private readonly Lazy _param; - private readonly Lazy _usedContext; + private readonly ValueLazy _param; + private readonly ValueLazy _usedContext; internal CXXDefaultArgExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_CXXDefaultArgExpr) { Debug.Assert(NumChildren is 0); - _param = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _usedContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UsedContext) as IDeclContext); + _param = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _usedContext = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UsedContext) as IDeclContext); } public ParmVarDecl Param => _param.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXDefaultInitExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXDefaultInitExpr.cs index 0d1e0609..0b1908e4 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXDefaultInitExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXDefaultInitExpr.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class CXXDefaultInitExpr : Expr { - private readonly Lazy _field; - private readonly Lazy _usedContext; + private readonly ValueLazy _field; + private readonly ValueLazy _usedContext; internal CXXDefaultInitExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_CXXDefaultInitExpr) { Debug.Assert(NumChildren is 0); - _field = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _usedContext = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UsedContext) as IDeclContext); + _field = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _usedContext = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UsedContext) as IDeclContext); } public Expr Expr => Field.InClassInitializer; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXDeleteExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXDeleteExpr.cs index 5b7ce069..6c1272cb 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXDeleteExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXDeleteExpr.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class CXXDeleteExpr : Expr { - private readonly Lazy _destroyedType; - private readonly Lazy _operatorDelete; + private readonly ValueLazy _destroyedType; + private readonly ValueLazy _operatorDelete; internal CXXDeleteExpr(CXCursor handle) : base(handle, CXCursor_CXXDeleteExpr, CX_StmtClass_CXXDeleteExpr) { Debug.Assert(NumChildren is 1); - _destroyedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _operatorDelete = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _destroyedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _operatorDelete = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public Expr Argument => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXDependentScopeMemberExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXDependentScopeMemberExpr.cs index 1e85bc6f..41998327 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXDependentScopeMemberExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXDependentScopeMemberExpr.cs @@ -5,35 +5,24 @@ using System.Diagnostics; using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class CXXDependentScopeMemberExpr : Expr { - private readonly Lazy _baseType; - private readonly Lazy _firstQualifierFoundInScope; - private readonly Lazy> _templateArgs; + private readonly ValueLazy _baseType; + private readonly ValueLazy _firstQualifierFoundInScope; + private readonly LazyList _templateArgs; internal CXXDependentScopeMemberExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_CXXDependentScopeMemberExpr) { Debug.Assert(NumChildren is 0 or 1); - _baseType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _firstQualifierFoundInScope = new Lazy(() => TranslationUnit.GetOrCreate(handle.Referenced)); - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _baseType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _firstQualifierFoundInScope = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.Referenced)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } public Expr? Base => (Expr?)Children.SingleOrDefault(); @@ -54,5 +43,5 @@ internal CXXDependentScopeMemberExpr(CXCursor handle) : base(handle, CXCursor_Me public uint NumTemplateArgs => unchecked((uint)Handle.NumTemplateArguments); - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/CXXInheritedCtorInitExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXInheritedCtorInitExpr.cs index 9f49018c..a32fd684 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXInheritedCtorInitExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXInheritedCtorInitExpr.cs @@ -11,12 +11,12 @@ namespace ClangSharp; public sealed class CXXInheritedCtorInitExpr : Expr { - private readonly Lazy _constructor; + private readonly ValueLazy _constructor; internal CXXInheritedCtorInitExpr(CXCursor handle) : base(handle, CXCursor_CallExpr, CX_StmtClass_CXXInheritedCtorInitExpr) { Debug.Assert(NumChildren is 0); - _constructor = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _constructor = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public CX_ConstructionKind ConstructionKind => ConstructsVBase ? CX_CK_VirtualBase : CX_CK_NonVirtualBase; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXNewExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXNewExpr.cs index bb2d5970..27fc2039 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXNewExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXNewExpr.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,15 +10,15 @@ namespace ClangSharp; public sealed class CXXNewExpr : Expr { - private readonly Lazy _operatorDelete; - private readonly Lazy _operatorNew; - private readonly Lazy> _placementArgs; + private readonly ValueLazy _operatorDelete; + private readonly ValueLazy _operatorNew; + private readonly LazyList _placementArgs; internal CXXNewExpr(CXCursor handle) : base(handle, CXCursor_CXXNewExpr, CX_StmtClass_CXXNewExpr) { - _operatorDelete = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(0))); - _operatorNew = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(1))); - _placementArgs = new Lazy>(() => Children.Skip(PlacementNewArgsOffset).Cast().ToList()); + _operatorDelete = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(0))); + _operatorNew = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(1))); + _placementArgs = LazyList.Create(_children, skip: PlacementNewArgsOffset); } public Type AllocatedType => ((PointerType)Type).PointeeType; @@ -44,7 +43,7 @@ internal CXXNewExpr(CXCursor handle) : base(handle, CXCursor_CXXNewExpr, CX_Stmt public FunctionDecl OperatorNew => _operatorNew.Value; - public IReadOnlyList PlacementArgs => _placementArgs.Value; + public IReadOnlyList PlacementArgs => _placementArgs; private static int ArraySizeOffset => 0; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXParenListInitExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXParenListInitExpr.cs index a850d718..3d118c5a 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXParenListInitExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXParenListInitExpr.cs @@ -1,53 +1,31 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System.Collections.Generic; using System; +using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class CXXParenListInitExpr : Expr { - private readonly Lazy _arrayFillerOrUnionFieldInit; - private readonly Lazy> _initExprs; - private readonly Lazy> _userSpecifiedInitExprs; + private readonly ValueLazy _arrayFillerOrUnionFieldInit; + private readonly LazyList _initExprs; + private readonly LazyList _userSpecifiedInitExprs; internal CXXParenListInitExpr(CXCursor handle) : base(handle, CXCursor_CXXParenListInitExpr, CX_StmtClass_CXXParenListInitExpr) { - _arrayFillerOrUnionFieldInit = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); - _initExprs = new Lazy>(() => { - var numInitExprs = Handle.NumExprs; - var initExprs = new List(numInitExprs); - - for (var i = 0; i < numInitExprs; i++) - { - var initExpr = TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i))); - initExprs.Add(initExpr); - } - - return initExprs; - }); - _userSpecifiedInitExprs = new Lazy>(() => { - var numUserSpecifiedInitExprs = Handle.NumExprsOther; - var userSpecifiedInitExprs = new List(numUserSpecifiedInitExprs); - - for (var i = 0; i < numUserSpecifiedInitExprs; i++) - { - var initExpr = TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i))); - userSpecifiedInitExprs.Add(initExpr); - } - - return userSpecifiedInitExprs; - }); + _arrayFillerOrUnionFieldInit = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); + _initExprs = LazyList.Create(Handle.NumExprs, (i) => TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i)))); + _userSpecifiedInitExprs = LazyList.Create(Handle.NumExprsOther, (i) => TranslationUnit.GetOrCreate(Handle.GetExpr(unchecked((uint)i)))); } public Expr? ArrayFiller => _arrayFillerOrUnionFieldInit.Value as Expr; - public IReadOnlyList InitExprs => _initExprs.Value; + public IReadOnlyList InitExprs => _initExprs; public FieldDecl? InitializedFieldInUnion => _arrayFillerOrUnionFieldInit.Value as FieldDecl; - public IReadOnlyList UserSpecifiedInitExprs => _userSpecifiedInitExprs.Value; + public IReadOnlyList UserSpecifiedInitExprs => _userSpecifiedInitExprs; } diff --git a/sources/ClangSharp/Cursors/Exprs/CXXPseudoDestructorExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXPseudoDestructorExpr.cs index 9ae182cb..2786d77c 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXPseudoDestructorExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXPseudoDestructorExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class CXXPseudoDestructorExpr : Expr { - private readonly Lazy _destroyedType; + private readonly ValueLazy _destroyedType; internal CXXPseudoDestructorExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_CXXPseudoDestructorExpr) { Debug.Assert(NumChildren is 1); - _destroyedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _destroyedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Expr Base => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXRewrittenBinaryOperator.cs b/sources/ClangSharp/Cursors/Exprs/CXXRewrittenBinaryOperator.cs index d1de6a59..425b307b 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXRewrittenBinaryOperator.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXRewrittenBinaryOperator.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class CXXRewrittenBinaryOperator : Expr { - private readonly Lazy _lhs; - private readonly Lazy _rhs; + private readonly ValueLazy _lhs; + private readonly ValueLazy _rhs; internal CXXRewrittenBinaryOperator(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_CXXRewrittenBinaryOperator) { Debug.Assert(NumChildren is 1); - _lhs = new Lazy(() => TranslationUnit.GetOrCreate(Handle.LhsExpr)); - _rhs = new Lazy(() => TranslationUnit.GetOrCreate(Handle.RhsExpr)); + _lhs = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.LhsExpr)); + _rhs = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.RhsExpr)); } public Expr LHS => _lhs.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXScalarValueInitExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXScalarValueInitExpr.cs index 4a79e38b..3ea071f6 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXScalarValueInitExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXScalarValueInitExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class CXXScalarValueInitExpr : Expr { - private readonly Lazy _typeSourceInfoType; + private readonly ValueLazy _typeSourceInfoType; internal CXXScalarValueInitExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_CXXScalarValueInitExpr) { Debug.Assert(NumChildren is 0); - _typeSourceInfoType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _typeSourceInfoType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Type TypeSourceInfoType => _typeSourceInfoType.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXTemporaryObjectExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXTemporaryObjectExpr.cs index 31e25694..ded5561d 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXTemporaryObjectExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXTemporaryObjectExpr.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class CXXTemporaryObjectExpr : CXXConstructExpr { - private readonly Lazy _typeSourceInfoType; + private readonly ValueLazy _typeSourceInfoType; internal CXXTemporaryObjectExpr(CXCursor handle) : base(handle, CXCursor_CallExpr, CX_StmtClass_CXXTemporaryObjectExpr) { - _typeSourceInfoType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _typeSourceInfoType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Type TypeSourceInfoType => _typeSourceInfoType.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXTypeidExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXTypeidExpr.cs index b90efcdc..a6e9249c 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXTypeidExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXTypeidExpr.cs @@ -11,12 +11,12 @@ namespace ClangSharp; public sealed class CXXTypeidExpr : Expr { - private readonly Lazy _typeOperand; + private readonly ValueLazy _typeOperand; internal CXXTypeidExpr(CXCursor handle) : base(handle, CXCursor_CXXTypeidExpr, CX_StmtClass_CXXTypeidExpr) { Debug.Assert(NumChildren is 0 or 1); - _typeOperand = new Lazy(() => TranslationUnit.GetOrCreate(handle.TypeOperand)); + _typeOperand = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.TypeOperand)); } public Expr? ExprOperand => (Expr?)Children.SingleOrDefault(); diff --git a/sources/ClangSharp/Cursors/Exprs/CXXUnresolvedConstructExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXUnresolvedConstructExpr.cs index 1d1bdf40..82558693 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXUnresolvedConstructExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXUnresolvedConstructExpr.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,16 +10,16 @@ namespace ClangSharp; public sealed class CXXUnresolvedConstructExpr : Expr { - private readonly Lazy> _args; - private readonly Lazy _typeAsWritten; + private readonly LazyList _args; + private readonly ValueLazy _typeAsWritten; internal CXXUnresolvedConstructExpr(CXCursor handle) : base(handle, CXCursor_CallExpr, CX_StmtClass_CXXUnresolvedConstructExpr) { - _args = new Lazy>(() => Children.Cast().ToList()); - _typeAsWritten = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _args = LazyList.Create(_children); + _typeAsWritten = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } - public IReadOnlyList Args => _args.Value; + public IReadOnlyList Args => _args; public bool IsListInitialization => Handle.IsListInitialization; diff --git a/sources/ClangSharp/Cursors/Exprs/CXXUuidofExpr.cs b/sources/ClangSharp/Cursors/Exprs/CXXUuidofExpr.cs index 5873afa4..19ac1b64 100644 --- a/sources/ClangSharp/Cursors/Exprs/CXXUuidofExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CXXUuidofExpr.cs @@ -11,15 +11,15 @@ namespace ClangSharp; public sealed class CXXUuidofExpr : Expr { - private readonly Lazy _typeOperand; - private readonly Lazy _guidDecl; + private readonly ValueLazy _typeOperand; + private readonly ValueLazy _guidDecl; internal CXXUuidofExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_CXXUuidofExpr) { Debug.Assert(NumChildren is 0 or 1); - _typeOperand = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _guidDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _typeOperand = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _guidDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public Expr? ExprOperand => (Expr?)Children.SingleOrDefault(); diff --git a/sources/ClangSharp/Cursors/Exprs/CallExpr.cs b/sources/ClangSharp/Cursors/Exprs/CallExpr.cs index 0fb2f058..9f2076e7 100644 --- a/sources/ClangSharp/Cursors/Exprs/CallExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CallExpr.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -12,8 +11,8 @@ namespace ClangSharp; public class CallExpr : Expr { - private readonly Lazy> _args; - private readonly Lazy _calleeDecl; + private readonly LazyList _args; + private readonly ValueLazy _calleeDecl; internal CallExpr(CXCursor handle) : this(handle, CXCursor_CallExpr, CX_StmtClass_CallExpr) { @@ -28,11 +27,11 @@ private protected CallExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_ Debug.Assert(NumChildren >= 1); - _args = new Lazy>(() => Children.Skip(1).Take((int)NumArgs).Cast().ToList()); - _calleeDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _args = LazyList.Create(_children, skip: 1, take: (int)NumArgs); + _calleeDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } - public IReadOnlyList Args => _args.Value; + public IReadOnlyList Args => _args; public Expr Callee => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/CastExpr.cs b/sources/ClangSharp/Cursors/Exprs/CastExpr.cs index e69580a8..c5d56d51 100644 --- a/sources/ClangSharp/Cursors/Exprs/CastExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CastExpr.cs @@ -11,8 +11,8 @@ namespace ClangSharp; public class CastExpr : Expr { - private readonly Lazy> _path; - private readonly Lazy _targetUnionField; + private readonly LazyList _path; + private readonly ValueLazy _targetUnionField; private protected CastExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind, expectedStmtClass) { @@ -23,19 +23,8 @@ private protected CastExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_ Debug.Assert(NumChildren is 1); - _path = new Lazy>(() => { - var pathSize = Handle.NumArguments; - var path = new List(pathSize); - - for (var i = 0; i < pathSize; i++) - { - var item = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - path.Add(item); - } - - return path; - }); - _targetUnionField = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TargetUnionField)); + _path = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); + _targetUnionField = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TargetUnionField)); } public CX_CastKind CastKind => Handle.CastKind; @@ -72,7 +61,7 @@ public NamedDecl? ConversionFunction public bool PathEmpty => PathSize == 0; - public IReadOnlyList Path => _path.Value; + public IReadOnlyList Path => _path; public uint PathSize => unchecked((uint)Handle.NumArguments); diff --git a/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs b/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs index 3741af7f..7f3addf1 100644 --- a/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/CharacterLiteral.cs @@ -12,13 +12,13 @@ namespace ClangSharp; public sealed class CharacterLiteral : Expr { - private readonly Lazy _valueString; + private readonly ValueLazy _valueString; internal CharacterLiteral(CXCursor handle) : base(handle, CXCursor_CharacterLiteral, CX_StmtClass_CharacterLiteral) { Debug.Assert(NumChildren is 0); - _valueString = new Lazy(() => { + _valueString = new ValueLazy(() => { var tokens = Handle.TranslationUnit.Tokenize(Handle.SourceRange); if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) diff --git a/sources/ClangSharp/Cursors/Exprs/CompoundAssignOperator.cs b/sources/ClangSharp/Cursors/Exprs/CompoundAssignOperator.cs index 435b09b2..d3903c7a 100644 --- a/sources/ClangSharp/Cursors/Exprs/CompoundAssignOperator.cs +++ b/sources/ClangSharp/Cursors/Exprs/CompoundAssignOperator.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class CompoundAssignOperator : BinaryOperator { - private readonly Lazy _computationLHSType; - private readonly Lazy _computationResultType; + private readonly ValueLazy _computationLHSType; + private readonly ValueLazy _computationResultType; internal CompoundAssignOperator(CXCursor handle) : base(handle, CXCursor_CompoundAssignOperator, CX_StmtClass_CompoundAssignOperator) { - _computationLHSType = new Lazy(() => TranslationUnit.GetOrCreate(handle.ComputationLhsType)); - _computationResultType = new Lazy(() => TranslationUnit.GetOrCreate(handle.ComputationResultType)); + _computationLHSType = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.ComputationLhsType)); + _computationResultType = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.ComputationResultType)); } public Type ComputationLHSType => _computationLHSType.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/CompoundLiteralExpr.cs b/sources/ClangSharp/Cursors/Exprs/CompoundLiteralExpr.cs index 5cb661d6..3316992c 100644 --- a/sources/ClangSharp/Cursors/Exprs/CompoundLiteralExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/CompoundLiteralExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class CompoundLiteralExpr : Expr { - private readonly Lazy _typeSourceInfoType; + private readonly ValueLazy _typeSourceInfoType; internal CompoundLiteralExpr(CXCursor handle) : base(handle, CXCursor_CompoundLiteralExpr, CX_StmtClass_CompoundLiteralExpr) { Debug.Assert(NumChildren is 1); - _typeSourceInfoType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _typeSourceInfoType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public bool IsFileScope => Handle.IsFileScope; diff --git a/sources/ClangSharp/Cursors/Exprs/DeclRefExpr.cs b/sources/ClangSharp/Cursors/Exprs/DeclRefExpr.cs index 826e1cdd..83915f4a 100644 --- a/sources/ClangSharp/Cursors/Exprs/DeclRefExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/DeclRefExpr.cs @@ -4,16 +4,16 @@ using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class DeclRefExpr : Expr { - private readonly Lazy _decl; - private readonly Lazy _foundDecl; - private readonly Lazy> _templateArgs; + private readonly ValueLazy _decl; + private readonly ValueLazy _foundDecl; + private readonly LazyList _templateArgs; internal DeclRefExpr(CXCursor handle) : base(handle, handle.Kind, CX_StmtClass_DeclRefExpr) { @@ -24,21 +24,9 @@ internal DeclRefExpr(CXCursor handle) : base(handle, handle.Kind, CX_StmtClass_D Debug.Assert(NumChildren is 0); - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _foundDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.FoundDecl)); - - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _foundDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.FoundDecl)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } public ValueDecl Decl => _decl.Value; @@ -55,5 +43,5 @@ internal DeclRefExpr(CXCursor handle) : base(handle, handle.Kind, CX_StmtClass_D public uint NumTemplateArgs => unchecked((uint)Handle.NumTemplateArguments); - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/DependentScopeDeclRefExpr.cs b/sources/ClangSharp/Cursors/Exprs/DependentScopeDeclRefExpr.cs index 6798c20a..793df4cf 100644 --- a/sources/ClangSharp/Cursors/Exprs/DependentScopeDeclRefExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/DependentScopeDeclRefExpr.cs @@ -1,34 +1,21 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class DependentScopeDeclRefExpr : Expr { - private readonly Lazy> _templateArgs; + private readonly LazyList _templateArgs; internal DependentScopeDeclRefExpr(CXCursor handle) : base(handle, CXCursor_DeclRefExpr, CX_StmtClass_DependentScopeDeclRefExpr) { Debug.Assert(NumChildren is 0); - - _templateArgs = new Lazy>(() => { - var numTemplateArgs = Handle.NumTemplateArguments; - var templateArgs = new List(numTemplateArgs); - - for (var i = 0; i < numTemplateArgs; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } public string DeclName => Handle.Name.CString; @@ -37,5 +24,5 @@ internal DependentScopeDeclRefExpr(CXCursor handle) : base(handle, CXCursor_Decl public bool HasTemplateKeyword => Handle.HasTemplateKeyword; - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/ExplicitCastExpr.cs b/sources/ClangSharp/Cursors/Exprs/ExplicitCastExpr.cs index 6c066bab..1dc88bec 100644 --- a/sources/ClangSharp/Cursors/Exprs/ExplicitCastExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ExplicitCastExpr.cs @@ -8,7 +8,7 @@ namespace ClangSharp; public class ExplicitCastExpr : CastExpr { - private readonly Lazy _typeAsWritten; + private readonly ValueLazy _typeAsWritten; private protected ExplicitCastExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind, expectedStmtClass) { @@ -17,7 +17,7 @@ private protected ExplicitCastExpr(CXCursor handle, CXCursorKind expectedCursorK throw new ArgumentOutOfRangeException(nameof(handle)); } - _typeAsWritten = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _typeAsWritten = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Type TypeAsWritten => _typeAsWritten.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/Expr.cs b/sources/ClangSharp/Cursors/Exprs/Expr.cs index 331ca03a..4d5debe7 100644 --- a/sources/ClangSharp/Cursors/Exprs/Expr.cs +++ b/sources/ClangSharp/Cursors/Exprs/Expr.cs @@ -57,7 +57,7 @@ public class Expr : ValueStmt return e; }; - private readonly Lazy _type; + private readonly ValueLazy _type; private protected Expr(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind, expectedStmtClass) { @@ -66,7 +66,7 @@ private protected Expr(CXCursor handle, CXCursorKind expectedCursorKind, CX_Stmt throw new ArgumentOutOfRangeException(nameof(handle)); } - _type = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Type)); + _type = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Type)); } public bool ContainsErrors => (Dependence & CX_ED_Error) != 0; diff --git a/sources/ClangSharp/Cursors/Exprs/ExprWithCleanups.cs b/sources/ClangSharp/Cursors/Exprs/ExprWithCleanups.cs index ddc57336..648cd5a4 100644 --- a/sources/ClangSharp/Cursors/Exprs/ExprWithCleanups.cs +++ b/sources/ClangSharp/Cursors/Exprs/ExprWithCleanups.cs @@ -1,34 +1,22 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ExprWithCleanups : FullExpr { - private readonly Lazy> _objects; + private readonly LazyList _objects; internal ExprWithCleanups(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ExprWithCleanups) { - _objects = new Lazy>(() => { - var numObjects = Handle.NumArguments; - var objects = new List(numObjects); - - for (var i = 0; i < numObjects; i++) - { - var obj = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - objects.Add(obj); - } - - return objects; - }); + _objects = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); } public uint NumObjects => unchecked((uint)Handle.NumArguments); - public IReadOnlyList Objects => _objects.Value; + public IReadOnlyList Objects => _objects; } diff --git a/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs b/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs index b99fbeb6..fd6d4afc 100644 --- a/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/FloatingLiteral.cs @@ -12,11 +12,11 @@ namespace ClangSharp; public sealed class FloatingLiteral : Expr { - private readonly Lazy _valueString; + private readonly ValueLazy _valueString; internal FloatingLiteral(CXCursor handle) : base(handle, CXCursor_FloatingLiteral, CX_StmtClass_FloatingLiteral) { - _valueString = new Lazy(() => { + _valueString = new ValueLazy(() => { var tokens = Handle.TranslationUnit.Tokenize(Handle.SourceRange); if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) diff --git a/sources/ClangSharp/Cursors/Exprs/FunctionParmPackExpr.cs b/sources/ClangSharp/Cursors/Exprs/FunctionParmPackExpr.cs index f406b5b7..fee590ae 100644 --- a/sources/ClangSharp/Cursors/Exprs/FunctionParmPackExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/FunctionParmPackExpr.cs @@ -4,36 +4,25 @@ using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class FunctionParmPackExpr : Expr { - private readonly Lazy> _expansions; - private readonly Lazy _parameterPack; + private readonly LazyList _expansions; + private readonly ValueLazy _parameterPack; internal FunctionParmPackExpr(CXCursor handle) : base(handle, CXCursor_DeclRefExpr, CX_StmtClass_FunctionParmPackExpr) { Debug.Assert(NumChildren is 0); - _expansions = new Lazy>(() => { - var numExpansions = Handle.NumDecls; - var expansions = new List(numExpansions); - - for (var i = 0; i < numExpansions; i++) - { - var expansion = TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i))); - expansions.Add(expansion); - } - - return expansions; - }); - _parameterPack = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _expansions = LazyList.Create(Handle.NumDecls, (i) => TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i)))); + _parameterPack = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } - public IReadOnlyList Expansions => _expansions.Value; + public IReadOnlyList Expansions => _expansions; public uint NumExpansions => unchecked((uint)Handle.NumDecls); diff --git a/sources/ClangSharp/Cursors/Exprs/GenericSelectionExpr.cs b/sources/ClangSharp/Cursors/Exprs/GenericSelectionExpr.cs index c1d1db04..aa1ec431 100644 --- a/sources/ClangSharp/Cursors/Exprs/GenericSelectionExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/GenericSelectionExpr.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,14 +9,14 @@ namespace ClangSharp; public sealed class GenericSelectionExpr : Expr { - private readonly Lazy> _assocExprs; + private readonly LazyList _assocExprs; internal GenericSelectionExpr(CXCursor handle) : base(handle, CXCursor_GenericSelectionExpr, CX_StmtClass_GenericSelectionExpr) { - _assocExprs = new Lazy>(() => Children.Skip(1).Take((int)NumAssocs).Cast().ToList()); + _assocExprs = LazyList.Create(_children, skip: 1, take: (int)NumAssocs); } - public IReadOnlyList AssocExprs => _assocExprs.Value; + public IReadOnlyList AssocExprs => _assocExprs; public Expr ControllingExpr => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/InitListExpr.cs b/sources/ClangSharp/Cursors/Exprs/InitListExpr.cs index aa3a9742..72850454 100644 --- a/sources/ClangSharp/Cursors/Exprs/InitListExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/InitListExpr.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,15 +10,15 @@ namespace ClangSharp; public sealed class InitListExpr : Expr { - private readonly Lazy _arrayFiller; - private readonly Lazy _initializedFieldInUnion; - private readonly Lazy> _inits; + private readonly ValueLazy _arrayFiller; + private readonly ValueLazy _initializedFieldInUnion; + private readonly LazyList _inits; internal InitListExpr(CXCursor handle) : base(handle, CXCursor_InitListExpr, CX_StmtClass_InitListExpr) { - _arrayFiller = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); - _initializedFieldInUnion = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _inits = new Lazy>(() => Children.Cast().ToList()); + _arrayFiller = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); + _initializedFieldInUnion = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _inits = LazyList.Create(_children); } public Expr ArrayFiller => _arrayFiller.Value; @@ -28,7 +27,7 @@ internal InitListExpr(CXCursor handle) : base(handle, CXCursor_InitListExpr, CX_ public FieldDecl InitializedFieldInUnion => _initializedFieldInUnion.Value; - public IReadOnlyList Inits => _inits.Value; + public IReadOnlyList Inits => _inits; public bool IsExplicit => !Handle.IsImplicit; diff --git a/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs b/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs index 976c965a..beb9c67b 100644 --- a/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/IntegerLiteral.cs @@ -12,11 +12,11 @@ namespace ClangSharp; public sealed class IntegerLiteral : Expr { - private readonly Lazy _valueString; + private readonly ValueLazy _valueString; internal IntegerLiteral(CXCursor handle) : base(handle, CXCursor_IntegerLiteral, CX_StmtClass_IntegerLiteral) { - _valueString = new Lazy(() => { + _valueString = new ValueLazy(() => { var tokens = Handle.TranslationUnit.Tokenize(Handle.SourceRange); if ((tokens.Length == 0) || (tokens[0].Kind is not CXToken_Literal and not CXToken_Identifier)) diff --git a/sources/ClangSharp/Cursors/Exprs/MaterializeTemporaryExpr.cs b/sources/ClangSharp/Cursors/Exprs/MaterializeTemporaryExpr.cs index 82a3cfc2..48d96376 100644 --- a/sources/ClangSharp/Cursors/Exprs/MaterializeTemporaryExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/MaterializeTemporaryExpr.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class MaterializeTemporaryExpr : Expr { - private readonly Lazy _lifetimeExtendedTemporaryDecl; + private readonly ValueLazy _lifetimeExtendedTemporaryDecl; internal MaterializeTemporaryExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_MaterializeTemporaryExpr) { - _lifetimeExtendedTemporaryDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _lifetimeExtendedTemporaryDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public ValueDecl ExtendingDecl => LifetimeExtendedTemporaryDecl.ExtendingDecl; diff --git a/sources/ClangSharp/Cursors/Exprs/MemberExpr.cs b/sources/ClangSharp/Cursors/Exprs/MemberExpr.cs index 465f0a40..61388818 100644 --- a/sources/ClangSharp/Cursors/Exprs/MemberExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/MemberExpr.cs @@ -4,33 +4,22 @@ using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class MemberExpr : Expr { - private readonly Lazy _memberDecl; - private readonly Lazy> _templateArgs; + private readonly ValueLazy _memberDecl; + private readonly LazyList _templateArgs; internal MemberExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_MemberExpr) { Debug.Assert(NumChildren is 1); - _memberDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _memberDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } public Expr Base => (Expr)Children[0]; @@ -51,5 +40,5 @@ internal MemberExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_S public uint NumTemplateArgs => unchecked((uint)Handle.NumTemplateArguments); - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCArrayLiteral.cs b/sources/ClangSharp/Cursors/Exprs/ObjCArrayLiteral.cs index b3433a04..a9e55a10 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCArrayLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCArrayLiteral.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,18 +10,18 @@ namespace ClangSharp; public sealed class ObjCArrayLiteral : Expr { - private readonly Lazy _arrayWithObjectsMethod; - private readonly Lazy> _elements; + private readonly ValueLazy _arrayWithObjectsMethod; + private readonly LazyList _elements; internal ObjCArrayLiteral(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ObjCArrayLiteral) { - _arrayWithObjectsMethod = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _elements = new Lazy>(() => Children.Cast().ToList()); + _arrayWithObjectsMethod = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _elements = LazyList.Create(_children); } public ObjCMethodDecl ArrayWithObjectsMethod => _arrayWithObjectsMethod.Value; - public IReadOnlyList Elements => _elements.Value; + public IReadOnlyList Elements => _elements; public uint NumElements => NumChildren; } diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCBoxedExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCBoxedExpr.cs index 0537c4a2..9088c34d 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCBoxedExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCBoxedExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCBoxedExpr : Expr { - private readonly Lazy _boxingMethod; + private readonly ValueLazy _boxingMethod; internal ObjCBoxedExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ObjCBoxedExpr) { Debug.Assert(NumChildren is 1); - _boxingMethod = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _boxingMethod = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public ObjCMethodDecl BoxingMethod => _boxingMethod.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCDictionaryLiteral.cs b/sources/ClangSharp/Cursors/Exprs/ObjCDictionaryLiteral.cs index c77597cf..820c4d6c 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCDictionaryLiteral.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCDictionaryLiteral.cs @@ -11,15 +11,15 @@ namespace ClangSharp; public sealed class ObjCDictionaryLiteral : Expr { - private readonly Lazy _dictWithObjectsMethod; - private readonly Lazy> _keyValueElements; + private readonly ValueLazy _dictWithObjectsMethod; + private readonly ValueLazy> _keyValueElements; internal ObjCDictionaryLiteral(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ObjCDictionaryLiteral) { Debug.Assert((NumChildren % 2) == 0); - _dictWithObjectsMethod = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _dictWithObjectsMethod = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _keyValueElements = new Lazy>(() => { + _keyValueElements = new ValueLazy>(() => { var numChildren = Handle.NumChildren; var keyValueElements = new List<(Expr Key, Expr Value)>(numChildren / 2); diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCEncodeExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCEncodeExpr.cs index 79e1918d..69273d6e 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCEncodeExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCEncodeExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCEncodeExpr : Expr { - private readonly Lazy _encodedType; + private readonly ValueLazy _encodedType; internal ObjCEncodeExpr(CXCursor handle) : base(handle, CXCursor_ObjCEncodeExpr, CX_StmtClass_ObjCEncodeExpr) { Debug.Assert(NumChildren is 0); - _encodedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _encodedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Type EncodedType => _encodedType.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCIvarRefExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCIvarRefExpr.cs index cd186a8d..e3e8fad5 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCIvarRefExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCIvarRefExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCIvarRefExpr : Expr { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal ObjCIvarRefExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_ObjCIvarRefExpr) { Debug.Assert(NumChildren is 1); - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public Expr Base => (Expr)Children[0]; diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCMessageExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCMessageExpr.cs index b8c75891..2ed3d7e6 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCMessageExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCMessageExpr.cs @@ -3,43 +3,31 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class ObjCMessageExpr : Expr { - private readonly Lazy> _args; - private readonly Lazy _classReceiver; - private readonly Lazy _instanceReceiver; - private readonly Lazy _methodDecl; - private readonly Lazy _receiverType; - private readonly Lazy _superType; + private readonly LazyList _args; + private readonly ValueLazy _classReceiver; + private readonly ValueLazy _instanceReceiver; + private readonly ValueLazy _methodDecl; + private readonly ValueLazy _receiverType; + private readonly ValueLazy _superType; internal ObjCMessageExpr(CXCursor handle) : base(handle, CXCursor_ObjCMessageExpr, CX_StmtClass_ObjCMessageExpr) { - _args = new Lazy>(() => { - var numArgs = Handle.NumArguments; - var args = new List(numArgs); - - for (var i = 0; i < numArgs; i++) - { - var arg = TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i))); - args.Add(arg); - } - - return args; - }); - - _classReceiver = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _instanceReceiver = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); - _methodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _receiverType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ReceiverType)); - _superType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ThisObjectType)); + _args = LazyList.Create(Handle.NumArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetArgument(unchecked((uint)i)))); + _classReceiver = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _instanceReceiver = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _methodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _receiverType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ReceiverType)); + _superType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ThisObjectType)); } - public IReadOnlyList Args => _args.Value; + public IReadOnlyList Args => _args; public Type ClassReceiver => _classReceiver.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCPropertyRefExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCPropertyRefExpr.cs index 28b277fa..4851c323 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCPropertyRefExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCPropertyRefExpr.cs @@ -9,21 +9,21 @@ namespace ClangSharp; public sealed class ObjCPropertyRefExpr : Expr { - private readonly Lazy _base; - private readonly Lazy _classReceiver; - private readonly Lazy _explicitProperty; - private readonly Lazy _implicitPropertyGetter; - private readonly Lazy _implicitPropertySetter; - private readonly Lazy _superReceiverType; + private readonly ValueLazy _base; + private readonly ValueLazy _classReceiver; + private readonly ValueLazy _explicitProperty; + private readonly ValueLazy _implicitPropertyGetter; + private readonly ValueLazy _implicitPropertySetter; + private readonly ValueLazy _superReceiverType; internal ObjCPropertyRefExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_ObjCPropertyRefExpr) { - _base = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); - _classReceiver = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(0))); - _explicitProperty = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(1))); - _implicitPropertyGetter = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(2))); - _implicitPropertySetter = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(3))); - _superReceiverType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _base = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetExpr(0))); + _classReceiver = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(0))); + _explicitProperty = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(1))); + _implicitPropertyGetter = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(2))); + _implicitPropertySetter = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetDecl(3))); + _superReceiverType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCProtocolExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCProtocolExpr.cs index 53304d90..0e312de8 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCProtocolExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCProtocolExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCProtocolExpr : Expr { - private readonly Lazy _protocol; + private readonly ValueLazy _protocol; internal ObjCProtocolExpr(CXCursor handle) : base(handle, CXCursor_ObjCProtocolExpr, CX_StmtClass_ObjCProtocolExpr) { Debug.Assert(NumChildren is 0); - _protocol = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _protocol = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public ObjCProtocolDecl Protocol => _protocol.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/ObjCSubscriptRefExpr.cs b/sources/ClangSharp/Cursors/Exprs/ObjCSubscriptRefExpr.cs index 8d95aa35..c7fe326f 100644 --- a/sources/ClangSharp/Cursors/Exprs/ObjCSubscriptRefExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ObjCSubscriptRefExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCSubscriptRefExpr : Expr { - private readonly Lazy _atIndexMethodDecl; + private readonly ValueLazy _atIndexMethodDecl; internal ObjCSubscriptRefExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ObjCSubscriptRefExpr) { Debug.Assert(NumChildren is 2); - _atIndexMethodDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _atIndexMethodDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public ObjCMethodDecl AtIndexMethodDecl => _atIndexMethodDecl.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/OffsetOfExpr.cs b/sources/ClangSharp/Cursors/Exprs/OffsetOfExpr.cs index 75c9f639..1d078c0a 100644 --- a/sources/ClangSharp/Cursors/Exprs/OffsetOfExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/OffsetOfExpr.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,18 +10,18 @@ namespace ClangSharp; public sealed class OffsetOfExpr : Expr { - private readonly Lazy> _indexExprs; - private readonly Lazy _referenced; - private readonly Lazy _typeSourceInfoType; + private readonly LazyList _indexExprs; + private readonly ValueLazy _referenced; + private readonly ValueLazy _typeSourceInfoType; internal OffsetOfExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_OffsetOfExpr) { - _indexExprs = new Lazy>(() => Children.Cast().ToList()); - _referenced = new Lazy(() => !Handle.Referenced.IsNull ? TranslationUnit.GetOrCreate(Handle.Referenced) : null); - _typeSourceInfoType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _indexExprs = LazyList.Create(_children); + _referenced = new ValueLazy(() => !Handle.Referenced.IsNull ? TranslationUnit.GetOrCreate(Handle.Referenced) : null); + _typeSourceInfoType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } - public IReadOnlyList IndexExprs => _indexExprs.Value; + public IReadOnlyList IndexExprs => _indexExprs; public uint NumExpressions => NumChildren; diff --git a/sources/ClangSharp/Cursors/Exprs/OpaqueValueExpr.cs b/sources/ClangSharp/Cursors/Exprs/OpaqueValueExpr.cs index 742cce12..66347db2 100644 --- a/sources/ClangSharp/Cursors/Exprs/OpaqueValueExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/OpaqueValueExpr.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class OpaqueValueExpr : Expr { - private readonly Lazy _sourceExpr; + private readonly ValueLazy _sourceExpr; internal OpaqueValueExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_OpaqueValueExpr) { - _sourceExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.SubExpr)); + _sourceExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.SubExpr)); } public Expr SourceExpr => _sourceExpr.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/OverloadExpr.cs b/sources/ClangSharp/Cursors/Exprs/OverloadExpr.cs index 0a7e4640..ce3f4951 100644 --- a/sources/ClangSharp/Cursors/Exprs/OverloadExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/OverloadExpr.cs @@ -9,9 +9,9 @@ namespace ClangSharp; public class OverloadExpr : Expr { - private readonly Lazy> _decls; - private readonly Lazy _namingClass; - private readonly Lazy> _templateArgs; + private readonly LazyList _decls; + private readonly ValueLazy _namingClass; + private readonly LazyList _templateArgs; private protected OverloadExpr(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind, expectedStmtClass) { @@ -20,36 +20,12 @@ private protected OverloadExpr(CXCursor handle, CXCursorKind expectedCursorKind, throw new ArgumentOutOfRangeException(nameof(handle)); } - _decls = new Lazy>(() => { - var numDecls = Handle.NumDecls; - var decls = new List(numDecls); - - for (var i = 0; i < numDecls; i++) - { - var decl = TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i))); - decls.Add(decl); - } - - return decls; - }); - - _namingClass = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _decls = LazyList.Create(Handle.NumDecls, (i) => TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i)))); + _namingClass = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgumentLoc(unchecked((uint)i)))); } - public IReadOnlyList Decls => _decls.Value; + public IReadOnlyList Decls => _decls; public bool HasExplicitTemplateArgs => Handle.HasExplicitTemplateArgs; @@ -63,5 +39,5 @@ private protected OverloadExpr(CXCursor handle, CXCursorKind expectedCursorKind, public uint NumTemplateArgs => unchecked((uint)Handle.NumTemplateArguments); - public IReadOnlyList TemplateArgs => _templateArgs.Value; + public IReadOnlyList TemplateArgs => _templateArgs; } diff --git a/sources/ClangSharp/Cursors/Exprs/ParenListExpr.cs b/sources/ClangSharp/Cursors/Exprs/ParenListExpr.cs index 034b1d29..d2ca3b95 100644 --- a/sources/ClangSharp/Cursors/Exprs/ParenListExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/ParenListExpr.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,14 +9,14 @@ namespace ClangSharp; public sealed class ParenListExpr : Expr { - private readonly Lazy> _exprs; + private readonly LazyList _exprs; internal ParenListExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_ParenListExpr) { - _exprs = new Lazy>(() => Children.Cast().ToList()); + _exprs = LazyList.Create(_children); } - public IReadOnlyList Exprs => _exprs.Value; + public IReadOnlyList Exprs => _exprs; public uint NumExprs => NumChildren; } diff --git a/sources/ClangSharp/Cursors/Exprs/PseudoObjectExpr.cs b/sources/ClangSharp/Cursors/Exprs/PseudoObjectExpr.cs index 667efb19..3b5ba34e 100644 --- a/sources/ClangSharp/Cursors/Exprs/PseudoObjectExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/PseudoObjectExpr.cs @@ -1,9 +1,7 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -12,12 +10,12 @@ namespace ClangSharp; public sealed class PseudoObjectExpr : Expr { - private readonly Lazy> _semantics; + private readonly LazyList _semantics; internal PseudoObjectExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_PseudoObjectExpr) { Debug.Assert(NumChildren >= 1); - _semantics = new Lazy>(() => Children.Skip(1).Cast().ToList()); + _semantics = LazyList.Create(_children, skip: 1); } public uint NumSemanticExprs => NumChildren - 1; @@ -26,7 +24,7 @@ internal PseudoObjectExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr public uint ResultExprIndex => unchecked((uint)Handle.ResultIndex); - public IReadOnlyList Semantics => _semantics.Value; + public IReadOnlyList Semantics => _semantics; public Expr SyntacticForm => (Expr)Children[0]; } diff --git a/sources/ClangSharp/Cursors/Exprs/RecoveryExpr.cs b/sources/ClangSharp/Cursors/Exprs/RecoveryExpr.cs index c821a900..8dbae0e9 100644 --- a/sources/ClangSharp/Cursors/Exprs/RecoveryExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/RecoveryExpr.cs @@ -1,8 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -11,12 +9,12 @@ namespace ClangSharp; public sealed class RecoveryExpr : Expr { - private readonly Lazy> _subExpressions; + private readonly LazyList _subExpressions; internal RecoveryExpr(CXCursor handle) : base(handle, CXCursor_UnexposedExpr, CX_StmtClass_RecoveryExpr) { - _subExpressions = new Lazy>(() => Children.Cast().ToList()); + _subExpressions = LazyList.Create(_children); } - public IReadOnlyList SubExpressions => _subExpressions.Value; + public IReadOnlyList SubExpressions => _subExpressions; } diff --git a/sources/ClangSharp/Cursors/Exprs/SizeOfPackExpr.cs b/sources/ClangSharp/Cursors/Exprs/SizeOfPackExpr.cs index 5117791d..909ccf3b 100644 --- a/sources/ClangSharp/Cursors/Exprs/SizeOfPackExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/SizeOfPackExpr.cs @@ -3,31 +3,20 @@ using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class SizeOfPackExpr : Expr { - private readonly Lazy _pack; - private readonly Lazy> _partialArguments; + private readonly ValueLazy _pack; + private readonly LazyList _partialArguments; internal SizeOfPackExpr(CXCursor handle) : base(handle, CXCursor_SizeOfPackExpr, CX_StmtClass_SizeOfPackExpr) { - _pack = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _partialArguments = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _pack = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _partialArguments = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } public NamedDecl Pack => _pack.Value; @@ -36,5 +25,5 @@ internal SizeOfPackExpr(CXCursor handle) : base(handle, CXCursor_SizeOfPackExpr, public bool IsPartiallySubstituted => Handle.IsPartiallySubstituted; - public IReadOnlyList PartialArguments => _partialArguments.Value; + public IReadOnlyList PartialArguments => _partialArguments; } diff --git a/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmExpr.cs b/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmExpr.cs index 59c908a9..2f4dc90c 100644 --- a/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmExpr.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class SubstNonTypeTemplateParmExpr : Expr { - private readonly Lazy _parameter; + private readonly ValueLazy _parameter; internal SubstNonTypeTemplateParmExpr(CXCursor handle) : base(handle, CXCursor_DeclRefExpr, CX_StmtClass_SubstNonTypeTemplateParmExpr) { Debug.Assert(NumChildren is 1); - _parameter = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _parameter = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public NonTypeTemplateParmDecl Parameter => _parameter.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmPackExpr.cs b/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmPackExpr.cs index 002ed4b7..f1685281 100644 --- a/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmPackExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/SubstNonTypeTemplateParmPackExpr.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class SubstNonTypeTemplateParmPackExpr : Expr { - private readonly Lazy _argumentPack; - private readonly Lazy _parameterPack; + private readonly ValueLazy _argumentPack; + private readonly ValueLazy _parameterPack; internal SubstNonTypeTemplateParmPackExpr(CXCursor handle) : base(handle, CXCursor_DeclRefExpr, CX_StmtClass_SubstNonTypeTemplateParmPackExpr) { Debug.Assert(NumChildren is 0); - _argumentPack = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(0))); - _parameterPack = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _argumentPack = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(0))); + _parameterPack = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public TemplateArgument ArgumentPack => _argumentPack.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/UnaryExprOrTypeTraitExpr.cs b/sources/ClangSharp/Cursors/Exprs/UnaryExprOrTypeTraitExpr.cs index c31604f9..8d572adb 100644 --- a/sources/ClangSharp/Cursors/Exprs/UnaryExprOrTypeTraitExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/UnaryExprOrTypeTraitExpr.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class UnaryExprOrTypeTraitExpr : Expr { - private readonly Lazy _argumentExpr; - private readonly Lazy _argumentType; + private readonly ValueLazy _argumentExpr; + private readonly ValueLazy _argumentType; internal UnaryExprOrTypeTraitExpr(CXCursor handle) : base(handle, CXCursor_UnaryExpr, CX_StmtClass_UnaryExprOrTypeTraitExpr) { - _argumentExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); - _argumentType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ArgumentType)); + _argumentExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SubExpr)); + _argumentType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ArgumentType)); } public Expr ArgumentExpr => _argumentExpr.Value; diff --git a/sources/ClangSharp/Cursors/Exprs/UnresolvedMemberExpr.cs b/sources/ClangSharp/Cursors/Exprs/UnresolvedMemberExpr.cs index eab67a04..83253ef3 100644 --- a/sources/ClangSharp/Cursors/Exprs/UnresolvedMemberExpr.cs +++ b/sources/ClangSharp/Cursors/Exprs/UnresolvedMemberExpr.cs @@ -11,12 +11,12 @@ namespace ClangSharp; public sealed class UnresolvedMemberExpr : OverloadExpr { - private readonly Lazy _baseType; + private readonly ValueLazy _baseType; internal UnresolvedMemberExpr(CXCursor handle) : base(handle, CXCursor_MemberRefExpr, CX_StmtClass_UnresolvedMemberExpr) { Debug.Assert(NumChildren is 0 or 1); - _baseType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _baseType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); } public Expr? Base => (Expr?)Children.SingleOrDefault(); diff --git a/sources/ClangSharp/Cursors/Preprocessings/MacroExpansion.cs b/sources/ClangSharp/Cursors/Preprocessings/MacroExpansion.cs index 313ad512..25305c3b 100644 --- a/sources/ClangSharp/Cursors/Preprocessings/MacroExpansion.cs +++ b/sources/ClangSharp/Cursors/Preprocessings/MacroExpansion.cs @@ -8,11 +8,11 @@ namespace ClangSharp; public sealed class MacroExpansion : PreprocessedEntity { - private readonly Lazy _definition; + private readonly ValueLazy _definition; internal MacroExpansion(CXCursor handle) : base(handle, CXCursor_MacroExpansion) { - _definition = new Lazy(() => TranslationUnit.GetOrCreate(handle.Referenced)); + _definition = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.Referenced)); } public MacroDefinitionRecord Definition => _definition.Value; diff --git a/sources/ClangSharp/Cursors/Refs/OverloadedDeclRef.cs b/sources/ClangSharp/Cursors/Refs/OverloadedDeclRef.cs index 47e82638..a91749f7 100644 --- a/sources/ClangSharp/Cursors/Refs/OverloadedDeclRef.cs +++ b/sources/ClangSharp/Cursors/Refs/OverloadedDeclRef.cs @@ -10,16 +10,15 @@ namespace ClangSharp; public sealed class OverloadedDeclRef : Ref { - private readonly Lazy> _overloadedDecls; + private readonly ValueLazy> _overloadedDecls; internal OverloadedDeclRef(CXCursor handle) : base(handle, CXCursor_OverloadedDeclRef) { - _overloadedDecls = new Lazy>(() => { + _overloadedDecls = new ValueLazy>(() => { var num = Handle.NumOverloadedDecls; - return Enumerable.Range(0, (int)num) + return [.. Enumerable.Range(0, (int)num) .Select(i => Handle.GetOverloadedDecl((uint)i)) - .Select(c => TranslationUnit.GetOrCreate(c)) - .ToArray(); + .Select(c => TranslationUnit.GetOrCreate(c))]; }); } diff --git a/sources/ClangSharp/Cursors/Refs/Ref.cs b/sources/ClangSharp/Cursors/Refs/Ref.cs index 8a8901fb..8cfa820d 100644 --- a/sources/ClangSharp/Cursors/Refs/Ref.cs +++ b/sources/ClangSharp/Cursors/Refs/Ref.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public class Ref : Cursor { - private readonly Lazy _referenced; - private readonly Lazy _type; + private readonly ValueLazy _referenced; + private readonly ValueLazy _type; private protected Ref(CXCursor handle, CXCursorKind expectedCursorKind) : base(handle, expectedCursorKind) { - _referenced = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); - _type = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Type)); + _referenced = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _type = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Type)); } public NamedDecl Referenced => _referenced.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/AttributedStmt.cs b/sources/ClangSharp/Cursors/Stmts/AttributedStmt.cs index 325dc2af..7ecb9250 100644 --- a/sources/ClangSharp/Cursors/Stmts/AttributedStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/AttributedStmt.cs @@ -1,37 +1,25 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class AttributedStmt : ValueStmt { - private readonly Lazy> _attrs; + private readonly LazyList _attrs; internal AttributedStmt(CXCursor handle) : base(handle, CXCursor_UnexposedStmt, CX_StmtClass_AttributedStmt) { Debug.Assert(NumChildren == 1); - _attrs = new Lazy>(() => { - var numAttrs = Handle.NumAttrs; - var attrs = new List(numAttrs); - - for (var i = 0; i < numAttrs; i++) - { - var attr = TranslationUnit.GetOrCreate(Handle.GetAttr(unchecked((uint)i))); - attrs.Add(attr); - } - - return attrs; - }); + _attrs = LazyList.Create(Handle.NumAttrs, (i) => TranslationUnit.GetOrCreate(Handle.GetAttr(unchecked((uint)i)))); } - public IReadOnlyList Attrs => _attrs.Value; + public IReadOnlyList Attrs => _attrs; public Stmt SubStmt => Children[0]; } diff --git a/sources/ClangSharp/Cursors/Stmts/CXXCatchStmt.cs b/sources/ClangSharp/Cursors/Stmts/CXXCatchStmt.cs index 53f825d1..277b31fb 100644 --- a/sources/ClangSharp/Cursors/Stmts/CXXCatchStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/CXXCatchStmt.cs @@ -10,15 +10,15 @@ namespace ClangSharp; public sealed class CXXCatchStmt : Stmt { - private readonly Lazy _caughtType; - private readonly Lazy _exceptionDecl; + private readonly ValueLazy _caughtType; + private readonly ValueLazy _exceptionDecl; internal CXXCatchStmt(CXCursor handle) : base(handle, CXCursor_CXXCatchStmt, CX_StmtClass_CXXCatchStmt) { Debug.Assert(NumChildren is 1); - _caughtType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); - _exceptionDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _caughtType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TypeOperand)); + _exceptionDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public Type CaughtType => _caughtType.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/CXXTryStmt.cs b/sources/ClangSharp/Cursors/Stmts/CXXTryStmt.cs index f08daccc..4317033c 100644 --- a/sources/ClangSharp/Cursors/Stmts/CXXTryStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/CXXTryStmt.cs @@ -1,9 +1,7 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -12,15 +10,15 @@ namespace ClangSharp; public sealed class CXXTryStmt : Stmt { - private readonly Lazy> _handlers; + private readonly LazyList _handlers; internal CXXTryStmt(CXCursor handle) : base(handle, CXCursor_CXXTryStmt, CX_StmtClass_CXXTryStmt) { Debug.Assert(NumChildren is >= 1); - _handlers = new Lazy>(() => Children.Skip(1).Cast().ToList()); + _handlers = LazyList.Create(_children, skip: 1); } - public IReadOnlyList Handlers => _handlers.Value; + public IReadOnlyList Handlers => _handlers; public uint NumHandlers => (uint)(Children.Count - 1); diff --git a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.Capture.cs b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.Capture.cs index cb54e9d1..6b9f8176 100644 --- a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.Capture.cs +++ b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.Capture.cs @@ -12,14 +12,14 @@ public sealed class Capture { private readonly CapturedStmt _parentStmt; private readonly uint _index; - private readonly Lazy _capturedVar; + private readonly ValueLazy _capturedVar; internal Capture(CapturedStmt parentStmt, uint index) { _parentStmt = parentStmt; _index = index; - _capturedVar = new Lazy(() => _parentStmt.TranslationUnit.GetOrCreate(_parentStmt.Handle.GetCapturedVar(_index))); + _capturedVar = new ValueLazy(() => _parentStmt.TranslationUnit.GetOrCreate(_parentStmt.Handle.GetCapturedVar(_index))); } public VarDecl CapturedVar => _capturedVar.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs index b194370d..4a266e63 100644 --- a/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/CapturedStmt.cs @@ -2,41 +2,27 @@ using System; using System.Collections.Generic; -using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed partial class CapturedStmt : Stmt { - private readonly Lazy _capturedDecl; - private readonly Lazy _capturedRecordDecl; - private readonly Lazy _captureStmt; - private readonly Lazy> _captures; - private readonly Lazy> _captureInits; + private readonly ValueLazy _capturedDecl; + private readonly ValueLazy _capturedRecordDecl; + private readonly ValueLazy _captureStmt; + private readonly LazyList _captures; + private readonly LazyList _captureInits; internal CapturedStmt(CXCursor handle) : base(handle, CXCursor_UnexposedStmt, CX_StmtClass_CapturedStmt) { - _capturedDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CapturedDecl)); - _capturedRecordDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CapturedRecordDecl)); - _captureStmt = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CapturedStmt)); - - _captures = new Lazy>(() => { - var numCaptures = Handle.NumCaptures; - var captures = new List(numCaptures); - - for (var i = 0; i < numCaptures; i++) - { - var capture = new Capture(this, unchecked((uint)i)); - captures.Add(capture); - } - - return captures; - }); - - _captureInits = new Lazy>(() => Children.Cast().ToList()); + _capturedDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CapturedDecl)); + _capturedRecordDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CapturedRecordDecl)); + _captureStmt = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CapturedStmt)); + _captures = LazyList.Create(Handle.NumCaptures, (i) => new Capture(this, unchecked((uint)i))); + _captureInits = LazyList.Create(_children); } public CapturedDecl CapturedDecl => _capturedDecl.Value; @@ -47,11 +33,11 @@ internal CapturedStmt(CXCursor handle) : base(handle, CXCursor_UnexposedStmt, CX public Stmt CaptureStmt => _captureStmt.Value; - public IReadOnlyList Captures => _captures.Value; + public IReadOnlyList Captures => _captures; public uint CaptureSize => unchecked((uint)Handle.NumCaptures); - public IReadOnlyList CaptureInits => _captureInits.Value; + public IReadOnlyList CaptureInits => _captureInits; public bool CapturesVariable(VarDecl var) { diff --git a/sources/ClangSharp/Cursors/Stmts/DeclStmt.cs b/sources/ClangSharp/Cursors/Stmts/DeclStmt.cs index 4aebe8c5..c0d4f3c0 100644 --- a/sources/ClangSharp/Cursors/Stmts/DeclStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/DeclStmt.cs @@ -1,35 +1,23 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using System.Linq; using ClangSharp.Interop; -using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; +using static ClangSharp.Interop.CXCursorKind; namespace ClangSharp; public sealed class DeclStmt : Stmt { - private readonly Lazy> _decls; + private readonly LazyList _decls; internal DeclStmt(CXCursor handle) : base(handle, CXCursor_DeclStmt, CX_StmtClass_DeclStmt) { - _decls = new Lazy>(() => { - var numDecls = Handle.NumDecls; - var decls = new List(numDecls); - - for (var i = 0; i < numDecls; i++) - { - var decl = TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i))); - decls.Add(decl); - } - - return decls; - }); + _decls = LazyList.Create(Handle.NumDecls, (i) => TranslationUnit.GetOrCreate(Handle.GetDecl(unchecked((uint)i)))); } - public IReadOnlyList Decls => _decls.Value; + public IReadOnlyList Decls => _decls; public bool IsSingleDecl => Decls.Count == 1; diff --git a/sources/ClangSharp/Cursors/Stmts/GotoStmt.cs b/sources/ClangSharp/Cursors/Stmts/GotoStmt.cs index 310a23a1..9672b2aa 100644 --- a/sources/ClangSharp/Cursors/Stmts/GotoStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/GotoStmt.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class GotoStmt : Stmt { - private readonly Lazy _label; + private readonly ValueLazy _label; internal GotoStmt(CXCursor handle) : base(handle, CXCursor_GotoStmt, CX_StmtClass_GotoStmt) { Debug.Assert(NumChildren is 0); - _label = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _label = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public LabelDecl Label => _label.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/IndirectGotoStmt.cs b/sources/ClangSharp/Cursors/Stmts/IndirectGotoStmt.cs index 38eeaf1b..ac9ad30b 100644 --- a/sources/ClangSharp/Cursors/Stmts/IndirectGotoStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/IndirectGotoStmt.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class IndirectGotoStmt : Stmt { - private readonly Lazy _constantTarget; + private readonly ValueLazy _constantTarget; internal IndirectGotoStmt(CXCursor handle) : base(handle, CXCursor_IndirectGotoStmt, CX_StmtClass_IndirectGotoStmt) { Debug.Assert(NumChildren is 1); - _constantTarget = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _constantTarget = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public LabelDecl ConstantTarget => _constantTarget.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/LabelStmt.cs b/sources/ClangSharp/Cursors/Stmts/LabelStmt.cs index 90b11473..48b0e8dc 100644 --- a/sources/ClangSharp/Cursors/Stmts/LabelStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/LabelStmt.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class LabelStmt : ValueStmt { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal LabelStmt(CXCursor handle) : base(handle, CXCursor_LabelStmt, CX_StmtClass_LabelStmt) { Debug.Assert(NumChildren is 1); - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public LabelDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/ObjCAtCatchStmt.cs b/sources/ClangSharp/Cursors/Stmts/ObjCAtCatchStmt.cs index 02ce7c63..0187a8bd 100644 --- a/sources/ClangSharp/Cursors/Stmts/ObjCAtCatchStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/ObjCAtCatchStmt.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class ObjCAtCatchStmt : Stmt { - private readonly Lazy _catchParamDecl; + private readonly ValueLazy _catchParamDecl; internal ObjCAtCatchStmt(CXCursor handle) : base(handle, CXCursor_ObjCAtCatchStmt, CX_StmtClass_ObjCAtCatchStmt) { Debug.Assert(NumChildren is 1); - _catchParamDecl = new Lazy(() => !Handle.Referenced.IsNull ? TranslationUnit.GetOrCreate(Handle.Referenced) : null); + _catchParamDecl = new ValueLazy(() => !Handle.Referenced.IsNull ? TranslationUnit.GetOrCreate(Handle.Referenced) : null); } public Stmt CatchBody => Children[0]; diff --git a/sources/ClangSharp/Cursors/Stmts/ObjCAtTryStmt.cs b/sources/ClangSharp/Cursors/Stmts/ObjCAtTryStmt.cs index 84a0cd67..fe97d351 100644 --- a/sources/ClangSharp/Cursors/Stmts/ObjCAtTryStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/ObjCAtTryStmt.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; using ClangSharp.Interop; using static ClangSharp.Interop.CXCursorKind; using static ClangSharp.Interop.CX_StmtClass; @@ -12,25 +11,27 @@ namespace ClangSharp; public sealed class ObjCAtTryStmt : Stmt { - private readonly Lazy> _catchStmts; - private readonly Lazy _finallyStmt; + private readonly ValueLazy> _catchStmts; + private readonly ValueLazy _finallyStmt; internal ObjCAtTryStmt(CXCursor handle) : base(handle, CXCursor_ObjCAtTryStmt, CX_StmtClass_ObjCAtTryStmt) { Debug.Assert(NumChildren is >= 1); - _catchStmts = new Lazy>(() => { - var children = Children; + _catchStmts = new ValueLazy>(() => { + var children = _children; var skipLast = 0; - if (children[children.Count - 1] is ObjCAtFinallyStmt) { + if (children[children.Count - 1] is ObjCAtFinallyStmt) + { skipLast++; } - return children.Skip(1).Take((int)(NumChildren - 1 - skipLast)).Cast().ToList(); + var take = (int)(NumChildren - 1 - skipLast); + return LazyList.Create(_children, skip: 1, take); }); - _finallyStmt = new Lazy(() => { + _finallyStmt = new ValueLazy(() => { var children = Children; return (children[children.Count - 1] is ObjCAtFinallyStmt finallyStmt) ? finallyStmt : null; diff --git a/sources/ClangSharp/Cursors/Stmts/ReturnStmt.cs b/sources/ClangSharp/Cursors/Stmts/ReturnStmt.cs index 628b5ebe..d5efac5f 100644 --- a/sources/ClangSharp/Cursors/Stmts/ReturnStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/ReturnStmt.cs @@ -10,13 +10,13 @@ namespace ClangSharp; public sealed class ReturnStmt : Stmt { - private readonly Lazy _nrvoCandidate; + private readonly ValueLazy _nrvoCandidate; internal ReturnStmt(CXCursor handle) : base(handle, CXCursor_ReturnStmt, CX_StmtClass_ReturnStmt) { Debug.Assert(NumChildren is 0 or 1); - _nrvoCandidate = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); + _nrvoCandidate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Referenced)); } public VarDecl NRVOCandidate => _nrvoCandidate.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/Stmt.cs b/sources/ClangSharp/Cursors/Stmts/Stmt.cs index bf50feb3..fe8a77bd 100644 --- a/sources/ClangSharp/Cursors/Stmts/Stmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/Stmt.cs @@ -10,8 +10,8 @@ namespace ClangSharp; public class Stmt : Cursor { - private readonly Lazy> _children; - private readonly Lazy _declContext; + private protected readonly LazyList _children; + private readonly ValueLazy _declContext; private protected Stmt(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind) { @@ -20,21 +20,11 @@ private protected Stmt(CXCursor handle, CXCursorKind expectedCursorKind, CX_Stmt throw new ArgumentOutOfRangeException(nameof(handle)); } - _children = new Lazy>(() => { - var numChildren = Handle.NumChildren; - var children = new List(numChildren); - - for (var i = 0; i < numChildren; i++) - { - var childHandle = Handle.GetChild(unchecked((uint)i)); - var child = !childHandle.IsNull ? TranslationUnit.GetOrCreate(childHandle) : null; - children.Add(child); - } - - return children; + _children = LazyList.Create(Handle.NumChildren, (i) => { + var childHandle = Handle.GetChild(unchecked((uint)i)); + return !childHandle.IsNull ? TranslationUnit.GetOrCreate(childHandle) : null!; }); - - _declContext = new Lazy(() => { + _declContext = new ValueLazy(() => { var semanticParent = TranslationUnit.GetOrCreate(Handle.SemanticParent); while (semanticParent is not IDeclContext and not null) @@ -47,7 +37,7 @@ private protected Stmt(CXCursor handle, CXCursorKind expectedCursorKind, CX_Stmt }); } - public IReadOnlyList Children => _children.Value!; + public IReadOnlyList Children => _children; public IDeclContext DeclContext => _declContext.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/SwitchCase.cs b/sources/ClangSharp/Cursors/Stmts/SwitchCase.cs index 1dbbd90b..59a07753 100644 --- a/sources/ClangSharp/Cursors/Stmts/SwitchCase.cs +++ b/sources/ClangSharp/Cursors/Stmts/SwitchCase.cs @@ -9,7 +9,7 @@ namespace ClangSharp; public class SwitchCase : Stmt { - private readonly Lazy _nextSwitchCase; + private readonly ValueLazy _nextSwitchCase; private protected SwitchCase(CXCursor handle, CXCursorKind expectedCursorKind, CX_StmtClass expectedStmtClass) : base(handle, expectedCursorKind, expectedStmtClass) { @@ -18,7 +18,7 @@ private protected SwitchCase(CXCursor handle, CXCursorKind expectedCursorKind, C throw new ArgumentOutOfRangeException(nameof(handle)); } - _nextSwitchCase = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NextSwitchCase)); + _nextSwitchCase = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NextSwitchCase)); } public SwitchCase NextSwitchCase => _nextSwitchCase.Value; diff --git a/sources/ClangSharp/Cursors/Stmts/SwitchStmt.cs b/sources/ClangSharp/Cursors/Stmts/SwitchStmt.cs index 66121d69..72bccd3a 100644 --- a/sources/ClangSharp/Cursors/Stmts/SwitchStmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/SwitchStmt.cs @@ -10,12 +10,12 @@ namespace ClangSharp; public sealed class SwitchStmt : Stmt { - private readonly Lazy _switchCaseList; + private readonly ValueLazy _switchCaseList; internal SwitchStmt(CXCursor handle) : base(handle, CXCursor_SwitchStmt, CX_StmtClass_SwitchStmt) { Debug.Assert(NumChildren is >= 2 and <= 4); - _switchCaseList = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SubStmt)); + _switchCaseList = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SubStmt)); } public Stmt Body => Children[BodyOffset]; diff --git a/sources/ClangSharp/LazyList.cs b/sources/ClangSharp/LazyList.cs new file mode 100644 index 00000000..463005d0 --- /dev/null +++ b/sources/ClangSharp/LazyList.cs @@ -0,0 +1,26 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace ClangSharp; + +internal static class LazyList +{ + public static LazyList Create<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>(int count, Func valueFactory) + where T : class + { + if (count <= 0) + { + return LazyList.Empty; + } + return new LazyList(count, valueFactory); + } + + public static LazyList Create(LazyList list, int skip = -1, int take = -1) + where T : class, TBase + where TBase : class + { + return new LazyList(list, skip, take); + } +} diff --git a/sources/ClangSharp/LazyList`1.cs b/sources/ClangSharp/LazyList`1.cs new file mode 100644 index 00000000..507eeceb --- /dev/null +++ b/sources/ClangSharp/LazyList`1.cs @@ -0,0 +1,165 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace ClangSharp; + +internal sealed class LazyList<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : IList, IReadOnlyList + where T : class +{ + internal readonly T[] _items; + internal readonly Func _valueFactory; + + public static readonly LazyList Empty = new LazyList(0, _ => null!); + + public LazyList(int count, Func valueFactory) + { + _items = (count <= 0) ? [] : new T[count]; + _valueFactory = valueFactory; + } + + public T this[int index] + { + get + { + var items = _items.AsSpan(); + var item = items[index]; + + if (item is null) + { + item = _valueFactory(index); + items[index] = item; + } + + return item; + } + } + + public int Count => _items.Length; + + public bool IsReadOnly => true; + + public bool Contains(T item) => IndexOf(item) >= 0; + + public void CopyTo(T[] array, int arrayIndex) + { + var items = _items; + ArgumentNullException.ThrowIfNull(array); + + if ((arrayIndex < 0) || (arrayIndex > array.Length) || ((array.Length - arrayIndex) < items.Length)) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + + for (var i = 0; i < items.Length; i++) + { + var currentItem = items[i]; + + if (currentItem is null) + { + currentItem = _valueFactory(i); + items[i] = currentItem; + } + + array[arrayIndex + i] = currentItem; + } + } + + public Enumerator GetEnumerator() => new Enumerator(this); + + public int IndexOf(T item) + { + var items = _items; + + for (var i = 0; i < items.Length; i++) + { + var currentItem = items[i]; + + if (currentItem is null) + { + currentItem = _valueFactory(i); + items[i] = currentItem; + } + + if (EqualityComparer.Default.Equals(currentItem, item)) + { + return i; + } + } + + return -1; + } + + T IList.this[int index] + { + get + { + return this[index]; + } + + set + { + throw new NotSupportedException(); + } + } + + void ICollection.Add(T item) => throw new NotSupportedException(); + + void ICollection.Clear() => throw new NotSupportedException(); + + bool ICollection.Remove(T item) => throw new NotSupportedException(); + + void IList.Insert(int index, T item) => throw new NotSupportedException(); + + void IList.RemoveAt(int index) => throw new NotSupportedException(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator + { + private readonly LazyList _list; + + private int _index; + private T? _current; + + internal Enumerator(LazyList list) + { + _list = list; + } + + public readonly void Dispose() + { + } + + public bool MoveNext() + { + var localList = _list; + + if ((uint)_index < (uint)localList.Count) + { + _current = localList[_index]; + _index++; + return true; + } + + _current = default; + _index = -1; + return false; + } + + public readonly T Current => _current!; + + readonly object? IEnumerator.Current => Current; + + void IEnumerator.Reset() + { + _index = 0; + _current = default; + } + } +} diff --git a/sources/ClangSharp/LazyList`2.cs b/sources/ClangSharp/LazyList`2.cs new file mode 100644 index 00000000..0e40def2 --- /dev/null +++ b/sources/ClangSharp/LazyList`2.cs @@ -0,0 +1,173 @@ +// Copyright © Tanner Gooding and Contributors. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; + +namespace ClangSharp; + +internal sealed class LazyList : IList, IReadOnlyList + where T : class, TBase + where TBase : class +{ + internal readonly TBase[] _items; + internal readonly Func _valueFactory; + + private readonly int _start; + private readonly int _count; + + public LazyList(LazyList list, int skip = -1, int take = -1) + { + skip = (skip < 0) ? 0 : skip; + take = (take < 0) ? (list.Count - skip) : take; + + _items = list._items; + _valueFactory = list._valueFactory; + + _start = skip; + _count = take; + } + + public T this[int index] + { + get + { + var items = _items.AsSpan(_start, _count); + var item = items[index]; + + if (item is null) + { + item = _valueFactory(index + _start); + items[index] = item; + } + + return (T)item; + } + } + + public int Count => _count; + + public bool IsReadOnly => true; + + public bool Contains(T item) => IndexOf(item) >= 0; + + public void CopyTo(T[] array, int arrayIndex) + { + var items = _items.AsSpan(_start, _count); + ArgumentNullException.ThrowIfNull(array); + + if ((arrayIndex < 0) || (arrayIndex > array.Length) || ((array.Length - arrayIndex) < items.Length)) + { + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + } + + for (var i = 0; i < _count; i++) + { + var currentItem = items[i]; + + if (currentItem is null) + { + currentItem = _valueFactory(i + _start); + items[i] = currentItem; + } + + array[arrayIndex + i] = (T)currentItem; + } + } + + public Enumerator GetEnumerator() => new Enumerator(this); + + public int IndexOf(T item) + { + var items = _items.AsSpan(_start, _count); + + for (var i = 0; i < items.Length; i++) + { + var currentItem = items[i]; + + if (currentItem is null) + { + currentItem = _valueFactory(i + _start); + items[i] = currentItem; + } + + if (EqualityComparer.Default.Equals((T)currentItem, item)) + { + return i; + } + } + + return -1; + } + + T IList.this[int index] + { + get + { + return this[index]; + } + + set + { + throw new NotSupportedException(); + } + } + + void ICollection.Add(T item) => throw new NotSupportedException(); + + void ICollection.Clear() => throw new NotSupportedException(); + + bool ICollection.Remove(T item) => throw new NotSupportedException(); + + void IList.Insert(int index, T item) => throw new NotSupportedException(); + + void IList.RemoveAt(int index) => throw new NotSupportedException(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public struct Enumerator : IEnumerator + { + private readonly LazyList _list; + + private int _index; + private T? _current; + + internal Enumerator(LazyList list) + { + _list = list; + } + + public readonly void Dispose() + { + } + + public bool MoveNext() + { + var localList = _list; + + if ((uint)_index < (uint)localList.Count) + { + _current = localList[_index]; + _index++; + return true; + } + + _current = default; + _index = -1; + return false; + } + + public readonly T Current => _current!; + + readonly object? IEnumerator.Current => Current; + + void IEnumerator.Reset() + { + _index = 0; + _current = default; + } + } +} diff --git a/sources/ClangSharp/TemplateArgument.cs b/sources/ClangSharp/TemplateArgument.cs index 7ca67eb3..5f450f19 100644 --- a/sources/ClangSharp/TemplateArgument.cs +++ b/sources/ClangSharp/TemplateArgument.cs @@ -4,56 +4,43 @@ using System.Collections.Generic; using System.Diagnostics; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTemplateArgumentKind; using static ClangSharp.Interop.CX_TemplateArgumentDependence; +using static ClangSharp.Interop.CXTemplateArgumentKind; namespace ClangSharp; public sealed unsafe class TemplateArgument : IDisposable { - private readonly Lazy _asDecl; - private readonly Lazy _asExpr; - private readonly Lazy _asTemplate; - private readonly Lazy _asTemplateOrTemplatePattern; - private readonly Lazy _asType; - private readonly Lazy _integralType; - private readonly Lazy _nonTypeTemplateArgumentType; - private readonly Lazy _nullPtrType; - private readonly Lazy> _packElements; - private readonly Lazy _packExpansionPattern; - private readonly Lazy _paramTypeForDecl; - private readonly Lazy _translationUnit; + private readonly ValueLazy _asDecl; + private readonly ValueLazy _asExpr; + private readonly ValueLazy _asTemplate; + private readonly ValueLazy _asTemplateOrTemplatePattern; + private readonly ValueLazy _asType; + private readonly ValueLazy _integralType; + private readonly ValueLazy _nonTypeTemplateArgumentType; + private readonly ValueLazy _nullPtrType; + private readonly LazyList _packElements; + private readonly ValueLazy _packExpansionPattern; + private readonly ValueLazy _paramTypeForDecl; + private readonly ValueLazy _translationUnit; internal TemplateArgument(CX_TemplateArgument handle) { Handle = handle; - _translationUnit = new Lazy(() => TranslationUnit.GetOrCreate(Handle.tu)); - - _asDecl = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsDecl)); - _asExpr = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsExpr)); - _asTemplate = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsTemplate)); - _asTemplateOrTemplatePattern = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsTemplateOrTemplatePattern)); - _asType = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsType)); - _integralType = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.IntegralType)); - _nonTypeTemplateArgumentType = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.NonTypeTemplateArgumentType)); - _nullPtrType = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.NullPtrType)); - _packExpansionPattern = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.PackExpansionPattern)); - - _packElements = new Lazy>(() => { - var numPackElements = Handle.NumPackElements; - var packElements = new List(numPackElements); - - for (var i = 0; i < numPackElements; i++) - { - var packElement = _translationUnit.Value.GetOrCreate(Handle.GetPackElement(unchecked((uint)i))); - packElements.Add(packElement); - } - - return packElements; - }); - - _paramTypeForDecl = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.ParamTypeForDecl)); + _translationUnit = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.tu)); + + _asDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsDecl)); + _asExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsExpr)); + _asTemplate = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsTemplate)); + _asTemplateOrTemplatePattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsTemplateOrTemplatePattern)); + _asType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AsType)); + _integralType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.IntegralType)); + _nonTypeTemplateArgumentType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NonTypeTemplateArgumentType)); + _nullPtrType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NullPtrType)); + _packExpansionPattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.PackExpansionPattern)); + _packElements = LazyList.Create(Handle.NumPackElements, (i) => TranslationUnit.GetOrCreate(Handle.GetPackElement(unchecked((uint)i)))); + _paramTypeForDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ParamTypeForDecl)); } ~TemplateArgument() => Dispose(isDisposing: false); @@ -127,7 +114,7 @@ public bool IsPackExpansion public Type NullPtrType => _nullPtrType.Value; - public IReadOnlyList PackElements => _packElements.Value; + public IReadOnlyList PackElements => _packElements; public TemplateArgument PackExpansionPattern => _packExpansionPattern.Value; diff --git a/sources/ClangSharp/TemplateArgumentLoc.cs b/sources/ClangSharp/TemplateArgumentLoc.cs index 8b0f380f..845b83d3 100644 --- a/sources/ClangSharp/TemplateArgumentLoc.cs +++ b/sources/ClangSharp/TemplateArgumentLoc.cs @@ -7,24 +7,24 @@ namespace ClangSharp; public sealed unsafe class TemplateArgumentLoc { - private readonly Lazy _argument; - private readonly Lazy _sourceDeclExpression; - private readonly Lazy _sourceExpression; - private readonly Lazy _sourceIntegralExpression; - private readonly Lazy _sourceNullPtrExpression; - private readonly Lazy _translationUnit; + private readonly ValueLazy _argument; + private readonly ValueLazy _sourceDeclExpression; + private readonly ValueLazy _sourceExpression; + private readonly ValueLazy _sourceIntegralExpression; + private readonly ValueLazy _sourceNullPtrExpression; + private readonly ValueLazy _translationUnit; internal TemplateArgumentLoc(CX_TemplateArgumentLoc handle) { Handle = handle; - _translationUnit = new Lazy(() => TranslationUnit.GetOrCreate(Handle.tu)); + _translationUnit = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.tu)); - _argument = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.Argument)); - _sourceDeclExpression = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceDeclExpression)); - _sourceExpression = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceExpression)); - _sourceIntegralExpression = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceIntegralExpression)); - _sourceNullPtrExpression = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceNullPtrExpression)); + _argument = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.Argument)); + _sourceDeclExpression = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceDeclExpression)); + _sourceExpression = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceExpression)); + _sourceIntegralExpression = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceIntegralExpression)); + _sourceNullPtrExpression = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.SourceNullPtrExpression)); } public TemplateArgument Argument => _argument.Value; diff --git a/sources/ClangSharp/TemplateName.cs b/sources/ClangSharp/TemplateName.cs index 2a8bc1a5..71ea0240 100644 --- a/sources/ClangSharp/TemplateName.cs +++ b/sources/ClangSharp/TemplateName.cs @@ -7,15 +7,15 @@ namespace ClangSharp; public sealed unsafe class TemplateName { - private readonly Lazy _asTemplateDecl; - private readonly Lazy _translationUnit; + private readonly ValueLazy _asTemplateDecl; + private readonly ValueLazy _translationUnit; internal TemplateName(CX_TemplateName handle) { Handle = handle; - _translationUnit = new Lazy(() => TranslationUnit.GetOrCreate(Handle.tu)); - _asTemplateDecl = new Lazy(() => _translationUnit.Value.GetOrCreate(Handle.AsTemplateDecl)); + _translationUnit = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.tu)); + _asTemplateDecl = new ValueLazy(() => _translationUnit.Value.GetOrCreate(Handle.AsTemplateDecl)); } public TemplateDecl AsTemplateDecl => _asTemplateDecl.Value; diff --git a/sources/ClangSharp/TranslationUnit.cs b/sources/ClangSharp/TranslationUnit.cs index 41f16045..6f9ca963 100644 --- a/sources/ClangSharp/TranslationUnit.cs +++ b/sources/ClangSharp/TranslationUnit.cs @@ -4,24 +4,25 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Threading; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTypeKind; -using static ClangSharp.Interop.CXTemplateArgumentKind; using static ClangSharp.Interop.CX_TemplateNameKind; +using static ClangSharp.Interop.CXTemplateArgumentKind; +using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed unsafe class TranslationUnit : IDisposable, IEquatable { private static readonly ConcurrentDictionary> s_createdTranslationUnits = new ConcurrentDictionary>(); - private static readonly object s_createTranslationUnitLock = new object(); + private static readonly Lock s_createTranslationUnitLock = new Lock(); private readonly Dictionary> _createdCursors; private readonly Dictionary> _createdTemplateArguments; private readonly Dictionary> _createdTemplateArgumentLocs; private readonly Dictionary> _createdTemplateNames; private readonly Dictionary> _createdTypes; - private readonly Lazy _translationUnitDecl; + private readonly ValueLazy _translationUnitDecl; private bool _isDisposed; @@ -35,7 +36,7 @@ private TranslationUnit(CXTranslationUnit handle) _createdTemplateNames = []; _createdTypes = []; - _translationUnitDecl = new Lazy(() => GetOrCreate(Handle.Cursor)); + _translationUnitDecl = new ValueLazy(() => GetOrCreate(Handle.Cursor)); } ~TranslationUnit() @@ -94,7 +95,7 @@ internal TCursor GetOrCreate(CXCursor handle) if (handle.IsNull) { - Debug.Assert(!handle.IsNull); + // Debug.Assert(!handle.IsNull); return null!; } else if (!_createdCursors.TryGetValue(handle, out cursorRef)) diff --git a/sources/ClangSharp/Types/AdjustedType.cs b/sources/ClangSharp/Types/AdjustedType.cs index cd6c2d31..8a8f1bed 100644 --- a/sources/ClangSharp/Types/AdjustedType.cs +++ b/sources/ClangSharp/Types/AdjustedType.cs @@ -9,8 +9,8 @@ namespace ClangSharp; public class AdjustedType : Type { - private readonly Lazy _adjustedType; - private readonly Lazy _originalType; + private readonly ValueLazy _adjustedType; + private readonly ValueLazy _originalType; internal AdjustedType(CXType handle) : this(handle, CXType_Unexposed, CX_TypeClass_Adjusted) { @@ -18,8 +18,8 @@ internal AdjustedType(CXType handle) : this(handle, CXType_Unexposed, CX_TypeCla private protected AdjustedType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _adjustedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.AdjustedType)); - _originalType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _adjustedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AdjustedType)); + _originalType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); } public Type GetAdjustedType => _adjustedType.Value; diff --git a/sources/ClangSharp/Types/ArrayType.cs b/sources/ClangSharp/Types/ArrayType.cs index adb43ed4..75626a17 100644 --- a/sources/ClangSharp/Types/ArrayType.cs +++ b/sources/ClangSharp/Types/ArrayType.cs @@ -7,11 +7,11 @@ namespace ClangSharp; public class ArrayType : Type { - private readonly Lazy _elementType; + private readonly ValueLazy _elementType; private protected ArrayType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ArrayElementType)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ArrayElementType)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/AtomicType.cs b/sources/ClangSharp/Types/AtomicType.cs index 9e26c1de..5c174e51 100644 --- a/sources/ClangSharp/Types/AtomicType.cs +++ b/sources/ClangSharp/Types/AtomicType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class AtomicType : Type { - private readonly Lazy _valueType; + private readonly ValueLazy _valueType; internal AtomicType(CXType handle) : base(handle, CXType_Atomic, CX_TypeClass_Atomic) { - _valueType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ValueType)); + _valueType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ValueType)); } public Type ValueType => _valueType.Value; diff --git a/sources/ClangSharp/Types/AttributedType.cs b/sources/ClangSharp/Types/AttributedType.cs index a7a56aca..2a867e0b 100644 --- a/sources/ClangSharp/Types/AttributedType.cs +++ b/sources/ClangSharp/Types/AttributedType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class AttributedType : Type { - private readonly Lazy _equivalentType; - private readonly Lazy _modifiedType; + private readonly ValueLazy _equivalentType; + private readonly ValueLazy _modifiedType; internal AttributedType(CXType handle) : base(handle, CXType_Attributed, CX_TypeClass_Attributed) { - _equivalentType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.EquivalentType)); - _modifiedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ModifiedType)); + _equivalentType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.EquivalentType)); + _modifiedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ModifiedType)); } public CX_AttrKind AttrKind => Handle.AttrKind; diff --git a/sources/ClangSharp/Types/AutoType.cs b/sources/ClangSharp/Types/AutoType.cs index 8b7613ae..9e1a30ea 100644 --- a/sources/ClangSharp/Types/AutoType.cs +++ b/sources/ClangSharp/Types/AutoType.cs @@ -1,32 +1,20 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTypeKind; using static ClangSharp.Interop.CX_TypeClass; +using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed class AutoType : DeducedType { - private readonly Lazy> _templateArgs; + private readonly LazyList _templateArgs; internal AutoType(CXType handle) : base(handle, CXType_Auto, CX_TypeClass_Auto) { - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } - public IReadOnlyList Args => _templateArgs.Value; + public IReadOnlyList Args => _templateArgs; } diff --git a/sources/ClangSharp/Types/ComplexType.cs b/sources/ClangSharp/Types/ComplexType.cs index 4998f44f..0f45d043 100644 --- a/sources/ClangSharp/Types/ComplexType.cs +++ b/sources/ClangSharp/Types/ComplexType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ComplexType : Type { - private readonly Lazy _elementType; + private readonly ValueLazy _elementType; internal ComplexType(CXType handle) : base(handle, CXType_Complex, CX_TypeClass_Complex) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/ConstantArrayType.cs b/sources/ClangSharp/Types/ConstantArrayType.cs index dc2e556b..012ca250 100644 --- a/sources/ClangSharp/Types/ConstantArrayType.cs +++ b/sources/ClangSharp/Types/ConstantArrayType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ConstantArrayType : ArrayType { - private readonly Lazy _sizeExpr; + private readonly ValueLazy _sizeExpr; internal ConstantArrayType(CXType handle) : base(handle, CXType_ConstantArray, CX_TypeClass_ConstantArray) { - _sizeExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); + _sizeExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); } public long Size => Handle.ArraySize; diff --git a/sources/ClangSharp/Types/DecayedType.cs b/sources/ClangSharp/Types/DecayedType.cs index d826e5da..99fc54a9 100644 --- a/sources/ClangSharp/Types/DecayedType.cs +++ b/sources/ClangSharp/Types/DecayedType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class DecayedType : AdjustedType { - private readonly Lazy _decayedType; + private readonly ValueLazy _decayedType; internal DecayedType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_Decayed) { - _decayedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DecayedType)); + _decayedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DecayedType)); } public Type GetDecayedType => _decayedType.Value; diff --git a/sources/ClangSharp/Types/DecltypeType.cs b/sources/ClangSharp/Types/DecltypeType.cs index da4047f7..b4272015 100644 --- a/sources/ClangSharp/Types/DecltypeType.cs +++ b/sources/ClangSharp/Types/DecltypeType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class DecltypeType : Type { - private readonly Lazy _underlyingExpr; - private readonly Lazy _underlyingType; + private readonly ValueLazy _underlyingExpr; + private readonly ValueLazy _underlyingType; internal DecltypeType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_Decltype) { - _underlyingExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingExpr)); - _underlyingType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _underlyingExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingExpr)); + _underlyingType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); } public Expr UnderlyingExpr => _underlyingExpr.Value; diff --git a/sources/ClangSharp/Types/DeducedTemplateSpecializationType.cs b/sources/ClangSharp/Types/DeducedTemplateSpecializationType.cs index 89bab893..6d893a63 100644 --- a/sources/ClangSharp/Types/DeducedTemplateSpecializationType.cs +++ b/sources/ClangSharp/Types/DeducedTemplateSpecializationType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class DeducedTemplateSpecializationType : DeducedType { - private readonly Lazy _templateName; + private readonly ValueLazy _templateName; internal DeducedTemplateSpecializationType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DeducedTemplateSpecialization) { - _templateName = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); + _templateName = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); } public TemplateName TemplateName => _templateName.Value; diff --git a/sources/ClangSharp/Types/DeducedType.cs b/sources/ClangSharp/Types/DeducedType.cs index 4c77aa5a..fc630fe6 100644 --- a/sources/ClangSharp/Types/DeducedType.cs +++ b/sources/ClangSharp/Types/DeducedType.cs @@ -7,11 +7,11 @@ namespace ClangSharp; public class DeducedType : Type { - private readonly Lazy _deducedType; + private readonly ValueLazy _deducedType; private protected DeducedType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _deducedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.DeducedType)); + _deducedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.DeducedType)); } public Type GetDeducedType => _deducedType.Value; diff --git a/sources/ClangSharp/Types/DependentAddressSpaceType.cs b/sources/ClangSharp/Types/DependentAddressSpaceType.cs index 07470cb8..6f8bc6ff 100644 --- a/sources/ClangSharp/Types/DependentAddressSpaceType.cs +++ b/sources/ClangSharp/Types/DependentAddressSpaceType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class DependentAddressSpaceType : Type { - private readonly Lazy _addrSpaceExpr; + private readonly ValueLazy _addrSpaceExpr; internal DependentAddressSpaceType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentAddressSpace) { - _addrSpaceExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.AddrSpaceExpr)); + _addrSpaceExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.AddrSpaceExpr)); } public Expr AddrSpaceExpr => _addrSpaceExpr.Value; diff --git a/sources/ClangSharp/Types/DependentBitIntType.cs b/sources/ClangSharp/Types/DependentBitIntType.cs index 859c80ad..d0cb756a 100644 --- a/sources/ClangSharp/Types/DependentBitIntType.cs +++ b/sources/ClangSharp/Types/DependentBitIntType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class DependentBitIntType : Type { - private readonly Lazy _numBitsExpr; + private readonly ValueLazy _numBitsExpr; internal DependentBitIntType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentBitInt) { - _numBitsExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.NumBitsExpr)); + _numBitsExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.NumBitsExpr)); } public bool IsSigned => Handle.IsSigned; diff --git a/sources/ClangSharp/Types/DependentSizedArrayType.cs b/sources/ClangSharp/Types/DependentSizedArrayType.cs index bb35f032..7ab68928 100644 --- a/sources/ClangSharp/Types/DependentSizedArrayType.cs +++ b/sources/ClangSharp/Types/DependentSizedArrayType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class DependentSizedArrayType : ArrayType { - private readonly Lazy _sizeExpr; + private readonly ValueLazy _sizeExpr; internal DependentSizedArrayType(CXType handle) : base(handle, CXType_DependentSizedArray, CX_TypeClass_DependentSizedArray) { - _sizeExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); + _sizeExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); } public Expr SizeExpr => _sizeExpr.Value; diff --git a/sources/ClangSharp/Types/DependentSizedExtVectorType.cs b/sources/ClangSharp/Types/DependentSizedExtVectorType.cs index c527be0b..3d3a63fc 100644 --- a/sources/ClangSharp/Types/DependentSizedExtVectorType.cs +++ b/sources/ClangSharp/Types/DependentSizedExtVectorType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class DependentSizedExtVectorType : Type { - private readonly Lazy _elementType; - private readonly Lazy _sizeExpr; + private readonly ValueLazy _elementType; + private readonly ValueLazy _sizeExpr; internal DependentSizedExtVectorType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentSizedExtVector) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); - _sizeExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); + _sizeExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/DependentSizedMatrixType.cs b/sources/ClangSharp/Types/DependentSizedMatrixType.cs index 6e61861b..cb1ad796 100644 --- a/sources/ClangSharp/Types/DependentSizedMatrixType.cs +++ b/sources/ClangSharp/Types/DependentSizedMatrixType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class DependentSizedMatrixType : MatrixType { - private readonly Lazy _rowExpr; - private readonly Lazy _columnExpr; + private readonly ValueLazy _rowExpr; + private readonly ValueLazy _columnExpr; internal DependentSizedMatrixType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentSizedMatrix) { - _rowExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.RowExpr)); - _columnExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.ColumnExpr)); + _rowExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.RowExpr)); + _columnExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.ColumnExpr)); } public Expr ColumnExpr => _columnExpr.Value; diff --git a/sources/ClangSharp/Types/DependentTemplateSpecializationType.cs b/sources/ClangSharp/Types/DependentTemplateSpecializationType.cs index b63182c5..05957f8f 100644 --- a/sources/ClangSharp/Types/DependentTemplateSpecializationType.cs +++ b/sources/ClangSharp/Types/DependentTemplateSpecializationType.cs @@ -1,32 +1,20 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTypeKind; using static ClangSharp.Interop.CX_TypeClass; +using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed class DependentTemplateSpecializationType : TypeWithKeyword { - private readonly Lazy> _templateArgs; + private readonly LazyList _templateArgs; internal DependentTemplateSpecializationType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentTemplateSpecialization) { - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); } - public IReadOnlyList Args => _templateArgs.Value; + public IReadOnlyList Args => _templateArgs; } diff --git a/sources/ClangSharp/Types/DependentVectorType.cs b/sources/ClangSharp/Types/DependentVectorType.cs index ff267692..6b050677 100644 --- a/sources/ClangSharp/Types/DependentVectorType.cs +++ b/sources/ClangSharp/Types/DependentVectorType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class DependentVectorType : Type { - private readonly Lazy _elementType; - private readonly Lazy _sizeExpr; + private readonly ValueLazy _elementType; + private readonly ValueLazy _sizeExpr; internal DependentVectorType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_DependentVector) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); - _sizeExpr = new Lazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); + _sizeExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.SizeExpr)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/ElaboratedType.cs b/sources/ClangSharp/Types/ElaboratedType.cs index d8514fdb..ef004efb 100644 --- a/sources/ClangSharp/Types/ElaboratedType.cs +++ b/sources/ClangSharp/Types/ElaboratedType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class ElaboratedType : TypeWithKeyword { - private readonly Lazy _namedType; - private readonly Lazy _ownedTagDecl; + private readonly ValueLazy _namedType; + private readonly ValueLazy _ownedTagDecl; internal ElaboratedType(CXType handle) : base(handle, CXType_Elaborated, CX_TypeClass_Elaborated) { - _namedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.NamedType)); - _ownedTagDecl = new Lazy(() => !Handle.OwnedTagDecl.IsNull ?TranslationUnit.GetOrCreate(Handle.OwnedTagDecl) : null); + _namedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.NamedType)); + _ownedTagDecl = new ValueLazy(() => !Handle.OwnedTagDecl.IsNull ?TranslationUnit.GetOrCreate(Handle.OwnedTagDecl) : null); } public Type NamedType => _namedType.Value; diff --git a/sources/ClangSharp/Types/FunctionProtoType.cs b/sources/ClangSharp/Types/FunctionProtoType.cs index f87af112..771fd8b8 100644 --- a/sources/ClangSharp/Types/FunctionProtoType.cs +++ b/sources/ClangSharp/Types/FunctionProtoType.cs @@ -1,31 +1,19 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. -using System; using System.Collections.Generic; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTypeKind; using static ClangSharp.Interop.CX_TypeClass; +using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed class FunctionProtoType : FunctionType { - private readonly Lazy> _paramTypes; + private readonly LazyList _paramTypes; internal FunctionProtoType(CXType handle) : base(handle, CXType_FunctionProto, CX_TypeClass_FunctionProto) { - _paramTypes = new Lazy>(() => { - var paramTypeCount = Handle.NumArgTypes; - var paramTypes = new List(paramTypeCount); - - for (var i = 0; i < paramTypeCount; i++) - { - var paramType = TranslationUnit.GetOrCreate(Handle.GetArgType(unchecked((uint)i))); - paramTypes.Add(paramType); - } - - return paramTypes; - }); + _paramTypes = LazyList.Create(Handle.NumArgTypes, (i) => TranslationUnit.GetOrCreate(Handle.GetArgType(unchecked((uint)i)))); } public CXCursor_ExceptionSpecificationKind ExceptionSpecType => Handle.ExceptionSpecificationType; @@ -34,7 +22,7 @@ internal FunctionProtoType(CXType handle) : base(handle, CXType_FunctionProto, C public uint NumParams => (uint)Handle.NumArgTypes; - public IReadOnlyList ParamTypes => _paramTypes.Value; + public IReadOnlyList ParamTypes => _paramTypes; public CXRefQualifierKind RefQualifier => Handle.CXXRefQualifier; } diff --git a/sources/ClangSharp/Types/FunctionType.cs b/sources/ClangSharp/Types/FunctionType.cs index 343ce3de..00af1eee 100644 --- a/sources/ClangSharp/Types/FunctionType.cs +++ b/sources/ClangSharp/Types/FunctionType.cs @@ -7,11 +7,11 @@ namespace ClangSharp; public class FunctionType : Type { - private readonly Lazy _returnType; + private readonly ValueLazy _returnType; private protected FunctionType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _returnType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ResultType)); + _returnType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ResultType)); } public CXCallingConv CallConv => Handle.FunctionTypeCallingConv; diff --git a/sources/ClangSharp/Types/InjectedClassNameType.cs b/sources/ClangSharp/Types/InjectedClassNameType.cs index a29ea665..429d0c9a 100644 --- a/sources/ClangSharp/Types/InjectedClassNameType.cs +++ b/sources/ClangSharp/Types/InjectedClassNameType.cs @@ -9,17 +9,17 @@ namespace ClangSharp; public sealed class InjectedClassNameType : Type { - private readonly Lazy _decl; - private readonly Lazy _injectedSpecializationType; - private readonly Lazy _injectedTST; - private readonly Lazy _templateName; + private readonly ValueLazy _decl; + private readonly ValueLazy _injectedSpecializationType; + private readonly ValueLazy _injectedTST; + private readonly ValueLazy _templateName; internal InjectedClassNameType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_InjectedClassName) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(handle.Declaration)); - _injectedSpecializationType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); - _injectedTST = new Lazy(() => TranslationUnit.GetOrCreate(Handle.InjectedTST)); - _templateName = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.Declaration)); + _injectedSpecializationType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InjectedSpecializationType)); + _injectedTST = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.InjectedTST)); + _templateName = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); } public CXXRecordDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/MacroQualifiedType.cs b/sources/ClangSharp/Types/MacroQualifiedType.cs index 855fea8e..3cd17380 100644 --- a/sources/ClangSharp/Types/MacroQualifiedType.cs +++ b/sources/ClangSharp/Types/MacroQualifiedType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class MacroQualifiedType : Type { - private readonly Lazy _modifiedType; - private readonly Lazy _underlyingType; + private readonly ValueLazy _modifiedType; + private readonly ValueLazy _underlyingType; internal MacroQualifiedType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_MacroQualified) { - _modifiedType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ModifiedType)); - _underlyingType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _modifiedType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ModifiedType)); + _underlyingType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); } public Type ModifiedType => _modifiedType.Value; diff --git a/sources/ClangSharp/Types/MatrixType.cs b/sources/ClangSharp/Types/MatrixType.cs index b5098601..54c906d3 100644 --- a/sources/ClangSharp/Types/MatrixType.cs +++ b/sources/ClangSharp/Types/MatrixType.cs @@ -7,11 +7,11 @@ namespace ClangSharp; public class MatrixType : Type { - private readonly Lazy _elementType; + private readonly ValueLazy _elementType; private protected MatrixType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(handle.ElementType)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.ElementType)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/ObjCInterfaceType.cs b/sources/ClangSharp/Types/ObjCInterfaceType.cs index f2295836..f762af11 100644 --- a/sources/ClangSharp/Types/ObjCInterfaceType.cs +++ b/sources/ClangSharp/Types/ObjCInterfaceType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ObjCInterfaceType : ObjCObjectType { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal ObjCInterfaceType(CXType handle) : base(handle, CXType_ObjCObject, CX_TypeClass_ObjCInterface) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public ObjCInterfaceDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/ObjCObjectPointerType.cs b/sources/ClangSharp/Types/ObjCObjectPointerType.cs index d6f2b9c8..e992c99d 100644 --- a/sources/ClangSharp/Types/ObjCObjectPointerType.cs +++ b/sources/ClangSharp/Types/ObjCObjectPointerType.cs @@ -10,13 +10,13 @@ namespace ClangSharp; public sealed class ObjCObjectPointerType : Type { - private readonly Lazy _interfaceType; - private readonly Lazy _superClassType; + private readonly ValueLazy _interfaceType; + private readonly ValueLazy _superClassType; internal ObjCObjectPointerType(CXType handle) : base(handle, CXType_ObjCObjectPointer, CX_TypeClass_ObjCObjectPointer) { - _interfaceType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); - _superClassType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _interfaceType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _superClassType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); } public ObjCInterfaceDecl InterfaceDecl => ObjectType.Interface; diff --git a/sources/ClangSharp/Types/ObjCObjectType.cs b/sources/ClangSharp/Types/ObjCObjectType.cs index 64c696cf..ec0c6287 100644 --- a/sources/ClangSharp/Types/ObjCObjectType.cs +++ b/sources/ClangSharp/Types/ObjCObjectType.cs @@ -10,11 +10,11 @@ namespace ClangSharp; public class ObjCObjectType : Type { - private readonly Lazy _baseType; - private readonly Lazy _interface; - private readonly Lazy> _protocols; - private readonly Lazy _superClassType; - private readonly Lazy> _typeArgs; + private readonly ValueLazy _baseType; + private readonly ValueLazy _interface; + private readonly LazyList _protocols; + private readonly ValueLazy _superClassType; + private readonly LazyList _typeArgs; internal ObjCObjectType(CXType handle) : this(handle, CXType_ObjCObject, CX_TypeClass_ObjCObject) { @@ -22,44 +22,20 @@ internal ObjCObjectType(CXType handle) : this(handle, CXType_ObjCObject, CX_Type private protected ObjCObjectType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _baseType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ObjCObjectBaseType)); - _interface = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); - - _protocols = new Lazy>(() => { - var numProtocols = unchecked((int)Handle.NumObjCProtocolRefs); - var protocols = new List(numProtocols); - - for (var i = 0; i < numProtocols; i++) - { - var protocol = TranslationUnit.GetOrCreate(Handle.GetObjCProtocolDecl(unchecked((uint)i))); - protocols.Add(protocol); - } - - return protocols; - }); - - _superClassType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); - _typeArgs = new Lazy>(() => { - var numTypeArgs = unchecked((int)Handle.NumObjCTypeArgs); - var typeArgs = new List(numTypeArgs); - - for (var i = 0; i < numTypeArgs; i++) - { - var typeArg = TranslationUnit.GetOrCreate(Handle.GetObjCTypeArg(unchecked((uint)i))); - typeArgs.Add(typeArg); - } - - return typeArgs; - }); + _baseType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ObjCObjectBaseType)); + _interface = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _protocols = LazyList.Create(unchecked((int)Handle.NumObjCProtocolRefs), (i) => TranslationUnit.GetOrCreate(Handle.GetObjCProtocolDecl(unchecked((uint)i)))); + _superClassType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _typeArgs = LazyList.Create(unchecked((int)Handle.NumObjCTypeArgs), (i) => TranslationUnit.GetOrCreate(Handle.GetObjCTypeArg(unchecked((uint)i)))); } public Type BaseType => _baseType.Value; public ObjCInterfaceDecl Interface => _interface.Value; - public IReadOnlyList Protocols => _protocols.Value; + public IReadOnlyList Protocols => _protocols; public Type SuperClassType => _superClassType.Value; - public IReadOnlyList TypeArgs => _typeArgs.Value; + public IReadOnlyList TypeArgs => _typeArgs; } diff --git a/sources/ClangSharp/Types/ObjCTypeParamType.cs b/sources/ClangSharp/Types/ObjCTypeParamType.cs index ca8f139b..9c42cba0 100644 --- a/sources/ClangSharp/Types/ObjCTypeParamType.cs +++ b/sources/ClangSharp/Types/ObjCTypeParamType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class ObjCTypeParamType : Type { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal ObjCTypeParamType(CXType handle) : base(handle, CXType_ObjCTypeParam, CX_TypeClass_ObjCTypeParam) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public ObjCTypeParamDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/PackExpansionType.cs b/sources/ClangSharp/Types/PackExpansionType.cs index 34201091..e2c64c11 100644 --- a/sources/ClangSharp/Types/PackExpansionType.cs +++ b/sources/ClangSharp/Types/PackExpansionType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class PackExpansionType : Type { - private readonly Lazy _pattern; + private readonly ValueLazy _pattern; internal PackExpansionType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_PackExpansion) { - _pattern = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _pattern = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); } public Type Pattern => _pattern.Value; diff --git a/sources/ClangSharp/Types/PipeType.cs b/sources/ClangSharp/Types/PipeType.cs index 429608be..58727e23 100644 --- a/sources/ClangSharp/Types/PipeType.cs +++ b/sources/ClangSharp/Types/PipeType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class PipeType : Type { - private readonly Lazy _elementType; + private readonly ValueLazy _elementType; internal PipeType(CXType handle) : base(handle, CXType_Pipe, CX_TypeClass_Pipe) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/Types/SubstTemplateTypeParmPackType.cs b/sources/ClangSharp/Types/SubstTemplateTypeParmPackType.cs index dd4672e4..e7ae53f3 100644 --- a/sources/ClangSharp/Types/SubstTemplateTypeParmPackType.cs +++ b/sources/ClangSharp/Types/SubstTemplateTypeParmPackType.cs @@ -9,13 +9,13 @@ namespace ClangSharp; public sealed class SubstTemplateTypeParmPackType : Type { - private readonly Lazy _argumentPack; - private readonly Lazy _replacedParameter; + private readonly ValueLazy _argumentPack; + private readonly ValueLazy _replacedParameter; internal SubstTemplateTypeParmPackType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_SubstTemplateTypeParmPack) { - _argumentPack = new Lazy(() => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(0))); - _replacedParameter = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _argumentPack = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(0))); + _replacedParameter = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); } public TemplateArgument ArgumentPack => _argumentPack.Value; diff --git a/sources/ClangSharp/Types/SubstTemplateTypeParmType.cs b/sources/ClangSharp/Types/SubstTemplateTypeParmType.cs index d09e2a5c..68c9a92f 100644 --- a/sources/ClangSharp/Types/SubstTemplateTypeParmType.cs +++ b/sources/ClangSharp/Types/SubstTemplateTypeParmType.cs @@ -9,16 +9,16 @@ namespace ClangSharp; public sealed class SubstTemplateTypeParmType : Type { - private readonly Lazy _associatedDecl; - private readonly Lazy _replacedParameter; + private readonly ValueLazy _associatedDecl; + private readonly ValueLazy _replacedParameter; internal SubstTemplateTypeParmType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_SubstTemplateTypeParm) { - _associatedDecl = new Lazy(() => { - CXCursor cursor = clangsharp.Type_getSubstTemplateTypeParamAssociatedDecl(Handle); + _associatedDecl = new ValueLazy(() => { + var cursor = clangsharp.Type_getSubstTemplateTypeParamAssociatedDecl(Handle); return cursor.IsNull ? null : TranslationUnit.GetOrCreate(cursor); }); - _replacedParameter = new Lazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); + _replacedParameter = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.OriginalType)); } public TemplateTypeParmType ReplacedParameter => _replacedParameter.Value; diff --git a/sources/ClangSharp/Types/TagType.cs b/sources/ClangSharp/Types/TagType.cs index 52c25460..70ee8f95 100644 --- a/sources/ClangSharp/Types/TagType.cs +++ b/sources/ClangSharp/Types/TagType.cs @@ -7,11 +7,11 @@ namespace ClangSharp; public class TagType : Type { - private readonly Lazy _decl; + private readonly ValueLazy _decl; private protected TagType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public TagDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/TemplateSpecializationType.cs b/sources/ClangSharp/Types/TemplateSpecializationType.cs index b83317d5..c78075e6 100644 --- a/sources/ClangSharp/Types/TemplateSpecializationType.cs +++ b/sources/ClangSharp/Types/TemplateSpecializationType.cs @@ -4,37 +4,25 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using ClangSharp.Interop; -using static ClangSharp.Interop.CXTypeKind; using static ClangSharp.Interop.CX_TypeClass; +using static ClangSharp.Interop.CXTypeKind; namespace ClangSharp; public sealed class TemplateSpecializationType : Type { - private readonly Lazy> _templateArgs; - private readonly Lazy _templateName; + private readonly LazyList _templateArgs; + private readonly ValueLazy _templateName; internal TemplateSpecializationType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_TemplateSpecialization) { - _templateArgs = new Lazy>(() => { - var templateArgCount = Handle.NumTemplateArguments; - var templateArgs = new List(templateArgCount); - - for (var i = 0; i < templateArgCount; i++) - { - var templateArg = TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i))); - templateArgs.Add(templateArg); - } - - return templateArgs; - }); - - _templateName = new Lazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); + _templateArgs = LazyList.Create(Handle.NumTemplateArguments, (i) => TranslationUnit.GetOrCreate(Handle.GetTemplateArgument(unchecked((uint)i)))); + _templateName = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.TemplateName)); } public Type? AliasedType => IsTypeAlias ? Desugar : null; - public IReadOnlyList Args => _templateArgs.Value; + public IReadOnlyList Args => _templateArgs; [MemberNotNullWhen(true, nameof(AliasedType))] public bool IsTypeAlias => Handle.IsTypeAlias; diff --git a/sources/ClangSharp/Types/TemplateTypeParmType.cs b/sources/ClangSharp/Types/TemplateTypeParmType.cs index 37adda7b..ca3a626d 100644 --- a/sources/ClangSharp/Types/TemplateTypeParmType.cs +++ b/sources/ClangSharp/Types/TemplateTypeParmType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TemplateTypeParmType : Type { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal TemplateTypeParmType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_TemplateTypeParm) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public TemplateTypeParmDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/Type.cs b/sources/ClangSharp/Types/Type.cs index a5653549..0c54d5bf 100644 --- a/sources/ClangSharp/Types/Type.cs +++ b/sources/ClangSharp/Types/Type.cs @@ -11,12 +11,12 @@ namespace ClangSharp; [DebuggerDisplay("{Handle.DebuggerDisplayString,nq}")] public unsafe class Type : IEquatable { - private readonly Lazy _asString; - private readonly Lazy _canonicalType; - private readonly Lazy _desugar; - private readonly Lazy _kindSpelling; - private readonly Lazy _pointeeType; - private readonly Lazy _translationUnit; + private readonly ValueLazy _asString; + private readonly ValueLazy _canonicalType; + private readonly ValueLazy _desugar; + private readonly ValueLazy _kindSpelling; + private readonly ValueLazy _pointeeType; + private readonly ValueLazy _translationUnit; protected Type(CXType handle, CXTypeKind expectedKind, CX_TypeClass expectedTypeClass) { @@ -31,12 +31,12 @@ protected Type(CXType handle, CXTypeKind expectedKind, CX_TypeClass expectedType } Handle = handle; - _asString = new Lazy(Handle.Spelling.ToString); - _canonicalType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.CanonicalType)); - _desugar = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Desugar)); - _kindSpelling = new Lazy(Handle.KindSpelling.ToString); - _pointeeType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.PointeeType)); - _translationUnit = new Lazy(() => TranslationUnit.GetOrCreate((CXTranslationUnit)Handle.data[1])); + _asString = new ValueLazy(Handle.Spelling.ToString); + _canonicalType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.CanonicalType)); + _desugar = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Desugar)); + _kindSpelling = new ValueLazy(Handle.KindSpelling.ToString); + _pointeeType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.PointeeType)); + _translationUnit = new ValueLazy(() => TranslationUnit.GetOrCreate((CXTranslationUnit)Handle.data[1])); } public CXXRecordDecl? AsCXXRecordDecl => AsTagDecl as CXXRecordDecl; diff --git a/sources/ClangSharp/Types/TypeOfExprType.cs b/sources/ClangSharp/Types/TypeOfExprType.cs index 2d9ef803..98759484 100644 --- a/sources/ClangSharp/Types/TypeOfExprType.cs +++ b/sources/ClangSharp/Types/TypeOfExprType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TypeOfExprType : Type { - private readonly Lazy _underlyingExpr; + private readonly ValueLazy _underlyingExpr; internal TypeOfExprType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_TypeOfExpr) { - _underlyingExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.UnderlyingExpr)); + _underlyingExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.UnderlyingExpr)); } public Expr UnderlyingExpr => _underlyingExpr.Value; diff --git a/sources/ClangSharp/Types/TypeOfType.cs b/sources/ClangSharp/Types/TypeOfType.cs index 114cc3a2..e2572208 100644 --- a/sources/ClangSharp/Types/TypeOfType.cs +++ b/sources/ClangSharp/Types/TypeOfType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TypeOfType : Type { - private readonly Lazy _underlyingType; + private readonly ValueLazy _underlyingType; internal TypeOfType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_TypeOf) { - _underlyingType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _underlyingType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); } public Type UnderlyingType => _underlyingType.Value; diff --git a/sources/ClangSharp/Types/TypedefType.cs b/sources/ClangSharp/Types/TypedefType.cs index 1846c071..2f0082db 100644 --- a/sources/ClangSharp/Types/TypedefType.cs +++ b/sources/ClangSharp/Types/TypedefType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class TypedefType : Type { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal TypedefType(CXType handle) : base(handle, CXType_Typedef, CX_TypeClass_Typedef) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public TypedefNameDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/UnaryTransformType.cs b/sources/ClangSharp/Types/UnaryTransformType.cs index ac0283c7..52c9d266 100644 --- a/sources/ClangSharp/Types/UnaryTransformType.cs +++ b/sources/ClangSharp/Types/UnaryTransformType.cs @@ -9,8 +9,8 @@ namespace ClangSharp; public class UnaryTransformType : Type { - private readonly Lazy _baseType; - private readonly Lazy _underlyingType; + private readonly ValueLazy _baseType; + private readonly ValueLazy _underlyingType; internal UnaryTransformType(CXType handle) : this(handle, CXType_Unexposed, CX_TypeClass_UnaryTransform) { @@ -18,8 +18,8 @@ internal UnaryTransformType(CXType handle) : this(handle, CXType_Unexposed, CX_T private protected UnaryTransformType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _baseType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.BaseType)); - _underlyingType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); + _baseType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.BaseType)); + _underlyingType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.UnderlyingType)); } public Type BaseType => _baseType.Value; diff --git a/sources/ClangSharp/Types/UnresolvedUsingType.cs b/sources/ClangSharp/Types/UnresolvedUsingType.cs index 1072a548..460fb453 100644 --- a/sources/ClangSharp/Types/UnresolvedUsingType.cs +++ b/sources/ClangSharp/Types/UnresolvedUsingType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class UnresolvedUsingType : Type { - private readonly Lazy _decl; + private readonly ValueLazy _decl; internal UnresolvedUsingType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_UnresolvedUsing) { - _decl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _decl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public UnresolvedUsingTypenameDecl Decl => _decl.Value; diff --git a/sources/ClangSharp/Types/UsingType.cs b/sources/ClangSharp/Types/UsingType.cs index 78662422..bcf149c8 100644 --- a/sources/ClangSharp/Types/UsingType.cs +++ b/sources/ClangSharp/Types/UsingType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class UsingType : Type { - private readonly Lazy _foundDecl; + private readonly ValueLazy _foundDecl; internal UsingType(CXType handle) : base(handle, CXType_Unexposed, CX_TypeClass_Using) { - _foundDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); + _foundDecl = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } public UsingShadowDecl FoundDecl => _foundDecl.Value; diff --git a/sources/ClangSharp/Types/VariableArrayType.cs b/sources/ClangSharp/Types/VariableArrayType.cs index ac154804..33c745ed 100644 --- a/sources/ClangSharp/Types/VariableArrayType.cs +++ b/sources/ClangSharp/Types/VariableArrayType.cs @@ -9,11 +9,11 @@ namespace ClangSharp; public sealed class VariableArrayType : ArrayType { - private readonly Lazy _sizeExpr; + private readonly ValueLazy _sizeExpr; internal VariableArrayType(CXType handle) : base(handle, CXType_VariableArray, CX_TypeClass_VariableArray) { - _sizeExpr = new Lazy(() => TranslationUnit.GetOrCreate(handle.SizeExpr)); + _sizeExpr = new ValueLazy(() => TranslationUnit.GetOrCreate(handle.SizeExpr)); } public Expr SizeExpr => _sizeExpr.Value; diff --git a/sources/ClangSharp/Types/VectorType.cs b/sources/ClangSharp/Types/VectorType.cs index 6f93a1ef..2f2ef8fc 100644 --- a/sources/ClangSharp/Types/VectorType.cs +++ b/sources/ClangSharp/Types/VectorType.cs @@ -9,7 +9,7 @@ namespace ClangSharp; public class VectorType : Type { - private readonly Lazy _elementType; + private readonly ValueLazy _elementType; internal VectorType(CXType handle) : this(handle, CXType_Vector, CX_TypeClass_Vector) { @@ -17,7 +17,7 @@ internal VectorType(CXType handle) : this(handle, CXType_Vector, CX_TypeClass_Ve private protected VectorType(CXType handle, CXTypeKind expectedTypeKind, CX_TypeClass expectedTypeClass) : base(handle, expectedTypeKind, expectedTypeClass) { - _elementType = new Lazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); + _elementType = new ValueLazy(() => TranslationUnit.GetOrCreate(Handle.ElementType)); } public Type ElementType => _elementType.Value; diff --git a/sources/ClangSharp/ValueLazy`1.cs b/sources/ClangSharp/ValueLazy`1.cs new file mode 100644 index 00000000..7d5edf36 --- /dev/null +++ b/sources/ClangSharp/ValueLazy`1.cs @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. + +// This file includes code based on the Lazy class from https://github.com/dotnet/runtime/ +// The original code is Copyright © .NET Foundation and Contributors. All rights reserved. Licensed under the MIT License (MIT). + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace ClangSharp; + +internal partial struct ValueLazy<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T> : IEquatable> +{ + private Func? _factory; + private T _value; + + public ValueLazy(Func factory) + { + Unsafe.SkipInit(out this); + Reset(factory); + } + + public readonly bool IsValueCreated => _factory is null; + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public T Value + { + get + { + if (_factory is Func factory) + { + _value = factory(); + } + return _value; + } + } + + public static bool operator ==(ValueLazy left, ValueLazy right) + => (left._factory == right._factory) + && EqualityComparer.Default.Equals(left._value, right._value); + + public static bool operator !=(ValueLazy left, ValueLazy right) => !(left == right); + + public override readonly bool Equals([NotNullWhen(true)] object? obj) => (obj is ValueLazy other) && Equals(other); + + public readonly bool Equals(ValueLazy other) => this == other; + + public override readonly int GetHashCode() => HashCode.Combine(_factory, _value); + + public void Reset(Func factory) + { + ArgumentNullException.ThrowIfNull(factory); + _factory = factory; + } + + public override readonly string ToString() + { + if (!IsValueCreated || (_value is not T value)) + { + return string.Empty; + } + return value.ToString() ?? string.Empty; + } +} diff --git a/sources/ClangSharpPInvokeGenerator/ClangSharpPInvokeGenerator.csproj b/sources/ClangSharpPInvokeGenerator/ClangSharpPInvokeGenerator.csproj index 9343641f..111dc037 100644 --- a/sources/ClangSharpPInvokeGenerator/ClangSharpPInvokeGenerator.csproj +++ b/sources/ClangSharpPInvokeGenerator/ClangSharpPInvokeGenerator.csproj @@ -6,7 +6,7 @@ true win-x64 - net8.0 + net10.0 diff --git a/sources/ClangSharpPInvokeGenerator/Program.cs b/sources/ClangSharpPInvokeGenerator/Program.cs index 0545723b..8e10ac88 100644 --- a/sources/ClangSharpPInvokeGenerator/Program.cs +++ b/sources/ClangSharpPInvokeGenerator/Program.cs @@ -20,7 +20,7 @@ namespace ClangSharp; -public static class Program +internal static class Program { private static readonly string[] s_additionalOptionAliases = ["--additional", "-a"]; private static readonly string[] s_configOptionAliases = ["--config", "-c"]; diff --git a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj index cfdb757b..1b0f3bb7 100644 --- a/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj +++ b/tests/ClangSharp.PInvokeGenerator.UnitTests/ClangSharp.PInvokeGenerator.UnitTests.csproj @@ -3,13 +3,15 @@ ClangSharp.UnitTests - net8.0 + net10.0 + - $(NoWarn);CA1707;CA1711 + + $(NoWarn);CA1515;CA1707;CA1711;IDE0130 diff --git a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj index 837ec2d8..96f00b0a 100644 --- a/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj +++ b/tests/ClangSharp.UnitTests/ClangSharp.UnitTests.csproj @@ -2,12 +2,14 @@ - net8.0 + net10.0 + - $(NoWarn);CA1707 + + $(NoWarn);CA1515;CA1707;IDE0130