Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
30e7ad0
Support @access and @usage
pshao25 Aug 18, 2023
1541150
Update
pshao25 Aug 23, 2023
6ddf3fc
Update
pshao25 Aug 24, 2023
a9ac379
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Aug 24, 2023
169bab8
Update
pshao25 Aug 24, 2023
e7d6034
update
pshao25 Aug 24, 2023
4f7eb42
Update
pshao25 Aug 24, 2023
3a0617b
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Aug 25, 2023
19980a3
Update
pshao25 Aug 25, 2023
b2bb081
update
pshao25 Aug 25, 2023
dc5f5b8
Update
pshao25 Aug 28, 2023
c2352f6
update
pshao25 Aug 29, 2023
d39aeb0
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Aug 29, 2023
a7de125
update
pshao25 Aug 29, 2023
ac39170
update
pshao25 Aug 29, 2023
6457f75
update
pshao25 Aug 29, 2023
88c8f4a
update
pshao25 Aug 29, 2023
0ab7c29
Update
pshao25 Aug 29, 2023
73b6623
update
pshao25 Aug 30, 2023
a68e4a7
update
pshao25 Sep 7, 2023
805586e
update
pshao25 Sep 7, 2023
199843c
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 7, 2023
e3e6332
update
pshao25 Sep 12, 2023
065147b
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 12, 2023
50a7369
update
pshao25 Sep 12, 2023
35bf22e
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 12, 2023
799549c
Update
pshao25 Sep 12, 2023
45008aa
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 19, 2023
7815a56
update
pshao25 Sep 19, 2023
04268fe
update
pshao25 Sep 19, 2023
e0ed387
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 19, 2023
5fb3e08
update
pshao25 Sep 19, 2023
86c38c5
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 20, 2023
bb6a25d
Merge branch 'feature/v3' of https://github.com/Azure/autorest.csharp…
pshao25 Sep 21, 2023
083ae9f
update
pshao25 Sep 21, 2023
a4c54d1
update
pshao25 Sep 21, 2023
59f6464
update
pshao25 Sep 21, 2023
ae5417c
Merge branch 'feature/v3' into access3519
pshao25 Sep 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions eng/testProjects.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"authentication/union",
"azure/core/basic",
"azure/core/traits",
"azure/client-generator-core/access",
"azure/client-generator-core/internal",
"azure/client-generator-core/usage",
"encode/bytes",
"encode/datetime",
"encode/duration",
Expand Down
234 changes: 125 additions & 109 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ public async Task PostProcess(Func<Project, Task<Project>> processor)
/// <returns></returns>
public async Task PostProcessAsync(PostProcessor? postProcessor = null)
{
postProcessor ??= new PostProcessor();
postProcessor ??= new PostProcessor(ImmutableHashSet<string>.Empty);
switch (Configuration.UnreferencedTypesHandling)
{
case Configuration.UnreferencedTypesHandlingOption.KeepAll:
Expand Down
2 changes: 2 additions & 0 deletions src/AutoRest.CSharp/Common/Output/Models/Types/EnumType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public EnumType(InputEnumType input, string defaultNamespace, string defaultAcce

DefaultName = input.Name.ToCleanName();
DefaultAccessibility = input.Accessibility ?? defaultAccessibility;
IsAccessibilityOverride = input.Accessibility != null;

var isExtensible = input.IsExtensible;
if (ExistingType != null)
Expand Down Expand Up @@ -73,6 +74,7 @@ public EnumType(InputEnumType input, string defaultNamespace, string defaultAcce
protected override string DefaultName { get; }
protected override string DefaultAccessibility { get; }
protected override TypeKind TypeKind => IsExtensible ? TypeKind.Struct : TypeKind.Enum;
public bool IsAccessibilityOverride { get; }
Comment thread
pshao25 marked this conversation as resolved.
Outdated

public IList<EnumTypeValue> Values => _values ??= BuildValues();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ internal sealed class ModelTypeProvider : SerializableObjectType

protected override string DefaultName { get; }
protected override string DefaultAccessibility { get; }
public bool IsAccessibilityOverride { get; }
public override bool IncludeConverter => false;
protected override bool IsAbstract => !Configuration.SuppressAbstractBaseClasses.Contains(DefaultName) && _inputModel.DiscriminatorPropertyName is not null;

Expand All @@ -63,6 +64,7 @@ public ModelTypeProvider(InputModelType inputModel, string defaultNamespace, Sou
_sourceInputModel = sourceInputModel;
DefaultName = GetValidIdentifier(inputModel.Name); // TODO -- this is only a workaround only to solve the anonymous model names, in other cases, the name is unchanged.
DefaultAccessibility = inputModel.Accessibility ?? "public";
IsAccessibilityOverride = inputModel.Accessibility != null;
_deprecated = inputModel.Deprecated;
_derivedTypes = derivedTypes;
_defaultDerivedType = defaultDerivedType ?? (inputModel.IsUnknownDiscriminatorModel ? this : null);
Expand Down
20 changes: 18 additions & 2 deletions src/AutoRest.CSharp/Common/Output/PostProcessing/PostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ internal class PostProcessor
private const string AspDotNetExtensionNamespace = "Microsoft.Extensions.Azure";
private readonly string? _modelFactoryFullName;
private readonly string? _aspExtensionClassName;
private readonly ImmutableHashSet<string> _modelsToKeep;

public PostProcessor(string? modelFactoryFullName = null, string? aspExtensionClassName = null)
public PostProcessor(ImmutableHashSet<string> modelsToKeep, string? modelFactoryFullName = null, string? aspExtensionClassName = null)
{
_modelsToKeep = modelsToKeep;
_modelFactoryFullName = modelFactoryFullName;
_aspExtensionClassName = aspExtensionClassName;
}
Expand Down Expand Up @@ -352,10 +354,24 @@ protected HashSet<INamedTypeSymbol> GetRootSymbols(Project project, TypeSymbols

protected virtual bool IsRootDocument(Document document)
{
var root = document.GetSyntaxRootAsync().GetAwaiter().GetResult();
// a document is a root document, when
// 1. it is a custom document (not generated or shared)
// 2. it is a client
return GeneratedCodeWorkspace.IsCustomDocument(document) || IsClientDocument(document);
// 3. user exceptions
return GeneratedCodeWorkspace.IsCustomDocument(document) || IsClientDocument(document) || ShouldKeepModel(root, _modelsToKeep);
}

private static bool ShouldKeepModel(SyntaxNode? root, ImmutableHashSet<string> modelsToKeep)
{
if (root is null)
return false;

// use `BaseTypeDeclarationSyntax` to also include enums because `EnumDeclarationSyntax` extends `BaseTypeDeclarationSyntax`
// `ClassDeclarationSyntax` and `StructDeclarationSyntax` both inherit `TypeDeclarationSyntax`
var typeNodes = root.DescendantNodes().OfType<BaseTypeDeclarationSyntax>();
// there is possibility that we have multiple types defined in the same document (for instance, custom code)
return typeNodes.Any(t => modelsToKeep.Contains(t.Identifier.Text));
}

private static bool IsClientDocument(Document document)
Expand Down
19 changes: 17 additions & 2 deletions src/AutoRest.CSharp/LowLevel/AutoRest/DpgOutputLibrary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,25 @@ internal class DpgOutputLibrary : OutputLibrary

public TypeFactory TypeFactory { get; }
public IEnumerable<EnumType> Enums => _enums.Values;
public IEnumerable<ModelTypeProvider> Models => _models.Values;
public IEnumerable<ModelTypeProvider> Models
{
get
{
foreach (var key in _models.Keys)
{
if (key is { Namespace: "Azure.Core.Foundations", Name: "Error" })
{
continue;
}
Comment thread
pshao25 marked this conversation as resolved.
Outdated
yield return _models[key];
}
}
}
public IReadOnlyList<LowLevelClient> RestClients { get; }
public ClientOptionsTypeProvider ClientOptions { get; }
public IEnumerable<TypeProvider> AllModels => new List<TypeProvider>(_enums.Values).Concat(_models.Values);
public IEnumerable<TypeProvider> AllModels => new List<TypeProvider>(_enums.Values).Concat(Models);
public IEnumerable<string> AccessOverrideModels => Enums.Where(e => e.IsAccessibilityOverride).Select(e => e.Declaration.Name)
Comment thread
pshao25 marked this conversation as resolved.
Outdated
.Concat(Models.Where(m => m.IsAccessibilityOverride).Select(m => m.Declaration.Name));
Comment thread
pshao25 marked this conversation as resolved.
Outdated

public DpgOutputLibrary(string libraryName, IReadOnlyDictionary<InputEnumType, EnumType> enums, IReadOnlyDictionary<InputModelType, ModelTypeProvider> models, IReadOnlyList<LowLevelClient> restClients, ClientOptionsTypeProvider clientOptions, bool isTspInput, SourceInputModel? sourceInputModel)
{
Expand Down
2 changes: 2 additions & 0 deletions src/AutoRest.CSharp/LowLevel/AutoRest/LowLevelTarget.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Threading.Tasks;
using AutoRest.CSharp.Common.Generation.Writers;
using AutoRest.CSharp.Common.Input;
Expand Down Expand Up @@ -64,6 +65,7 @@ public static async Task ExecuteAsync(GeneratedCodeWorkspace project, InputNames
}

await project.PostProcessAsync(new PostProcessor(
modelsToKeep: library.AccessOverrideModels.ToImmutableHashSet(),
modelFactoryFullName: modelFactoryProvider?.FullName,
aspExtensionClassName: library.AspDotNetExtension.FullName));
}
Expand Down
21 changes: 2 additions & 19 deletions src/AutoRest.CSharp/Mgmt/AutoRest/PostProcess/MgmtPostProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ namespace AutoRest.CSharp.Mgmt.AutoRest.PostProcess
{
internal sealed class MgmtPostProcessor : PostProcessor
{
private readonly ImmutableHashSet<string> _modelsToKeep;

public MgmtPostProcessor(ImmutableHashSet<string> modelsToKeep, string? modelFactoryFullName) : base(modelFactoryFullName)
{
_modelsToKeep = modelsToKeep;
}
public MgmtPostProcessor(ImmutableHashSet<string> modelsToKeep, string? modelFactoryFullName) : base(modelsToKeep, modelFactoryFullName) { }

protected override bool IsRootDocument(Document document)
{
Expand All @@ -28,7 +23,7 @@ protected override bool IsRootDocument(Document document)
// 1. the file is under `Generated` or `Generated/Extensions` which is handled by `IsMgmtRootDocument`
// 2. the declaration has a ReferenceType or similar attribute on it which is handled by `IsReferenceType`
// 3. the file is custom code (not generated and not shared) which is handled by `IsCustomDocument`
return IsMgmtRootDocument(document) || IsReferenceType(root) || GeneratedCodeWorkspace.IsCustomDocument(document) || ShouldKeepModel(root, _modelsToKeep);
return IsMgmtRootDocument(document) || IsReferenceType(root) || base.IsRootDocument(document);
}

private static bool IsMgmtRootDocument(Document document) => GeneratedCodeWorkspace.IsGeneratedDocument(document) && Path.GetDirectoryName(document.Name) is "Extensions" or "";
Expand Down Expand Up @@ -60,18 +55,6 @@ private static bool IsReferenceType(SyntaxNode? root)
return false;
}

private static bool ShouldKeepModel(SyntaxNode? root, ImmutableHashSet<string> modelsToKeep)
{
if (root is null)
return false;

// use `BaseTypeDeclarationSyntax` to also include enums because `EnumDeclarationSyntax` extends `BaseTypeDeclarationSyntax`
// `ClassDeclarationSyntax` and `StructDeclarationSyntax` both inherit `TypeDeclarationSyntax`
var typeNodes = root.DescendantNodes().OfType<BaseTypeDeclarationSyntax>();
// there is possibility that we have multiple types defined in the same document (for instance, custom code)
return typeNodes.Any(t => modelsToKeep.Contains(t.Identifier.Text));
}

private static SyntaxList<AttributeListSyntax>? GetAttributeLists(SyntaxNode node)
{
if (node is StructDeclarationSyntax structDeclaration)
Expand Down
8 changes: 8 additions & 0 deletions src/AutoRest.CSharp/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -624,10 +624,18 @@
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\authentication\\union\\src\\Generated -n"
},
"typespec-azure/client-generator-core/access": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\client-generator-core\\access\\src\\Generated -n"
},
"typespec-azure/client-generator-core/internal": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\client-generator-core\\internal\\src\\Generated -n"
},
"typespec-azure/client-generator-core/usage": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\client-generator-core\\usage\\src\\Generated -n"
},
"typespec-azure/core/basic": {
"commandName": "Project",
"commandLineArgs": "--standalone $(SolutionDir)\\test\\CadlRanchProjects\\azure\\core\\basic\\src\\Generated -n"
Expand Down
2 changes: 1 addition & 1 deletion src/TypeSpec.Extension/Emitter.Csharp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"dependencies": {
"@autorest/csharp": "3.0.0-beta.20230309.1",
"@azure-tools/typespec-azure-core": "0.33.1",
"@azure-tools/typespec-client-generator-core": "0.33.0",
"@azure-tools/typespec-client-generator-core": "0.34.0-dev.6",
"@typespec/compiler": "0.47.1",
"@typespec/eslint-config-typespec": "0.47.0",
"@typespec/eslint-plugin": "0.47.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ function setUsage(
models: Map<string, InputModelType | InputEnumType>
) {
for (const [name, m] of models) {
if (m.Usage !== undefined && m.Usage !== Usage.None) continue;
Comment thread
pshao25 marked this conversation as resolved.
if (usages.inputs.includes(name)) {
m.Usage = Usage.Input;
} else if (usages.outputs.includes(name)) {
Expand Down
52 changes: 43 additions & 9 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,20 @@ import {
InputIntrinsicType,
InputUnknownType,
isInputEnumType,
isInputLiteralType
isInputLiteralType,
isInputModelType
} from "../type/inputType.js";
import { InputTypeKind } from "../type/inputTypeKind.js";
import { Usage } from "../type/usage.js";
import { logger } from "./logger.js";
import {
SdkContext,
getLibraryName,
getSdkSimpleType,
getAccess,
getClientType,
getUsageOverride,
isInternal
} from "@azure-tools/typespec-client-generator-core";
import { capitalize, getModelName, getNameForTemplate } from "./utils.js";
import { capitalize, getModelName } from "./utils.js";
import { FormattedType } from "../type/formattedType.js";
import { LiteralTypeContext } from "../type/literalTypeContext.js";
/**
Expand Down Expand Up @@ -142,6 +144,13 @@ function getCSharpInputTypeKindByIntrinsicModelName(
return InputTypeKind.Float32;
case "float64":
return InputTypeKind.Float64;
case "uri":
Comment thread
pshao25 marked this conversation as resolved.
case "url":
return InputTypeKind.Uri;
case "uuid":
return InputTypeKind.Guid;
case "etag":
return InputTypeKind.String;
case "string":
switch (format?.toLowerCase()) {
case "date":
Expand Down Expand Up @@ -307,12 +316,12 @@ export function getInputType(
// In such cases, we don't want to emit a ref and instead just
// emit the base type directly.
default:
const sdkType = getSdkSimpleType(context, type);
const sdkType = getClientType(context, type);
return {
Name: type.name,
Kind: getCSharpInputTypeKindByIntrinsicModelName(
sdkType.kind,
sdkType.format ?? formattedType.format,
formattedType.format,
formattedType.encode
),
IsNullable: false
Expand Down Expand Up @@ -464,14 +473,15 @@ export function getInputType(
enumType = {
Name: e.name,
Namespace: getFullNamespaceString(e.namespace),
Accessibility: undefined, //TODO: need to add accessibility
Accessibility: getAccess(context, e),
Deprecated: getDeprecated(program, e),
Description: getDoc(program, e) ?? "",
EnumValueType: enumValueType,
AllowedValues: allowValues,
IsExtensible: !isFixed(program, e),
IsNullable: false
} as InputEnumType;
setUsage(context, e, enumType);
if (addToCollection) enums.set(e.name, enumType);
}
return enumType;
Expand Down Expand Up @@ -528,7 +538,9 @@ export function getInputType(
model = {
Name: name,
Namespace: getFullNamespaceString(m.namespace),
Accessibility: isInternal(context, m) ? "internal" : undefined,
Accessibility: isInternal(context, m)
? "internal"
: getAccess(context, m),
Deprecated: getDeprecated(program, m),
Description: getDoc(program, m),
IsNullable: false,
Expand All @@ -538,7 +550,7 @@ export function getInputType(
Usage: Usage.None,
Properties: properties // DerivedModels should be the last assigned to model, if no derived models, properties should be the last
} as InputModelType;

setUsage(context, m, model);
models.set(name, model);

// Resolve properties after model is added to the map to resolve possible circular dependencies
Expand Down Expand Up @@ -625,6 +637,13 @@ export function getInputType(
enums,
literalTypeContext
);
if (
model.Namespace === "Azure.Core.Foundations" &&
model.Name === "Error" &&
isInputModelType(inputType)
) {
inputType.Accessibility = undefined;
Comment thread
pshao25 marked this conversation as resolved.
}
const inputProp = {
Name: name,
SerializedName: serializedName,
Expand Down Expand Up @@ -754,6 +773,21 @@ export function getInputType(
}
}

function setUsage(
context: SdkContext,
source: Model | Enum,
target: InputModelType | InputEnumType
) {
const sourceUsage = getUsageOverride(context, source);
if (sourceUsage === UsageFlags.Input) {
target.Usage = Usage.Input;
} else if (sourceUsage === UsageFlags.Output) {
target.Usage = Usage.Output;
} else if (sourceUsage === (UsageFlags.Input | UsageFlags.Output)) {
Comment thread
pshao25 marked this conversation as resolved.
target.Usage = Usage.RoundTrip;
}
}

export function getUsages(
context: SdkContext,
ops?: HttpOperation[],
Expand Down
7 changes: 5 additions & 2 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/operation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
isInternal,
shouldGenerateConvenient,
shouldGenerateProtocol,
SdkContext
SdkContext,
getAccess
} from "@azure-tools/typespec-client-generator-core";
import {
EmitContext,
Expand Down Expand Up @@ -199,7 +200,9 @@ export function loadOperation(
Summary: summary,
Deprecated: getDeprecated(program, op),
Description: desc,
Accessibility: isInternal(sdkContext, op) ? "internal" : undefined,
Accessibility: isInternal(sdkContext, op)
Comment thread
pshao25 marked this conversation as resolved.
? "internal"
: getAccess(sdkContext, op),
Parameters: parameters,
Responses: responses,
HttpMethod: requestMethod,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using AutoRest.CSharp.Common.Output.PostProcessing;
using Microsoft.CodeAnalysis;
Expand All @@ -13,6 +14,10 @@ internal class PostProcessorTests
{
internal class TestPostProcessor : PostProcessor
{
public TestPostProcessor(ImmutableHashSet<string> modelsToKeep) : base(modelsToKeep)
{
}

protected override bool IsRootDocument(Document document)
{
return document.Name.EndsWith("Client.cs");
Expand Down Expand Up @@ -42,7 +47,7 @@ public void Setup()
[TestCase("TestSDK.PageableItem", true, false)]
public async Task ValidateTypeAccessibility(string typeFullName, bool exist, bool? isInternal)
{
var postProcessor = new TestPostProcessor();
var postProcessor = new TestPostProcessor(ImmutableHashSet<string>.Empty);

_project = await postProcessor.InternalizeAsync(_project);

Expand Down
2 changes: 1 addition & 1 deletion test/CadlRanchMockApis/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
"dist/**"
],
"peerDependencies": {
"@azure-tools/cadl-ranch-specs": "0.19.0"
"@azure-tools/cadl-ranch-specs": "0.20.0"
}
}
Loading