Skip to content

Commit 9ef915c

Browse files
authored
[dotnet-svcutil] Add option to support generating sync operations only. (#5751)
* Add option to support generating sync operations only. * Update option name to SyncOnly the same as svcutil.exe.
1 parent 21444e4 commit 9ef915c

23 files changed

+1283
-2
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace Microsoft.Tools.ServiceModel.Svcutil
6+
{
7+
using Microsoft.CodeDom;
8+
9+
internal class RemoveAsyncMethodsFromClientClass : ClientClassVisitor
10+
{
11+
protected override void VisitClientClass(CodeTypeDeclaration type)
12+
{
13+
base.VisitClientClass(type);
14+
15+
CollectionHelpers.MapList<CodeMemberMethod>(
16+
type.Members,
17+
delegate (CodeMemberMethod method)
18+
{
19+
return !(CodeDomHelpers.IsBeginMethod(method) ||
20+
CodeDomHelpers.IsEndMethod(method) ||
21+
CodeDomHelpers.IsTaskAsyncMethod(method));
22+
},
23+
null
24+
);
25+
}
26+
}
27+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.CodeDom;
6+
using System.ServiceModel;
7+
8+
namespace Microsoft.Tools.ServiceModel.Svcutil
9+
{
10+
internal class RemoveAsyncMethodsFromInterface : ServiceContractVisitor
11+
{
12+
protected override void VisitAttributedType(CodeTypeDeclaration type)
13+
{
14+
base.VisitAttributedType(type);
15+
16+
CollectionHelpers.MapList<CodeMemberMethod>(
17+
type.Members,
18+
delegate (CodeMemberMethod method)
19+
{
20+
return !(CodeDomHelpers.IsBeginMethod(method) ||
21+
CodeDomHelpers.IsTaskAsyncMethod(method) ||
22+
CodeDomHelpers.IsEndMethod(method));
23+
},
24+
null
25+
);
26+
}
27+
}
28+
}

src/dotnet-svcutil/lib/src/CodeDomFixup/VisitorFixup.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,17 @@ private static CodeDomVisitor[] GetVisitors(ServiceContractGenerator generator,
2929
new TypeNameFixup()
3030
};
3131

32-
if (options.Sync != true)
32+
// Default behavior: Remove sync methods, so only async methods are generated.
33+
if (options.Sync != true && options.SyncOnly != true)
3334
{
3435
visitors = AddSyncVisitors(visitors);
3536
}
37+
// If --syncOnly specified, remove async methods, only sync methods remain.
38+
else if (options.SyncOnly == true)
39+
{
40+
visitors = AddAsyncVisitors(visitors);
41+
}
42+
// If --sync is specified (and --syncOnly is NOT specified), do nothing, keep both sync and async methods.
3643

3744
return visitors;
3845
}
@@ -55,6 +62,18 @@ private static CodeDomVisitor[] AddSyncVisitors(CodeDomVisitor[] visitors)
5562

5663
return list.ToArray();
5764
}
65+
66+
private static CodeDomVisitor[] AddAsyncVisitors(CodeDomVisitor[] visitors)
67+
{
68+
List<CodeDomVisitor> list = new List<CodeDomVisitor>(visitors);
69+
70+
list.InsertRange(4, new CodeDomVisitor[] {
71+
new RemoveAsyncMethodsFromInterface(),
72+
new RemoveAsyncMethodsFromClientClass()
73+
});
74+
75+
return list.ToArray();
76+
}
5877
}
5978
}
6079

