| // Copyright (c) 2016, 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 'package:analyzer/dart/ast/token.dart' show Token; |
| import 'package:analyzer/error/error.dart'; |
| import 'package:analyzer/error/listener.dart'; |
| import 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
| import 'package:analyzer/src/error/codes.dart'; |
| import 'package:front_end/src/fasta/messages.dart' show Code, Message; |
| |
| /// An error reporter that knows how to convert a Fasta error into an analyzer |
| /// error. |
| class FastaErrorReporter { |
| /// The underlying error reporter to which errors are reported. |
| final ErrorReporter errorReporter; |
| |
| /// Initialize a newly created error reporter to report errors to the given |
| /// [errorReporter]. |
| FastaErrorReporter(this.errorReporter); |
| |
| void reportByCode( |
| String analyzerCode, int offset, int length, Message message) { |
| Map<String, dynamic> arguments = message.arguments; |
| |
| String lexeme() => (arguments['token'] as Token).lexeme; |
| |
| switch (analyzerCode) { |
| case "ANNOTATION_WITH_TYPE_ARGUMENTS": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, |
| offset, |
| length); |
| return; |
| case "ASYNC_FOR_IN_WRONG_CONTEXT": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT, offset, length); |
| return; |
| case "ASYNC_KEYWORD_USED_AS_IDENTIFIER": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, offset, length); |
| return; |
| case "AWAIT_IN_WRONG_CONTEXT": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, offset, length); |
| return; |
| case "BUILT_IN_IDENTIFIER_AS_TYPE": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, |
| offset, |
| length, |
| [lexeme()]); |
| return; |
| case "CONCRETE_CLASS_WITH_ABSTRACT_MEMBER": |
| errorReporter?.reportErrorForOffset( |
| StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, |
| offset, |
| length); |
| return; |
| case "CONST_CONSTRUCTOR_WITH_BODY": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, offset, length); |
| return; |
| case "CONST_NOT_INITIALIZED": |
| String name = arguments['name']; |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.CONST_NOT_INITIALIZED, offset, length, [name]); |
| return; |
| case "DEFAULT_VALUE_IN_FUNCTION_TYPE": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE, offset, length); |
| return; |
| case "LABEL_UNDEFINED": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.LABEL_UNDEFINED, |
| offset, |
| length, |
| [arguments['name']]); |
| return; |
| case "EMPTY_ENUM_BODY": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.EMPTY_ENUM_BODY, offset, length); |
| return; |
| case "EXPECTED_CLASS_MEMBER": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.EXPECTED_CLASS_MEMBER, offset, length); |
| return; |
| case "EXPECTED_EXECUTABLE": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.EXPECTED_EXECUTABLE, offset, length); |
| return; |
| case "EXPECTED_STRING_LITERAL": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.EXPECTED_STRING_LITERAL, offset, length); |
| return; |
| case "EXPECTED_TOKEN": |
| errorReporter?.reportErrorForOffset(ParserErrorCode.EXPECTED_TOKEN, |
| offset, length, [arguments['string']]); |
| return; |
| case "EXPECTED_TYPE_NAME": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.EXPECTED_TYPE_NAME, offset, length); |
| return; |
| case "FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, |
| offset, |
| length); |
| return; |
| case "FINAL_NOT_INITIALIZED": |
| String name = arguments['name']; |
| errorReporter?.reportErrorForOffset( |
| StaticWarningCode.FINAL_NOT_INITIALIZED, offset, length, [name]); |
| return; |
| case "FINAL_NOT_INITIALIZED_CONSTRUCTOR_1": |
| String name = arguments['name']; |
| errorReporter?.reportErrorForOffset( |
| StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1, |
| offset, |
| length, |
| [name]); |
| return; |
| case "FUNCTION_TYPED_PARAMETER_VAR": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, offset, length); |
| return; |
| case "GETTER_WITH_PARAMETERS": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.GETTER_WITH_PARAMETERS, offset, length); |
| return; |
| case "ILLEGAL_CHARACTER": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.ILLEGAL_CHARACTER, offset, length); |
| return; |
| case "INVALID_ASSIGNMENT": |
| var type1 = arguments['type']; |
| var type2 = arguments['type2']; |
| errorReporter?.reportErrorForOffset( |
| StaticTypeWarningCode.INVALID_ASSIGNMENT, |
| offset, |
| length, |
| [type1, type2]); |
| return; |
| case "INVALID_INLINE_FUNCTION_TYPE": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, offset, length); |
| return; |
| case "INVALID_LITERAL_IN_CONFIGURATION": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, offset, length); |
| return; |
| case "IMPORT_OF_NON_LIBRARY": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, offset, length); |
| return; |
| case "INVALID_CAST_FUNCTION": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_FUNCTION, offset, length); |
| return; |
| case "INVALID_CAST_FUNCTION_EXPR": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_FUNCTION_EXPR, offset, length); |
| return; |
| case "INVALID_CAST_LITERAL_LIST": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_LITERAL_LIST, offset, length); |
| return; |
| case "INVALID_CAST_LITERAL_MAP": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_LITERAL_MAP, offset, length); |
| return; |
| case "INVALID_CAST_METHOD": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_METHOD, offset, length); |
| return; |
| case "INVALID_CAST_NEW_EXPR": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_CAST_NEW_EXPR, offset, length); |
| return; |
| case "INVALID_CODE_POINT": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.INVALID_CODE_POINT, offset, length, ['\\u{...}']); |
| return; |
| case "INVALID_CONSTRUCTOR_NAME": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, offset, length); |
| return; |
| case "INVALID_GENERIC_FUNCTION_TYPE": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE, offset, length); |
| return; |
| case "INVALID_METHOD_OVERRIDE": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.INVALID_OVERRIDE, offset, length); |
| return; |
| case "INVALID_MODIFIER_ON_SETTER": |
| _reportByCode(CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, message, |
| offset, length); |
| return; |
| case "INVALID_OPERATOR_FOR_SUPER": |
| _reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message, |
| offset, length); |
| return; |
| case "INVALID_SUPER_INVOCATION": |
| errorReporter?.reportErrorForOffset( |
| StrongModeCode.INVALID_SUPER_INVOCATION, offset, length); |
| return; |
| case "MISSING_CLASS_BODY": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_CLASS_BODY, offset, length); |
| return; |
| case "MISSING_DIGIT": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.MISSING_DIGIT, offset, length); |
| return; |
| case "MISSING_ENUM_BODY": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_ENUM_BODY, offset, length); |
| return; |
| case "MISSING_FUNCTION_BODY": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_FUNCTION_BODY, offset, length); |
| return; |
| case "MISSING_FUNCTION_PARAMETERS": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_FUNCTION_PARAMETERS, offset, length); |
| return; |
| case "MISSING_HEX_DIGIT": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.MISSING_HEX_DIGIT, offset, length); |
| return; |
| case "MISSING_IDENTIFIER": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_IDENTIFIER, offset, length); |
| return; |
| case "MISSING_METHOD_PARAMETERS": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_METHOD_PARAMETERS, offset, length); |
| return; |
| case "MISSING_STAR_AFTER_SYNC": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_STAR_AFTER_SYNC, offset, length); |
| return; |
| case "MISSING_TYPEDEF_PARAMETERS": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, offset, length); |
| return; |
| case "MULTIPLE_IMPLEMENTS_CLAUSES": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, offset, length); |
| return; |
| case "NAMED_FUNCTION_EXPRESSION": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.NAMED_FUNCTION_EXPRESSION, offset, length); |
| return; |
| case "NAMED_PARAMETER_OUTSIDE_GROUP": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP, offset, length); |
| return; |
| case "NON_PART_OF_DIRECTIVE_IN_PART": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART, offset, length); |
| return; |
| case "NON_SYNC_FACTORY": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.NON_SYNC_FACTORY, offset, length); |
| return; |
| case "POSITIONAL_AFTER_NAMED_ARGUMENT": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, offset, length); |
| return; |
| case "RECURSIVE_CONSTRUCTOR_REDIRECT": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, |
| offset, |
| length); |
| return; |
| case "RETURN_IN_GENERATOR": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.RETURN_IN_GENERATOR, offset, length, |
| // TODO(danrubel): Update the parser to report the modifier |
| // involved in this error... either async* or sync* |
| ['async*']); |
| return; |
| case "SUPER_IN_REDIRECTING_CONSTRUCTOR": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, |
| offset, |
| length); |
| return; |
| case "TYPE_PARAMETER_ON_CONSTRUCTOR": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.TYPE_PARAMETER_ON_CONSTRUCTOR, offset, length); |
| return; |
| case "UNDEFINED_CLASS": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.UNDEFINED_CLASS, offset, length); |
| return; |
| case "UNDEFINED_GETTER": |
| errorReporter?.reportErrorForOffset( |
| StaticTypeWarningCode.UNDEFINED_GETTER, offset, length); |
| return; |
| case "UNDEFINED_METHOD": |
| errorReporter?.reportErrorForOffset( |
| StaticTypeWarningCode.UNDEFINED_METHOD, offset, length); |
| return; |
| case "UNDEFINED_SETTER": |
| errorReporter?.reportErrorForOffset( |
| StaticTypeWarningCode.UNDEFINED_SETTER, offset, length); |
| return; |
| case "UNEXPECTED_DOLLAR_IN_STRING": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.UNEXPECTED_DOLLAR_IN_STRING, offset, length); |
| return; |
| case "UNEXPECTED_TOKEN": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.UNEXPECTED_TOKEN, offset, length, [lexeme()]); |
| return; |
| case "UNTERMINATED_MULTI_LINE_COMMENT": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT, offset, length); |
| return; |
| case "UNTERMINATED_STRING_LITERAL": |
| errorReporter?.reportErrorForOffset( |
| ScannerErrorCode.UNTERMINATED_STRING_LITERAL, offset, length); |
| return; |
| case "WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, |
| offset, |
| length); |
| return; |
| case "WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR": |
| errorReporter?.reportErrorMessage( |
| StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, |
| offset, |
| length, |
| message); |
| return; |
| case "WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER": |
| errorReporter?.reportErrorForOffset( |
| ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER, |
| offset, |
| length); |
| return; |
| case "YIELD_IN_NON_GENERATOR": |
| errorReporter?.reportErrorForOffset( |
| CompileTimeErrorCode.YIELD_IN_NON_GENERATOR, offset, length); |
| return; |
| default: |
| // fall through |
| } |
| } |
| |
| /// Report an error based on the given [message] whose range is described by |
| /// the given [offset] and [length]. |
| void reportMessage(Message message, int offset, int length) { |
| Code code = message.code; |
| int index = code.index; |
| if (index != null && index > 0 && index < fastaAnalyzerErrorCodes.length) { |
| ErrorCode errorCode = fastaAnalyzerErrorCodes[index]; |
| if (errorCode != null) { |
| errorReporter.reportError(new AnalysisError.forValues( |
| errorReporter.source, |
| offset, |
| length, |
| errorCode, |
| message.message, |
| message.tip)); |
| return; |
| } |
| } |
| reportByCode(code.analyzerCodes?.first, offset, length, message); |
| } |
| |
| void reportScannerError( |
| ScannerErrorCode errorCode, int offset, List<Object> arguments) { |
| // TODO(danrubel): update client to pass length in addition to offset. |
| int length = 1; |
| errorReporter?.reportErrorForOffset(errorCode, offset, length, arguments); |
| } |
| |
| void _reportByCode( |
| ErrorCode errorCode, Message message, int offset, int length) { |
| if (errorReporter != null) { |
| errorReporter.reportError(new AnalysisError.forValues( |
| errorReporter.source, |
| offset, |
| length, |
| errorCode, |
| message.message, |
| null)); |
| } |
| } |
| } |