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 f01e964e510c102b25e6a3608f369ab65fb95766..95564851763141045b5239961f9ab5af35a6f8db 100644 |
--- a/dart/sdk/lib/_internal/compiler/implementation/compiler.dart |
+++ b/dart/sdk/lib/_internal/compiler/implementation/compiler.dart |
@@ -454,6 +454,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. |
@@ -1282,53 +1288,62 @@ 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); |
+ if (main == null) { |
+ if (analyzeOnly) { |
+ if (!analyzeAll) { |
+ reportWarning( |
+ mainApp, MessageKind.CONSIDER_ANALYZE_ALL, {'main': MAIN}); |
} |
} 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. |
+ reportWarning(mainApp, MessageKind.MISSING_MAIN, {'main': MAIN}); |
+ } |
+ mainFunction = backend.helperForMissingMain(); |
+ } else if (main.isErroneous && main.isSynthesized) { |
+ if (main is ErroneousElement) { |
+ reportWarning(main, main.messageKind, main.messageArguments); |
+ } else { |
+ internalError(main, 'Problem with $MAIN.'); |
} |
+ mainFunction = backend.helperForBadMain(); |
+ } else if (!main.isFunction) { |
+ reportWarning(main, MessageKind.MAIN_NOT_A_FUNCTION, {'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; |
+ reportWarning( |
+ parameter, MessageKind.MAIN_WITH_EXTRA_PARAMETER, {'main': MAIN}); |
+ mainFunction = backend.helperForMainArity(); |
+ // Don't warn about main not being used: |
+ enqueuer.resolution.registerStaticUse(main); |
+ }); |
+ } |
+ } |
+ if (mainFunction == null) { |
+ 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.
|
+ } |
+ } |
- mirrorUsageAnalyzerTask.analyzeUsage(mainApp); |
+ /// Performs the compilation when all libraries have been loaded. |
+ void compileLoadedLibraries() { |
+ computeMain(); |
- // 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); |
- } |
+ 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); |
phase = PHASE_RESOLVING; |
if (analyzeAll) { |
@@ -1344,7 +1359,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; |
@@ -1372,7 +1387,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 |
@@ -1382,13 +1397,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; |
@@ -1397,7 +1412,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(enqueuer.codegen); |
@@ -1407,7 +1422,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; |