diff --git a/.ado/publish.yml b/.ado/publish.yml index 6dafbbfc..07269945 100644 --- a/.ado/publish.yml +++ b/.ado/publish.yml @@ -11,7 +11,7 @@ trigger: none parameters: # Matrix with target build platforms. # x86 versions are not supported by Native AOT. - # Use net8.0 as the latest stable version. + # Use net9.0 as the latest stable version. - name: buildMatrix type: object default: @@ -64,41 +64,41 @@ parameters: os: windows TargetRuntime: win-x64 DotNetVersion: net472 - - Name: win_x64_net60 + - Name: win_x64_net80 Pool: name: Azure-Pipelines-1ESPT-ExDShared vmImage: windows-latest os: windows TargetRuntime: win-x64 - DotNetVersion: net6.0 - - Name: win_x64_net80 + DotNetVersion: net8.0 + - Name: win_x64_net90 Pool: name: Azure-Pipelines-1ESPT-ExDShared vmImage: windows-latest os: windows TargetRuntime: win-x64 - DotNetVersion: net8.0 - - Name: osx_x64_net80 + DotNetVersion: net9.0 + - Name: osx_x64_net90 Pool: name: Azure Pipelines vmImage: macos-14 os: macOS TargetRuntime: osx-x64 - DotNetVersion: net8.0 - - Name: osx_arm64_net80 + DotNetVersion: net9.0 + - Name: osx_arm64_net90 Pool: name: Azure Pipelines vmImage: macos-14-arm64 os: macOS TargetRuntime: osx-arm64 - DotNetVersion: net8.0 - - Name: linux_x64_net80 + DotNetVersion: net9.0 + - Name: linux_x64_net90 Pool: name: Azure-Pipelines-1ESPT-ExDShared image: ubuntu-latest os: linux TargetRuntime: linux-x64 - DotNetVersion: net8.0 + DotNetVersion: net9.0 resources: repositories: @@ -141,7 +141,7 @@ extends: cancelTimeoutInMinutes: 45 # to allow more time to collect CodeQL debug info. variables: - DotNetMoniker: net8.0 + DotNetMoniker: net9.0 ${{ if and( variables.DisableOsxArm64CodeQL, eq( MatrixEntry.TargetRuntime, 'osx-arm64' )) }}: ONEES_ENFORCED_CODEQL_ENABLED: false @@ -233,12 +233,12 @@ extends: - checkout: self displayName: Shallow git fetch - - ${{ if eq( MatrixEntry.DotNetVersion, 'net6.0' ) }}: + - ${{ if eq( MatrixEntry.DotNetVersion, 'net8.0' ) }}: - task: UseDotNet@2 - displayName: Install .Net 6.0.x + displayName: Install .Net 8.0.x inputs: packageType: sdk - version: 6.0.x + version: 8.0.x - task: UseDotNet@2 displayName: Install .NET SDK using global.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e06a15a0..6d1e0ac0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,18 +12,18 @@ jobs: strategy: matrix: os: [ windows-latest, macos-latest, ubuntu-latest ] - dotnet-version: [ net472, net6.0, net8.0] - node-version: [ 18.x, 20.x ] + dotnet-version: [ net472, net8.0, net9.0] + node-version: [ 18.x, 22.x ] configuration: [ Release ] exclude: - # Exclude Node 18.x on .NET < 8, to thin the matrix. - - dotnet-version: net6.0 + # Exclude Node 18.x on .NET < 9, to thin the matrix. + - dotnet-version: net8.0 node-version: 18.x - dotnet-version: net472 node-version: 18.x # Exclude .NET 4.x on non-Windows OS. - os: macos-latest - dotnet-version: net472 + dotnet-version: net472 - os: ubuntu-latest dotnet-version: net472 @@ -36,20 +36,15 @@ jobs: with: fetch-depth: 0 # Deep clone is required for versioning on git commit height - - name: Link libdl.so # Required by .NET 6 - if: matrix.os == 'ubuntu-latest' - run: sudo ln -s /lib/x86_64-linux-gnu/libdl.so.2 /lib/x86_64-linux-gnu/libdl.so - - - name: Setup .NET 6 + - name: Setup .NET 8 uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - # The .NET 8 SDK is required even when the build matrix targets other .NET versions. - - name: Setup .NET 8 + - name: Setup .NET 9 uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Setup Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 @@ -67,7 +62,7 @@ jobs: # limit-access-to-actor: true - name: Upload build artifacts - if: matrix.dotnet-version == 'net8.0' && matrix.node-version == '20.x' + if: matrix.dotnet-version == 'net9.0' && matrix.node-version == '22.x' uses: actions/upload-artifact@v4 with: name: ${{ matrix.os }}-${{ matrix.configuration }}-packages @@ -87,8 +82,7 @@ jobs: continue-on-error: true - name: Upload test logs - # upload-artifact@v4 breaks the test reporter: https://github.com/dorny/test-reporter/issues/343 - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-logs-${{ matrix.os }}-${{matrix.dotnet-version}}-node${{matrix.node-version}}-${{matrix.configuration}} path: | diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 430a9d53..68e66ffe 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -47,16 +47,16 @@ jobs: # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs # queries: security-extended,security-and-quality - - name: Setup .NET 8 + - name: Setup .NET 9 if: matrix.language == 'csharp' uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Build C# if: matrix.language == 'csharp' - run: dotnet build -f:net8.0 -p:Configuration=Debug -p:NBGV_GitEngine=Disabled - # Just build the .NET 8 target framework; other targets would be redundant for CodeQL. + run: dotnet build -f:net9.0 -p:Configuration=Debug -p:NBGV_GitEngine=Disabled + # Just build the .NET 9 target framework; other targets would be redundant for CodeQL. # Disable git-versioning to prevent the shallow clone from causing build errors. - name: Perform CodeQL Analysis diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index f960f489..aec23d34 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -36,13 +36,13 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: npm cache-dependency-path: './docs/package-lock.json' - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Setup Pages uses: actions/configure-pages@v4 diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml index fe1420d0..f422070d 100644 --- a/.github/workflows/test-report.yml +++ b/.github/workflows/test-report.yml @@ -18,18 +18,18 @@ jobs: strategy: matrix: # This must be kept in sync with the PR build matrix. os: [ windows-latest, macos-latest, ubuntu-latest ] - dotnet-version: [ net472, net6.0, net8.0] - node-version: [ 18.x, 20.x ] + dotnet-version: [ net472, net8.0, net9.0] + node-version: [ 18.x, 22.x ] configuration: [ Release ] exclude: - # Exclude Node 18.x on .NET < 8, to thin the matrix. - - dotnet-version: net6.0 + # Exclude Node 18.x on .NET < 9, to thin the matrix. + - dotnet-version: net8.0 node-version: 18.x - dotnet-version: net472 node-version: 18.x # Exclude .NET 4.x on non-Windows OS. - os: macos-latest - dotnet-version: net472 + dotnet-version: net472 - os: ubuntu-latest dotnet-version: net472 diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 8ba5f43b..3b7fea61 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -46,7 +46,7 @@ "-c", "Release", "-f", - "net8.0", + "net9.0", "--", "--filter", "*.NonAot.*" @@ -68,7 +68,7 @@ "-c", "Release", "-f", - "net8.0", + "net9.0", "--", "--filter", "*.Aot.*" diff --git a/Directory.Build.props b/Directory.Build.props index 0635bc9f..f920bd04 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,8 @@ - net8.0;net6.0;netstandard2.0 - net8.0;net6.0;netstandard2.0;net472 - net8.0 + net9.0;net8.0;netstandard2.0 + net9.0;net8.0;netstandard2.0;net472 + net9.0 12 enable Debug diff --git a/bench/Directory.Build.props b/bench/Directory.Build.props index 51e69b6b..955581fd 100644 --- a/bench/Directory.Build.props +++ b/bench/Directory.Build.props @@ -2,8 +2,8 @@ - net8.0;net6.0 - net8.0;net6.0;net472 + net9.0;net8.0 + net9.0;net8.0;net472 12 enable false diff --git a/bench/README.md b/bench/README.md index c6c349f9..245eba29 100644 --- a/bench/README.md +++ b/bench/README.md @@ -9,21 +9,21 @@ though the "Dynamic" benchmarks are CLR-only. ### Run all benchmarks ``` -dotnet run -c Release -f net8.0 --filter * +dotnet run -c Release -f net9.0 --filter * ``` ### Run only CLR or only AOT benchmarks ``` -dotnet run -c Release -f net8.0 --filter *clr.* -dotnet run -c Release -f net8.0 --filter *aot.* +dotnet run -c Release -f net9.0 --filter *clr.* +dotnet run -c Release -f net9.0 --filter *aot.* ``` ### Run a specific benchmark ``` -dotnet run -c Release -f net8.0 --filter *clr.CallDotnetFunction +dotnet run -c Release -f net9.0 --filter *clr.CallDotnetFunction ``` ### List benchmarks ``` -dotnet run -c Release -f net8.0 --list flat +dotnet run -c Release -f net9.0 --list flat ``` diff --git a/docs/features/type-definitions.md b/docs/features/type-definitions.md index 5e1510f5..c0500f9e 100644 --- a/docs/features/type-definitions.md +++ b/docs/features/type-definitions.md @@ -20,7 +20,7 @@ The easiest way to generate type definitions is to leverage the provided MSBuild the `Microsoft.JavaScript.NodeApi.Generator` NuGet package: ```xml - + ``` diff --git a/docs/scenarios/js-dotnet-dynamic.md b/docs/scenarios/js-dotnet-dynamic.md index e282b6f1..7c7d1c43 100644 --- a/docs/scenarios/js-dotnet-dynamic.md +++ b/docs/scenarios/js-dotnet-dynamic.md @@ -11,7 +11,7 @@ For examples of this scenario, see one of these directories in the repo: ```xml - net6.0 + net8.0 bin commonjs// [!code highlight] @@ -72,16 +72,16 @@ For examples of this scenario, see one of these directories in the repo: A `.js` suffix is required when using ES modules, optional with CommonJS. ::: code-group ```JavaScript [ES (TS or JS)] - import dotnet from 'node-api-dotnet/net6.0.js'; + import dotnet from 'node-api-dotnet/net8.0.js'; ``` ```TypeScript [CommonJS (TS)] - import * as dotnet from 'node-api-dotnet/net6.0'; + import * as dotnet from 'node-api-dotnet/net8.0'; ``` ```JavaScript [CommonJS (JS)] - const dotnet = require('node-api-dotnet/net6.0'); + const dotnet = require('node-api-dotnet/net8.0'); ``` ::: - Currently the supported target frameworks are `net472`, `net6.0`, and `net8.0`. + Currently the supported target frameworks are `net472`, `net8.0`, and `net9.0`. 4. Load one or more .NET packages using the generated `.js` files: ::: code-group diff --git a/docs/scenarios/js-dotnet-module.md b/docs/scenarios/js-dotnet-module.md index 75e38630..7b27f5ae 100644 --- a/docs/scenarios/js-dotnet-module.md +++ b/docs/scenarios/js-dotnet-module.md @@ -3,11 +3,11 @@ For a minimal example of this scenario, see [/examples/dotnet-module/](https://github.com/microsoft/node-api-dotnet/blob/main/examples/dotnet-module/). -1. Create a .NET Class library project that targets .NET 6 or later. (.NET 8 for AOT.) +1. Create a .NET Class library project that targets .NET 8 or later. ```shell mkdir ExampleModule cd ExampleModule - dotnet new classlib --framework net6.0 + dotnet new classlib --framework net8.0 ``` 2. Add a reference to the `Microsoft.JavaScript.NodeApi` and @@ -20,8 +20,8 @@ For a minimal example of this scenario, see Afterward you should have the two references in your project file: ```xml - - + + ``` @@ -86,7 +86,7 @@ For a minimal example of this scenario, see const dotnet = require('node-api-dotnet/net8.0'); ``` ::: - Currently the supported target frameworks are `net472`, `net6.0`, and `net8.0`. + Currently the supported target frameworks are `net472`, `net8.0`, and `net9.0`. 7. Load your .NET module assembly from its path using the `dotnet.require()` function: ```JavaScript diff --git a/docs/tools/build-dotnet-api-docs.js b/docs/tools/build-dotnet-api-docs.js index adc6b75f..ed93627f 100644 --- a/docs/tools/build-dotnet-api-docs.js +++ b/docs/tools/build-dotnet-api-docs.js @@ -6,7 +6,7 @@ const fs = require('node:fs'); const path = require('node:path'); const assemblyNamePrefix = 'Microsoft.JavaScript.'; -const docsTargetFramework = 'net6.0'; +const docsTargetFramework = 'net8.0'; const docsConfiguration = 'Release'; const ridPlatform = process.platform === 'win32' ? 'win' : diff --git a/examples/semantic-kernel/semantic-kernel.csproj b/examples/semantic-kernel/semantic-kernel.csproj index 44788d20..a4da870f 100644 --- a/examples/semantic-kernel/semantic-kernel.csproj +++ b/examples/semantic-kernel/semantic-kernel.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 $(MSBuildThisFileDirectory)/pkg bin diff --git a/examples/wpf/WpfExample.csproj b/examples/wpf/WpfExample.csproj index 74c5f426..6f904189 100644 --- a/examples/wpf/WpfExample.csproj +++ b/examples/wpf/WpfExample.csproj @@ -1,7 +1,7 @@ - net6.0-windows + net8.0-windows $(MSBuildThisFileDirectory)/pkg bin true diff --git a/global.json b/global.json index 61d88a71..b3db90e6 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.100", "allowPrerelease": true, "rollForward": "latestFeature" } diff --git a/src/NodeApi.DotNetHost/DebugHelper.cs b/src/NodeApi.DotNetHost/DebugHelper.cs index 6a6c77c1..29adf3aa 100644 --- a/src/NodeApi.DotNetHost/DebugHelper.cs +++ b/src/NodeApi.DotNetHost/DebugHelper.cs @@ -5,6 +5,8 @@ using System.Diagnostics; using System.Threading; +#pragma warning disable IDE0130 // Namespace does not match folder structure + namespace Microsoft.JavaScript.NodeApi; // Only checking the environment variable for debugging. diff --git a/src/NodeApi.DotNetHost/JSInterfaceMarshaller.cs b/src/NodeApi.DotNetHost/JSInterfaceMarshaller.cs index 68397526..e1faf545 100644 --- a/src/NodeApi.DotNetHost/JSInterfaceMarshaller.cs +++ b/src/NodeApi.DotNetHost/JSInterfaceMarshaller.cs @@ -121,7 +121,7 @@ FieldBuilder CreateDelegateField(MethodInfo method) { FieldBuilder fieldBuilder = CreateDelegateField(method); - BuildMethodImplementation(typeBuilder, method, fieldBuilder, marshaller); + BuildMethodImplementation(typeBuilder, method, fieldBuilder); } foreach (EventInfo eventInfo in interfaceEvents) @@ -176,7 +176,7 @@ FieldBuilder CreateDelegateField(MethodInfo method) private static IEnumerable GetInterfaces(Type type) { - IEnumerable result = Enumerable.Empty(); + IEnumerable result = []; foreach (Type interfaceType in type.GetInterfaces()) { result = result.Concat(new[] { interfaceType }); @@ -317,8 +317,7 @@ private static void BuildPropertyImplementation( private void BuildMethodImplementation( TypeBuilder typeBuilder, MethodInfo method, - FieldInfo delegateField, - JSMarshaller marshaller) + FieldInfo delegateField) { MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | diff --git a/src/NodeApi.DotNetHost/JSMarshaller.cs b/src/NodeApi.DotNetHost/JSMarshaller.cs index 612e3d20..baa2122b 100644 --- a/src/NodeApi.DotNetHost/JSMarshaller.cs +++ b/src/NodeApi.DotNetHost/JSMarshaller.cs @@ -496,8 +496,7 @@ public Expression BuildFromJSConstructorExpression(ConstructorInfo c createExternalMethod, resultVariable)); } - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables, statements), name: "new_" + FullTypeName(constructor.DeclaringType!), parameters: s_argsArray); @@ -1095,8 +1094,7 @@ private LambdaExpression BuildFromJSFunctionExpression(Type delegateType) nameof(JSValue.CreateFunction), new[] { typeof(string), typeof(JSCallback), typeof(object) }); - Expression lambdaExpression = Expression.Lambda( - typeof(JSCallback), + Expression lambdaExpression = Expression.Lambda( Expression.Invoke(methodExpression, valueParameter, s_argsParameter), s_argsArray); @@ -1314,14 +1312,13 @@ public Expression> BuildConstructorOverloadDescriptor Expression.Constant(constructors[0].DeclaringType!.Name), overloadsVariable); - return (Expression>)Expression.Lambda( - typeof(Func), + return Expression.Lambda>( Expression.Block( typeof(JSCallbackDescriptor), new[] { overloadsVariable }, statements), name: "new_" + FullTypeName(constructors[0].DeclaringType!), - Array.Empty()); + []); } /// @@ -1406,14 +1403,13 @@ public Expression> BuildMethodOverloadDescriptorExpre Expression.Constant(methods[0].Name), overloadsVariable); - return (Expression>)Expression.Lambda( - typeof(Func), + return Expression.Lambda>( Expression.Block( typeof(JSCallbackDescriptor), new[] { overloadsVariable }, statements), name, - Array.Empty()); + []); } /// @@ -1421,7 +1417,7 @@ public Expression> BuildMethodOverloadDescriptorExpre /// with specific generic element types to collection interfaces with object element types. /// This simplifies the checks required during overload resolution and avoids the need /// for reflection at resolution time, which is not supported in AOT. (The JS collections - /// will still be marshalled to the more specific collection type after resolution when + /// will still be marshalled to the more specific collection type after resolution when /// an overload is invoked.) /// private static Type EnsureObjectCollectionTypeForOverloadResolution(Type type) @@ -1573,8 +1569,7 @@ private Expression BuildFromJSStaticMethodExpression(MethodInfo meth statements.Add(Expression.Default(typeof(JSValue))); } - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables.Concat(argVariables), statements), name: FullMethodName(method), parameters: s_argsArray); @@ -1662,8 +1657,7 @@ private Expression BuildFromJSInstanceMethodExpression(MethodInfo me statements.Add(Expression.Label(returnTarget, Expression.Default(typeof(JSValue)))); } - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables.Concat(argVariables), statements), name: FullMethodName(method), parameters: s_argsArray); @@ -1746,8 +1740,7 @@ private Expression BuildFromJSStaticPropertyGetExpression(PropertyIn Expression.Assign(resultVariable, Expression.Property(null, property)), BuildResultExpression(resultVariable, property.PropertyType), }; - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables, statements), name: FullMethodName(property.GetMethod!), parameters: s_argsArray); @@ -1792,8 +1785,7 @@ private Expression BuildFromJSInstancePropertyGetExpression(Property statements.Add(Expression.Label(returnTarget, BuildResultExpression(resultVariable, property.PropertyType))); - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables, statements), name: FullMethodName(property.GetMethod!), parameters: s_argsArray); @@ -1819,8 +1811,7 @@ private Expression BuildFromJSStaticPropertySetExpression(PropertyIn Expression.Call(property.SetMethod!, valueVariable), Expression.Default(typeof(JSValue)), }; - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables, statements), name: FullMethodName(property.SetMethod!), parameters: s_argsArray); @@ -1869,8 +1860,7 @@ private Expression BuildFromJSInstancePropertySetExpression(Property statements.Add(setExpression); statements.Add(Expression.Label(returnTarget, Expression.Default(typeof(JSValue)))); - return (Expression)Expression.Lambda( - delegateType: typeof(JSCallback), + return Expression.Lambda( body: Expression.Block(typeof(JSValue), variables, statements), name: FullMethodName(property.SetMethod!), parameters: s_argsArray); @@ -2248,7 +2238,7 @@ Expression TupleItem(int index) => InlineOrInvoke( MethodInfo asDouble = typeof(JSValue).GetExplicitConversion( typeof(JSValue), typeof(double)); MethodInfo toTimeSpan = typeof(TimeSpan).GetStaticMethod( - nameof(TimeSpan.FromMilliseconds)); + nameof(TimeSpan.FromMilliseconds), new[] { typeof(double) }); statements = new[] { Expression.Call(toTimeSpan, Expression.Call(asDouble, valueParameter)), @@ -2331,7 +2321,7 @@ Expression TupleItem(int index) => InlineOrInvoke( (toType.Namespace == typeof(List<>).Namespace || toType.Namespace == typeof(Collection<>).Namespace)) { - statements = BuildFromJSToCollectionClassExpressions(toType, variables, valueParameter); + statements = BuildFromJSToCollectionClassExpressions(toType, valueParameter); } else if (toType.IsGenericType && toType.Name.StartsWith("Tuple`")) { @@ -3024,7 +3014,7 @@ private IEnumerable BuildToJSFromStructExpressions( ParameterExpression jsValueVariable = Expression.Variable(typeof(JSValue), "jsValue"); variables.Add(jsValueVariable); - if (fromType.GetCustomAttribute(typeof(JSImportAttribute)) != null) + if (fromType.GetCustomAttribute() != null) { // Imported structs are assumed to be plain JS objects (not JS classes). MethodInfo createObjectMethod = typeof(JSValue) @@ -3256,7 +3246,6 @@ private IEnumerable BuildFromJSToCollectionInterfaceExpressions( private IEnumerable BuildFromJSToCollectionClassExpressions( Type toType, - List variables, Expression valueExpression) { Type elementType = toType.GenericTypeArguments[0]; diff --git a/src/NodeApi.DotNetHost/NodeApi.DotNetHost.csproj b/src/NodeApi.DotNetHost/NodeApi.DotNetHost.csproj index e7aaec89..58b70bfd 100644 --- a/src/NodeApi.DotNetHost/NodeApi.DotNetHost.csproj +++ b/src/NodeApi.DotNetHost/NodeApi.DotNetHost.csproj @@ -28,7 +28,7 @@ It's necessary to use here rather than a recursive task because PublishAot modifies properties/targets which would not be re-computed by the task. --> - + GetExtensionMethods(Type type) { if (!type.IsDefined(typeof(ExtensionAttribute), inherit: false)) { - return Enumerable.Empty(); + return []; } return type.GetMethods(BindingFlags.Static | BindingFlags.Public) diff --git a/src/NodeApi.Generator/NodeApi.Generator.csproj b/src/NodeApi.Generator/NodeApi.Generator.csproj index 9169d307..7825a59f 100644 --- a/src/NodeApi.Generator/NodeApi.Generator.csproj +++ b/src/NodeApi.Generator/NodeApi.Generator.csproj @@ -26,7 +26,7 @@ @@ -65,10 +65,10 @@ - - - - + + + + diff --git a/src/NodeApi.Generator/NodeApi.Generator.targets b/src/NodeApi.Generator/NodeApi.Generator.targets index c7392514..66e9ce62 100644 --- a/src/NodeApi.Generator/NodeApi.Generator.targets +++ b/src/NodeApi.Generator/NodeApi.Generator.targets @@ -4,7 +4,7 @@ $(TargetName).d.ts Microsoft.JavaScript.NodeApi.Generator - $(MSBuildThisFileDirectory)../lib/net6.0/ + $(MSBuildThisFileDirectory)../lib/net8.0/ $(MSBuildThisFileDirectory)../lib/net472/ $(MSBuildThisFileDirectory)../lib/netstandard2.0/ diff --git a/src/NodeApi.Generator/Program.cs b/src/NodeApi.Generator/Program.cs index d1490266..bc4b7a7b 100644 --- a/src/NodeApi.Generator/Program.cs +++ b/src/NodeApi.Generator/Program.cs @@ -405,7 +405,7 @@ private static void ResolveSystemAssemblies( } else if (s_targetFramework.Contains('-')) { - // Strip off a platform suffix from a target framework like "net6.0-windows". + // Strip off a platform suffix from a target framework like "net8.0-windows". s_targetFramework = s_targetFramework.Substring(0, s_targetFramework.IndexOf('-')); } diff --git a/src/NodeApi.Generator/SymbolExtensions.cs b/src/NodeApi.Generator/SymbolExtensions.cs index 8f4d4723..f8104e24 100644 --- a/src/NodeApi.Generator/SymbolExtensions.cs +++ b/src/NodeApi.Generator/SymbolExtensions.cs @@ -401,8 +401,7 @@ static void BuildType( return; } - referencingSymbols = (referencingSymbols ?? Enumerable.Empty()) - .Append(typeSymbol); + referencingSymbols = (referencingSymbols ?? []).Append(typeSymbol); foreach (INamedTypeSymbol typeArgSymbol in typeSymbol.TypeArguments.OfType()) @@ -670,7 +669,7 @@ public static MethodInfo AsMethodInfo(this IMethodSymbol methodSymbol) Type[] typeParameters = type.GetGenericArguments(); #if NETFRAMEWORK || NETSTANDARD // .NET Framework cannot make generic method parameter types. - IEnumerable methodTypeParameters = Enumerable.Empty(); + IEnumerable methodTypeParameters = []; #else IEnumerable methodTypeParameters = methodSymbol.TypeParameters.Select( (t) => t.AsType(typeParameters, buildType: true)); diff --git a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs index e6eb4746..f0c32532 100644 --- a/src/NodeApi.Generator/TypeDefinitionsGenerator.cs +++ b/src/NodeApi.Generator/TypeDefinitionsGenerator.cs @@ -337,7 +337,7 @@ private static Version InferReferenceAssemblyVersionFromPath(string assemblyPath Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar).ToList(); // Infer the version from a system reference assembly path such as - // dotnet\packs\Microsoft.NETCore.App.Ref\\ref\net6.0\AssemblyName.dll + // dotnet\packs\Microsoft.NETCore.App.Ref\\ref\\AssemblyName.dll int refIndex = pathParts.IndexOf("ref"); if (refIndex > 0 && Version.TryParse(pathParts[refIndex - 1], out Version? refVersion)) { @@ -345,7 +345,7 @@ private static Version InferReferenceAssemblyVersionFromPath(string assemblyPath } // Infer the version from a nuget package assembly reference path such as - // \\lib\net6.0\AssemblyName.dll + // \\lib\\AssemblyName.dll int libIndex = pathParts.IndexOf("lib"); if (libIndex > 0 && Version.TryParse(pathParts[libIndex - 1], out Version? libVersion)) { diff --git a/src/NodeApi/Interop/EmptyAttributes.cs b/src/NodeApi/Interop/EmptyAttributes.cs index 74595488..d9617639 100644 --- a/src/NodeApi/Interop/EmptyAttributes.cs +++ b/src/NodeApi/Interop/EmptyAttributes.cs @@ -3,6 +3,8 @@ #if NETFRAMEWORK || NETSTANDARD +#pragma warning disable IDE0130 // Namespace does not match folder structure + // This file provides empty definitions for attributes that are not available in .NET Framework. using System; diff --git a/src/NodeApi/Interop/JSCollectionExtensions.cs b/src/NodeApi/Interop/JSCollectionExtensions.cs index d2b0f3ed..0ae81864 100644 --- a/src/NodeApi/Interop/JSCollectionExtensions.cs +++ b/src/NodeApi/Interop/JSCollectionExtensions.cs @@ -736,7 +736,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) JSValue jsValue = map.CallMethod("get", KeyToJS(key)); if (jsValue.IsUndefined()) { - return (false, default(TValue)!); + return (false, default!); } return (true, ValueFromJS(jsValue)); }); @@ -942,7 +942,7 @@ public bool TryGetValue(string key, [MaybeNullWhen(false)] out TValue value) JSValue jsValue = obj.GetProperty(key); if (jsValue.IsUndefined()) { - return (false, default(TValue)!); + return (false, default!); } return (true, ValueFromJS(jsValue)); }); diff --git a/src/NodeApi/JSError.cs b/src/NodeApi/JSError.cs index 0c74ce58..7a6b2563 100644 --- a/src/NodeApi/JSError.cs +++ b/src/NodeApi/JSError.cs @@ -376,7 +376,9 @@ public ref struct FatalIfFailedScope private readonly bool _previousIsFatal = false; private bool _isDisposed = false; +#pragma warning disable IDE0032 // Use auto property [ThreadStatic] private static bool s_isFatal; +#pragma warning restore IDE0032 public static bool IsFatal => s_isFatal; diff --git a/src/NodeApi/JSValue.cs b/src/NodeApi/JSValue.cs index 421b0273..52f30e3b 100644 --- a/src/NodeApi/JSValue.cs +++ b/src/NodeApi/JSValue.cs @@ -1151,9 +1151,9 @@ public ulong[] GetBigIntWords(out int sign) } public JSValue GetAllPropertyNames( - JSKeyCollectionMode mode, - JSKeyFilter filter, - JSKeyConversion conversion) + JSValue.KeyCollectionMode mode, + JSValue.KeyFilter filter, + JSValue.KeyConversion conversion) => GetRuntime(out napi_env env, out napi_value handle) .GetAllPropertyNames( env, @@ -1708,4 +1708,26 @@ private unsafe delegate void UseUnmanagedDescriptors( private static napi_value GetUndefined(JSRuntime runtime, napi_env env) => runtime.GetUndefined(env, out napi_value result).ThrowIfFailed(result); + + public enum KeyCollectionMode : int + { + IncludePrototypes, + OwnOnly, + } + + public enum KeyConversion : int + { + KeepNumbers, + NumbersToStrings, + } + + public enum KeyFilter : int + { + AllProperties = 0, + Writable = 1 << 0, + Enumerable = 1 << 1, + Configurable = 1 << 2, + SkipStrings = 1 << 3, + SkipSymbols = 1 << 4, + } } diff --git a/src/NodeApi/Native/JSKeyCollectionMode.cs b/src/NodeApi/Native/JSKeyCollectionMode.cs deleted file mode 100644 index 8483e920..00000000 --- a/src/NodeApi/Native/JSKeyCollectionMode.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.JavaScript.NodeApi; - -public enum JSKeyCollectionMode : int -{ - IncludePrototypes, - OwnOnly, -} diff --git a/src/NodeApi/Native/JSKeyConversion.cs b/src/NodeApi/Native/JSKeyConversion.cs deleted file mode 100644 index 40cb11e1..00000000 --- a/src/NodeApi/Native/JSKeyConversion.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace Microsoft.JavaScript.NodeApi; - -public enum JSKeyConversion : int -{ - KeepNumbers, - NumbersToStrings, -} diff --git a/src/NodeApi/Native/JSKeyFilter.cs b/src/NodeApi/Native/JSKeyFilter.cs deleted file mode 100644 index 317f4d2c..00000000 --- a/src/NodeApi/Native/JSKeyFilter.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; - -namespace Microsoft.JavaScript.NodeApi; - -[Flags] -public enum JSKeyFilter : int -{ - AllProperties = 0, - Writable = 1 << 0, - Enumerable = 1 << 1, - Configurable = 1 << 2, - SkipStrings = 1 << 3, - SkipSymbols = 1 << 4, -} diff --git a/src/NodeApi/NodeApi.csproj b/src/NodeApi/NodeApi.csproj index 97fec4cd..565fe9a9 100644 --- a/src/NodeApi/NodeApi.csproj +++ b/src/NodeApi/NodeApi.csproj @@ -18,7 +18,7 @@ true - + true diff --git a/src/NodeApi/NodeApi.targets b/src/NodeApi/NodeApi.targets index 955634d7..14fb3888 100644 --- a/src/NodeApi/NodeApi.targets +++ b/src/NodeApi/NodeApi.targets @@ -22,6 +22,17 @@ + + + + true + + + (), + [], () => (_runtime.GetVersion(env, out value), value.ToString())); result = value; return status; @@ -545,7 +545,7 @@ public override napi_status GetInstanceData(napi_env env, out nint result) { nint value = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetInstanceData(env, out value), Format(value))); result = value; return status; @@ -646,7 +646,7 @@ public override napi_status IsExceptionPending(napi_env env, out bool result) { bool value = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.IsExceptionPending(env, out value), Format(value))); result = value; return status; @@ -657,7 +657,7 @@ public override unsafe napi_status GetLastErrorInfo( { napi_extended_error_info? value = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetLastErrorInfo(env, out value), Format( value == null || value.Value.error_message == null ? null : Marshal.PtrToStringAnsi((nint)value.Value.error_message)))); @@ -669,7 +669,7 @@ public override napi_status GetAndClearLastException(napi_env env, out napi_valu { napi_value value = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetAndClearLastException(env, out value), Format(env, value))); result = value; return status; @@ -1169,7 +1169,7 @@ public override napi_status GetGlobal(napi_env env, out napi_value result) { napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetGlobal(env, out resultValue), Format(env, resultValue))); result = resultValue; return status; @@ -1179,7 +1179,7 @@ public override napi_status GetUndefined(napi_env env, out napi_value result) { napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetUndefined(env, out resultValue), Format(env, resultValue))); result = resultValue; return status; @@ -1189,7 +1189,7 @@ public override napi_status GetNull(napi_env env, out napi_value result) { napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetNull(env, out resultValue), Format(env, resultValue))); result = resultValue; return status; @@ -1356,7 +1356,7 @@ public override napi_status CreateObject(napi_env env, out napi_value result) { napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.CreateObject(env, out resultValue), Format(env, resultValue))); result = resultValue; return status; @@ -1366,7 +1366,7 @@ public override napi_status CreateArray(napi_env env, out napi_value result) { napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.CreateArray(env, out resultValue), Format(env, resultValue))); result = resultValue; return status; @@ -1528,7 +1528,7 @@ public override napi_status CreatePromise( napi_deferred deferredValue = default; napi_value resultValue = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.CreatePromise(env, out deferredValue, out resultValue), Format(env, resultValue))); deferred = deferredValue; @@ -1612,7 +1612,7 @@ public override napi_status OpenHandleScope(napi_env env, out napi_handle_scope { napi_handle_scope resultScope = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.OpenHandleScope(env, out resultScope), Format(resultScope))); result = resultScope; return status; @@ -1630,7 +1630,7 @@ public override napi_status OpenEscapableHandleScope( { napi_escapable_handle_scope resultScope = default; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.OpenEscapableHandleScope(env, out resultScope), Format(resultScope))); result = resultScope; return status; @@ -2615,7 +2615,7 @@ public override napi_status GetUVEventLoop(napi_env env, out uv_loop_t result) public override void RegisterModule(ref napi_module module) { - TraceCall(Array.Empty()); + TraceCall([]); try { @@ -2635,7 +2635,7 @@ public override napi_status GetModuleFileName(napi_env env, out string result) { string resultValue = default!; napi_status status = TraceCall( - Array.Empty(), + [], () => (_runtime.GetModuleFileName(env, out resultValue), resultValue)); result = resultValue; return status; diff --git a/src/node-api-dotnet/index.d.ts b/src/node-api-dotnet/index.d.ts index 8b21fdf5..253683bd 100644 --- a/src/node-api-dotnet/index.d.ts +++ b/src/node-api-dotnet/index.d.ts @@ -18,16 +18,16 @@ * To load a specific version of .NET, append the target framework moniker to the package name: * ::: code-group * ```JavaScript [ES (TS or JS)] - * import dotnet from 'node-api-dotnet/net6.0'; + * import dotnet from 'node-api-dotnet/net8.0'; * ``` * ```TypeScript [CommonJS (TS)] - * import * as dotnet from 'node-api-dotnet/net6.0'; + * import * as dotnet from 'node-api-dotnet/net8.0'; * ``` * ```JavaScript [CommonJS (JS)] - * const dotnet = require('node-api-dotnet/net6.0'); + * const dotnet = require('node-api-dotnet/net8.0'); * ``` * ::: - * Currently the supported target frameworks are `net472`, `net6.0`, and `net8.0`. + * Currently the supported target frameworks are `net472`, `net8.0`, and `net9.0`. * @module node-api-dotnet */ declare module 'node-api-dotnet' { diff --git a/src/node-api-dotnet/init.js b/src/node-api-dotnet/init.js index 6682c8f4..b7518afd 100644 --- a/src/node-api-dotnet/init.js +++ b/src/node-api-dotnet/init.js @@ -5,7 +5,7 @@ // for each supported target framework version, generated by pack.js: // - index.js // - net472.js -// - net6.0.js +// - net8.0.js // - ... module.exports = initialize; diff --git a/src/node-api-dotnet/pack.js b/src/node-api-dotnet/pack.js index 7ae2abda..de6fd493 100644 --- a/src/node-api-dotnet/pack.js +++ b/src/node-api-dotnet/pack.js @@ -20,11 +20,9 @@ if (!packageName || !configuration || rids.length === 0) { const assemblyName = 'Microsoft.JavaScript.NodeApi'; -const targetFrameworks = ['net8.0', 'net6.0']; +const targetFrameworks = ['net9.0', 'net8.0']; if (process.platform === 'win32') targetFrameworks.push('net472'); -const aotTargetFramework = 'net8.0'; - const fs = require('fs'); const path = require('path'); const childProcess = require('child_process'); @@ -110,7 +108,7 @@ function packGeneratorPackage() { copyScriptFiles(packageStageDir, '../..', 'README.md'); copyFrameworkSpecificBinaries( - [ 'net6.0' ], + [ 'net8.0' ], packageStageDir, `NodeApi.Generator/${assemblyName}.Generator.dll`, `NodeApi.Generator/Microsoft.CodeAnalysis.dll`, diff --git a/test/NativeAotTests.cs b/test/NativeAotTests.cs index 3eb1202d..decd1497 100644 --- a/test/NativeAotTests.cs +++ b/test/NativeAotTests.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -#if NET7_0_OR_GREATER +#if NET9_0_OR_GREATER using System; using System.Collections.Generic; @@ -108,4 +108,4 @@ private static void BuildTestModuleTypeScript(string _ /*testCaseName*/) } } -#endif // NET7_0_OR_GREATER +#endif // NET9_0_OR_GREATER diff --git a/test/NodeApi.Test.csproj b/test/NodeApi.Test.csproj index 7da84e60..8aa0a447 100644 --- a/test/NodeApi.Test.csproj +++ b/test/NodeApi.Test.csproj @@ -2,12 +2,12 @@ - net8.0;net6.0 - net8.0;net6.0;net472 + net9.0;net8.0 + net9.0;net8.0;net472 + false Microsoft.JavaScript.NodeApi.Test Microsoft.JavaScript.NodeApi.Test - false false diff --git a/test/TestBuilder.cs b/test/TestBuilder.cs index a2ee104e..d8986815 100644 --- a/test/TestBuilder.cs +++ b/test/TestBuilder.cs @@ -211,8 +211,11 @@ public static void BuildProject( WorkingDirectory = workingDirectory, }; - // Prevent the launched build from using the same MSBuild SDK that was used to run the test. - startInfo.Environment["MSBuildSDKsPath"] = ""; + if (Environment.Version.Major == 8) + { + // Prevent the launched build from using the same MSBuild SDK that was used to run the test. + startInfo.Environment["MSBuildSDKsPath"] = ""; + } logWriter.WriteLine($"dotnet {startInfo.Arguments}"); logWriter.WriteLine($"CWD={workingDirectory}"); diff --git a/test/TestCases/Directory.Build.props b/test/TestCases/Directory.Build.props index c88bbd2b..4c544991 100644 --- a/test/TestCases/Directory.Build.props +++ b/test/TestCases/Directory.Build.props @@ -25,7 +25,7 @@ 9057 - + true true true diff --git a/test/TestCases/projects/js-cjs-dynamic/net6.0.js b/test/TestCases/projects/js-cjs-dynamic/net9.0.js similarity index 70% rename from test/TestCases/projects/js-cjs-dynamic/net6.0.js rename to test/TestCases/projects/js-cjs-dynamic/net9.0.js index 5898022e..7f93b5b0 100644 --- a/test/TestCases/projects/js-cjs-dynamic/net6.0.js +++ b/test/TestCases/projects/js-cjs-dynamic/net9.0.js @@ -2,10 +2,10 @@ // Licensed under the MIT License. const assert = require('assert'); -const dotnet = require('node-api-dotnet/net6.0'); +const dotnet = require('node-api-dotnet/net9.0'); require('./bin/System.Runtime'); require('./bin/System.Console'); dotnet.System.Console.WriteLine(`Hello from .NET ${dotnet.runtimeVersion}!`); -assert.strictEqual(dotnet.frameworkMoniker, 'net6.0'); +assert.strictEqual(dotnet.frameworkMoniker, 'net9.0'); diff --git a/test/TestCases/projects/js-esm-dynamic/net6.0.js b/test/TestCases/projects/js-esm-dynamic/net9.0.js similarity index 71% rename from test/TestCases/projects/js-esm-dynamic/net6.0.js rename to test/TestCases/projects/js-esm-dynamic/net9.0.js index 5f0ef8ad..b5598bef 100644 --- a/test/TestCases/projects/js-esm-dynamic/net6.0.js +++ b/test/TestCases/projects/js-esm-dynamic/net9.0.js @@ -2,10 +2,10 @@ // Licensed under the MIT License. import assert from 'assert'; -import dotnet from 'node-api-dotnet/net6.0'; +import dotnet from 'node-api-dotnet/net9.0'; import './bin/System.Runtime.js'; import './bin/System.Console.js'; dotnet.System.Console.WriteLine(`Hello from .NET ${dotnet.runtimeVersion}!`); -assert.strictEqual(dotnet.frameworkMoniker, 'net6.0'); +assert.strictEqual(dotnet.frameworkMoniker, 'net9.0'); diff --git a/test/TestCases/projects/ts-cjs-dynamic/net6.0.ts b/test/TestCases/projects/ts-cjs-dynamic/net9.0.ts similarity index 70% rename from test/TestCases/projects/ts-cjs-dynamic/net6.0.ts rename to test/TestCases/projects/ts-cjs-dynamic/net9.0.ts index 1754bf16..43324107 100644 --- a/test/TestCases/projects/ts-cjs-dynamic/net6.0.ts +++ b/test/TestCases/projects/ts-cjs-dynamic/net9.0.ts @@ -2,10 +2,10 @@ // Licensed under the MIT License. import * as assert from 'assert'; -import * as dotnet from 'node-api-dotnet/net6.0'; +import * as dotnet from 'node-api-dotnet/net9.0'; import './bin/System.Runtime'; import './bin/System.Console'; dotnet.System.Console.WriteLine(`Hello from .NET ${dotnet.runtimeVersion}!`); -assert.strictEqual(dotnet.frameworkMoniker, 'net6.0'); +assert.strictEqual(dotnet.frameworkMoniker, 'net9.0'); diff --git a/test/TestCases/projects/ts-esm-dynamic/net6.0.ts b/test/TestCases/projects/ts-esm-dynamic/net9.0.ts similarity index 72% rename from test/TestCases/projects/ts-esm-dynamic/net6.0.ts rename to test/TestCases/projects/ts-esm-dynamic/net9.0.ts index f2c05e71..d3b54e45 100644 --- a/test/TestCases/projects/ts-esm-dynamic/net6.0.ts +++ b/test/TestCases/projects/ts-esm-dynamic/net9.0.ts @@ -2,10 +2,10 @@ // Licensed under the MIT License. import * as assert from 'assert'; -import dotnet from 'node-api-dotnet/net6.0'; +import dotnet from 'node-api-dotnet/net9.0'; import './bin/System.Runtime.js'; import './bin/System.Console.js'; dotnet.System.Console.WriteLine(`Hello from .NET ${dotnet.runtimeVersion}!`); -assert.strictEqual(dotnet.frameworkMoniker, 'net6.0'); +assert.strictEqual(dotnet.frameworkMoniker, 'net9.0'); diff --git a/version.json b/version.json index 1c25d5e1..97ff12e1 100644 --- a/version.json +++ b/version.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.8", + "version": "0.9", "publicReleaseRefSpec": [ "^refs/heads/main$",