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

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: Merged with r38186. 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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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 }
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