Skip to content

Commit

Permalink
Fix types derived from primitives with attributes or enumerations.
Browse files Browse the repository at this point in the history
  • Loading branch information
jjrv committed Jan 15, 2016
1 parent 9c8d569 commit aaa52f2
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 17 deletions.
5 changes: 3 additions & 2 deletions src/schema/Type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ export class Type {
var output: string[] = [];

if(this.primitiveList && this.primitiveList.length) {
//TODO: if parent is a string restricted to enumerated alternatives, output them joined with pipe characters.
output.push(this.primitiveList[0]);
if(this.primitiveList.length > 1) {
output.push('(' + this.primitiveList.join(' | ') + ')');
} else output.push(this.primitiveList[0]);
} else {
var members = this.exportMembersTS(namespace, indent + '\t', '');

Expand Down
32 changes: 22 additions & 10 deletions src/xsd/Exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,21 +162,33 @@ function exportType(type: types.TypeBase, namespace: schema.Namespace) {
var outType = type.getOutType();
outType.comment = comment;

var parent = type.parent;
var parentPrimitive = type.getParent(types.Primitive, true);

if(parentPrimitive) {
var primitiveList: string[];
var parentSimple = type.getParent(types.SimpleType, false) as types.SimpleType;

if(parent && parent instanceof types.Primitive) {
// TODO: if parent is a string restricted to enumerated alternatives, output those instead.
outType.primitiveList = [parent.name];
} else {
if(parent instanceof types.TypeBase) {
outType.parent = parent.getOutType();
namespace.markUsed(parent.qName.namespace.id);
if(parentSimple) {
// If parent is restricted to enumerated alternatives, output those instead.
primitiveList = parentSimple.getEnumerationList();
if(primitiveList) primitiveList = primitiveList.map((content: string) => '"' + content + '"');
}

outType.attributeList = exportAttributes(scope, namespace);
outType.childList = exportChildren(scope, namespace);
if(!primitiveList) primitiveList = [parentPrimitive.name];

outType.primitiveList = primitiveList;
}

var parent = type.parent;

if(parent instanceof types.TypeBase && parent != parentPrimitive) {
outType.parent = parent.getOutType();
if(parent.qName) namespace.markUsed(parent.qName.namespace.id);
}

outType.attributeList = exportAttributes(scope, namespace);
outType.childList = exportChildren(scope, namespace);

return(outType);
}

Expand Down
6 changes: 5 additions & 1 deletion src/xsd/Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ export class Parser {
/** Bind references, call after all imports have been initialized. */
resolve() {
try {
this.pendingList.forEach((state: State) => state.xsdElement.resolve(state));
for(var pos = 0; pos < this.pendingList.length; ++pos) {
var state = this.pendingList[pos];
state.xsdElement.resolve(state);
}

this.pendingList = [];
} catch(err) {
console.error(err);
Expand Down
8 changes: 8 additions & 0 deletions src/xsd/Scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@ console.log('Missing ' + type + ': ' + name.name);
return((this.expose['attribute'] || {}) as {[name: string]: TypeMember});
}

hasAttributes() {
var tbl = this.expose['attribute'];

for(var key in tbl) if(tbl.hasOwnProperty(key)) return(true);

return(false);
}

static getPrimitiveScope() {
var scope = this.primitiveScope;

Expand Down
10 changes: 10 additions & 0 deletions src/xsd/types/ComplexType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ export class SimpleType extends types.TypeBase {
List,
Union
];

setEnumerationList(enumerationList: string[]) {
this.enumerationList = enumerationList;
}

getEnumerationList() {
return(this.enumerationList);
}

private enumerationList: string[];
}

/** <xsd:complextype> */
Expand Down
4 changes: 3 additions & 1 deletion src/xsd/types/Enumeration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export class Enumeration extends types.Base {
];

init(state: State) {
(state.parent.xsdElement as types.Restriction).addEnumeration(this.value);
var parent = state.parent.xsdElement;

if(parent instanceof types.Restriction) parent.addEnumeration(this.value);
}

value: string = null;
Expand Down
30 changes: 28 additions & 2 deletions src/xsd/types/Restriction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,36 @@ export class Restriction extends DerivationBase {
types.Enumeration
]);

// TODO: Remove this.
init(state: State) {
this.parent = state.parent;
}

/*
TODO: uncomment this when resolve function dependencies are handled.
resolve(state: State) {
var parent = state.parent.xsdElement;
if(parent instanceof types.SimpleType) {
parent.setEnumerationList(this.enumerationList);
}
}
*/

addEnumeration(content: string) {
if(!this.enumerationList) this.enumerationList = [];
if(!this.enumerationList) {
this.enumerationList = [];

// TODO: Remove this and uncomment the resolve function.
var parent = this.parent.xsdElement;

if(parent instanceof types.SimpleType) {
parent.setEnumerationList(this.enumerationList);
}
}
this.enumerationList.push(content);
}

enumerationList: string[];
private parent: State; // TODO: Remove this.
private enumerationList: string[];
}
22 changes: 21 additions & 1 deletion src/xsd/types/TypeBase.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// This file is part of fast-xml, copyright (c) 2015-2016 BusFaster Ltd.
// Released under the MIT license, see LICENSE.

import {Base} from './Base';
import {Base, BaseClass} from './Base';
import {State} from '../State';
import {QName} from '../QName';
import * as schema from '../../schema';
Expand Down Expand Up @@ -33,6 +33,26 @@ export class TypeBase extends Base {
return(outType);
}

/** Find parent type inheriting from a base type. */

getParent(base: BaseClass, breakAtContent: boolean) {
var next: TypeBase | QName = this;
var type: TypeBase | QName;
/** Maximum iterations in case type inheritance forms a loop. */
var iter = 100;

while(--iter) {
type = next;

if(!(type instanceof TypeBase)) break;
else if(type instanceof base) return(type);
else if(breakAtContent && type.scope && type.scope.hasAttributes()) break;
else next = type.parent;
}

return(null);
}

id: string = null;
name: string = null;

Expand Down

0 comments on commit aaa52f2

Please sign in to comment.