OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of dart2js; | 5 part of dart2js; |
6 | 6 |
7 /** | 7 /** |
8 * If true, print a warning for each method that was resolved, but not | 8 * If true, print a warning for each method that was resolved, but not |
9 * compiled. | 9 * compiled. |
10 */ | 10 */ |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
447 return true; | 447 return true; |
448 } | 448 } |
449 | 449 |
450 /// Called after [element] has been resolved. | 450 /// Called after [element] has been resolved. |
451 // TODO(johnniwinther): Change [TreeElements] to [Registry] or a dependency | 451 // TODO(johnniwinther): Change [TreeElements] to [Registry] or a dependency |
452 // node. [elements] is currently unused by the implementation. | 452 // node. [elements] is currently unused by the implementation. |
453 void onElementResolved(Element element, TreeElements elements) {} | 453 void onElementResolved(Element element, TreeElements elements) {} |
454 | 454 |
455 // Does this element belong in the output | 455 // Does this element belong in the output |
456 bool shouldOutput(Element element) => true; | 456 bool shouldOutput(Element element) => true; |
457 | |
458 FunctionElement helperForBadMain() => null; | |
459 | |
460 FunctionElement helperForMissingMain() => null; | |
461 | |
462 FunctionElement helperForMainArity() => null; | |
457 } | 463 } |
458 | 464 |
459 /// Backend callbacks function specific to the resolution phase. | 465 /// Backend callbacks function specific to the resolution phase. |
460 class ResolutionCallbacks { | 466 class ResolutionCallbacks { |
461 /// Register that [node] is a call to `assert`. | 467 /// Register that [node] is a call to `assert`. |
462 void onAssert(Send node, Registry registry) {} | 468 void onAssert(Send node, Registry registry) {} |
463 | 469 |
464 /// Called during resolution to notify to the backend that the | 470 /// Called during resolution to notify to the backend that the |
465 /// program uses string interpolation. | 471 /// program uses string interpolation. |
466 void onStringInterpolation(Registry registry) {} | 472 void onStringInterpolation(Registry registry) {} |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 } | 1281 } |
1276 }).then((_) { | 1282 }).then((_) { |
1277 if (!compilationFailed) { | 1283 if (!compilationFailed) { |
1278 // TODO(johnniwinther): Reenable analysis of programs with load failures | 1284 // TODO(johnniwinther): Reenable analysis of programs with load failures |
1279 // when these are handled as erroneous libraries/compilation units. | 1285 // when these are handled as erroneous libraries/compilation units. |
1280 compileLoadedLibraries(); | 1286 compileLoadedLibraries(); |
1281 } | 1287 } |
1282 }); | 1288 }); |
1283 } | 1289 } |
1284 | 1290 |
1291 void computeMain() { | |
1292 if (mainApp == null) return; | |
1293 | |
1294 Element main = mainApp.findExported(MAIN); | |
1295 if (main == null) { | |
1296 if (analyzeOnly) { | |
1297 if (!analyzeAll) { | |
1298 reportWarning( | |
1299 mainApp, MessageKind.CONSIDER_ANALYZE_ALL, {'main': MAIN}); | |
1300 } | |
1301 } else { | |
1302 // Compilation requires a main method. | |
1303 reportWarning(mainApp, MessageKind.MISSING_MAIN, {'main': MAIN}); | |
1304 } | |
1305 mainFunction = backend.helperForMissingMain(); | |
1306 } else if (main.isErroneous && main.isSynthesized) { | |
1307 if (main is ErroneousElement) { | |
1308 reportWarning(main, main.messageKind, main.messageArguments); | |
1309 } else { | |
1310 internalError(main, 'Problem with $MAIN.'); | |
1311 } | |
1312 mainFunction = backend.helperForBadMain(); | |
1313 } else if (!main.isFunction) { | |
1314 reportWarning(main, MessageKind.MAIN_NOT_A_FUNCTION, {'main': MAIN}); | |
1315 mainFunction = backend.helperForBadMain(); | |
1316 } else { | |
1317 mainFunction = main; | |
1318 FunctionSignature parameters = mainFunction.computeSignature(this); | |
1319 if (parameters.requiredParameterCount > 2) { | |
1320 int index = 0; | |
1321 parameters.orderedForEachParameter((Element parameter) { | |
1322 if (index++ < 2) return; | |
1323 reportWarning( | |
1324 parameter, MessageKind.MAIN_WITH_EXTRA_PARAMETER, {'main': MAIN}); | |
1325 mainFunction = backend.helperForMainArity(); | |
1326 // Don't warn about main not being used: | |
1327 enqueuer.resolution.registerStaticUse(main); | |
1328 }); | |
1329 } | |
1330 } | |
1331 if (mainFunction == null) { | |
1332 internalError(mainApp, 'Unable to find method "$MAIN".'); | |
Johnni Winther
2014/07/11 13:19:26
dart2dart will result in [internalError] instead o
ahe
2014/07/11 13:24:01
Yes. I'll call reportFatalError instead. How about
Johnni Winther
2014/07/13 12:31:43
Sounds good.
| |
1333 } | |
1334 } | |
1335 | |
1285 /// Performs the compilation when all libraries have been loaded. | 1336 /// Performs the compilation when all libraries have been loaded. |
1286 void compileLoadedLibraries() { | 1337 void compileLoadedLibraries() { |
1287 Element main = null; | 1338 computeMain(); |
1288 if (mainApp != null) { | |
1289 main = mainApp.findExported(MAIN); | |
1290 if (main == null) { | |
1291 if (!analyzeOnly) { | |
1292 // Allow analyze only of libraries with no main. | |
1293 reportFatalError( | |
1294 mainApp, | |
1295 MessageKind.GENERIC, | |
1296 {'text': "Could not find '$MAIN'."}); | |
1297 } else if (!analyzeAll) { | |
1298 reportFatalError(mainApp, MessageKind.GENERIC, | |
1299 {'text': "Could not find '$MAIN'. " | |
1300 "No source will be analyzed. " | |
1301 "Use '--analyze-all' to analyze all code in the " | |
1302 "library."}); | |
1303 } | |
1304 } else { | |
1305 if (main.isErroneous && main.isSynthesized) { | |
1306 reportFatalError(main, MessageKind.GENERIC, | |
1307 {'text': "Cannot determine which '$MAIN' to use."}); | |
1308 } else if (!main.isFunction) { | |
1309 reportFatalError(main, MessageKind.GENERIC, | |
1310 {'text': "'$MAIN' is not a function."}); | |
1311 } | |
1312 mainFunction = main; | |
1313 FunctionSignature parameters = mainFunction.computeSignature(this); | |
1314 if (parameters.parameterCount > 2) { | |
1315 int index = 0; | |
1316 parameters.forEachParameter((Element parameter) { | |
1317 if (index++ < 2) return; | |
1318 reportError(parameter, MessageKind.GENERIC, | |
1319 {'text': "'$MAIN' cannot have more than two parameters."}); | |
1320 }); | |
1321 } | |
1322 } | |
1323 | 1339 |
1324 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 1340 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
1325 | 1341 |
1326 // In order to see if a library is deferred, we must compute the | 1342 // In order to see if a library is deferred, we must compute the |
1327 // compile-time constants that are metadata. This means adding | 1343 // compile-time constants that are metadata. This means adding |
1328 // something to the resolution queue. So we cannot wait with | 1344 // something to the resolution queue. So we cannot wait with |
1329 // this until after the resolution queue is processed. | 1345 // this until after the resolution queue is processed. |
1330 deferredLoadTask.ensureMetadataResolved(this); | 1346 deferredLoadTask.ensureMetadataResolved(this); |
1331 } | |
1332 | 1347 |
1333 phase = PHASE_RESOLVING; | 1348 phase = PHASE_RESOLVING; |
1334 if (analyzeAll) { | 1349 if (analyzeAll) { |
1335 libraryLoader.libraries.forEach((LibraryElement library) { | 1350 libraryLoader.libraries.forEach((LibraryElement library) { |
1336 log('Enqueuing ${library.canonicalUri}'); | 1351 log('Enqueuing ${library.canonicalUri}'); |
1337 fullyEnqueueLibrary(library, enqueuer.resolution); | 1352 fullyEnqueueLibrary(library, enqueuer.resolution); |
1338 }); | 1353 }); |
1339 } else if (analyzeMain && mainApp != null) { | 1354 } else if (analyzeMain && mainApp != null) { |
1340 fullyEnqueueLibrary(mainApp, enqueuer.resolution); | 1355 fullyEnqueueLibrary(mainApp, enqueuer.resolution); |
1341 } | 1356 } |
1342 // Elements required by enqueueHelpers are global dependencies | 1357 // Elements required by enqueueHelpers are global dependencies |
1343 // that are not pulled in by a particular element. | 1358 // that are not pulled in by a particular element. |
1344 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | 1359 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); |
1345 resolveLibraryMetadata(); | 1360 resolveLibraryMetadata(); |
1346 log('Resolving...'); | 1361 log('Resolving...'); |
1347 processQueue(enqueuer.resolution, main); | 1362 processQueue(enqueuer.resolution, mainFunction); |
1348 enqueuer.resolution.logSummary(log); | 1363 enqueuer.resolution.logSummary(log); |
1349 | 1364 |
1350 if (compilationFailed) return; | 1365 if (compilationFailed) return; |
1351 if (!showPackageWarnings && !suppressWarnings) { | 1366 if (!showPackageWarnings && !suppressWarnings) { |
1352 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { | 1367 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { |
1353 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; | 1368 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; |
1354 if (info.warnings == 0) { | 1369 if (info.warnings == 0) { |
1355 kind = MessageKind.HIDDEN_HINTS; | 1370 kind = MessageKind.HIDDEN_HINTS; |
1356 } else if (info.hints == 0) { | 1371 } else if (info.hints == 0) { |
1357 kind = MessageKind.HIDDEN_WARNINGS; | 1372 kind = MessageKind.HIDDEN_WARNINGS; |
1358 } | 1373 } |
1359 reportDiagnostic(null, | 1374 reportDiagnostic(null, |
1360 kind.message({'warnings': info.warnings, | 1375 kind.message({'warnings': info.warnings, |
1361 'hints': info.hints, | 1376 'hints': info.hints, |
1362 'uri': uri}, | 1377 'uri': uri}, |
1363 terseDiagnostics), | 1378 terseDiagnostics), |
1364 api.Diagnostic.HINT); | 1379 api.Diagnostic.HINT); |
1365 }); | 1380 }); |
1366 } | 1381 } |
1367 if (analyzeOnly) { | 1382 if (analyzeOnly) { |
1368 if (!analyzeAll) { | 1383 if (!analyzeAll) { |
1369 // No point in reporting unused code when [analyzeAll] is true: all | 1384 // No point in reporting unused code when [analyzeAll] is true: all |
1370 // code is artificially used. | 1385 // code is artificially used. |
1371 reportUnusedCode(); | 1386 reportUnusedCode(); |
1372 } | 1387 } |
1373 return; | 1388 return; |
1374 } | 1389 } |
1375 assert(main != null); | 1390 assert(mainFunction != null); |
1376 phase = PHASE_DONE_RESOLVING; | 1391 phase = PHASE_DONE_RESOLVING; |
1377 | 1392 |
1378 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 1393 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
1379 // should know this. | 1394 // should know this. |
1380 world.populate(); | 1395 world.populate(); |
1381 // Compute whole-program-knowledge that the backend needs. (This might | 1396 // Compute whole-program-knowledge that the backend needs. (This might |
1382 // require the information computed in [world.populate].) | 1397 // require the information computed in [world.populate].) |
1383 backend.onResolutionComplete(); | 1398 backend.onResolutionComplete(); |
1384 | 1399 |
1385 deferredLoadTask.onResolutionComplete(main); | 1400 deferredLoadTask.onResolutionComplete(mainFunction); |
1386 | 1401 |
1387 log('Building IR...'); | 1402 log('Building IR...'); |
1388 irBuilder.buildNodes(); | 1403 irBuilder.buildNodes(); |
1389 | 1404 |
1390 log('Inferring types...'); | 1405 log('Inferring types...'); |
1391 typesTask.onResolutionComplete(main); | 1406 typesTask.onResolutionComplete(mainFunction); |
1392 | 1407 |
1393 if(stopAfterTypeInference) return; | 1408 if(stopAfterTypeInference) return; |
1394 | 1409 |
1395 log('Compiling...'); | 1410 log('Compiling...'); |
1396 phase = PHASE_COMPILING; | 1411 phase = PHASE_COMPILING; |
1397 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. | 1412 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. |
1398 if (hasIsolateSupport) { | 1413 if (hasIsolateSupport) { |
1399 backend.enableIsolateSupport(enqueuer.codegen); | 1414 backend.enableIsolateSupport(enqueuer.codegen); |
1400 enqueuer.codegen.registerGetOfStaticFunction(main); | 1415 enqueuer.codegen.registerGetOfStaticFunction(mainFunction); |
1401 } | 1416 } |
1402 if (enabledNoSuchMethod) { | 1417 if (enabledNoSuchMethod) { |
1403 backend.enableNoSuchMethod(enqueuer.codegen); | 1418 backend.enableNoSuchMethod(enqueuer.codegen); |
1404 } | 1419 } |
1405 if (compileAll) { | 1420 if (compileAll) { |
1406 libraryLoader.libraries.forEach((LibraryElement library) { | 1421 libraryLoader.libraries.forEach((LibraryElement library) { |
1407 fullyEnqueueLibrary(library, enqueuer.codegen); | 1422 fullyEnqueueLibrary(library, enqueuer.codegen); |
1408 }); | 1423 }); |
1409 } | 1424 } |
1410 processQueue(enqueuer.codegen, main); | 1425 processQueue(enqueuer.codegen, mainFunction); |
1411 enqueuer.codegen.logSummary(log); | 1426 enqueuer.codegen.logSummary(log); |
1412 | 1427 |
1413 if (compilationFailed) return; | 1428 if (compilationFailed) return; |
1414 | 1429 |
1415 backend.assembleProgram(); | 1430 backend.assembleProgram(); |
1416 | 1431 |
1417 if (dumpInfo) { | 1432 if (dumpInfo) { |
1418 dumpInfoTask.dumpInfo(); | 1433 dumpInfoTask.dumpInfo(); |
1419 } | 1434 } |
1420 | 1435 |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2023 static NullSink outputProvider(String name, String extension) { | 2038 static NullSink outputProvider(String name, String extension) { |
2024 return new NullSink('$name.$extension'); | 2039 return new NullSink('$name.$extension'); |
2025 } | 2040 } |
2026 } | 2041 } |
2027 | 2042 |
2028 /// Information about suppressed warnings and hints for a given library. | 2043 /// Information about suppressed warnings and hints for a given library. |
2029 class SuppressionInfo { | 2044 class SuppressionInfo { |
2030 int warnings = 0; | 2045 int warnings = 0; |
2031 int hints = 0; | 2046 int hints = 0; |
2032 } | 2047 } |
OLD | NEW |