| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import '../fasta_codes.dart'; |
| import 'parser.dart'; |
| import '../../scanner/token.dart'; |
| |
| class DirectiveContext { |
| DirectiveState state = DirectiveState.Unknown; |
| |
| void checkScriptTag(Parser parser, Token token) { |
| if (state == DirectiveState.Unknown) { |
| state = DirectiveState.Script; |
| return; |
| } |
| // The scanner only produces the SCRIPT_TAG |
| // when it is the first token in the file. |
| throw "Internal error: Unexpected script tag."; |
| } |
| |
| void checkDeclaration() { |
| if (state != DirectiveState.PartOf) { |
| state = DirectiveState.Declarations; |
| } |
| } |
| |
| void checkExport(Parser parser, Token token) { |
| if (state.index <= DirectiveState.ImportAndExport.index) { |
| state = DirectiveState.ImportAndExport; |
| return; |
| } |
| // Recovery |
| if (state == DirectiveState.Part) { |
| parser.reportRecoverableError(token, messageExportAfterPart); |
| } else if (state == DirectiveState.PartOf) { |
| parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart); |
| } else { |
| parser.reportRecoverableError(token, messageDirectiveAfterDeclaration); |
| } |
| } |
| |
| void checkImport(Parser parser, Token token) { |
| if (state.index <= DirectiveState.ImportAndExport.index) { |
| state = DirectiveState.ImportAndExport; |
| return; |
| } |
| // Recovery |
| if (state == DirectiveState.Part) { |
| parser.reportRecoverableError(token, messageImportAfterPart); |
| } else if (state == DirectiveState.PartOf) { |
| parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart); |
| } else { |
| parser.reportRecoverableError(token, messageDirectiveAfterDeclaration); |
| } |
| } |
| |
| void checkLibrary(Parser parser, Token token) { |
| if (state.index < DirectiveState.Library.index) { |
| state = DirectiveState.Library; |
| return; |
| } |
| // Recovery |
| if (state == DirectiveState.Library) { |
| parser.reportRecoverableError(token, messageMultipleLibraryDirectives); |
| } else if (state == DirectiveState.PartOf) { |
| parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart); |
| } else { |
| parser.reportRecoverableError(token, messageLibraryDirectiveNotFirst); |
| } |
| } |
| |
| void checkPart(Parser parser, Token token) { |
| if (state.index <= DirectiveState.Part.index) { |
| state = DirectiveState.Part; |
| return; |
| } |
| // Recovery |
| if (state == DirectiveState.PartOf) { |
| parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart); |
| } else { |
| parser.reportRecoverableError(token, messageDirectiveAfterDeclaration); |
| } |
| } |
| |
| void checkPartOf(Parser parser, Token token) { |
| if (state == DirectiveState.Unknown) { |
| state = DirectiveState.PartOf; |
| return; |
| } |
| // Recovery |
| if (state == DirectiveState.PartOf) { |
| parser.reportRecoverableError(token, messagePartOfTwice); |
| } else { |
| parser.reportRecoverableError(token, messageNonPartOfDirectiveInPart); |
| } |
| } |
| } |
| |
| enum DirectiveState { |
| Unknown, |
| Script, |
| Library, |
| ImportAndExport, |
| Part, |
| PartOf, |
| Declarations, |
| } |