Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(407)

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/compiler.dart

Issue 285903006: Fix main handling in dart2js and add tests. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update co19 status Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698