| 1297 | vector<pair<string,Type>> getCodeOfPolicyOptions(); |
| 1298 | |
| 1299 | void Program::lint ( TextWriter & /*logs*/, ModuleGroup & libGroup ) { |
| 1300 | if (!options.getBoolOption("lint", !policies.no_lint)) { |
| 1301 | return; |
| 1302 | } |
| 1303 | // note: build access flags is now called before patchAnnotations, and is no longer needed in lint |
| 1304 | // TextWriter logs; buildAccessFlags(logs); |
| 1305 | checkSideEffects(); |
| 1306 | // lint it |
| 1307 | LintVisitor lintV(this); |
| 1308 | visit(lintV); |
| 1309 | lintV.reportUnsafeTypeExpressions(); |
| 1310 | unsafe = lintV.anyUnsafe; |
| 1311 | // check for invalid options |
| 1312 | das_map<string,Type> ao; |
| 1313 | for ( const auto & opt : g_allOptions ) { |
| 1314 | auto it = ao.find(opt.name); |
| 1315 | if ( it != ao.end() ) { |
| 1316 | error("internal error: option '" + string(opt.name) + "' is already defined", |
| 1317 | "", "", LineInfo(), CompilationError::internal_options); |
| 1318 | } else { |
| 1319 | ao[opt.name] = opt.type; |
| 1320 | } |
| 1321 | } |
| 1322 | for ( const auto & opt : getCodeOfPolicyOptions() ) { |
| 1323 | auto it = ao.find(opt.first); |
| 1324 | if ( it != ao.end() ) { |
| 1325 | error("internal error: option '" + opt.first + "' is already defined", |
| 1326 | "", "", LineInfo(), CompilationError::internal_options); |
| 1327 | } else { |
| 1328 | ao[opt.first] = opt.second; |
| 1329 | } |
| 1330 | } |
| 1331 | for ( const auto & opt : options ) { |
| 1332 | Type optT = Type::none; |
| 1333 | auto it = ao.find(opt.name); |
| 1334 | if ( it != ao.end() ) { |
| 1335 | optT = it->second; |
| 1336 | } else { |
| 1337 | for ( auto & mod : libGroup.modules ) { |
| 1338 | auto ot = mod->getOptionType(opt.name); |
| 1339 | if ( ot!=Type::none ) { |
| 1340 | optT = ot; |
| 1341 | break; |
| 1342 | } |
| 1343 | } |
| 1344 | } |
| 1345 | if ( optT!=Type::none && optT!=opt.type ) { |
| 1346 | error("invalid option type for '" + opt.name |
| 1347 | + "', unexpected '" + das_to_string(opt.type) |
| 1348 | + "', expecting '" + das_to_string(optT) + "'", "", "", |
| 1349 | LineInfo(), CompilationError::invalid_options); |
| 1350 | } else if ( optT==Type::none ){ |
| 1351 | if ( opt.name[0]!='_' ) { |
| 1352 | error("invalid option '" + opt.name + "'", "", "", |
| 1353 | LineInfo(), CompilationError::invalid_options); |
| 1354 | } else { |
| 1355 | // custom user option (name starts with '_'), we don't care what's in there |
| 1356 | continue; |
no test coverage detected