1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
10 from idl_log
import ErrOut
, InfoOut
, WarnOut
11 from idl_node
import IDLAttribute
, IDLNode
12 from idl_ast
import IDLAst
13 from idl_option
import GetOption
, Option
, ParseOptions
14 from idl_outfile
import IDLOutFile
15 from idl_visitor
import IDLVisitor
18 Option('wcomment', 'Disable warning for missing comment.')
19 Option('wenum', 'Disable warning for missing enum value.')
20 Option('winline', 'Disable warning for inline blocks.')
21 Option('wname', 'Disable warning for inconsistent interface name.')
22 Option('wnone', 'Disable all warnings.')
23 Option('wparam', 'Disable warning for missing [in|out|inout] on param.')
24 Option('wpass', 'Disable warning for mixed passByValue and returnByValue.')
29 # Once the AST is build, we need to resolve the namespace and version
32 class IDLLinter(IDLVisitor
):
33 def VisitFilter(self
, node
, data
):
34 __pychecker__
= 'unusednames=node,data'
35 return not node
.IsA('Comment', 'Copyright')
37 def Arrive(self
, node
, errors
):
38 __pychecker__
= 'unusednames=node,errors'
40 if node
.IsA('Interface', 'Member', 'Struct', 'Enum', 'EnumItem', 'Typedef'):
41 comments
= node
.GetListOf('Comment')
42 if not comments
and not node
.GetProperty('wcomment'):
43 node
.Warning('Expecting a comment.')
47 labels
= node
.GetListOf('Label')
48 interfaces
= node
.GetListOf('Interface')
49 if interfaces
and not labels
:
50 node
.Warning('Expecting a label in a file containing interfaces.')
52 if node
.IsA('Struct', 'Typedef') and not node
.GetProperty('wpass'):
53 if node
.GetProperty('passByValue'):
57 if node
.GetProperty('returnByValue'):
62 node
.Warning('%s passByValue but %s returnByValue.' % (pbv
, ret
))
65 if node
.IsA('EnumItem'):
66 if not node
.GetProperty('VALUE') and not node
.GetProperty('wenum'):
67 node
.Warning('Expecting value for enumeration.')
70 if node
.IsA('Interface'):
71 macro
= node
.GetProperty('macro')
72 if macro
and not node
.GetProperty('wname'):
73 node
.Warning('Interface name inconsistent: %s' % macro
)
76 if node
.IsA('Inline') and not node
.GetProperty('winline'):
77 inline_type
= node
.GetProperty('NAME')
78 node
.parent
.Warning('Requires an inline %s block.' % inline_type
)
81 if node
.IsA('Callspec') and not node
.GetProperty('wparam'):
83 for arg
in node
.GetListOf('Param'):
84 if arg
.GetProperty('out'):
86 if arg
.GetProperty('in') and out
:
87 arg
.Warning('[in] parameter after [out] parameter')
90 if node
.IsA('Param') and not node
.GetProperty('wparam'):
92 for form
in ['in', 'inout', 'out']:
93 if node
.GetProperty(form
): found
= True
95 node
.Warning('Missing argument type: [in|out|inout]')
100 def Depart(self
, node
, warnings
, childdata
):
101 __pychecker__
= 'unusednames=node'
102 for child
in childdata
:
107 options
= ['wcomment', 'wenum', 'winline', 'wparam', 'wpass', 'wname']
108 wnone
= GetOption('wnone')
110 if wnone
or GetOption(opt
): ast
.SetProperty(opt
, True)
113 for filenode
in ast
.GetListOf('File'):
114 name
= filenode
.GetProperty('NAME')
115 if filenode
.GetProperty('ERRORS') > 0:
116 ErrOut
.Log('%s : Skipped due to errors.' % name
)
117 skipList
.append(filenode
)
119 warnings
= IDLLinter().Visit(filenode
, 0)
121 WarnOut
.Log('%s warning(s) for %s\n' % (warnings
, name
))