mirror of
				https://github.com/mgechev/revive.git
				synced 2025-10-30 23:37:49 +02:00 
			
		
		
		
	| @@ -14,7 +14,6 @@ func (*NestedStructs) Apply(file *lint.File, _ lint.Arguments) []lint.Failure { | ||||
| 	var failures []lint.Failure | ||||
|  | ||||
| 	walker := &lintNestedStructs{ | ||||
| 		fileAST: file.AST, | ||||
| 		onFailure: func(failure lint.Failure) { | ||||
| 			failures = append(failures, failure) | ||||
| 		}, | ||||
| @@ -31,47 +30,46 @@ func (*NestedStructs) Name() string { | ||||
| } | ||||
|  | ||||
| type lintNestedStructs struct { | ||||
| 	fileAST   *ast.File | ||||
| 	onFailure func(lint.Failure) | ||||
| } | ||||
|  | ||||
| func (l *lintNestedStructs) Visit(n ast.Node) ast.Visitor { | ||||
| 	switch v := n.(type) { | ||||
| 	case *ast.TypeSpec: | ||||
| 		_, isInterface := v.Type.(*ast.InterfaceType) | ||||
| 		if isInterface { | ||||
| 			return nil // do not analyze interface declarations | ||||
| 		} | ||||
| 	case *ast.FuncDecl: | ||||
| 		if v.Body != nil { | ||||
| 			ast.Walk(l, v.Body) | ||||
| 		} | ||||
| 		return nil | ||||
| 	case *ast.Field: | ||||
| 		_, isChannelField := v.Type.(*ast.ChanType) | ||||
| 		if isChannelField { | ||||
| 			return nil | ||||
| 		} | ||||
|  | ||||
| 		filter := func(n ast.Node) bool { | ||||
| 			switch n.(type) { | ||||
| 			case *ast.StructType: | ||||
| 				return true | ||||
| 			default: | ||||
| 				return false | ||||
| 			} | ||||
| 		} | ||||
| 		structs := pick(v, filter, nil) | ||||
| 		for _, s := range structs { | ||||
| 			l.onFailure(lint.Failure{ | ||||
| 				Failure:    "no nested structs are allowed", | ||||
| 				Category:   "style", | ||||
| 				Node:       s, | ||||
| 				Confidence: 1, | ||||
| 			}) | ||||
| 		} | ||||
| 		return nil // no need to visit (again) the field | ||||
| 	if v, ok := n.(*ast.StructType); ok { | ||||
| 		ls := &lintStruct{l.onFailure} | ||||
| 		ast.Walk(ls, v.Fields) | ||||
| 	} | ||||
|  | ||||
| 	return l | ||||
| } | ||||
|  | ||||
| type lintStruct struct { | ||||
| 	onFailure func(lint.Failure) | ||||
| } | ||||
|  | ||||
| func (l *lintStruct) Visit(n ast.Node) ast.Visitor { | ||||
| 	switch s := n.(type) { | ||||
| 	case *ast.StructType: | ||||
| 		l.fail(s) | ||||
| 		return nil | ||||
| 	case *ast.ArrayType: | ||||
| 		if _, ok := s.Elt.(*ast.StructType); ok { | ||||
| 			l.fail(s) | ||||
| 		} | ||||
| 		return nil | ||||
| 	case *ast.ChanType: | ||||
| 		return nil | ||||
| 	case *ast.MapType: | ||||
| 		return nil | ||||
| 	default: | ||||
| 		return l | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (l *lintStruct) fail(n ast.Node) { | ||||
| 	l.onFailure(lint.Failure{ | ||||
| 		Failure:    "no nested structs are allowed", | ||||
| 		Category:   "style", | ||||
| 		Node:       n, | ||||
| 		Confidence: 1, | ||||
| 	}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										17
									
								
								testdata/nested-structs.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								testdata/nested-structs.go
									
									
									
									
										vendored
									
									
								
							| @@ -18,6 +18,17 @@ type Quux struct { | ||||
| type Quuz struct { | ||||
| } | ||||
|  | ||||
| type Quiz struct { | ||||
| 	s struct{} // MATCH /no nested structs are allowed/ | ||||
| } | ||||
|  | ||||
| type nestedStructInChan struct { | ||||
| 	c chan struct { | ||||
| 		a int | ||||
| 		b struct{ c int } // MATCH /no nested structs are allowed/ | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func waldo() (s struct{ b bool }) { return s } | ||||
|  | ||||
| func fred() interface{} { | ||||
| @@ -45,3 +56,9 @@ type issue744 struct { | ||||
| type mySetInterface interface { | ||||
| 	GetSet() map[string]struct{} | ||||
| } | ||||
|  | ||||
| // issue 824 | ||||
| type test struct { | ||||
| 	foo []chan struct{}     // Must not match | ||||
| 	bar map[string]struct{} // Must not match | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user