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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | dart/sdk/lib/_internal/compiler/implementation/deferred_load.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/sdk/lib/_internal/compiler/implementation/compiler.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/compiler.dart b/dart/sdk/lib/_internal/compiler/implementation/compiler.dart
index 7aefe4c95d7e7c2953caddd762a17a3fe1c8ae66..a08b609bb38773ee24f1b027c123dd8621159ac7 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -456,6 +456,12 @@ abstract class Backend {
// Does this element belong in the output
bool shouldOutput(Element element) => true;
+
+ FunctionElement helperForBadMain() => null;
+
+ FunctionElement helperForMissingMain() => null;
+
+ FunctionElement helperForMainArity() => null;
}
/// Backend callbacks function specific to the resolution phase.
@@ -1284,53 +1290,75 @@ abstract class Compiler implements DiagnosticListener {
});
}
- /// Performs the compilation when all libraries have been loaded.
- void compileLoadedLibraries() {
- Element main = null;
- if (mainApp != null) {
- main = mainApp.findExported(MAIN);
- if (main == null) {
- if (!analyzeOnly) {
- // Allow analyze only of libraries with no main.
- reportFatalError(
- mainApp,
- MessageKind.GENERIC,
- {'text': "Could not find '$MAIN'."});
- } else if (!analyzeAll) {
- reportFatalError(mainApp, MessageKind.GENERIC,
- {'text': "Could not find '$MAIN'. "
- "No source will be analyzed. "
- "Use '--analyze-all' to analyze all code in the "
- "library."});
+ void computeMain() {
+ if (mainApp == null) return;
+
+ Element main = mainApp.findExported(MAIN);
+ ErroneousElement errorElement = null;
+ if (main == null) {
+ if (analyzeOnly) {
+ if (!analyzeAll) {
+ errorElement = new ErroneousElementX(
+ MessageKind.CONSIDER_ANALYZE_ALL, {'main': MAIN}, MAIN, mainApp);
}
} else {
- if (main.isErroneous && main.isSynthesized) {
- reportFatalError(main, MessageKind.GENERIC,
- {'text': "Cannot determine which '$MAIN' to use."});
- } else if (!main.isFunction) {
- reportFatalError(main, MessageKind.GENERIC,
- {'text': "'$MAIN' is not a function."});
- }
- mainFunction = main;
- FunctionSignature parameters = mainFunction.computeSignature(this);
- if (parameters.parameterCount > 2) {
- int index = 0;
- parameters.forEachParameter((Element parameter) {
- if (index++ < 2) return;
- reportError(parameter, MessageKind.GENERIC,
- {'text': "'$MAIN' cannot have more than two parameters."});
- });
- }
+ // Compilation requires a main method.
+ errorElement = new ErroneousElementX(
+ MessageKind.MISSING_MAIN, {'main': MAIN}, MAIN, mainApp);
+ }
+ mainFunction = backend.helperForMissingMain();
+ } else if (main.isErroneous && main.isSynthesized) {
+ if (main is ErroneousElement) {
+ errorElement = main;
+ } else {
+ internalError(main, 'Problem with $MAIN.');
+ }
+ mainFunction = backend.helperForBadMain();
+ } else if (!main.isFunction) {
+ errorElement = new ErroneousElementX(
+ MessageKind.MAIN_NOT_A_FUNCTION, {'main': MAIN}, MAIN, main);
+ mainFunction = backend.helperForBadMain();
+ } else {
+ mainFunction = main;
+ FunctionSignature parameters = mainFunction.computeSignature(this);
+ if (parameters.requiredParameterCount > 2) {
+ int index = 0;
+ parameters.orderedForEachParameter((Element parameter) {
+ if (index++ < 2) return;
+ errorElement = new ErroneousElementX(
+ MessageKind.MAIN_WITH_EXTRA_PARAMETER, {'main': MAIN}, MAIN,
+ parameter);
+ mainFunction = backend.helperForMainArity();
+ // Don't warn about main not being used:
+ enqueuer.resolution.registerStaticUse(main);
+ });
+ }
+ }
+ if (mainFunction == null) {
+ if (errorElement == null && !analyzeOnly && !analyzeAll) {
+ internalError(mainApp, "Problem with '$MAIN'.");
+ } else {
+ mainFunction = errorElement;
}
+ }
+ if (errorElement != null && errorElement.isSynthesized) {
+ reportWarning(
+ errorElement, errorElement.messageKind,
+ errorElement.messageArguments);
+ }
+ }
+
+ /// Performs the compilation when all libraries have been loaded.
+ void compileLoadedLibraries() {
+ computeMain();
- mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
+ mirrorUsageAnalyzerTask.analyzeUsage(mainApp);
- // In order to see if a library is deferred, we must compute the
- // compile-time constants that are metadata. This means adding
- // something to the resolution queue. So we cannot wait with
- // this until after the resolution queue is processed.
- deferredLoadTask.ensureMetadataResolved(this);
- }
+ // In order to see if a library is deferred, we must compute the
+ // compile-time constants that are metadata. This means adding
+ // something to the resolution queue. So we cannot wait with
+ // this until after the resolution queue is processed.
+ deferredLoadTask.ensureMetadataResolved(this);
phase = PHASE_RESOLVING;
if (analyzeAll) {
@@ -1346,7 +1374,7 @@ abstract class Compiler implements DiagnosticListener {
backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
resolveLibraryMetadata();
log('Resolving...');
- processQueue(enqueuer.resolution, main);
+ processQueue(enqueuer.resolution, mainFunction);
enqueuer.resolution.logSummary(log);
if (compilationFailed) return;
@@ -1374,7 +1402,7 @@ abstract class Compiler implements DiagnosticListener {
}
return;
}
- assert(main != null);
+ assert(mainFunction != null);
phase = PHASE_DONE_RESOLVING;
// TODO(ahe): Remove this line. Eventually, enqueuer.resolution
@@ -1384,13 +1412,13 @@ abstract class Compiler implements DiagnosticListener {
// require the information computed in [world.populate].)
backend.onResolutionComplete();
- deferredLoadTask.onResolutionComplete(main);
+ deferredLoadTask.onResolutionComplete(mainFunction);
log('Building IR...');
irBuilder.buildNodes();
log('Inferring types...');
- typesTask.onResolutionComplete(main);
+ typesTask.onResolutionComplete(mainFunction);
if(stopAfterTypeInference) return;
@@ -1399,7 +1427,7 @@ abstract class Compiler implements DiagnosticListener {
// TODO(johnniwinther): Move these to [CodegenEnqueuer].
if (hasIsolateSupport) {
backend.enableIsolateSupport(enqueuer.codegen);
- enqueuer.codegen.registerGetOfStaticFunction(main);
+ enqueuer.codegen.registerGetOfStaticFunction(mainFunction);
}
if (enabledNoSuchMethod) {
backend.enableNoSuchMethod(null, enqueuer.codegen);
@@ -1409,7 +1437,7 @@ abstract class Compiler implements DiagnosticListener {
fullyEnqueueLibrary(library, enqueuer.codegen);
});
}
- processQueue(enqueuer.codegen, main);
+ processQueue(enqueuer.codegen, mainFunction);
enqueuer.codegen.logSummary(log);
if (compilationFailed) return;
@@ -1460,7 +1488,7 @@ abstract class Compiler implements DiagnosticListener {
void processQueue(Enqueuer world, Element main) {
world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
- if (main != null) {
+ if (main != null && !main.isErroneous) {
FunctionElement mainMethod = main;
if (mainMethod.computeSignature(this).parameterCount != 0) {
// TODO(ngeoffray, floitsch): we should also ensure that the
« 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