in lib/parser.js [767:872]
fieldValue() {
// fieldValue = ( type | arrayType | modelBody | mapType )
// attrs = "(" attr { "," attr } ")"
// attr = attrName "=" constant
// type = "string" | "number" | "boolean"
// mapType = "map" "[" type "]" type
if (this.look.tag === '{') {
return this.modelBody();
}
if (this.look.tag === '[') {
const node = {
type: 'fieldType',
fieldType: 'array',
};
this.move();
if (this.look.tag === '[') {
node.fieldItemType = this.fieldValue();
} else if (this.look.tag === Tag.TYPE || this.look.tag === Tag.ID) {
const type = this.baseType();
node.fieldItemType = type;
} else if (this.look.tag === '{') {
node.fieldItemType = this.modelBody();
} else {
this.error('expect type or model name');
}
this.match(']');
return node;
}
if (this.look.tag === Tag.TYPE) {
const type = this.look;
this.move();
if (type.lexeme === 'map') {
this.match('[');
const keyType = this.baseType();
this.match(']');
const valueType = this.baseType();
return {
type: 'fieldType',
fieldType: type.lexeme,
keyType: keyType,
valueType: valueType
};
}
if (type.lexeme === 'entry') {
this.match('[');
const valueType = this.baseType();
this.match(']');
return {
type: 'fieldType',
fieldType: type.lexeme,
valueType: valueType
};
}
if (type.lexeme === 'iterator' || type.lexeme === 'asyncIterator') {
this.match('[');
const valueType = this.baseType();
this.match(']');
return {
type: 'fieldType',
fieldType: type.lexeme,
valueType: valueType,
};
}
return {
type: 'fieldType',
fieldType: type.lexeme
};
}
if (this.look.tag === Tag.ID) {
const model = this.look;
this.move();
// for A.B
if (this.look.tag === '.') {
const path = [model];
while (this.look.tag === '.') {
this.move();
const id = this.look;
path.push(id);
this.match(Tag.ID);
}
return {
type: 'fieldType',
fieldType: {
type: 'subModel_or_moduleModel',
path: path
}
};
}
return {
type: 'fieldType',
fieldType: model
};
}
this.error('expect "{", "[", "string", "number", "map", ID');
}