http-client-java, corner case of client without op or group (#4358)

Found when trying to write subclass as 
```ts
@client({
  name: "ContosoClient",
  service: Cadl.ContosoServer,
})
namespace Cadl.ContosoServer {
  @client({
    name: "ContosoSubClient",
    service: Cadl.ContosoServer,
  })
  namespace SubClient {
    @client({
      name: "ContosoSubSubClient",
      service: Cadl.ContosoServer,
    })
    @route("/contoso/")
    interface ServerOp {
      get(@path(#{ allowReserved: true }) group: string): OkResponse | NoContentResponse;
    }
  }
}
```

<-- this likely not the correct way to write subclient (as Client be
very different from subclient from nested namespace), but at least
emitter should not throw

After this PR, above tsp would result in `ContosoSubSubClient` client,
as this is the only one containing operation.
This commit is contained in:
Weidong Xu 2024-09-10 12:26:01 +08:00 коммит произвёл GitHub
Родитель 5a55338def
Коммит 27c263ee68
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 37 добавлений и 13 удалений

Просмотреть файл

@ -199,13 +199,12 @@ export class CodeModelBuilder {
}
const service = listServices(this.program)[0];
const serviceNamespace = service.type;
if (serviceNamespace === undefined) {
throw Error("Cannot emit yaml for a namespace that doesn't exist.");
if (!service) {
throw Error("TypeSpec for HTTP must define a service.");
}
this.serviceNamespace = serviceNamespace;
this.serviceNamespace = service.type;
this.namespace = getNamespaceFullName(serviceNamespace) || "Azure.Client";
this.namespace = getNamespaceFullName(this.serviceNamespace) || "Azure.Client";
// java namespace
const javaNamespace = this.getJavaNamespace(this.namespace);
@ -219,9 +218,9 @@ export class CodeModelBuilder {
};
// init code model
const title = this.options["service-name"] ?? serviceNamespace.name;
const title = this.options["service-name"] ?? this.serviceNamespace.name;
const description = this.getDoc(serviceNamespace);
const description = this.getDoc(this.serviceNamespace);
this.codeModel = new CodeModel(title, false, {
info: {
description: description,
@ -230,7 +229,7 @@ export class CodeModelBuilder {
default: {
name: title,
description: description,
summary: this.getSummary(serviceNamespace),
summary: this.getSummary(this.serviceNamespace),
namespace: this.namespace,
},
java: {

Просмотреть файл

@ -192,9 +192,11 @@ public class ClientMapper implements IMapper<CodeModel, Client> {
} else {
// service client
ServiceClient serviceClient = Mappers.getServiceClientMapper().map(codeModel);
builder.serviceClient(serviceClient);
if (serviceClient != null) {
builder.serviceClient(serviceClient);
serviceClientsMap.put(serviceClient, codeModel);
serviceClientsMap.put(serviceClient, codeModel);
}
}
}

Просмотреть файл

@ -54,9 +54,16 @@ public class Transformer {
markFlattenedSchemas(codeModel);
}
transformOperationGroups(codeModel.getOperationGroups(), codeModel);
if (codeModel.getGlobalParameters() != null) {
for (Parameter parameter : codeModel.getGlobalParameters()) {
if (parameter.getLanguage().getJava() == null) {
renameVariable(parameter);
}
}
}
// multi-clients for TypeSpec
if (codeModel.getClients() != null) {
transformClients(codeModel.getClients(), codeModel);
transformClients(codeModel.getClients());
}
return codeModel;
}
@ -108,7 +115,7 @@ public class Transformer {
}
}
private void transformClients(List<Client> clients, CodeModel codeModel) {
private void transformClients(List<Client> clients) {
for (Client client : clients) {
renameClient(client);
@ -138,6 +145,14 @@ public class Transformer {
}
}
}
if (client.getGlobalParameters() != null) {
for (Parameter parameter : client.getGlobalParameters()) {
if (parameter.getLanguage().getJava() == null) {
renameVariable(parameter);
}
}
}
}
}

Просмотреть файл

@ -35,7 +35,10 @@ public class TypeSpecClientMapper extends ClientMapper {
Map<ServiceClient, Client> serviceClientsMap = new LinkedHashMap<>();
TypeSpecServiceClientMapper mapper = new TypeSpecServiceClientMapper();
for (Client client : clients) {
serviceClientsMap.put(mapper.map(client, codeModel), client);
ServiceClient serviceClient = mapper.map(client, codeModel);
if (serviceClient != null) {
serviceClientsMap.put(serviceClient, client);
}
}
return serviceClientsMap;
}

Просмотреть файл

@ -55,6 +55,11 @@ public class TypeSpecServiceClientMapper extends ServiceClientMapper {
.forEach(og -> methodGroupClients.add(Mappers.getMethodGroupMapper().map(og, properties)));
builder.methodGroupClients(methodGroupClients);
if (proxy == null && CoreUtils.isNullOrEmpty(methodGroupClients)) {
// No operation in this client, and no operation group as well. Abort the processing.
return null;
}
if (proxy == null) {
proxy = methodGroupClients.iterator().next().getProxy();
}