// findAndExportStructFacts finds any struct fields that are annotated with the
// "// +checklocks:" annotation and exports relevant facts about the fields to
// be used in later analysis.
findAndExportStructFacts finds any struct fields that are annotated with the
"// +checklocks:" annotation and exports relevant facts about the fields to
be used in later analysis.
// findAndExportStructFacts finds any struct fields that are annotated with the // " // + checklocks : " annotation and exports relevant facts about the fields to // be used in later analysis .
func (pc *passContext) findAndExportStructFacts(ss *ast.StructType, structType *types.Struct) {
	type fieldRef struct {
		fieldObj *types.Var
		facts    *lockFieldFacts
	}
	mutexes := make(map[string]*fieldRef)
	rwMutexes := make(map[string]*fieldRef)
	guardedFields := make(map[string]*fieldRef)
	for i, field := range ss.Fields.List {
		fieldObj := structType.Field(i)
		fieldFacts := pc.extractFieldAnnotations(field, fieldObj)
		if fieldFacts == nil {
			continue
		}
		fieldFacts.FieldNumber = i
		ref := &fieldRef{fieldObj, fieldFacts}
		if fieldFacts.IsMutex {
			mutexes[fieldObj.Name()] = ref
		}
		if fieldFacts.IsRWMutex {
			rwMutexes[fieldObj.Name()] = ref
		}
		if len(fieldFacts.GuardedBy) != 0 {
			guardedFields[fieldObj.Name()] = ref
		}
	}
	for _, f := range mutexes {
		pc.pass.ExportObjectFact(f.fieldObj, f.facts)
	}
	for _, f := range rwMutexes {
		pc.pass.ExportObjectFact(f.fieldObj, f.facts)
	}
	for _, gf := range guardedFields {
		for g := range gf.facts.GuardedBy {
			if f, ok := mutexes[g]; ok {
				gf.facts.GuardedBy[g] = f.facts.FieldNumber
			} else if f, ok := rwMutexes[g]; ok {
				gf.facts.GuardedBy[g] = f.facts.FieldNumber
			} else {
				pc.maybeFail(gf.fieldObj.Pos(), false , "invalid mutex guard, no such mutex %s in struct %s", g, structType.String())
				continue
			}
			pc.pass.ExportObjectFact(gf.fieldObj, gf.facts)
		}
	}
}
func ( pc * passContext ) findAndExportStructFacts ( ss * ast . StructType , structType * types . Struct ) { type fieldRef struct { fieldObj * types . Var facts * lockFieldFacts } mutexes := make ( map [ string ] * fieldRef ) rwMutexes := make ( map [ string ] * fieldRef ) guardedFields := make ( map [ string ] * fieldRef ) for i , field := range ss . Fields . List { fieldObj := structType . Field ( i ) fieldFacts := pc . extractFieldAnnotations ( field , fieldObj ) if fieldFacts == nil { continue } fieldFacts . FieldNumber = i ref := & fieldRef { fieldObj , fieldFacts } if fieldFacts . IsMutex { mutexes [ fieldObj . Name ( ) ] = ref } if fieldFacts . IsRWMutex { rwMutexes [ fieldObj . Name ( ) ] = ref } if len ( fieldFacts . GuardedBy ) != 0 { guardedFields [ fieldObj . Name ( ) ] = ref } } for _ , f := range mutexes { pc . pass . ExportObjectFact ( f . fieldObj , f . facts ) } for _ , f := range rwMutexes { pc . pass . ExportObjectFact ( f . fieldObj , f . facts ) } for _ , gf := range guardedFields { for g := range gf . facts . GuardedBy { if f , ok := mutexes [ g ] ; ok { gf . facts . GuardedBy [ g ] = f . facts . FieldNumber } else if f , ok := rwMutexes [ g ] ; ok { gf . facts . GuardedBy [ g ] = f . facts . FieldNumber } else { pc . maybeFail ( gf . fieldObj . Pos ( ) , false , " " , g , structType . String ( ) ) continue } pc . pass . ExportObjectFact ( gf . fieldObj , gf . facts ) } } }
findAndExportStructFacts finds any struct fields that are annotated with the
"// +checklocks:" annotation and exports relevant facts about the fields to
be used in later analysis.
findAndExportStructFacts finds any struct fields that are annotated with the " // + checklocks : " annotation and exports relevant facts about the fields to be used in later analysis .
// Export facts about all mutexes. // Export facts about all rwMutexes. // Validate that guarded fields annotations refer to actual mutexes or // rwMutexes in the struct. /* isExempted */ // Export guarded field fact.