[go: nahoru, domu]

blob: df163c9e45276807a09961d12a25445d15c20987 [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281# Copyright 2012 The Chromium Authors
noelallen@google.comcaff0c32011-07-22 16:34:132# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5""" Lint for IDL """
6
7import os
8import sys
9
10from idl_log import ErrOut, InfoOut, WarnOut
11from idl_node import IDLAttribute, IDLNode
12from idl_ast import IDLAst
13from idl_option import GetOption, Option, ParseOptions
14from idl_outfile import IDLOutFile
15from idl_visitor import IDLVisitor
16
17
18Option('wcomment', 'Disable warning for missing comment.')
19Option('wenum', 'Disable warning for missing enum value.')
20Option('winline', 'Disable warning for inline blocks.')
noelallen@google.comfb94d1b2011-08-22 22:18:2721Option('wname', 'Disable warning for inconsistent interface name.')
22Option('wnone', 'Disable all warnings.')
noelallen@google.comcaff0c32011-07-22 16:34:1323Option('wparam', 'Disable warning for missing [in|out|inout] on param.')
24Option('wpass', 'Disable warning for mixed passByValue and returnByValue.')
25
26#
27# IDLLinter
28#
29# Once the AST is build, we need to resolve the namespace and version
30# information.
31#
32class IDLLinter(IDLVisitor):
33 def VisitFilter(self, node, data):
34 __pychecker__ = 'unusednames=node,data'
35 return not node.IsA('Comment', 'Copyright')
36
37 def Arrive(self, node, errors):
38 __pychecker__ = 'unusednames=node,errors'
39 warnings = 0
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.')
44 warnings += 1
45
noelallen@chromium.org9b1005962012-06-17 05:37:1546 if node.IsA('File'):
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.')
51
noelallen@google.comcaff0c32011-07-22 16:34:1352 if node.IsA('Struct', 'Typedef') and not node.GetProperty('wpass'):
53 if node.GetProperty('passByValue'):
54 pbv = 'is'
55 else:
56 pbv = 'is not'
57 if node.GetProperty('returnByValue'):
58 ret = 'is'
59 else:
60 ret = 'is not'
61 if pbv != ret:
62 node.Warning('%s passByValue but %s returnByValue.' % (pbv, ret))
63 warnings += 1
64
65 if node.IsA('EnumItem'):
66 if not node.GetProperty('VALUE') and not node.GetProperty('wenum'):
67 node.Warning('Expecting value for enumeration.')
68 warnings += 1
69
70 if node.IsA('Interface'):
noelallen@google.comcaff0c32011-07-22 16:34:1371 macro = node.GetProperty('macro')
noelallen@google.comfb94d1b2011-08-22 22:18:2772 if macro and not node.GetProperty('wname'):
noelallen@google.comcaff0c32011-07-22 16:34:1373 node.Warning('Interface name inconsistent: %s' % macro)
74 warnings += 1
75
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)
79 warnings += 1
80
noelallen@google.comfb94d1b2011-08-22 22:18:2781 if node.IsA('Callspec') and not node.GetProperty('wparam'):
noelallen@google.comcaff0c32011-07-22 16:34:1382 out = False
83 for arg in node.GetListOf('Param'):
84 if arg.GetProperty('out'):
85 out = True
86 if arg.GetProperty('in') and out:
87 arg.Warning('[in] parameter after [out] parameter')
88 warnings += 1
89
90 if node.IsA('Param') and not node.GetProperty('wparam'):
91 found = False;
92 for form in ['in', 'inout', 'out']:
93 if node.GetProperty(form): found = True
94 if not found:
95 node.Warning('Missing argument type: [in|out|inout]')
96 warnings += 1
97
98 return warnings
99
100 def Depart(self, node, warnings, childdata):
101 __pychecker__ = 'unusednames=node'
102 for child in childdata:
103 warnings += child
104 return warnings
105
106def Lint(ast):
noelallen@google.comfb94d1b2011-08-22 22:18:27107 options = ['wcomment', 'wenum', 'winline', 'wparam', 'wpass', 'wname']
108 wnone = GetOption('wnone')
109 for opt in options:
110 if wnone or GetOption(opt): ast.SetProperty(opt, True)
noelallen@google.comcaff0c32011-07-22 16:34:13111
112 skipList = []
113 for filenode in ast.GetListOf('File'):
114 name = filenode.GetProperty('NAME')
115 if filenode.GetProperty('ERRORS') > 0:
noelallen@google.comd6afb582011-07-27 17:03:52116 ErrOut.Log('%s : Skipped due to errors.' % name)
noelallen@google.comcaff0c32011-07-22 16:34:13117 skipList.append(filenode)
118 continue
119 warnings = IDLLinter().Visit(filenode, 0)
120 if warnings:
121 WarnOut.Log('%s warning(s) for %s\n' % (warnings, name))
122 return skipList