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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 return true; | 449 return true; |
450 } | 450 } |
451 | 451 |
452 /// Called after [element] has been resolved. | 452 /// Called after [element] has been resolved. |
453 // TODO(johnniwinther): Change [TreeElements] to [Registry] or a dependency | 453 // TODO(johnniwinther): Change [TreeElements] to [Registry] or a dependency |
454 // node. [elements] is currently unused by the implementation. | 454 // node. [elements] is currently unused by the implementation. |
455 void onElementResolved(Element element, TreeElements elements) {} | 455 void onElementResolved(Element element, TreeElements elements) {} |
456 | 456 |
457 // Does this element belong in the output | 457 // Does this element belong in the output |
458 bool shouldOutput(Element element) => true; | 458 bool shouldOutput(Element element) => true; |
| 459 |
| 460 FunctionElement helperForBadMain() => null; |
| 461 |
| 462 FunctionElement helperForMissingMain() => null; |
| 463 |
| 464 FunctionElement helperForMainArity() => null; |
459 } | 465 } |
460 | 466 |
461 /// Backend callbacks function specific to the resolution phase. | 467 /// Backend callbacks function specific to the resolution phase. |
462 class ResolutionCallbacks { | 468 class ResolutionCallbacks { |
463 /// Register that [node] is a call to `assert`. | 469 /// Register that [node] is a call to `assert`. |
464 void onAssert(Send node, Registry registry) {} | 470 void onAssert(Send node, Registry registry) {} |
465 | 471 |
466 /// Called during resolution to notify to the backend that the | 472 /// Called during resolution to notify to the backend that the |
467 /// program uses string interpolation. | 473 /// program uses string interpolation. |
468 void onStringInterpolation(Registry registry) {} | 474 void onStringInterpolation(Registry registry) {} |
(...skipping 808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 } | 1283 } |
1278 }).then((_) { | 1284 }).then((_) { |
1279 if (!compilationFailed) { | 1285 if (!compilationFailed) { |
1280 // TODO(johnniwinther): Reenable analysis of programs with load failures | 1286 // TODO(johnniwinther): Reenable analysis of programs with load failures |
1281 // when these are handled as erroneous libraries/compilation units. | 1287 // when these are handled as erroneous libraries/compilation units. |
1282 compileLoadedLibraries(); | 1288 compileLoadedLibraries(); |
1283 } | 1289 } |
1284 }); | 1290 }); |
1285 } | 1291 } |
1286 | 1292 |
| 1293 void computeMain() { |
| 1294 if (mainApp == null) return; |
| 1295 |
| 1296 Element main = mainApp.findExported(MAIN); |
| 1297 ErroneousElement errorElement = null; |
| 1298 if (main == null) { |
| 1299 if (analyzeOnly) { |
| 1300 if (!analyzeAll) { |
| 1301 errorElement = new ErroneousElementX( |
| 1302 MessageKind.CONSIDER_ANALYZE_ALL, {'main': MAIN}, MAIN, mainApp); |
| 1303 } |
| 1304 } else { |
| 1305 // Compilation requires a main method. |
| 1306 errorElement = new ErroneousElementX( |
| 1307 MessageKind.MISSING_MAIN, {'main': MAIN}, MAIN, mainApp); |
| 1308 } |
| 1309 mainFunction = backend.helperForMissingMain(); |
| 1310 } else if (main.isErroneous && main.isSynthesized) { |
| 1311 if (main is ErroneousElement) { |
| 1312 errorElement = main; |
| 1313 } else { |
| 1314 internalError(main, 'Problem with $MAIN.'); |
| 1315 } |
| 1316 mainFunction = backend.helperForBadMain(); |
| 1317 } else if (!main.isFunction) { |
| 1318 errorElement = new ErroneousElementX( |
| 1319 MessageKind.MAIN_NOT_A_FUNCTION, {'main': MAIN}, MAIN, main); |
| 1320 mainFunction = backend.helperForBadMain(); |
| 1321 } else { |
| 1322 mainFunction = main; |
| 1323 FunctionSignature parameters = mainFunction.computeSignature(this); |
| 1324 if (parameters.requiredParameterCount > 2) { |
| 1325 int index = 0; |
| 1326 parameters.orderedForEachParameter((Element parameter) { |
| 1327 if (index++ < 2) return; |
| 1328 errorElement = new ErroneousElementX( |
| 1329 MessageKind.MAIN_WITH_EXTRA_PARAMETER, {'main': MAIN}, MAIN, |
| 1330 parameter); |
| 1331 mainFunction = backend.helperForMainArity(); |
| 1332 // Don't warn about main not being used: |
| 1333 enqueuer.resolution.registerStaticUse(main); |
| 1334 }); |
| 1335 } |
| 1336 } |
| 1337 if (mainFunction == null) { |
| 1338 if (errorElement == null && !analyzeOnly && !analyzeAll) { |
| 1339 internalError(mainApp, "Problem with '$MAIN'."); |
| 1340 } else { |
| 1341 mainFunction = errorElement; |
| 1342 } |
| 1343 } |
| 1344 if (errorElement != null && errorElement.isSynthesized) { |
| 1345 reportWarning( |
| 1346 errorElement, errorElement.messageKind, |
| 1347 errorElement.messageArguments); |
| 1348 } |
| 1349 } |
| 1350 |
1287 /// Performs the compilation when all libraries have been loaded. | 1351 /// Performs the compilation when all libraries have been loaded. |
1288 void compileLoadedLibraries() { | 1352 void compileLoadedLibraries() { |
1289 Element main = null; | 1353 computeMain(); |
1290 if (mainApp != null) { | |
1291 main = mainApp.findExported(MAIN); | |
1292 if (main == null) { | |
1293 if (!analyzeOnly) { | |
1294 // Allow analyze only of libraries with no main. | |
1295 reportFatalError( | |
1296 mainApp, | |
1297 MessageKind.GENERIC, | |
1298 {'text': "Could not find '$MAIN'."}); | |
1299 } else if (!analyzeAll) { | |
1300 reportFatalError(mainApp, MessageKind.GENERIC, | |
1301 {'text': "Could not find '$MAIN'. " | |
1302 "No source will be analyzed. " | |
1303 "Use '--analyze-all' to analyze all code in the " | |
1304 "library."}); | |
1305 } | |
1306 } else { | |
1307 if (main.isErroneous && main.isSynthesized) { | |
1308 reportFatalError(main, MessageKind.GENERIC, | |
1309 {'text': "Cannot determine which '$MAIN' to use."}); | |
1310 } else if (!main.isFunction) { | |
1311 reportFatalError(main, MessageKind.GENERIC, | |
1312 {'text': "'$MAIN' is not a function."}); | |
1313 } | |
1314 mainFunction = main; | |
1315 FunctionSignature parameters = mainFunction.computeSignature(this); | |
1316 if (parameters.parameterCount > 2) { | |
1317 int index = 0; | |
1318 parameters.forEachParameter((Element parameter) { | |
1319 if (index++ < 2) return; | |
1320 reportError(parameter, MessageKind.GENERIC, | |
1321 {'text': "'$MAIN' cannot have more than two parameters."}); | |
1322 }); | |
1323 } | |
1324 } | |
1325 | 1354 |
1326 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); | 1355 mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
1327 | 1356 |
1328 // In order to see if a library is deferred, we must compute the | 1357 // In order to see if a library is deferred, we must compute the |
1329 // compile-time constants that are metadata. This means adding | 1358 // compile-time constants that are metadata. This means adding |
1330 // something to the resolution queue. So we cannot wait with | 1359 // something to the resolution queue. So we cannot wait with |
1331 // this until after the resolution queue is processed. | 1360 // this until after the resolution queue is processed. |
1332 deferredLoadTask.ensureMetadataResolved(this); | 1361 deferredLoadTask.ensureMetadataResolved(this); |
1333 } | |
1334 | 1362 |
1335 phase = PHASE_RESOLVING; | 1363 phase = PHASE_RESOLVING; |
1336 if (analyzeAll) { | 1364 if (analyzeAll) { |
1337 libraryLoader.libraries.forEach((LibraryElement library) { | 1365 libraryLoader.libraries.forEach((LibraryElement library) { |
1338 log('Enqueuing ${library.canonicalUri}'); | 1366 log('Enqueuing ${library.canonicalUri}'); |
1339 fullyEnqueueLibrary(library, enqueuer.resolution); | 1367 fullyEnqueueLibrary(library, enqueuer.resolution); |
1340 }); | 1368 }); |
1341 } else if (analyzeMain && mainApp != null) { | 1369 } else if (analyzeMain && mainApp != null) { |
1342 fullyEnqueueLibrary(mainApp, enqueuer.resolution); | 1370 fullyEnqueueLibrary(mainApp, enqueuer.resolution); |
1343 } | 1371 } |
1344 // Elements required by enqueueHelpers are global dependencies | 1372 // Elements required by enqueueHelpers are global dependencies |
1345 // that are not pulled in by a particular element. | 1373 // that are not pulled in by a particular element. |
1346 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); | 1374 backend.enqueueHelpers(enqueuer.resolution, globalDependencies); |
1347 resolveLibraryMetadata(); | 1375 resolveLibraryMetadata(); |
1348 log('Resolving...'); | 1376 log('Resolving...'); |
1349 processQueue(enqueuer.resolution, main); | 1377 processQueue(enqueuer.resolution, mainFunction); |
1350 enqueuer.resolution.logSummary(log); | 1378 enqueuer.resolution.logSummary(log); |
1351 | 1379 |
1352 if (compilationFailed) return; | 1380 if (compilationFailed) return; |
1353 if (!showPackageWarnings && !suppressWarnings) { | 1381 if (!showPackageWarnings && !suppressWarnings) { |
1354 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { | 1382 suppressedWarnings.forEach((Uri uri, SuppressionInfo info) { |
1355 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; | 1383 MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS; |
1356 if (info.warnings == 0) { | 1384 if (info.warnings == 0) { |
1357 kind = MessageKind.HIDDEN_HINTS; | 1385 kind = MessageKind.HIDDEN_HINTS; |
1358 } else if (info.hints == 0) { | 1386 } else if (info.hints == 0) { |
1359 kind = MessageKind.HIDDEN_WARNINGS; | 1387 kind = MessageKind.HIDDEN_WARNINGS; |
1360 } | 1388 } |
1361 reportDiagnostic(null, | 1389 reportDiagnostic(null, |
1362 kind.message({'warnings': info.warnings, | 1390 kind.message({'warnings': info.warnings, |
1363 'hints': info.hints, | 1391 'hints': info.hints, |
1364 'uri': uri}, | 1392 'uri': uri}, |
1365 terseDiagnostics), | 1393 terseDiagnostics), |
1366 api.Diagnostic.HINT); | 1394 api.Diagnostic.HINT); |
1367 }); | 1395 }); |
1368 } | 1396 } |
1369 if (analyzeOnly) { | 1397 if (analyzeOnly) { |
1370 if (!analyzeAll) { | 1398 if (!analyzeAll) { |
1371 // No point in reporting unused code when [analyzeAll] is true: all | 1399 // No point in reporting unused code when [analyzeAll] is true: all |
1372 // code is artificially used. | 1400 // code is artificially used. |
1373 reportUnusedCode(); | 1401 reportUnusedCode(); |
1374 } | 1402 } |
1375 return; | 1403 return; |
1376 } | 1404 } |
1377 assert(main != null); | 1405 assert(mainFunction != null); |
1378 phase = PHASE_DONE_RESOLVING; | 1406 phase = PHASE_DONE_RESOLVING; |
1379 | 1407 |
1380 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution | 1408 // TODO(ahe): Remove this line. Eventually, enqueuer.resolution |
1381 // should know this. | 1409 // should know this. |
1382 world.populate(); | 1410 world.populate(); |
1383 // Compute whole-program-knowledge that the backend needs. (This might | 1411 // Compute whole-program-knowledge that the backend needs. (This might |
1384 // require the information computed in [world.populate].) | 1412 // require the information computed in [world.populate].) |
1385 backend.onResolutionComplete(); | 1413 backend.onResolutionComplete(); |
1386 | 1414 |
1387 deferredLoadTask.onResolutionComplete(main); | 1415 deferredLoadTask.onResolutionComplete(mainFunction); |
1388 | 1416 |
1389 log('Building IR...'); | 1417 log('Building IR...'); |
1390 irBuilder.buildNodes(); | 1418 irBuilder.buildNodes(); |
1391 | 1419 |
1392 log('Inferring types...'); | 1420 log('Inferring types...'); |
1393 typesTask.onResolutionComplete(main); | 1421 typesTask.onResolutionComplete(mainFunction); |
1394 | 1422 |
1395 if(stopAfterTypeInference) return; | 1423 if(stopAfterTypeInference) return; |
1396 | 1424 |
1397 log('Compiling...'); | 1425 log('Compiling...'); |
1398 phase = PHASE_COMPILING; | 1426 phase = PHASE_COMPILING; |
1399 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. | 1427 // TODO(johnniwinther): Move these to [CodegenEnqueuer]. |
1400 if (hasIsolateSupport) { | 1428 if (hasIsolateSupport) { |
1401 backend.enableIsolateSupport(enqueuer.codegen); | 1429 backend.enableIsolateSupport(enqueuer.codegen); |
1402 enqueuer.codegen.registerGetOfStaticFunction(main); | 1430 enqueuer.codegen.registerGetOfStaticFunction(mainFunction); |
1403 } | 1431 } |
1404 if (enabledNoSuchMethod) { | 1432 if (enabledNoSuchMethod) { |
1405 backend.enableNoSuchMethod(null, enqueuer.codegen); | 1433 backend.enableNoSuchMethod(null, enqueuer.codegen); |
1406 } | 1434 } |
1407 if (compileAll) { | 1435 if (compileAll) { |
1408 libraryLoader.libraries.forEach((LibraryElement library) { | 1436 libraryLoader.libraries.forEach((LibraryElement library) { |
1409 fullyEnqueueLibrary(library, enqueuer.codegen); | 1437 fullyEnqueueLibrary(library, enqueuer.codegen); |
1410 }); | 1438 }); |
1411 } | 1439 } |
1412 processQueue(enqueuer.codegen, main); | 1440 processQueue(enqueuer.codegen, mainFunction); |
1413 enqueuer.codegen.logSummary(log); | 1441 enqueuer.codegen.logSummary(log); |
1414 | 1442 |
1415 if (compilationFailed) return; | 1443 if (compilationFailed) return; |
1416 | 1444 |
1417 backend.assembleProgram(); | 1445 backend.assembleProgram(); |
1418 | 1446 |
1419 if (dumpInfo) { | 1447 if (dumpInfo) { |
1420 dumpInfoTask.dumpInfo(); | 1448 dumpInfoTask.dumpInfo(); |
1421 } | 1449 } |
1422 | 1450 |
(...skipping 30 matching lines...) Expand all Loading... |
1453 if (library.metadata != null) { | 1481 if (library.metadata != null) { |
1454 for (MetadataAnnotation metadata in library.metadata) { | 1482 for (MetadataAnnotation metadata in library.metadata) { |
1455 metadata.ensureResolved(this); | 1483 metadata.ensureResolved(this); |
1456 } | 1484 } |
1457 } | 1485 } |
1458 } | 1486 } |
1459 } | 1487 } |
1460 | 1488 |
1461 void processQueue(Enqueuer world, Element main) { | 1489 void processQueue(Enqueuer world, Element main) { |
1462 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); | 1490 world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries); |
1463 if (main != null) { | 1491 if (main != null && !main.isErroneous) { |
1464 FunctionElement mainMethod = main; | 1492 FunctionElement mainMethod = main; |
1465 if (mainMethod.computeSignature(this).parameterCount != 0) { | 1493 if (mainMethod.computeSignature(this).parameterCount != 0) { |
1466 // TODO(ngeoffray, floitsch): we should also ensure that the | 1494 // TODO(ngeoffray, floitsch): we should also ensure that the |
1467 // class IsolateMessage is instantiated. Currently, just enabling | 1495 // class IsolateMessage is instantiated. Currently, just enabling |
1468 // isolate support works. | 1496 // isolate support works. |
1469 world.enableIsolateSupport(); | 1497 world.enableIsolateSupport(); |
1470 world.registerInstantiatedClass(listClass, globalDependencies); | 1498 world.registerInstantiatedClass(listClass, globalDependencies); |
1471 world.registerInstantiatedClass(stringClass, globalDependencies); | 1499 world.registerInstantiatedClass(stringClass, globalDependencies); |
1472 } | 1500 } |
1473 world.addToWorkList(main); | 1501 world.addToWorkList(main); |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2025 static NullSink outputProvider(String name, String extension) { | 2053 static NullSink outputProvider(String name, String extension) { |
2026 return new NullSink('$name.$extension'); | 2054 return new NullSink('$name.$extension'); |
2027 } | 2055 } |
2028 } | 2056 } |
2029 | 2057 |
2030 /// Information about suppressed warnings and hints for a given library. | 2058 /// Information about suppressed warnings and hints for a given library. |
2031 class SuppressionInfo { | 2059 class SuppressionInfo { |
2032 int warnings = 0; | 2060 int warnings = 0; |
2033 int hints = 0; | 2061 int hints = 0; |
2034 } | 2062 } |
OLD | NEW |