in lib/semantic.js [2006:2078]
checkProperty(ast, env) {
if (ast.id.lexeme === '__module') {
const [key] = ast.propertyPath;
const target = this.consts.get(key.lexeme);
if (!target) {
this.error(`the const ${key.lexeme} is undefined`, key);
}
replace(ast, target);
return;
}
this.checkId(ast.id, env);
// check property
const type = this.getVariableType(ast.id, env);
ast.id.inferred = type;
if (type.type === 'model' || type.type === 'map') {
// { type: 'map', keyTypeName: 'string', valueTypeName: 'any' }
const currentPath = [ast.id.lexeme];
let current = type;
ast.propertyPathTypes = new Array(ast.propertyPath.length);
for (let i = 0; i < ast.propertyPath.length; i++) {
let prop = ast.propertyPath[i];
let find = this.getPropertyType(current, prop.lexeme);
if (!find) {
this.error(`The property ${prop.lexeme} is undefined ` +
`in model ${currentPath.join('.')}(${current.name})`, prop);
}
ast.propertyPathTypes[i] = find;
currentPath.push(prop.lexeme);
current = find;
}
return;
}
if (this.models.has(ast.id.lexeme)) {
// submodel M.N
let current = this.models.get(ast.id.lexeme);
const currentPath = [ast.id.lexeme];
for (let i = 0; i < ast.propertyPath.length; i++) {
let prop = ast.propertyPath[i];
currentPath.push(prop.lexeme);
let find = this.findProperty(current, prop.lexeme, current.isException);
if (!find) {
this.error(`The model ${currentPath.join('.')} is undefined`, prop);
}
current = find.modelField;
}
ast.realType = {
type: 'class',
name: currentPath.join('.')
};
return;
}
if (this.dependencies.has(ast.id.lexeme)) {
// Alias.M.N
return;
}
if (this.enums.has(ast.id.lexeme)) {
// E.K
return;
}
const name = ast.id.lexeme;
this.error(`The type of '${name}' must be model, object or map`, ast.id);
}