src/dotnet-svcutil/lib/src/CommandProcessorOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ internal class CommandSwitches
8686
public readonly CommandSwitch RuntimeIdentifier = new CommandSwitch(RuntimeIdentifierKey, "ri", SwitchType.SingletonValue, OperationalContext.Global);
8787
public readonly CommandSwitch Serializer = new CommandSwitch(SerializerModeKey, "ser", SwitchType.SingletonValue);
8888
public readonly CommandSwitch Sync = new CommandSwitch(SyncKey, "syn", SwitchType.Flag);
89+
public readonly CommandSwitch SyncOnly = new CommandSwitch(SyncOnlyKey, "so", SwitchType.Flag);
8990
public readonly CommandSwitch TargetFramework = new CommandSwitch(TargetFrameworkKey, "tf", SwitchType.SingletonValue, OperationalContext.Global);
9091
public readonly CommandSwitch ToolContext = new CommandSwitch(ToolContextKey, "tc", SwitchType.SingletonValue, OperationalContext.Infrastructure);
9192
public readonly CommandSwitch Update = new CommandSwitch(UpdateServiceReferenceKey, "u", SwitchType.FlagOrSingletonValue, OperationalContext.Project);

src/dotnet-svcutil/lib/src/HelpGenerator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ private static void WriteCodeGenerationHelp()
6565
ArgumentInfo.CreateParameterHelpInfo(CommandProcessorOptions.Switches.Serializer.Name, SerializerMode.DataContractSerializer.ToString(), SR.HelpDataContractSerializer),
6666
ArgumentInfo.CreateParameterHelpInfo(CommandProcessorOptions.Switches.Serializer.Name, SerializerMode.XmlSerializer.ToString(), SR.HelpXmlSerializer),
6767
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.Sync.Name, string.Format(SR.HelpSyncFormat, CommandProcessorOptions.Switches.Sync.Abbreviation)),
68+
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.SyncOnly.Name, string.Format(SR.HelpSyncOnlyFormat, CommandProcessorOptions.Switches.SyncOnly.Abbreviation)),
6869
ArgumentInfo.CreateFlagHelpInfo( CommandProcessorOptions.Switches.Wrapped.Name, string.Format(SR.HelpWrappedFormat, CommandProcessorOptions.Switches.Wrapped.Abbreviation)),
6970
ArgumentInfo.CreateParameterHelpInfo(CommandProcessorOptions.Switches.Update.Name, SR.ParametersWebServiceReferenceName, string.Format(SR.HelpUpdateWebServiceReferenceFormat, CommandProcessorOptions.Switches.Update.Abbreviation)),
7071
ArgumentInfo.CreateParameterHelpInfo(CommandProcessorOptions.Switches.RuntimeIdentifier.Name, SR.ParametersRuntimeIdentifier, string.Format(SR.HelpRuntimeIdentifierFormat, CommandProcessorOptions.Switches.RuntimeIdentifier.Abbreviation)),

src/dotnet-svcutil/lib/src/SR.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,4 +628,7 @@ Your credentials will be sent to the server in clear text.</value>
628628
<data name="WrnOutOfSupportTargetFrameworkFormat" xml:space="preserve">
629629
<value>The target framework '{0}' is out of support and will not receive security updates in the future.</value>
630630
</data>
631-
</root>
631+
<data name="HelpSyncOnlyFormat" xml:space="preserve">
632+
<value>Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</value>
633+
</data>
634+
</root>

