一,逆變Contravariant
bool IsSubtypeOf(const Function& other, Heap::Space space) const;
如果此函數的類型是其他函數類型的子類型,則傳回true
bool Function::IsContravariantParameter(intptr_t parameter_position,
const Function& other,
intptr_t other_parameter_position,
Heap::Space space) const {
const AbstractType& param_type =
AbstractType::Handle(ParameterTypeAt(parameter_position));
if (param_type.IsTopType()) {//kDynamicCid,kVoidCid,kInstanceCid(kLegacy or kNullable),kFutureOrCid
return true;
}
const AbstractType& other_param_type =
AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
return other_param_type.IsSubtypeOf(param_type, space);
}
檢查此函數的指定參數的類型是否是另一個函數指定參數類型的父類型(即檢查參數逆變)。注意,标記為協變的類型已經在前端處理
二, 協變(Covariant)
Field:{
bool is_covariant() const {
return CovariantBit::decode(raw_ptr()->kind_bits_);
}
}
後續分析
三,泛型
bool Function::HasGenericParent() const {
if (IsImplicitClosureFunction()) {
return false;
}
Function& parent = Function::Handle(parent_function());
while (!parent.IsNull()) {
if (parent.IsGeneric()) {
return true;
}
parent = parent.parent_function();
}
return false;
}
bool IsGeneric() const {
return NumTypeParameters(Thread::Current()) > 0;
}
參數的類型數量大于0為泛型
四,分析一些方法
static const object& Cast(const Object& obj) {
ASSERT(obj.Is##object());
return reinterpret_cast<const object&>(obj);
}
T::Cast無法将其強制轉換null Object,因為沒有為類型T設定對象vtable,盡管某些方法應該使用null,例如Instance::Equals()
使用舉例:Function::Cast(obj).raw();
void Function::set_data(const Object& value) const {
StorePointer(&raw_ptr()->data_, value.raw());
}
void Function::SetRegExpData(const RegExp& regexp,
intptr_t string_specialization_cid,
bool sticky) const {
ASSERT(kind() == RawFunction::kIrregexpFunction);
ASSERT(RawObject::IsStringClassId(string_specialization_cid));
ASSERT(raw_ptr()->data_ == Object::null());
const Array& pair = Array::Handle(Array::New(2, Heap::kOld));
pair.SetAt(0, regexp);
pair.SetAt(1, Smi::Handle(Smi::New(StickySpecialization::encode(sticky) |
StringSpecializationCid::encode(
string_specialization_cid))));
set_data(pair);
}
以上setxxxData對應如下
eval函數:腳本表達式源
kernel eval function:Array[0]=腳本,Array[1]=核心資料,Array[2]=核心庫的核心偏移量
signature函數:SignatureData
method extractor:提取閉包函數的函數
implicit getter:Field
implicit setter:Field
impl. static final gttr:Field
field initializer:Field
noSuchMethod dispatcher:數組參數描述符
invoke-field dispatcher:數組參數描述符
redirecting constructor:RedirectionData
closure函數:closure Data
irregexp function:Array[0]=RegExp,Array[1]=Smi字元串,專門的cid
native function:Array[0]= native字元串名稱,Array[1]=隐式閉包函數的函數
regular function:隐式閉包函數的函數
ffi trampoline function:FfiTrampolineData(Dart->C)
dyn inv forwarder:Array[0]=函數目标,Array[1]=TypeArguments預設類型參數,Array[i]=參數類型檢查
RawType* Function::SignatureType(Nullability nullability) cons
此函數的函數類型尚未緩存,需要在此處構造和緩存,函數類型的類型參數化方式與其非靜态簽名函數的所有者類相同,如果它的簽名函數是靜态的,或者如果它的結果類型或形式參數類型都不是類型參數化的,那麼它就不屬于類型參數化,除非函數類型是typedef泛型,否則函數類型的類型參數不會作為類型參數的向量顯式存儲在函數類型中,typedef函數類型的類型類始終是typedef類,它可能是泛型的,在這種情況下,類型存儲類型參數,non-typedef 函數類型的類型參數始終為non-generic_Closure類,隻有當簽名被解析後,我們才能執行此操作。typedef F(f(int x)) F為typedef類的owner,f的類型是函數類型,如果函數類型的簽名是typedef的簽名,我們隻将函數類型的類型類設定為typedef類。
bool IsGenerativeConstructor() const {
return (kind() == RawFunction::kConstructor) && !is_static();
}
bool IsFactory() const {
return (kind() == RawFunction::kConstructor) && is_static();
}
工廠構造為static
總結:對于function對象,涵蓋的包括抽象,靜态,閉包,構造,參數,隐式函數,簽名,Ffi等.其中處理最多的是閉包,參數.對于父類object處理最多的是cid,handle,raw,cast,point,位操作等之間的轉換,存儲等