diff --git a/ets2panda/ir/base/property.cpp b/ets2panda/ir/base/property.cpp index 531954ca21084242c387790f7cfda39607dacd2e..6f5387e9dba5f2aad5b22c44690262318261fe8b 100644 --- a/ets2panda/ir/base/property.cpp +++ b/ets2panda/ir/base/property.cpp @@ -83,39 +83,6 @@ bool Property::ConvertibleToPatternProperty() return true; } -ValidationInfo Property::ValidateExpression() -{ - ValidationInfo info; - - if (!IsComputed() && !IsMethod() && !IsAccessor() && !IsShorthand()) { - bool currentIsProto = false; - - if (key_->IsIdentifier()) { - currentIsProto = key_->AsIdentifier()->Name().Is("__proto__"); - } else if (key_->IsStringLiteral()) { - currentIsProto = key_->AsStringLiteral()->Str().Is("__proto__"); - } - - if (currentIsProto) { - kind_ = PropertyKind::PROTO; - } - } - - if (value_ != nullptr) { - if (value_->IsAssignmentPattern()) { - return {"Invalid shorthand property initializer.", value_->Start()}; - } - - if (value_->IsObjectExpression()) { - info = value_->AsObjectExpression()->ValidateExpression(); - } else if (value_->IsArrayExpression()) { - info = value_->AsArrayExpression()->ValidateExpression(); - } - } - - return info; -} - void Property::TransformChildren(const NodeTransformer &cb, std::string_view transformationName) { if (auto *transformedNode = cb(key_); key_ != transformedNode) { diff --git a/ets2panda/ir/base/property.h b/ets2panda/ir/base/property.h index d71a9f13f4cef1d3b6a9898081379f998eab83a7..9053360af5bf94713691b9a30b3d617a01495fc1 100644 --- a/ets2panda/ir/base/property.h +++ b/ets2panda/ir/base/property.h @@ -1,5 +1,5 @@ /** - * Copyright (c) 2021-2024 Huawei Device Co., Ltd. + * Copyright (c) 2021-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -77,6 +77,11 @@ public: return kind_; } + void SetKind(PropertyKind kind) noexcept + { + kind_ = kind; + } + [[nodiscard]] bool IsMethod() const noexcept { return isMethod_; @@ -105,7 +110,6 @@ public: [[nodiscard]] Property *Clone(ArenaAllocator *allocator, AstNode *parent) override; bool ConvertibleToPatternProperty(); - ValidationInfo ValidateExpression(); void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; void Iterate(const NodeTraverser &cb) const override; diff --git a/ets2panda/ir/base/spreadElement.cpp b/ets2panda/ir/base/spreadElement.cpp index 9b504315154444509a9647ceb807d7c9d9109def..63e63714beb7cf4af9c117d9bb2075d86fa801b8 100644 --- a/ets2panda/ir/base/spreadElement.cpp +++ b/ets2panda/ir/base/spreadElement.cpp @@ -39,27 +39,6 @@ SpreadElement *SpreadElement::Clone(ArenaAllocator *const allocator, AstNode *co return clone; } -ValidationInfo SpreadElement::ValidateExpression() -{ - ValidationInfo info; - - switch (argument_->Type()) { - case AstNodeType::OBJECT_EXPRESSION: { - info = argument_->AsObjectExpression()->ValidateExpression(); - break; - } - case AstNodeType::ARRAY_EXPRESSION: { - info = argument_->AsArrayExpression()->ValidateExpression(); - break; - } - default: { - break; - } - } - - return info; -} - bool SpreadElement::ConvertibleToRest(bool isDeclaration, bool allowPattern) { bool convResult = true; diff --git a/ets2panda/ir/base/spreadElement.h b/ets2panda/ir/base/spreadElement.h index b3aff66d62505eabf0a7c8f48656427ec5232cfc..af378de974e264552105e51c6ca058eb5cd0219e 100644 --- a/ets2panda/ir/base/spreadElement.h +++ b/ets2panda/ir/base/spreadElement.h @@ -62,7 +62,6 @@ public: [[nodiscard]] SpreadElement *Clone(ArenaAllocator *allocator, AstNode *parent) override; - ValidationInfo ValidateExpression(); [[nodiscard]] bool ConvertibleToRest(bool isDeclaration, bool allowPattern = true); void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; diff --git a/ets2panda/ir/expressions/arrayExpression.cpp b/ets2panda/ir/expressions/arrayExpression.cpp index b74e9c4d71a55b9a9f7974a728e5d1c04f6d2abd..baa2a6f67fbab1cc94f823dbaef856971a5aad18 100644 --- a/ets2panda/ir/expressions/arrayExpression.cpp +++ b/ets2panda/ir/expressions/arrayExpression.cpp @@ -101,56 +101,6 @@ bool ArrayExpression::ConvertibleToArrayPattern() return convResult; } -ValidationInfo ArrayExpression::ValidateExpression() -{ - if (optional_) { - return {"Unexpected token '?'.", Start()}; - } - - if (TypeAnnotation() != nullptr) { - return {"Unexpected token.", TypeAnnotation()->Start()}; - } - - ValidationInfo info; - - for (auto *it : elements_) { - switch (it->Type()) { - case AstNodeType::OBJECT_EXPRESSION: { - info = it->AsObjectExpression()->ValidateExpression(); - break; - } - case AstNodeType::ARRAY_EXPRESSION: { - info = it->AsArrayExpression()->ValidateExpression(); - break; - } - case AstNodeType::ASSIGNMENT_EXPRESSION: { - auto *assignmentExpr = it->AsAssignmentExpression(); - - if (assignmentExpr->Left()->IsArrayExpression()) { - info = assignmentExpr->Left()->AsArrayExpression()->ValidateExpression(); - } else if (assignmentExpr->Left()->IsObjectExpression()) { - info = assignmentExpr->Left()->AsObjectExpression()->ValidateExpression(); - } - - break; - } - case AstNodeType::SPREAD_ELEMENT: { - info = it->AsSpreadElement()->ValidateExpression(); - break; - } - default: { - break; - } - } - - if (info.Fail()) { - break; - } - } - - return info; -} - void ArrayExpression::TransformChildren(const NodeTransformer &cb, std::string_view const transformationName) { for (auto *&it : VectorIterationGuard(elements_)) { diff --git a/ets2panda/ir/expressions/arrayExpression.h b/ets2panda/ir/expressions/arrayExpression.h index a903b77f01ddf79a192f467fbad35fef1cae8a1a..794d9319ef4f712971aa5ec37e7ec5bd1f57403d 100644 --- a/ets2panda/ir/expressions/arrayExpression.h +++ b/ets2panda/ir/expressions/arrayExpression.h @@ -108,7 +108,6 @@ public: [[nodiscard]] ArrayExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] bool ConvertibleToArrayPattern(); - [[nodiscard]] ValidationInfo ValidateExpression(); void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; diff --git a/ets2panda/ir/expressions/identifier.cpp b/ets2panda/ir/expressions/identifier.cpp index 050fd78b378553fa2a3a49ef2c12fb4a4d7d29ee..ed06caddb8ca356a2deabfbc3df80ac0e2d53a26 100644 --- a/ets2panda/ir/expressions/identifier.cpp +++ b/ets2panda/ir/expressions/identifier.cpp @@ -101,20 +101,6 @@ void Identifier::Iterate(const NodeTraverser &cb) const } } -ValidationInfo Identifier::ValidateExpression() -{ - if ((IdFlags() & IdentifierFlags::OPTIONAL) != 0U) { - return {"Unexpected token '?'.", Start()}; - } - - if (TypeAnnotation() != nullptr) { - return {"Unexpected token.", TypeAnnotation()->Start()}; - } - - ValidationInfo info; - return info; -} - void Identifier::Dump(ir::AstDumper *dumper) const { dumper->Add({{"type", IsPrivateIdent() ? "PrivateIdentifier" : "Identifier"}, diff --git a/ets2panda/ir/expressions/identifier.h b/ets2panda/ir/expressions/identifier.h index fd0db4eb01439684e38d4b10ea3198be2c095f4c..bb455f333bc16ddb7b0d64473f5578072563e004 100644 --- a/ets2panda/ir/expressions/identifier.h +++ b/ets2panda/ir/expressions/identifier.h @@ -184,8 +184,6 @@ public: [[nodiscard]] Identifier *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] Identifier *CloneReference(ArenaAllocator *allocator, AstNode *parent); - [[nodiscard]] ValidationInfo ValidateExpression(); - void TransformChildren(const NodeTransformer &cb, std::string_view transformationName) override; void Iterate(const NodeTraverser &cb) const override; void Dump(ir::AstDumper *dumper) const override; @@ -217,12 +215,12 @@ public: AnnotatedExpression::CopyTo(other); }; -private: IdentifierFlags IdFlags() const { return GetHistoryNodeAs()->flags_; } +private: void AddIdFlags(IdentifierFlags const flags) noexcept { if (!All(IdFlags(), flags)) { diff --git a/ets2panda/ir/expressions/objectExpression.cpp b/ets2panda/ir/expressions/objectExpression.cpp index 36bc52d2fffd16d886d8fed240cafe2d8e6163e8..9165f2cd3b80d33b41a0b23935808f72ae41a13f 100644 --- a/ets2panda/ir/expressions/objectExpression.cpp +++ b/ets2panda/ir/expressions/objectExpression.cpp @@ -45,65 +45,6 @@ ObjectExpression *ObjectExpression::Clone(ArenaAllocator *const allocator, AstNo return clone; } -static std::pair ValidateProperty(Property *prop, bool &foundProto) -{ - ValidationInfo info = prop->ValidateExpression(); - if (prop->Kind() == PropertyKind::PROTO) { - if (foundProto) { - return {{"Duplicate __proto__ fields are not allowed in object literals", prop->Key()->Start()}, true}; - } - - foundProto = true; - } - - return {info, false}; -} - -ValidationInfo ObjectExpression::ValidateExpression() -{ - if (optional_) { - return {"Unexpected token '?'.", Start()}; - } - - if (TypeAnnotation() != nullptr) { - return {"Unexpected token.", TypeAnnotation()->Start()}; - } - - ValidationInfo info; - bool foundProto = false; - - for (auto *it : properties_) { - switch (it->Type()) { - case AstNodeType::OBJECT_EXPRESSION: - case AstNodeType::ARRAY_EXPRESSION: { - return {"Unexpected token.", it->Start()}; - } - case AstNodeType::SPREAD_ELEMENT: { - info = it->AsSpreadElement()->ValidateExpression(); - break; - } - case AstNodeType::PROPERTY: { - auto *prop = it->AsProperty(); - bool ret = false; - std::tie(info, ret) = ValidateProperty(prop, foundProto); - if (ret) { - return info; - } - break; - } - default: { - break; - } - } - - if (info.Fail()) { - break; - } - } - - return info; -} - bool ObjectExpression::ConvertibleToObjectPattern() { // NOTE: rsipka. throw more precise messages in case of false results diff --git a/ets2panda/ir/expressions/objectExpression.h b/ets2panda/ir/expressions/objectExpression.h index df66bbdcc9481c43c132d87072d9df6cc13ea129..d0d4c09fb7bf6cb795b8f656f0db5291e0c04369 100644 --- a/ets2panda/ir/expressions/objectExpression.h +++ b/ets2panda/ir/expressions/objectExpression.h @@ -65,7 +65,6 @@ public: [[nodiscard]] ObjectExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; - [[nodiscard]] ValidationInfo ValidateExpression(); [[nodiscard]] bool ConvertibleToObjectPattern(); void SetDeclaration(); void SetOptional(bool optional); diff --git a/ets2panda/parser/expressionParser.cpp b/ets2panda/parser/expressionParser.cpp index 6d111ce34ace4c3348ba058e12bf2ad0e88774d0..03c210529e271968ca0ac676fa82f0c2418373a1 100644 --- a/ets2panda/parser/expressionParser.cpp +++ b/ets2panda/parser/expressionParser.cpp @@ -80,6 +80,188 @@ #include "parserImpl.h" namespace ark::es2panda::parser { + +static ir::ValidationInfo ValidateExpression(ir::ArrayExpression *arrExpr); +static ir::ValidationInfo ValidateExpression(ir::ObjectExpression *objExpr); +static ir::ValidationInfo ValidateExpression(ir::SpreadElement *spreadElement); + +static ir::ValidationInfo ValidateExpression(ir::Identifier *ident) +{ + if ((ident->IdFlags() & ir::IdentifierFlags::OPTIONAL) != 0U) { + return {diagnostic::UNEXPECTED_QUESTIONMARK.Message(), ident->Start()}; + } + + if (ident->TypeAnnotation() != nullptr) { + return {diagnostic::UNEXPECTED_TOKEN.Message(), ident->TypeAnnotation()->Start()}; + } + + ir::ValidationInfo info; + return info; +} + +static ir::ValidationInfo ValidateExpression(ir::Property *prop) +{ + ir::ValidationInfo info; + + if (!prop->IsComputed() && !prop->IsMethod() && !prop->IsAccessor() && !prop->IsShorthand()) { + bool currentIsProto = false; + + if (prop->Key()->IsIdentifier()) { + currentIsProto = prop->Key()->AsIdentifier()->Name().Is("__proto__"); + } else if (prop->Key()->IsStringLiteral()) { + currentIsProto = prop->Key()->AsStringLiteral()->Str().Is("__proto__"); + } + + if (currentIsProto) { + prop->SetKind(ir::PropertyKind::PROTO); + } + } + + if (prop->Value() != nullptr) { + if (prop->Value()->IsAssignmentPattern()) { + return {diagnostic::INVALID_SHORTHAND_PROPERTY_INITIALIZER.Message(), prop->Value()->Start()}; + } + + if (prop->Value()->IsObjectExpression()) { + info = ValidateExpression(prop->Value()->AsObjectExpression()); + } else if (prop->Value()->IsArrayExpression()) { + info = ValidateExpression(prop->Value()->AsArrayExpression()); + } + } + + return info; +} + +static std::pair ValidateProperty(ir::Property *prop, bool &foundProto) +{ + ir::ValidationInfo info = ValidateExpression(prop); + if (prop->Kind() == ir::PropertyKind::PROTO) { + if (foundProto) { + return {{diagnostic::DUPLICATE_PROTO_FIELDS.Message(), prop->Key()->Start()}, true}; + } + + foundProto = true; + } + + return {info, false}; +} + +static ir::ValidationInfo ValidateExpression(ir::ObjectExpression *objExpr) +{ + if (objExpr->IsOptional()) { + return {"Unexpected token '?'.", objExpr->Start()}; + } + + if (objExpr->TypeAnnotation() != nullptr) { + return {"Unexpected token.", objExpr->TypeAnnotation()->Start()}; + } + + ir::ValidationInfo info; + bool foundProto = false; + + for (auto *it : objExpr->Properties()) { + switch (it->Type()) { + case ir::AstNodeType::OBJECT_EXPRESSION: + case ir::AstNodeType::ARRAY_EXPRESSION: { + return {diagnostic::UNEXPECTED_TOKEN.Message(), it->Start()}; + } + case ir::AstNodeType::SPREAD_ELEMENT: { + info = ValidateExpression(it->AsSpreadElement()); + break; + } + case ir::AstNodeType::PROPERTY: { + auto *prop = it->AsProperty(); + bool ret = false; + std::tie(info, ret) = ValidateProperty(prop, foundProto); + if (ret) { + return info; + } + break; + } + default: { + break; + } + } + + if (info.Fail()) { + break; + } + } + + return info; +} + +static ir::ValidationInfo ValidateExpression(ir::SpreadElement *spreadElement) +{ + ir::ValidationInfo info; + + switch (spreadElement->Argument()->Type()) { + case ir::AstNodeType::OBJECT_EXPRESSION: { + info = ValidateExpression(spreadElement->Argument()->AsObjectExpression()); + break; + } + case ir::AstNodeType::ARRAY_EXPRESSION: { + info = ValidateExpression(spreadElement->Argument()->AsArrayExpression()); + break; + } + default: { + break; + } + } + + return info; +} + +static ir::ValidationInfo ValidateExpression(ir::ArrayExpression *arrExpr) +{ + if (arrExpr->IsOptional()) { + return {"Unexpected token '?'.", arrExpr->Start()}; + } + + if (arrExpr->TypeAnnotation() != nullptr) { + return {diagnostic::UNEXPECTED_TOKEN.Message(), arrExpr->TypeAnnotation()->Start()}; + } + + ir::ValidationInfo info; + + for (auto *it : arrExpr->Elements()) { + switch (it->Type()) { + case ir::AstNodeType::OBJECT_EXPRESSION: { + info = ValidateExpression(it->AsObjectExpression()); + break; + } + case ir::AstNodeType::ARRAY_EXPRESSION: { + info = ValidateExpression(it->AsArrayExpression()); + break; + } + case ir::AstNodeType::ASSIGNMENT_EXPRESSION: { + auto *assignmentExpr = it->AsAssignmentExpression(); + + if (assignmentExpr->Left()->IsArrayExpression()) { + info = ValidateExpression(assignmentExpr->Left()->AsArrayExpression()); + } else if (assignmentExpr->Left()->IsObjectExpression()) { + info = ValidateExpression(assignmentExpr->Left()->AsObjectExpression()); + } + + break; + } + case ir::AstNodeType::SPREAD_ELEMENT: { + info = ValidateExpression(it->AsSpreadElement()); + break; + } + default: { + break; + } + } + + if (info.Fail()) { + break; + } + } + + return info; +} + ir::YieldExpression *ParserImpl::ParseYieldExpression() { ES2PANDA_ASSERT(lexer_->GetToken().Type() == lexer::TokenType::KEYW_YIELD); @@ -233,7 +415,7 @@ void ParserImpl::ParseArrayExpressionErrorCheck(ir::ArrayExpression *arrayExpres !arrayExpressionNode->ConvertibleToArrayPattern()) { LogError(diagnostic::INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING, {}, arrayExpressionNode->Start()); } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { - ir::ValidationInfo info = arrayExpressionNode->ValidateExpression(); + ir::ValidationInfo info = ValidateExpression(arrayExpressionNode); if (info.Fail()) { LogSyntaxError(info.msg.Utf8(), info.pos); } @@ -507,7 +689,7 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) { switch (lhsExpression->Type()) { case ir::AstNodeType::IDENTIFIER: { - auto info = lhsExpression->AsIdentifier()->ValidateExpression(); + auto info = ValidateExpression(lhsExpression->AsIdentifier()); if (info.Fail()) { LogSyntaxError(info.msg.Utf8(), info.pos); } @@ -517,14 +699,14 @@ void ParserImpl::ValidateParenthesizedExpression(ir::Expression *lhsExpression) break; } case ir::AstNodeType::ARRAY_EXPRESSION: { - auto info = lhsExpression->AsArrayExpression()->ValidateExpression(); + auto info = ValidateExpression(lhsExpression->AsArrayExpression()); if (info.Fail()) { LogSyntaxError(info.msg.Utf8(), info.pos); } break; } case ir::AstNodeType::OBJECT_EXPRESSION: { - auto info = lhsExpression->AsObjectExpression()->ValidateExpression(); + auto info = ValidateExpression(lhsExpression->AsObjectExpression()); if (info.Fail()) { LogSyntaxError(info.msg.Utf8(), info.pos); } @@ -2275,7 +2457,7 @@ ir::ObjectExpression *ParserImpl::ParseObjectExpression(ExpressionParseFlags fla !objectExpression->ConvertibleToObjectPattern()) { LogError(diagnostic::INVALID_LEFT_SIDE_ARRAY_DESTRUCTURING, {}, objectExpression->Start()); } else if (!inPattern && lexer_->GetToken().Type() != lexer::TokenType::PUNCTUATOR_SUBSTITUTION) { - ir::ValidationInfo info = objectExpression->ValidateExpression(); + ir::ValidationInfo info = ValidateExpression(objectExpression); if (info.Fail()) { LogSyntaxError(info.msg.Utf8(), info.pos); } @@ -2461,4 +2643,5 @@ ir::FunctionExpression *ParserImpl::ParseFunctionExpression(ParserStatus newStat return funcExpr; } + } // namespace ark::es2panda::parser diff --git a/ets2panda/util/diagnostic/syntax.yaml b/ets2panda/util/diagnostic/syntax.yaml index 2401da7d0e2450558426cb7d33c1c12f4a8a8e92..22a267c7cdacec32961696969f93031d9f5a4111 100644 --- a/ets2panda/util/diagnostic/syntax.yaml +++ b/ets2panda/util/diagnostic/syntax.yaml @@ -209,6 +209,10 @@ syntax: id: 82 message: "Duplicate group name." +- name: DUPLICATE_PROTO_FIELDS + id: 119997 + message: "Duplicate __proto__ fields are not allowed in object literals" + - name: ENUM_INVALID_INIT id: 36 message: "Invalid enum initialization value" @@ -235,8 +239,8 @@ syntax: - name: ERROR_ARKTS_NO_FOR_IN_LOOP id: 6987 - message: "'for ... in' loop is not supported, please use regular 'for' or 'for ... of ...' loop to iterate through arrays\ - \ and iterable objects." + message: "'for ... in' loop is not supported, please use regular 'for' or 'for ... of ...' loop to iterate through arrays + and iterable objects." - name: ERROR_ARKTS_NO_IMPORT_ASSERTIONS id: 313 @@ -269,8 +273,8 @@ syntax: - name: ERROR_ARKTS_NO_SIDE_EFFECT_IMPORT id: 73297 - message: "Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import\ - \ all objects declared in the module!" + message: "Importing for side-effect only is prohibited! Please provide objects to be imported explicitly or use * to import + all objects declared in the module!" - name: ERROR_ARKTS_NO_UMD id: 114179 @@ -479,8 +483,8 @@ syntax: - name: IMPORT_TOP_LEVEL id: 226 - message: "Import declarations can only be used on the top level and before any other declaration, top level statement or\ - \ directive." + message: "Import declarations can only be used on the top level and before any other declaration, top level statement or + directive." - name: IMPROPER_NESTING_CLASS id: 233 @@ -516,8 +520,8 @@ syntax: - name: INIT_MODULE_DECLARATION_POSITION id: 322 - message: "initModule() must only be called immediately after the import statement, and before any other declarations or\ - \ statements." + message: "initModule() must only be called immediately after the import statement, and before any other declarations or + statements." - name: INSERT_NODE_ABSENT id: 10 @@ -601,8 +605,8 @@ syntax: - name: INVALID_DECORATOR_CONSTRUCTOR id: 201 - message: "The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and\ - \ 'native' modifiers." + message: "The modifier for a constructor should be limited to access modifiers (private, internal, protected, public), and + 'native' modifiers." - name: INVALID_DESTRUCTURING_TARGET id: 49 @@ -732,6 +736,10 @@ syntax: id: 130 message: "Invalid right-hand side in 'instanceof' expression." +- name: INVALID_SHORTHAND_PROPERTY_INITIALIZER + id: 18822 + message: "Invalid shorthand property initializer." + - name: INVALID_TYPE id: 138 message: "Invalid Type." @@ -770,8 +778,8 @@ syntax: - name: LITERAL_VALUE_IDENT id: 315 - message: "Number, string or computed value property name '{}' is not allowed, use classes to access data by property names\ - \ that are identifiers" + message: "Number, string or computed value property name '{}' is not allowed, use classes to access data by property names + that are identifiers" - name: LOCAL_CLASS_ACCESS_MOD id: 30 @@ -1173,6 +1181,10 @@ syntax: id: 47 message: "Unexpected private identifier." +- name: UNEXPECTED_QUESTIONMARK + id: 172384 + message: "Unexpected token '?'." + - name: UNEXPECTED_STRICT_MODE_RESERVED_KEYWORD id: 264 message: "Unexpected strict mode reserved keyword." @@ -1256,8 +1268,8 @@ syntax: - name: UNSUPPORTED_ENUM_TYPE id: 327 - message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal\ - \ types, not annotations." + message: "Unsupported enum type annotation. Supported enum types are: int, long or double. String is allowed for literal + types, not annotations." - name: UNTERMINATED_MULTI_LINE_COMMENT id: 245