src/dotnet-svcutil/lib/src/Shared/Options/UpdateOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ internal partial class UpdateOptions : ApplicationOptions
2424
public const string RuntimeIdentifierKey = "runtimeIdentifier";
2525
public const string SerializerModeKey = "serializer";
2626
public const string SyncKey = "sync";
27+
public const string SyncOnlyKey = "syncOnly";
2728
public const string TargetFrameworkKey = "targetFramework";
2829
public const string TypeReuseModeKey = "typeReuseMode";
2930
public const string WrappedKey = "wrapped";
@@ -42,6 +43,7 @@ internal partial class UpdateOptions : ApplicationOptions
4243
public string RuntimeIdentifier { get { return GetValue<string>(RuntimeIdentifierKey); } set { SetValue(RuntimeIdentifierKey, value); } }
4344
public SerializerMode? SerializerMode { get { return GetValue<SerializerMode?>(SerializerModeKey); } set { SetValue(SerializerModeKey, value); } }
4445
public bool? Sync { get { return GetValue<bool?>(SyncKey); } set { SetValue(SyncKey, value); } }
46+
public bool? SyncOnly { get { return GetValue<bool?>(SyncOnlyKey); } set { SetValue(SyncOnlyKey, value); } }
4547
public FrameworkInfo TargetFramework { get { return GetValue<FrameworkInfo>(TargetFrameworkKey); } set { SetValue(TargetFrameworkKey, value); } }
4648
public TypeReuseMode? TypeReuseMode { get { return GetValue<TypeReuseMode?>(TypeReuseModeKey); } set { SetValue(TypeReuseModeKey, value); } }
4749
public bool? Wrapped { get { return GetValue<bool?>(WrappedKey); } set { SetValue(WrappedKey, value); } }
@@ -62,6 +64,7 @@ public UpdateOptions()
6264
new SingleValueOption<string>(RuntimeIdentifierKey),
6365
new SingleValueOption<SerializerMode>(SerializerModeKey) { SerializationName = "serializerMode", DefaultValue = Svcutil.SerializerMode.Default },
6466
new SingleValueOption<bool>(SyncKey) { SerializationName = "sync" },
67+
new SingleValueOption<bool>(SyncOnlyKey) { SerializationName = "syncOnly" },
6568
new SingleValueOption<FrameworkInfo>(TargetFrameworkKey),
6669
new SingleValueOption<TypeReuseMode>(TypeReuseModeKey),
6770
new SingleValueOption<bool>(WrappedKey));

src/dotnet-svcutil/lib/src/xlf/SR.cs.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ Identifikátor dokumentu: {0}</target>
612612
<target state="translated">Kromě asynchronních metod generovat pro operace i synchronní metody (krátký tvar: -{0})</target>
613613
<note />
614614
</trans-unit>
615+
<trans-unit id="HelpSyncOnlyFormat">
616+
<source>Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</source>
617+
<target state="new">Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</target>
618+
<note />
619+
</trans-unit>
615620
<trans-unit id="HelpTargetFrameworkFormat">
616621
<source>The target framework used for building reference projects. (Short Form: -{0}).</source>
617622
<target state="translated">Cílová architektura, která byla použita k sestavení projektů odkazů. (Krátký tvar: /{0})</target>

src/dotnet-svcutil/lib/src/xlf/SR.de.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ Dokumentbezeichner: "{0}".</target>
612612
<target state="translated">Hiermit werden synchrone Methoden für Vorgänge generiert, die zusätzlich zu asynchronen Vorgängen ausgeführt werden. (Kurzform: -{0})</target>
613613
<note />
614614
</trans-unit>
615+
<trans-unit id="HelpSyncOnlyFormat">
616+
<source>Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</source>
617+
<target state="new">Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</target>
618+
<note />
619+
</trans-unit>
615620
<trans-unit id="HelpTargetFrameworkFormat">
616621
<source>The target framework used for building reference projects. (Short Form: -{0}).</source>
617622
<target state="translated">Das zum Erstellen von Verweisprojekten verwendete Zielframework. (Kurzform: /{0}).</target>

src/dotnet-svcutil/lib/src/xlf/SR.es.xlf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ Identificador del documento: "{0}".</target>
612612
<target state="translated">Genere métodos sincrónicos para las operaciones además de los asincrónicos. (Forma corta: -{0})</target>
613613
<note />
614614
</trans-unit>
615+
<trans-unit id="HelpSyncOnlyFormat">
616+
<source>Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</source>
617+
<target state="new">Generate only synchronous methods for operations. Default: generate task-based asynchronous method signatures. (Short Form: -{0})</target>
618+
<note />
619+
</trans-unit>
615620
<trans-unit id="HelpTargetFrameworkFormat">
616621
<source>The target framework used for building reference projects. (Short Form: -{0}).</source>
617622
<target state="translated">La plataforma de destino utilizada para compilar proyectos de referencia. (Forma corta: /{0}).</target>

0 commit comments

Comments
 (0)