in lib/semantic.js [216:308]
function isAssignable(expected, actual, expr) {
if (isSameType(expected, actual)) {
return true;
}
if (isSameNumber(expected, actual)) {
return true;
}
if(expected.type === 'model' && actual.type === 'model') {
// $Model vs model
if(expected.name === '$Model') {
return true;
}
// $Error vs exception
if(expected.name === '$Error' && actual.isException) {
return true;
}
if (isExtendOn(expected, actual)) {
return true;
}
}
// actual is null
if (actual.type === 'basic' && actual.name === 'null') {
return true;
}
if (expected.type === 'map' && actual.type === 'map') {
if (expr && expr.type === 'object' && expr.fields.length === 0) {
return true;
}
if (isAssignable(expected.valueType, actual.valueType)) {
return true;
}
}
if (expected.type === 'entry' && actual.type === 'entry') {
if (expr && expr.type === 'object' && expr.fields.length === 0) {
return true;
}
if (isAssignable(expected.valueType, actual.valueType)) {
return true;
}
}
if (expected.type === 'array' && actual.type === 'array') {
if (expr && expr.type === 'array' && expr.items.length === 0) {
return true;
}
if (isAssignable(expected.itemType, actual.itemType)) {
return true;
}
}
if (expected.type === 'basic' && expected.name === 'readable') {
// readable = string should ok
if (actual.type === 'basic' && actual.name === 'string') {
return true;
}
// readable = bytes should ok
if (actual.type === 'basic' && actual.name === 'bytes') {
return true;
}
}
if (expected.type === 'basic' && expected.name === 'any') {
// any = other type
return true;
}
if (expected.type === 'basic' && expected.name === 'object') {
// object = other type
return true;
}
if (expected.type === 'module_instance' && actual.type === 'module_instance') {
if (actual.parentModuleIds.includes(expected.name)) {
// basicModule = new derivedModule
return true;
}
}
return false;
}