Chromium Code Reviews| 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; |