| 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 | 
|---|