Skip to content

Commit

Permalink
Pre-calculate type aliases before processing models (#6559)
Browse files Browse the repository at this point in the history
A type alias in this context is where a model is simply another name for a
primitive type, such as `MyString` in the following model definitions:

    MyList:
      type: array
      items:
        $ref: '#/definitions/MyString'
    MyString:
      type: string

It is valid to use a type alias as a property in another object or array model,
even if the object/array is defined before the alias is, as in the example
above. However, the current alias logic only looks "back" in list of previously
defined models, meaning that `MyList` would not know that `MyString` is an
alias. This change fixes the incorrect behavior by pre-calculating the list of
aliases before any models are processed. It also changes the test endpoint to
verify the correct behavior even when an object is defined before an alias it
uses.
  • Loading branch information
bbdouglas authored and wing328 committed Oct 2, 2017
1 parent 8bd7d39 commit 6e7ad13
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public class DefaultCodegen {
// Then translated back during JSON encoding and decoding
protected Map<String, String> specialCharReplacements = new HashMap<String, String>();
// When a model is an alias for a simple type
protected Map<String, String> typeAliases = new HashMap<>();
protected Map<String, String> typeAliases = null;

protected String ignoreFilePathOverride;

Expand Down Expand Up @@ -1312,6 +1312,10 @@ public CodegenModel fromModel(String name, Model model) {
* @return Codegen Model object
*/
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
if (typeAliases == null) {
// Only do this once during first call
typeAliases = getAllAliases(allDefinitions);
}
CodegenModel m = CodegenModelFactory.newInstance(CodegenModelType.MODEL);
if (reservedWords.contains(name)) {
m.name = escapeReservedWord(name);
Expand All @@ -1327,6 +1331,7 @@ public CodegenModel fromModel(String name, Model model, Map<String, Model> allDe
m.modelJson = Json.pretty(model);
m.externalDocs = model.getExternalDocs();
m.vendorExtensions = model.getVendorExtensions();
m.isAlias = typeAliases.containsKey(name);

if (model instanceof ModelImpl) {
ModelImpl modelImpl = (ModelImpl) model;
Expand Down Expand Up @@ -1444,10 +1449,6 @@ public CodegenModel fromModel(String name, Model model, Map<String, Model> allDe
ModelImpl impl = (ModelImpl) model;
if (impl.getType() != null) {
Property p = PropertyBuilder.build(impl.getType(), impl.getFormat(), null);
if (!impl.getType().equals("object") && impl.getEnum() == null) {
typeAliases.put(name, impl.getType());
m.isAlias = true;
}
m.dataType = getSwaggerType(p);
}
if(impl.getEnum() != null && impl.getEnum().size() > 0) {
Expand Down Expand Up @@ -3166,6 +3167,31 @@ private void addVars(CodegenModel m, List<CodegenProperty> vars, Map<String, Pro
}
}

/**
* Determine all of the types in the model definitions that are aliases of
* simple types.
* @param allDefinitions The complete set of model definitions.
* @return A mapping from model name to type alias
*/
private static Map<String, String> getAllAliases(Map<String, Model> allDefinitions) {
Map<String, String> aliases = new HashMap<>();
if (allDefinitions != null) {
for (Map.Entry<String, Model> entry : allDefinitions.entrySet()) {
String swaggerName = entry.getKey();
Model m = entry.getValue();
if (m instanceof ModelImpl) {
ModelImpl impl = (ModelImpl) m;
if (impl.getType() != null &&
!impl.getType().equals("object") &&
impl.getEnum() == null) {
aliases.put(swaggerName, impl.getType());
}
}
}
}
return aliases;
}

/**
* Remove characters not suitable for variable or method name from the input and camelize it
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ public String getTypeDeclaration(Property p) {

@Override
public String getAlias(String name) {
if (typeAliases.containsKey(name)) {
if (typeAliases != null && typeAliases.containsKey(name)) {
return typeAliases.get(name);
}
return name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1402,12 +1402,6 @@ definitions:
- "placed"
- "approved"
- "delivered"
OuterNumber:
type: number
OuterString:
type: string
OuterBoolean:
type: boolean
OuterComposite:
type: object
properties:
Expand All @@ -1417,6 +1411,12 @@ definitions:
$ref: '#/definitions/OuterString'
my_boolean:
$ref: '#/definitions/OuterBoolean'
OuterNumber:
type: number
OuterString:
type: string
OuterBoolean:
type: boolean
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'

0 comments on commit 6e7ad13

Please sign in to comment.