diff --git a/ets2panda/BUILD.gn b/ets2panda/BUILD.gn index 0d43eb4ed387aaac1f98abf875ea65f1da89003d..a7c7cb0b19173c774f2db5a61872f3c567c45690 100644 --- a/ets2panda/BUILD.gn +++ b/ets2panda/BUILD.gn @@ -80,6 +80,7 @@ libes2panda_sources = [ "checker/types/ets/etsNonNullishType.cpp", "checker/types/ets/etsNullishTypes.cpp", "checker/types/ets/etsObjectType.cpp", + "checker/types/ets/etsReadonlyType.cpp", "checker/types/ets/etsStringType.cpp", "checker/types/ets/etsTupleType.cpp", "checker/types/ets/etsTypeParameter.cpp", diff --git a/ets2panda/CMakeLists.txt b/ets2panda/CMakeLists.txt index 75a4d072141fb55428bc1f70caa6b382e18bbdb1..31f4913bcc536f39ea34a36694d427a9c0ca1201 100644 --- a/ets2panda/CMakeLists.txt +++ b/ets2panda/CMakeLists.txt @@ -415,6 +415,7 @@ set(ES2PANDA_LIB_SRC checker/types/ets/etsExtensionFuncHelperType.cpp checker/types/ets/etsFunctionType.cpp checker/types/ets/etsNonNullishType.cpp + checker/types/ets/etsReadonlyType.cpp checker/types/ets/etsNullishTypes.cpp checker/types/ets/etsObjectType.cpp checker/types/ets/etsStringType.cpp diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index eafdbcdf4cf30871cc9e9e63e56e6e1713e028df..2a5994383ecaa5f20bdafdf176aee17f77213f7b 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -800,7 +800,7 @@ checker::Type *ETSAnalyzer::Check(ir::AssignmentExpression *const expr) const checker->ThrowTypeError("Invalid left-hand side of assignment expression", expr->Left()->Start()); } - if (expr->target_ != nullptr) { + if (expr->target_ != nullptr && !expr->IsIgnoreConstAssign()) { checker->ValidateUnaryOperatorOperand(expr->target_); } @@ -1074,6 +1074,12 @@ checker::Type *ETSAnalyzer::Check(ir::CallExpression *expr) const calleeType = checker->GetApparentType(expr->Callee()->Check(checker)); } checker->CheckNonNullish(expr->Callee()); + if (expr->Callee()->IsMemberExpression() && expr->Callee()->AsMemberExpression()->Object() != nullptr && + expr->Callee()->AsMemberExpression()->Object()->TsType()->IsETSObjectType() && + expr->Callee()->AsMemberExpression()->Object()->TsType()->AsETSObjectType()->HasObjectFlag( + ETSObjectFlags::READONLY)) { + checker->ThrowTypeError("Cannot call readonly type methods.", expr->Start()); + } checker::Type *returnType; if (calleeType->IsETSDynamicType() && !calleeType->AsETSDynamicType()->HasDecl()) { // Trailing lambda for js function call is not supported, check the correctness of `foo() {}` @@ -1385,9 +1391,6 @@ void ETSAnalyzer::CheckObjectExprProps(const ir::ObjectExpression *expr) const checker->ThrowTypeError({"type ", objType->Name(), " has no property named ", pname}, propExpr->Start()); } checker->ValidatePropertyAccess(lv, objType, propExpr->Start()); - if (lv->HasFlag(varbinder::VariableFlags::READONLY)) { - checker->ThrowTypeError({"cannot assign to readonly property ", pname}, propExpr->Start()); - } if (key->IsIdentifier()) { key->AsIdentifier()->SetVariable(lv); diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 4ac4fb8b9f6aefc1e1a8301251268b5633396531..d4983e4d28b42385b8a8366a68efde1e8e97e178 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -320,6 +320,8 @@ public: static void EmplaceSubstituted(Substitution *substitution, ETSTypeParameter *tparam, Type *typeArg); [[nodiscard]] bool EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution); + [[nodiscard]] bool EnhanceSubstitutionForReadonly(const ArenaVector &typeParams, ETSReadonlyType *paramType, + Type *argumentType, Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForObject(const ArenaVector &typeParams, ETSObjectType *paramType, Type *argumentType, Substitution *substitution); [[nodiscard]] bool EnhanceSubstitutionForUnion(const ArenaVector &typeParams, ETSUnionType *paramUn, @@ -481,7 +483,10 @@ public: Type *GetTypeFromClassReference(varbinder::Variable *var); void ValidateGenericTypeAliasForClonedNode(ir::TSTypeAliasDeclaration *typeAliasNode, const ir::TSTypeParameterInstantiation *exactTypeParams); + void MakePropertiesReadonly(ETSObjectType *classType); + Type *HandleReadonlyType(const ir::TSTypeParameterInstantiation *typeParams); Type *HandleTypeAlias(ir::Expression *name, const ir::TSTypeParameterInstantiation *typeParams); + Type *GetReadonlyType(Type *type); Type *GetTypeFromEnumReference(varbinder::Variable *var); Type *GetTypeFromTypeParameterReference(varbinder::LocalVariable *var, const lexer::SourcePosition &pos); Type *GetNonConstantTypeFromPrimitiveType(Type *type) const; diff --git a/ets2panda/checker/checker.h b/ets2panda/checker/checker.h index e3865173c69aec37399cd0767b7b5054edca2bc5..e8657b63c19196f2634b377c3c2ded285baf6cae 100644 --- a/ets2panda/checker/checker.h +++ b/ets2panda/checker/checker.h @@ -135,6 +135,11 @@ public: return typeStack_; } + [[nodiscard]] std::unordered_set &NamedTypeStack() noexcept + { + return namedTypeStack_; + } + [[nodiscard]] virtual bool IsETSChecker() const noexcept { return false; @@ -185,6 +190,7 @@ public: friend class ScopeContext; friend class TypeStackElement; friend class SavedCheckerContext; + friend class NamedTypeStackElement; varbinder::VarBinder *VarBinder() const; @@ -210,6 +216,26 @@ private: RelationHolder supertypeResults_ {{}, RelationType::SUPERTYPE}; std::unordered_set typeStack_; + std::unordered_set namedTypeStack_; +}; + +class NamedTypeStackElement { +public: + explicit NamedTypeStackElement(Checker *checker, Type *element) : checker_(checker), element_(element) + { + checker_->namedTypeStack_.insert(element); + } + + ~NamedTypeStackElement() + { + checker_->namedTypeStack_.erase(element_); + } + NO_COPY_SEMANTIC(NamedTypeStackElement); + NO_MOVE_SEMANTIC(NamedTypeStackElement); + +private: + Checker *checker_; + Type *element_; }; class TypeStackElement { diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index b1029acf50b586a77c58a3960401632c2ca89fd0..97b09c48aed834c28d4e8c5347da653015980970 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -143,6 +143,13 @@ bool ETSChecker::EnhanceSubstitutionForGenericType(const ArenaVector &ty return res; } +bool ETSChecker::EnhanceSubstitutionForReadonly(const ArenaVector &typeParams, ETSReadonlyType *paramType, + Type *argumentType, Substitution *substitution) +{ + return EnhanceSubstitutionForType(typeParams, paramType->GetUnderlying(), GetReadonlyType(argumentType), + substitution); +} + /* A very rough and imprecise partial type inference */ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParams, Type *paramType, Type *argumentType, Substitution *substitution) @@ -168,6 +175,9 @@ bool ETSChecker::EnhanceSubstitutionForType(const ArenaVector &typeParam } } + if (paramType->IsETSReadonlyType()) { + return EnhanceSubstitutionForReadonly(typeParams, paramType->AsETSReadonlyType(), argumentType, substitution); + } if (paramType->IsETSUnionType()) { return EnhanceSubstitutionForUnion(typeParams, paramType->AsETSUnionType(), argumentType, substitution); } diff --git a/ets2panda/checker/ets/helpers.cpp b/ets2panda/checker/ets/helpers.cpp index 25d286a6ad6ea92715513dc0765cd680c47ba5f0..bec37cf1163fce8d8830f78bdfd1100a84d06206 100644 --- a/ets2panda/checker/ets/helpers.cpp +++ b/ets2panda/checker/ets/helpers.cpp @@ -18,6 +18,7 @@ #include "parser/ETSparser.h" #include "checker/types/ets/etsTupleType.h" +#include "checker/types/ets/etsReadonlyType.h" #include "checker/ets/typeRelationContext.h" #include "checker/ETSchecker.h" #include "checker/types/globalTypesHolder.h" @@ -565,13 +566,11 @@ void ETSChecker::InferAliasLambdaType(ir::TypeNode *localTypeAnnotation, ir::Arr if (localTypeAnnotation->IsETSTypeReference()) { bool isAnnotationTypeAlias = true; while (localTypeAnnotation->IsETSTypeReference() && isAnnotationTypeAlias) { - auto *node = localTypeAnnotation->AsETSTypeReference() - ->Part() - ->Name() - ->AsIdentifier() - ->Variable() - ->Declaration() - ->Node(); + auto *nodeVar = localTypeAnnotation->AsETSTypeReference()->Part()->Name()->AsIdentifier()->Variable(); + if (nodeVar == nullptr) { + break; + } + auto *node = nodeVar->Declaration()->Node(); isAnnotationTypeAlias = node->IsTSTypeAliasDeclaration(); if (isAnnotationTypeAlias) { @@ -615,6 +614,8 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T checker::Type *annotationType = nullptr; const bool isConst = (flags & ir::ModifierFlags::CONST) != 0; + const bool isReadonly = (flags & ir::ModifierFlags::READONLY) != 0; + const bool isStatic = (flags & ir::ModifierFlags::STATIC) != 0; if (typeAnnotation != nullptr) { annotationType = typeAnnotation->GetType(this); @@ -689,7 +690,9 @@ checker::Type *ETSChecker::CheckVariableDeclaration(ir::Identifier *ident, ir::T const Type *sourceType = TryGettingFunctionTypeFromInvokeFunction(initType); AssignmentContext(Relation(), init, initType, annotationType, init->Start(), {"Type '", sourceType, "' cannot be assigned to type '", targetType, "'"}); - if (isConst && initType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE) && + // Note(lujiahui): It should be checked if the readonly function parameter and readonly number[] parameters + // are assigned with CONSTANT, which would not be correct. (After feature supported) + if (isConst && (!isReadonly || isStatic) && initType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE) && annotationType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { bindingVar->SetTsType(init->TsType()); } @@ -1047,6 +1050,55 @@ void ETSChecker::SetArrayPreferredTypeForNestedMemberExpressions(ir::MemberExpre } } +void ETSChecker::MakePropertiesReadonly(ETSObjectType *const classType) +{ + classType->UpdateTypeProperties(this, [this](auto *property, auto *propType) { + auto *newDecl = Allocator()->New(property->Name(), property->Declaration()->Node()); + auto *const propCopy = property->Copy(Allocator(), newDecl); + propCopy->AddFlag(varbinder::VariableFlags::READONLY); + propCopy->SetTsType(propType); + return propCopy; + }); +} + +Type *ETSChecker::GetReadonlyType(Type *type) +{ + if (type->IsETSObjectType()) { + type->AsETSObjectType()->InstanceFields(); + auto *clonedType = type->Clone(this)->AsETSObjectType(); + MakePropertiesReadonly(clonedType); + return clonedType; + } + if (type->IsETSTypeParameter()) { + return Allocator()->New(type->AsETSTypeParameter()); + } + if (type->IsETSUnionType()) { + ArenaVector unionTypes(Allocator()->Adapter()); + for (auto *t : type->AsETSUnionType()->ConstituentTypes()) { + unionTypes.emplace_back(t->IsETSObjectType() ? GetReadonlyType(t) : t->Clone(this)); + } + return CreateETSUnionType(std::move(unionTypes)); + } + return type; +} + +Type *ETSChecker::HandleReadonlyType(const ir::TSTypeParameterInstantiation *const typeParams) +{ + if (typeParams->Params().size() != 1) { + ThrowTypeError("Invalid number of type parameters for Readonly type", typeParams->Start()); + } + + auto *const typeParamNode = typeParams->Params()[0]; + auto *typeToBeReadonly = typeParamNode->Check(this); + + if (auto found = NamedTypeStack().find(typeToBeReadonly); found != NamedTypeStack().end()) { + return *found; + } + + NamedTypeStackElement ntse(this, typeToBeReadonly); + return GetReadonlyType(typeToBeReadonly); +} + static void CheckExpandedType(Type *expandedAliasType, std::set ¶metersNeedToBeBoxed, bool needToBeBoxed) { @@ -1099,6 +1151,10 @@ Type *ETSChecker::HandleTypeAlias(ir::Expression *const name, const ir::TSTypePa ThrowTypeError("Type alias declaration is not generic, but type parameters were provided", typeParams->Start()); } + if (name->AsIdentifier()->Name().Is(compiler::Signatures::READONLY_TYPE_NAME)) { + return HandleReadonlyType(typeParams); + } + if (typeParams == nullptr) { // SUPPRESS_CSA_NEXTLINE(alpha.core.AllocatorETSCheckerHint) return GetReferencedTypeBase(name); diff --git a/ets2panda/checker/types/ets/etsObjectType.cpp b/ets2panda/checker/types/ets/etsObjectType.cpp index 5181b1de18f8ea8a7463439327e2de335715cb9b..53d9e1f9981c54f8d84af9ea332ae5f30ca92558 100644 --- a/ets2panda/checker/types/ets/etsObjectType.cpp +++ b/ets2panda/checker/types/ets/etsObjectType.cpp @@ -343,7 +343,7 @@ void ETSObjectType::ToString(std::stringstream &ss, bool precise) const void ETSObjectType::IdenticalUptoTypeArguments(TypeRelation *relation, Type *other) { relation->Result(false); - if (!other->IsETSObjectType() || !CheckIdenticalFlags(other->AsETSObjectType()->ObjectFlags())) { + if (!other->IsETSObjectType() || !CheckIdenticalFlags(other->AsETSObjectType())) { return; } @@ -391,13 +391,17 @@ void ETSObjectType::Identical(TypeRelation *relation, Type *other) relation->Result(true); } -bool ETSObjectType::CheckIdenticalFlags(const ETSObjectFlags target) const +bool ETSObjectType::CheckIdenticalFlags(ETSObjectType *other) const { constexpr auto FLAGS_TO_REMOVE = ETSObjectFlags::INCOMPLETE_INSTANTIATION | ETSObjectFlags::CHECKED_COMPATIBLE_ABSTRACTS | - ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY; - - auto cleanedTargetFlags = target; + ETSObjectFlags::CHECKED_INVOKE_LEGITIMACY | ETSObjectFlags::READONLY; + // note(lujiahui): we support assigning T to Readonly, but do not support assigning Readonly to T + // more details in spec + if (!HasObjectFlag(ETSObjectFlags::READONLY) && other->HasObjectFlag(ETSObjectFlags::READONLY)) { + return false; + } + auto cleanedTargetFlags = other->ObjectFlags(); cleanedTargetFlags &= ~FLAGS_TO_REMOVE; auto cleanedSelfFlags = ObjectFlags(); @@ -413,6 +417,11 @@ bool ETSObjectType::AssignmentSource(TypeRelation *const relation, [[maybe_unuse void ETSObjectType::AssignmentTarget(TypeRelation *const relation, Type *source) { + if (source->IsETSObjectType() && source->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::READONLY)) { + relation->Result(false); + return; + } + if (HasObjectFlag(ETSObjectFlags::FUNCTIONAL)) { EnsurePropertiesInstantiated(); auto found = properties_[static_cast(PropertyType::INSTANCE_METHOD)].find( @@ -820,6 +829,44 @@ void ETSObjectType::SetCopiedTypeProperties(TypeRelation *const relation, ETSObj copiedType->substitution_ = substitution; } +void ETSObjectType::UpdateTypeProperty(checker::ETSChecker *checker, varbinder::LocalVariable *const prop, + PropertyType fieldType, PropertyProcesser const &func) +{ + auto *const propType = prop->Declaration()->Node()->Check(checker); + + if (propType->HasTypeFlag(TypeFlag::ETS_PRIMITIVE)) { + checker->ThrowTypeError("Base type of a Utility type can only contain fields with reference type.", + prop->Declaration()->Node()->Start()); + } + + auto *const propCopy = func(prop, propType); + if (fieldType == PropertyType::INSTANCE_FIELD) { + RemoveProperty(prop); + AddProperty(propCopy); + } else { + RemoveProperty(prop); + AddProperty(propCopy); + } +} + +void ETSObjectType::UpdateTypeProperties(checker::ETSChecker *checker, PropertyProcesser const &func) +{ + AddObjectFlag(ETSObjectFlags::READONLY); + for (auto const &prop : InstanceFields()) { + UpdateTypeProperty(checker, prop.second, PropertyType::INSTANCE_FIELD, func); + } + + for (auto const &prop : StaticFields()) { + UpdateTypeProperty(checker, prop.second, PropertyType::STATIC_FIELD, func); + } + + if (SuperType() != nullptr) { + auto *const superProp = SuperType()->Clone(checker)->AsETSObjectType(); + superProp->UpdateTypeProperties(checker, func); + SetSuperType(superProp); + } +} + ETSObjectType *ETSObjectType::Substitute(TypeRelation *relation, const Substitution *substitution, bool cache) { if (substitution == nullptr || substitution->empty()) { diff --git a/ets2panda/checker/types/ets/etsObjectType.h b/ets2panda/checker/types/ets/etsObjectType.h index d379eac35ce0a5c2434a97bd5cb47baa488dfdd8..f8829756dd2c09cfb3c7dd7718911f64f622294d 100644 --- a/ets2panda/checker/types/ets/etsObjectType.h +++ b/ets2panda/checker/types/ets/etsObjectType.h @@ -25,6 +25,7 @@ #include "ir/base/classDefinition.h" namespace ark::es2panda::checker { +using PropertyProcesser = std::function; class ETSObjectType : public Type { public: using PropertyMap = ArenaUnorderedMap; @@ -360,7 +361,7 @@ public: PropertySearchFlags flags) const; varbinder::LocalVariable *CollectSignaturesForSyntheticType(ETSFunctionType *funcType, const util::StringView &name, PropertySearchFlags flags) const; - bool CheckIdenticalFlags(ETSObjectFlags target) const; + bool CheckIdenticalFlags(ETSObjectType *other) const; bool CheckIdenticalVariable(varbinder::Variable *otherVar) const; void Iterate(const PropertyTraverser &cb) const; @@ -372,6 +373,7 @@ public: bool SubstituteTypeArgs(TypeRelation *relation, ArenaVector &newTypeArgs, const Substitution *substitution); void SetCopiedTypeProperties(TypeRelation *relation, ETSObjectType *copiedType, ArenaVector &newTypeArgs, const Substitution *substitution); + void UpdateTypeProperties(checker::ETSChecker *checker, PropertyProcesser const &func); ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution) override; ETSObjectType *Substitute(TypeRelation *relation, const Substitution *substitution, bool cache); void Cast(TypeRelation *relation, Type *target) override; @@ -445,6 +447,8 @@ private: TypeFlag narrowingFlags); void IdenticalUptoTypeArguments(TypeRelation *relation, Type *other); void IsGenericSupertypeOf(TypeRelation *relation, Type *source); + void UpdateTypeProperty(checker::ETSChecker *checker, varbinder::LocalVariable *const prop, PropertyType fieldType, + PropertyProcesser const &func); ir::TSTypeParameterDeclaration *GetTypeParams() const { diff --git a/ets2panda/checker/types/ets/etsObjectTypeConstants.h b/ets2panda/checker/types/ets/etsObjectTypeConstants.h index 5ed3004a25ccee72ad70750457097b0384327d8c..5b5879dc762306c7ea1ee81766fb1f8134cd66b4 100644 --- a/ets2panda/checker/types/ets/etsObjectTypeConstants.h +++ b/ets2panda/checker/types/ets/etsObjectTypeConstants.h @@ -39,6 +39,7 @@ enum class ETSObjectFlags : std::uint32_t { DYNAMIC = 1U << 14U, ASYNC_FUNC_RETURN_TYPE = 1U << 15U, CHECKED_INVOKE_LEGITIMACY = 1U << 16U, + READONLY = 1U << 18U, BUILTIN_BIGINT = 1U << 22U, BUILTIN_STRING = 1U << 23U, diff --git a/ets2panda/checker/types/ets/etsReadonlyType.cpp b/ets2panda/checker/types/ets/etsReadonlyType.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36019da541bd8b047309bdf2c4934a077ffc9e26 --- /dev/null +++ b/ets2panda/checker/types/ets/etsReadonlyType.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "etsTypeParameter.h" +#include "etsNullishTypes.h" +#include "etsReadonlyType.h" +#include "ir/expressions/identifier.h" +#include "ir/ts/tsTypeParameter.h" +#include "checker/ETSchecker.h" +#include "checker/ets/conversion.h" + +namespace ark::es2panda::checker { + +void ETSReadonlyType::ToString(std::stringstream &ss, bool precise) const +{ + ss << "Readonly<"; + GetUnderlying()->ToString(ss, precise); + ss << ">"; +} + +void ETSReadonlyType::Identical(TypeRelation *relation, Type *other) +{ + relation->Result(false); + if (other->IsETSReadonlyType()) { + relation->IsIdenticalTo(GetUnderlying(), other->AsETSReadonlyType()->GetUnderlying()); + } +} + +bool ETSReadonlyType::AssignmentSource([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) +{ + return relation->Result(false); +} + +void ETSReadonlyType::AssignmentTarget([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) +{ + if (source->IsETSTypeParameter() && source->AsETSTypeParameter()->GetOriginal() == GetUnderlying()) { + relation->Result(true); + return; + } + relation->Result(false); +} + +void ETSReadonlyType::Cast(TypeRelation *relation, [[maybe_unused]] Type *target) +{ + if (relation->IsSupertypeOf(target, this)) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + return; + } + if (target->IsETSObjectType() && target->AsETSObjectType()->HasObjectFlag(ETSObjectFlags::READONLY)) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + } + relation->Result(relation->InCastingContext()); +} + +void ETSReadonlyType::CastTarget(TypeRelation *relation, [[maybe_unused]] Type *source) +{ + this->AssignmentTarget(relation, source); + if (relation->IsTrue()) { + relation->RemoveFlags(TypeRelationFlag::UNCHECKED_CAST); + return; + } + + relation->Result(relation->InCastingContext()); +} + +void ETSReadonlyType::IsSupertypeOf([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *source) +{ + relation->Result(false); +} + +void ETSReadonlyType::IsSubtypeOf([[maybe_unused]] TypeRelation *relation, [[maybe_unused]] Type *target) +{ + if (relation->IsSupertypeOf(target, GetUnderlying())) { + return; + } + + relation->Result(false); +} + +Type *ETSReadonlyType::Substitute([[maybe_unused]] TypeRelation *relation, const Substitution *substitution) +{ + auto *substituted = GetUnderlying()->Substitute(relation, substitution); + if (substituted == GetUnderlying()) { + return this; + } + return relation->GetChecker()->AsETSChecker()->GetReadonlyType(substituted); +} + +void ETSReadonlyType::ToAssemblerType(std::stringstream &ss) const +{ + GetUnderlying()->ToAssemblerTypeWithRank(ss); +} + +void ETSReadonlyType::ToDebugInfoType(std::stringstream &ss) const +{ + GetUnderlying()->ToDebugInfoType(ss); +} + +Type *ETSReadonlyType::Instantiate([[maybe_unused]] ArenaAllocator *allocator, [[maybe_unused]] TypeRelation *relation, + [[maybe_unused]] GlobalTypesHolder *globalTypes) +{ + return allocator->New(GetUnderlying()); +} + +} // namespace ark::es2panda::checker diff --git a/ets2panda/checker/types/ets/etsReadonlyType.h b/ets2panda/checker/types/ets/etsReadonlyType.h new file mode 100644 index 0000000000000000000000000000000000000000..a4b2a2abb759ec4237ebf3ec92413f8e4776ff6e --- /dev/null +++ b/ets2panda/checker/types/ets/etsReadonlyType.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ES2PANDA_COMPILER_CHECKER_TYPES_ETS_READONLY_TYPE_H +#define ES2PANDA_COMPILER_CHECKER_TYPES_ETS_READONLY_TYPE_H + +#include "checker/types/type.h" +#include "ir/astNode.h" + +namespace ark::es2panda::checker { + +// The type of Readonly(the type of T is ETSTypeParameter) is ETSReadonlyType +class ETSReadonlyType : public Type { +public: + explicit ETSReadonlyType(ETSTypeParameter *tparam) : Type(TypeFlag::ETS_READONLY), tparam_(tparam) {} + + ETSTypeParameter *GetUnderlying() const + { + return tparam_; + } + + void Identical(TypeRelation *relation, Type *other) override; + void AssignmentTarget(TypeRelation *relation, Type *source) override; + bool AssignmentSource(TypeRelation *relation, Type *target) override; + void Cast(TypeRelation *relation, Type *target) override; + void CastTarget(TypeRelation *relation, Type *source) override; + void IsSupertypeOf(TypeRelation *relation, Type *source) override; + void IsSubtypeOf(TypeRelation *relation, Type *target) override; + Type *Substitute(TypeRelation *relation, const Substitution *substitution) override; + + void ToString(std::stringstream &ss, bool precise) const override; + void ToAssemblerType(std::stringstream &ss) const override; + void ToDebugInfoType(std::stringstream &ss) const override; + + Type *Instantiate(ArenaAllocator *allocator, TypeRelation *relation, GlobalTypesHolder *globalTypes) override; + +private: + ETSTypeParameter *const tparam_; +}; + +} // namespace ark::es2panda::checker + +#endif diff --git a/ets2panda/checker/types/ets/types.h b/ets2panda/checker/types/ets/types.h index d0a9efae1504c27277c46dc7711ac257fa3ca3a7..5ea3c52a77dad82237d641895081ed212976ce93 100644 --- a/ets2panda/checker/types/ets/types.h +++ b/ets2panda/checker/types/ets/types.h @@ -39,5 +39,6 @@ #include "etsNonNullishType.h" #include "etsNullishTypes.h" #include "checker/types/signature.h" +#include "etsReadonlyType.h" #endif /* TYPES_H */ diff --git a/ets2panda/checker/types/typeFlag.h b/ets2panda/checker/types/typeFlag.h index b05adfe3c860bd47bf5ac4625a7e36a9c9f9c520..825c56b186647397e574fc24b6f5933fb4dba9f7 100644 --- a/ets2panda/checker/types/typeFlag.h +++ b/ets2panda/checker/types/typeFlag.h @@ -84,11 +84,12 @@ enum class TypeFlag : uint64_t { ETS_NULL = 1ULL << 59ULL, // ETS null ETS_UNDEFINED = 1ULL << 60ULL, // ETS undefined ETS_NONNULLISH = 1ULL << 61ULL, // ETS nonnullish type parameter + ETS_READONLY = 1ULL << 62ULL, // ETS readonly type parameter ETS_DYNAMIC_TYPE = ETS_OBJECT | ETS_DYNAMIC_FLAG, ETS_DYNAMIC_FUNCTION_TYPE = FUNCTION | ETS_DYNAMIC_FLAG, ETS_TYPE = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_VOID | ETS_OBJECT | ETS_ARRAY | WILDCARD | ETS_TYPE_PARAMETER | ETS_ENUM | ETS_STRING_ENUM | ETS_DYNAMIC_TYPE | ETS_UNION | ETS_NULL | - ETS_UNDEFINED | ETS_NONNULLISH, + ETS_UNDEFINED | ETS_NONNULLISH | ETS_READONLY, ETS_PRIMITIVE = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN, ETS_PRIMITIVE_RETURN = BYTE | SHORT | INT | LONG | FLOAT | DOUBLE | CHAR | ETS_BOOLEAN | ETS_ENUM, ETS_ARRAY_INDEX = BYTE | SHORT | INT, diff --git a/ets2panda/checker/types/typeMapping.h b/ets2panda/checker/types/typeMapping.h index 1b7fedc04a027a999574650c5395d1abd33a2415..653fc40c15796b534fbe661e853d0e7044b334c2 100644 --- a/ets2panda/checker/types/typeMapping.h +++ b/ets2panda/checker/types/typeMapping.h @@ -60,6 +60,7 @@ _(TypeFlag::WILDCARD, WildcardType) \ _(TypeFlag::ETS_TYPE_PARAMETER, ETSTypeParameter) \ _(TypeFlag::ETS_NONNULLISH, ETSNonNullishType) \ + _(TypeFlag::ETS_READONLY, ETSReadonlyType) \ _(TypeFlag::ETS_ENUM, ETSEnumType) \ _(TypeFlag::ETS_STRING_ENUM, ETSStringEnumType) \ _(TypeFlag::ETS_EXTENSION_FUNC_HELPER, ETSExtensionFuncHelperType) \ diff --git a/ets2panda/compiler/core/ASTVerifier.cpp b/ets2panda/compiler/core/ASTVerifier.cpp index ccb7f657496761e548672d4b6aee23c9119e95b6..28f47ded42495d4e99cd04235e0696b111766799 100644 --- a/ets2panda/compiler/core/ASTVerifier.cpp +++ b/ets2panda/compiler/core/ASTVerifier.cpp @@ -565,6 +565,11 @@ private: bool CheckAstExceptions(const ir::Identifier *ast) const { + // NOTE(lujiahui): skip Readonly property + if (ast->Parent()->IsETSTypeReferencePart() && ast->Name().Is("Readonly")) { + return true; + } + // E // NOTE(kkonkuznetsov): skip enums if (ast->Parent()->IsMemberExpression() && (ast->Parent()->AsMemberExpression()->Object()->TsType() == nullptr || diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 7efd2df7656df64692d33f60bf6011ebe1a417b7..856923635e9be769b8c78d41b4e1b77397709366 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -51,7 +51,7 @@ namespace ark::es2panda::compiler { static constexpr auto TYPE_FLAG_BYTECODE_REF = checker::TypeFlag::ETS_ARRAY | checker::TypeFlag::ETS_OBJECT | checker::TypeFlag::ETS_UNION | checker::TypeFlag::ETS_TYPE_PARAMETER | checker::TypeFlag::ETS_NONNULLISH | checker::TypeFlag::ETS_NULL | - checker::TypeFlag::ETS_UNDEFINED; + checker::TypeFlag::ETS_UNDEFINED | checker::TypeFlag::ETS_READONLY; ETSGen::ETSGen(ArenaAllocator *allocator, RegSpiller *spiller, public_lib::Context *context, std::tuple toCompile) noexcept diff --git a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp index 45a68d5ab3c9f4a446abf6ca2eeee98711a0b68b..0feed81b3df15ff32ce871f83ddb6609d1fc18cf 100644 --- a/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp +++ b/ets2panda/compiler/lowering/ets/objectLiteralLowering.cpp @@ -26,6 +26,28 @@ std::string_view ObjectLiteralLowering::Name() const return "ObjectLiteralLowering"; } +static void MaybeAllowConstAssign(checker::Type *targetType, ArenaVector &statements) +{ + if (!targetType->IsETSObjectType()) { + return; + } + for (auto *stmt : statements) { + if (stmt->IsExpressionStatement() && stmt->AsExpressionStatement()->GetExpression()->IsAssignmentExpression()) { + auto *variable = stmt->AsExpressionStatement() + ->GetExpression() + ->AsAssignmentExpression() + ->Left() + ->AsMemberExpression() + ->Property() + ->AsIdentifier() + ->Variable(); + if (variable != nullptr && variable->HasFlag(varbinder::VariableFlags::READONLY)) { + stmt->AsExpressionStatement()->GetExpression()->AsAssignmentExpression()->SetIgnoreConstAssign(); + } + } + } +} + static constexpr std::string_view NESTED_BLOCK_EXPRESSION = "_$NESTED_BLOCK_EXPRESSION$_"; static void RestoreNestedBlockExpression(const ArenaVector &statements, @@ -141,6 +163,8 @@ static ir::AstNode *HandleObjectLiteralLowering(public_lib::Context *ctx, ir::Ob auto *loweringResult = parser->CreateFormattedExpression(ss.str(), newStmts); loweringResult->SetParent(objExpr->Parent()); + MaybeAllowConstAssign(objExpr->PreferredType(), loweringResult->AsBlockExpression()->Statements()); + auto scopeCtx = varbinder::LexicalScope::Enter(varbinder, NearestScope(objExpr)); InitScopesPhaseETS::RunExternalNode(loweringResult, varbinder); diff --git a/ets2panda/compiler/scripts/signatures.yaml b/ets2panda/compiler/scripts/signatures.yaml index f25a39dd74d7180bb7d2a167ab2c9047bf196086..6da692a029e104d2dbffe4a3c638ef8ae7bf4489 100644 --- a/ets2panda/compiler/scripts/signatures.yaml +++ b/ets2panda/compiler/scripts/signatures.yaml @@ -126,6 +126,8 @@ defines: ref: UNDEFINED - name: 'null' ref: NULL_LITERAL + - name: 'Readonly' + ref: READONLY_TYPE_NAME packages: - name: 'std.core' diff --git a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp index 780c438a01bd24d67cc6cca35138594840d544a3..19a169dd1190dd8e759f3883c32d1361f62e57be 100644 --- a/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp +++ b/ets2panda/declgen_ets2ts/declgenEts2Ts.cpp @@ -152,6 +152,7 @@ void TSDeclGen::GenType(const checker::Type *checkerType) case checker::TypeFlag::ETS_BOOLEAN: case checker::TypeFlag::ETS_TYPE_PARAMETER: case checker::TypeFlag::ETS_NONNULLISH: + case checker::TypeFlag::ETS_READONLY: Out(checkerType->ToString()); return; case checker::TypeFlag::ETS_ENUM: diff --git a/ets2panda/ir/ets/etsTypeReferencePart.cpp b/ets2panda/ir/ets/etsTypeReferencePart.cpp index fbc40255c9c201c341bf4530fc748c7e91909b53..81e399f64d46b73e7eae3d30386d879da35d1867 100644 --- a/ets2panda/ir/ets/etsTypeReferencePart.cpp +++ b/ets2panda/ir/ets/etsTypeReferencePart.cpp @@ -106,6 +106,8 @@ checker::Type *ETSTypeReferencePart::GetType(checker::ETSChecker *checker) SetTsType(checker->GlobalETSUndefinedType()); } else if (ident->Name() == compiler::Signatures::NULL_LITERAL) { SetTsType(checker->GlobalETSNullType()); + } else if (ident->Name() == compiler::Signatures::READONLY_TYPE_NAME) { + SetTsType(checker->HandleReadonlyType(typeParams_)); } } if (TsType() == nullptr) { diff --git a/ets2panda/ir/expressions/assignmentExpression.h b/ets2panda/ir/expressions/assignmentExpression.h index ecdd1a9159ef5a2400a65e48113e97e1b3ff5291..c455e4627622e0f62e3152107d8f832d9f5cdb53 100644 --- a/ets2panda/ir/expressions/assignmentExpression.h +++ b/ets2panda/ir/expressions/assignmentExpression.h @@ -121,6 +121,16 @@ public: return target_; } + void SetIgnoreConstAssign() + { + ignoreConstAssign_ = true; + } + + [[nodiscard]] bool IsIgnoreConstAssign() const + { + return ignoreConstAssign_; + } + [[nodiscard]] AssignmentExpression *Clone(ArenaAllocator *allocator, AstNode *parent) override; [[nodiscard]] bool ConvertibleToAssignmentPattern(bool mustBePattern = true); @@ -155,6 +165,7 @@ private: lexer::TokenType operator_; varbinder::Variable *target_ {}; checker::Type *operationType_ {}; + bool ignoreConstAssign_ = false; }; } // namespace ark::es2panda::ir diff --git a/ets2panda/parser/ETSparser.cpp b/ets2panda/parser/ETSparser.cpp index d96387437cea35fc366fb81cfa0b464d98d327fb..e65c1145f760b0dab3a31bf929db69f636f31f4b 100644 --- a/ets2panda/parser/ETSparser.cpp +++ b/ets2panda/parser/ETSparser.cpp @@ -570,7 +570,7 @@ ir::ModifierFlags ETSParser::ParseClassFieldModifiers(bool seenStatic) } case lexer::TokenType::KEYW_READONLY: { // NOTE(OCs): Use ir::ModifierFlags::READONLY once compiler is ready for it. - currentFlag = ir::ModifierFlags::CONST; + currentFlag = ir::ModifierFlags::CONST | ir::ModifierFlags::READONLY; break; } default: { diff --git a/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt b/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt index 71e5cb1cc77588c9efaf504783374950f6fcbbd0..e9cf95bd05657dd456cccfe656ed38ff8d7b4329 100644 --- a/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt +++ b/ets2panda/test/compiler/ets/objectLiteralReadonlyKey-expected.txt @@ -41,7 +41,7 @@ }, "accessibility": "public", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -612,4 +612,3 @@ } } } -TypeError: cannot assign to readonly property f [objectLiteralReadonlyKey.ets:21:5] diff --git a/ets2panda/test/compiler/ets/readonlyField-expected.txt b/ets2panda/test/compiler/ets/readonlyField-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..3af0de7e774fdc1e2218491583b654afb7a73ce5 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyField-expected.txt @@ -0,0 +1,932 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ReadonlyData", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 7 + }, + "end": { + "line": 15, + "column": 19 + } + } + }, + "typeParameters": { + "type": "TSTypeParameterDeclaration", + "params": [ + { + "type": "TSTypeParameter", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 15, + "column": 20 + }, + "end": { + "line": 15, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 20 + }, + "end": { + "line": 15, + "column": 22 + } + } + } + ], + "loc": { + "start": { + "line": 15, + "column": 19 + }, + "end": { + "line": 15, + "column": 22 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 19 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 21 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 14 + }, + "end": { + "line": 16, + "column": 23 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "value", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "T", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 24 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 17 + }, + "end": { + "line": 17, + "column": 26 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 13 + } + } + }, + "property": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 19 + } + } + }, + "right": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 18, + "column": 28 + } + } + } + ], + "loc": { + "start": { + "line": 17, + "column": 27 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 16 + }, + "end": { + "line": 19, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 19, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 15, + "column": 23 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 15, + "column": 1 + }, + "end": { + "line": 20, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 10 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 22 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "myData", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 15 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "ReadonlyData", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 34 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 41 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 35 + }, + "end": { + "line": 23, + "column": 42 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 34 + }, + "end": { + "line": 23, + "column": 42 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 43 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 23, + "column": 43 + } + } + }, + "arguments": [ + { + "type": "StringLiteral", + "value": "import data", + "loc": { + "start": { + "line": 23, + "column": 43 + }, + "end": { + "line": 23, + "column": 56 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 58 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 9 + }, + "end": { + "line": 23, + "column": 58 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 58 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "myData", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "value", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 17 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 17 + } + } + }, + "right": { + "type": "StringLiteral", + "value": "new data", + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 31 + } + } + } + ], + "loc": { + "start": { + "line": 22, + "column": 23 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 14 + }, + "end": { + "line": 25, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 1 + }, + "end": { + "line": 25, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 26, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable value [readonlyField.ets:16:14] diff --git a/ets2panda/test/compiler/ets/readonlyField.ets b/ets2panda/test/compiler/ets/readonlyField.ets new file mode 100644 index 0000000000000000000000000000000000000000..9c1041e96b9b63de5f9c52dee26fe1765efcba48 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyField.ets @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class ReadonlyData { + readonly value: T; + constructor(value: T) { + this.value = value; + } +} + +function main(): void { + let myData = new ReadonlyData("import data"); + myData.value = "new data"; +} diff --git a/ets2panda/test/compiler/ets/readonlyField_2-expected.txt b/ets2panda/test/compiler/ets/readonlyField_2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..7e561ad368b2689bda3fdc79c9021e38a2663f80 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyField_2-expected.txt @@ -0,0 +1,1124 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ReadonlyPerson", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 21 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "name", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "string", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 20 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 14 + }, + "end": { + "line": 17, + "column": 27 + } + } + }, + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "age", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 17 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": true, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "number", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 19 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 2 + }, + "end": { + "line": 19, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 22 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 19, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "updatePerson", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "updatePerson", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 10 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "person", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "ReadonlyPerson", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 31 + }, + "end": { + "line": 21, + "column": 45 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 31 + }, + "end": { + "line": 21, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 31 + }, + "end": { + "line": 21, + "column": 46 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 23 + }, + "end": { + "line": 21, + "column": 46 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 23 + }, + "end": { + "line": 21, + "column": 46 + } + } + } + ], + "returnType": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "ReadonlyPerson", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 48 + }, + "end": { + "line": 21, + "column": 62 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 48 + }, + "end": { + "line": 21, + "column": 64 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 48 + }, + "end": { + "line": 21, + "column": 64 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "person", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "name", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 12 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "right": { + "type": "StringLiteral", + "value": "Bob", + "loc": { + "start": { + "line": 22, + "column": 19 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 25 + } + } + }, + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "person", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 12 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 5 + }, + "end": { + "line": 23, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 63 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 22 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 22 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 1 + }, + "end": { + "line": 24, + "column": 2 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 10 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "main", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 10 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 25, + "column": 18 + }, + "end": { + "line": 25, + "column": 22 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "person", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "ReadonlyPerson", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 17 + }, + "end": { + "line": 26, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 17 + }, + "end": { + "line": 26, + "column": 33 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 17 + }, + "end": { + "line": 26, + "column": 33 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 15 + } + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "name", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 35 + }, + "end": { + "line": 26, + "column": 39 + } + } + }, + "value": { + "type": "StringLiteral", + "value": "Alice", + "loc": { + "start": { + "line": 26, + "column": 41 + }, + "end": { + "line": 26, + "column": 48 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 26, + "column": 35 + }, + "end": { + "line": 26, + "column": 48 + } + } + }, + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "age", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 50 + }, + "end": { + "line": 26, + "column": 53 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 22, + "loc": { + "start": { + "line": 26, + "column": 54 + }, + "end": { + "line": 26, + "column": 56 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 26, + "column": 50 + }, + "end": { + "line": 26, + "column": 56 + } + } + } + ], + "loc": { + "start": { + "line": 26, + "column": 34 + }, + "end": { + "line": 26, + "column": 57 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 9 + }, + "end": { + "line": 26, + "column": 57 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 58 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "updatePerson", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 17 + } + } + }, + "arguments": [ + { + "type": "Identifier", + "name": "person", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 18 + }, + "end": { + "line": 27, + "column": 24 + } + } + } + ], + "optional": false, + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 26 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 23 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 14 + }, + "end": { + "line": 28, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 1 + }, + "end": { + "line": 28, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 29, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable name [readonlyField_2.ets:17:14] diff --git a/ets2panda/test/compiler/ets/readonlyField_2.ets b/ets2panda/test/compiler/ets/readonlyField_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..1e25c5dcab1ffbdbf05b2b33593e7936065b516a --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyField_2.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class ReadonlyPerson { + readonly name: string; + readonly age: number; +} + +function updatePerson(person: ReadonlyPerson): ReadonlyPerson { + person.name = "Bob"; //CTE + return person; +} +function main(): void { + let person: ReadonlyPerson = {name: "Alice", age:22}; + updatePerson(person); +} diff --git a/ets2panda/test/compiler/ets/readonlyType_1-expected.txt b/ets2panda/test/compiler/ets/readonlyType_1-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ec120a182733afcdf327a11cb24f88cb3404a3b --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_1-expected.txt @@ -0,0 +1,987 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "fld", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 30 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 24 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 18 + }, + "end": { + "line": 18, + "column": 31 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "right": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 32 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 18 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 14 + }, + "end": { + "line": 23, + "column": 20 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 20 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 30 + }, + "end": { + "line": 24, + "column": 32 + } + } + }, + "arguments": [ + { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 24, + "column": 32 + }, + "end": { + "line": 24, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 26 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 25, + "column": 6 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 10 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 10 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 25, + "column": 13 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 26, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 28, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable fld [readonlyType_1.ets:17:5] diff --git a/ets2panda/test/compiler/ets/readonlyType_1.ets b/ets2panda/test/compiler/ets/readonlyType_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..00bd705f5d6dd2a034a706469cbfb033c936c500 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_1.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number + constructor (fld : Number) { + this.fld = fld + } +} + +function foo(a0: A) { + let a: Readonly = new A(2) + a.fld = 5 +} + diff --git a/ets2panda/test/compiler/ets/readonlyType_2-expected.txt b/ets2panda/test/compiler/ets/readonlyType_2-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..6926d78b450e4c0338da2e74aa670069bb539af9 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_2-expected.txt @@ -0,0 +1,835 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 18 + }, + "end": { + "line": 20, + "column": 20 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 14 + }, + "end": { + "line": 20, + "column": 20 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 20 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 10 + } + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 21, + "column": 30 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 21, + "column": 32 + }, + "end": { + "line": 21, + "column": 33 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 21, + "column": 27 + }, + "end": { + "line": 21, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 26 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 34 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 7 + }, + "end": { + "line": 22, + "column": 10 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 10 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 22, + "column": 13 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 14 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 21 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable fld [readonlyType_2.ets:17:5] diff --git a/ets2panda/test/compiler/ets/readonlyType_2.ets b/ets2panda/test/compiler/ets/readonlyType_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..abfb3614154c9e544164022c2cebd2778d537dd3 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_2.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number = 2 +} + +function foo(a0: A) { + let a: Readonly = {fld: 3} + a.fld = 5 +} diff --git a/ets2panda/test/compiler/ets/readonlyType_3-expected.txt b/ets2panda/test/compiler/ets/readonlyType_3-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..392482fd3a43f438782d5690d29ab562830bb059 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_3-expected.txt @@ -0,0 +1,689 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 22 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 23 + }, + "end": { + "line": 18, + "column": 25 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 22 + }, + "end": { + "line": 18, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 26 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a0", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 27 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 2 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 22, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable fld [readonlyType_3.ets:17:5] diff --git a/ets2panda/test/compiler/ets/readonlyType_3.ets b/ets2panda/test/compiler/ets/readonlyType_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d97b58a37861a22197c4d7e44142bb374d1c2d0 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_3.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number = 2 + foo (a0: Readonly) { + a0.fld = 5 + } +} diff --git a/ets2panda/test/compiler/ets/readonlyType_4-expected.txt b/ets2panda/test/compiler/ets/readonlyType_4-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..32d2ada28b5493959083b7e281e346ede6a3f612 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_4-expected.txt @@ -0,0 +1,1385 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 15 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 14 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 10 + }, + "end": { + "line": 18, + "column": 16 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a0", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 12 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 15 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 5, + "loc": { + "start": { + "line": 19, + "column": 18 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 17 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 2 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 7 + }, + "end": { + "line": 23, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 17 + }, + "end": { + "line": 23, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 17 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 17 + }, + "end": { + "line": 23, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 21 + }, + "end": { + "line": 23, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 19 + }, + "end": { + "line": 23, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 23, + "column": 21 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "C", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 8 + } + } + }, + "superClass": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "B", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 17 + }, + "end": { + "line": 25, + "column": 20 + } + } + }, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 26, + "column": 19 + }, + "end": { + "line": 26, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 26, + "column": 10 + }, + "end": { + "line": 26, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 26, + "column": 5 + }, + "end": { + "line": 26, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 8 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 27, + "column": 8 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [ + { + "type": "ETSParameterExpression", + "name": { + "type": "Identifier", + "name": "a0", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 14 + }, + "end": { + "line": 27, + "column": 22 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 27, + "column": 24 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 27, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 23 + }, + "end": { + "line": 27, + "column": 25 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 22 + }, + "end": { + "line": 27, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 14 + }, + "end": { + "line": 27, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 14 + }, + "end": { + "line": 27, + "column": 26 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 26 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 10 + }, + "end": { + "line": 27, + "column": 26 + } + } + } + ], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a0", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 11 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 28, + "column": 12 + }, + "end": { + "line": 28, + "column": 15 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 15 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 6, + "loc": { + "start": { + "line": 28, + "column": 18 + }, + "end": { + "line": 28, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 28, + "column": 9 + }, + "end": { + "line": 28, + "column": 19 + } + } + } + ], + "loc": { + "start": { + "line": 27, + "column": 27 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 27, + "column": 9 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 27, + "column": 5 + }, + "end": { + "line": 29, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 30, + "column": 2 + }, + "end": { + "line": 30, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 25, + "column": 19 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 1 + }, + "end": { + "line": 30, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 31, + "column": 1 + } + } +} +TypeError: Cannot assign to a constant variable fld [readonlyType_4.ets:17:5] diff --git a/ets2panda/test/compiler/ets/readonlyType_4.ets b/ets2panda/test/compiler/ets/readonlyType_4.ets new file mode 100644 index 0000000000000000000000000000000000000000..f28271d72b5336296cf76a2125dc1dc57ebc53d8 --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_4.ets @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number = 2 + foo (a0: A) { + a0.fld = 5 + } +} + +class B extends A {} + +class C extends B { + fld: Number = 2 + foo (a0: Readonly) { + a0.fld = 6 + } +} diff --git a/ets2panda/test/compiler/ets/readonlyType_5-expected.txt b/ets2panda/test/compiler/ets/readonlyType_5-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..0380712f5ec796eeb90f05560702fec22a066c5d --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_5-expected.txt @@ -0,0 +1,786 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 2 + }, + "end": { + "line": 18, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 18, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 10 + }, + "end": { + "line": 20, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 20, + "column": 17 + }, + "end": { + "line": 20, + "column": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 20 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 21 + }, + "end": { + "line": 21, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 21, + "column": 20 + }, + "end": { + "line": 21, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 12 + }, + "end": { + "line": 21, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 10 + } + } + }, + "init": { + "type": "ETSNewClassInstanceExpression", + "typeReference": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 31 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 32 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 30 + }, + "end": { + "line": 21, + "column": 32 + } + } + }, + "arguments": [], + "loc": { + "start": { + "line": 21, + "column": 26 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 21, + "column": 9 + }, + "end": { + "line": 21, + "column": 34 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 21, + "column": 5 + }, + "end": { + "line": 21, + "column": 34 + } + } + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a_class", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 19 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 18 + }, + "end": { + "line": 22, + "column": 21 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 16 + } + } + }, + "init": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 22, + "column": 22 + }, + "end": { + "line": 22, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 22, + "column": 9 + }, + "end": { + "line": 22, + "column": 23 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 22, + "column": 5 + }, + "end": { + "line": 22, + "column": 24 + } + } + } + ], + "loc": { + "start": { + "line": 20, + "column": 22 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 20, + "column": 13 + }, + "end": { + "line": 23, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 20, + "column": 1 + }, + "end": { + "line": 23, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 24, + "column": 1 + } + } +} +TypeError: Type 'A' cannot be assigned to type 'A' [readonlyType_5.ets:22:22] diff --git a/ets2panda/test/compiler/ets/readonlyType_5.ets b/ets2panda/test/compiler/ets/readonlyType_5.ets new file mode 100644 index 0000000000000000000000000000000000000000..72f34d35a2724b463376feede9880ab351592a5a --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_5.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number = 2 +} + +function foo(): void { + let a: Readonly = new A(); + let a_class: A = a; +} diff --git a/ets2panda/test/compiler/ets/readonlyType_6-expected.txt b/ets2panda/test/compiler/ets/readonlyType_6-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..72f2e8b247b054c34450eac6a870a74729506aca --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_6-expected.txt @@ -0,0 +1,944 @@ +{ + "type": "Program", + "statements": [ + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 16, + "column": 7 + }, + "end": { + "line": 16, + "column": 8 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "ClassProperty", + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 8 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 2, + "loc": { + "start": { + "line": 17, + "column": 19 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + "accessibility": "public", + "static": false, + "readonly": false, + "declare": false, + "optional": false, + "computed": false, + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Number", + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 16 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "loc": { + "start": { + "line": 17, + "column": 10 + }, + "end": { + "line": 17, + "column": 18 + } + } + }, + "definite": false, + "decorators": [], + "loc": { + "start": { + "line": 17, + "column": 5 + }, + "end": { + "line": 17, + "column": 20 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo2", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo2", + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 18, + "column": 9 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "MemberExpression", + "object": { + "type": "ThisExpression", + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 13 + } + } + }, + "property": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 19, + "column": 14 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 17 + } + } + }, + "right": { + "type": "NumberLiteral", + "value": 6, + "loc": { + "start": { + "line": 19, + "column": 20 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 21 + } + } + }, + "loc": { + "start": { + "line": 19, + "column": 9 + }, + "end": { + "line": 19, + "column": 21 + } + } + } + ], + "loc": { + "start": { + "line": 18, + "column": 12 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "loc": { + "start": { + "line": 18, + "column": 9 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 18, + "column": 5 + }, + "end": { + "line": 20, + "column": 6 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "constructor", + "static": false, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "constructor", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 21, + "column": 2 + }, + "end": { + "line": 21, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 16, + "column": 9 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 16, + "column": 1 + }, + "end": { + "line": 21, + "column": 2 + } + } + }, + { + "type": "ClassDeclaration", + "definition": { + "id": { + "type": "Identifier", + "name": "ETSGLOBAL", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "superClass": null, + "implements": [], + "body": [ + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "_$init$_", + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "body": { + "type": "BlockStatement", + "statements": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "MethodDefinition", + "key": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "kind": "method", + "accessibility": "public", + "static": true, + "optional": false, + "computed": false, + "value": { + "type": "FunctionExpression", + "function": { + "type": "ScriptFunction", + "id": { + "type": "Identifier", + "name": "foo", + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 10 + }, + "end": { + "line": 23, + "column": 13 + } + } + }, + "generator": false, + "async": false, + "expression": false, + "params": [], + "returnType": { + "type": "ETSPrimitiveType", + "loc": { + "start": { + "line": 23, + "column": 17 + }, + "end": { + "line": 23, + "column": 21 + } + } + }, + "body": { + "type": "BlockStatement", + "statements": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a", + "typeAnnotation": { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "Readonly", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 20 + } + } + }, + "typeParams": { + "type": "TSTypeParameterInstantiation", + "params": [ + { + "type": "ETSTypeReference", + "part": { + "type": "ETSTypeReferencePart", + "name": { + "type": "Identifier", + "name": "A", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 22 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 21 + }, + "end": { + "line": 24, + "column": 23 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 20 + }, + "end": { + "line": 24, + "column": 23 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 25 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 12 + }, + "end": { + "line": 24, + "column": 25 + } + } + }, + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 10 + } + } + }, + "init": { + "type": "ObjectExpression", + "properties": [ + { + "type": "Property", + "method": false, + "shorthand": false, + "computed": false, + "key": { + "type": "Identifier", + "name": "fld", + "decorators": [], + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 24, + "column": 30 + } + } + }, + "value": { + "type": "NumberLiteral", + "value": 3, + "loc": { + "start": { + "line": 24, + "column": 32 + }, + "end": { + "line": 24, + "column": 33 + } + } + }, + "kind": "init", + "loc": { + "start": { + "line": 24, + "column": 27 + }, + "end": { + "line": 24, + "column": 33 + } + } + } + ], + "loc": { + "start": { + "line": 24, + "column": 26 + }, + "end": { + "line": 24, + "column": 34 + } + } + }, + "loc": { + "start": { + "line": 24, + "column": 9 + }, + "end": { + "line": 24, + "column": 34 + } + } + } + ], + "kind": "let", + "loc": { + "start": { + "line": 24, + "column": 5 + }, + "end": { + "line": 24, + "column": 35 + } + } + }, + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 6 + } + } + }, + "property": { + "type": "Identifier", + "name": "foo2", + "decorators": [], + "loc": { + "start": { + "line": 25, + "column": 7 + }, + "end": { + "line": 25, + "column": 11 + } + } + }, + "computed": false, + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 11 + } + } + }, + "arguments": [], + "optional": false, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 13 + } + } + }, + "loc": { + "start": { + "line": 25, + "column": 5 + }, + "end": { + "line": 25, + "column": 14 + } + } + } + ], + "loc": { + "start": { + "line": 23, + "column": 22 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "loc": { + "start": { + "line": 23, + "column": 13 + }, + "end": { + "line": 26, + "column": 2 + } + } + }, + "overloads": [], + "decorators": [], + "loc": { + "start": { + "line": 23, + "column": 1 + }, + "end": { + "line": 26, + "column": 2 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 1 + } + } + } + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 27, + "column": 1 + } + } +} +TypeError: Cannot call readonly type methods. [readonlyType_6.ets:25:5] diff --git a/ets2panda/test/compiler/ets/readonlyType_6.ets b/ets2panda/test/compiler/ets/readonlyType_6.ets new file mode 100644 index 0000000000000000000000000000000000000000..980ce73b86233a9e2a86d90540d4a596a25ef96d --- /dev/null +++ b/ets2panda/test/compiler/ets/readonlyType_6.ets @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + fld: Number = 2 + foo2() { + this.fld = 6 + } +} + +function foo(): void { + let a: Readonly = {fld: 3}; + a.foo2(); +} diff --git a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt index 0f884e5274c0ef3367ba6113b9ed66f38f41f6e6..dc1df3cfa778f6718fbb7969a911f7d217b4cf36 100644 --- a/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt +++ b/ets2panda/test/parser/ets/AccessBinaryTrees-expected.txt @@ -1478,7 +1478,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -1528,7 +1528,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -1593,7 +1593,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/AccessNBody-expected.txt b/ets2panda/test/parser/ets/AccessNBody-expected.txt index 02f26f447134d8b44ac1481a5a712d703f83379b..0cf58f31f6a0c70e72065658363f714ea9ed6a69 100644 --- a/ets2panda/test/parser/ets/AccessNBody-expected.txt +++ b/ets2panda/test/parser/ets/AccessNBody-expected.txt @@ -185,7 +185,7 @@ }, "accessibility": "public", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -10595,7 +10595,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -10658,7 +10658,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -13502,7 +13502,7 @@ }, "accessibility": "public", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/AccessNSieve-expected.txt b/ets2panda/test/parser/ets/AccessNSieve-expected.txt index 7638c0a7f0b27ff89b927e51821b15111c36fdbc..d8edc02f316e9c5f1119ac65a06d7ef07c517d65 100644 --- a/ets2panda/test/parser/ets/AccessNSieve-expected.txt +++ b/ets2panda/test/parser/ets/AccessNSieve-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -118,7 +118,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -181,7 +181,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt index f4aad7a9711901e6921fcddfee5f217063145086..e086c166123b5acc0ac6b0257512ef8e2f8de573 100644 --- a/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/Bitops3BitBitsInByte-expected.txt @@ -998,7 +998,7 @@ }, "accessibility": "private", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt index 215124ba275186e6e6f809fa04e0e5509aa7292a..31395939131263d37a818876aa1fbd5520ddab4e 100644 --- a/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitsInByte-expected.txt @@ -772,7 +772,7 @@ }, "accessibility": "private", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt index d4747bb310857f606e3282b263a7098fbb0852ed..8b90f5bd649c0811665bff853a6de57c6d8080e0 100644 --- a/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt +++ b/ets2panda/test/parser/ets/BitopsBitwiseAnd-expected.txt @@ -118,7 +118,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt index bd39afb2f68a129bf6e753592376acf50a3b046a..c5433b705b1462654eaf546d174c19899f2c6168 100644 --- a/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt +++ b/ets2panda/test/parser/ets/BitopsNSieveBits-expected.txt @@ -2284,7 +2284,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt index 17ec672e2d6e888b875e74bccc007806d1b9f64e..51665dd7b32811494c3dd16f780dd737dcc4d2e9 100644 --- a/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt +++ b/ets2panda/test/parser/ets/ControlFlowRecursive-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -118,7 +118,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -181,7 +181,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/MathCordic-expected.txt b/ets2panda/test/parser/ets/MathCordic-expected.txt index 600f5588e2e01b8dd7eb4380ae6017cbf31eabef..0cee8e63a0f0443daf149f6bbd5f8fa47c1cd67f 100644 --- a/ets2panda/test/parser/ets/MathCordic-expected.txt +++ b/ets2panda/test/parser/ets/MathCordic-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -118,7 +118,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -181,7 +181,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -1145,7 +1145,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/MathPartialSums-expected.txt b/ets2panda/test/parser/ets/MathPartialSums-expected.txt index 5203c78f1fd29ea5b18e102e6c620d87930325bc..0cc0a42e4ca393551cd62b38b114bf4ff434bae0 100644 --- a/ets2panda/test/parser/ets/MathPartialSums-expected.txt +++ b/ets2panda/test/parser/ets/MathPartialSums-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -118,7 +118,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -181,7 +181,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt index a5e9ad21486853aae237ca3bc602fa8466c980f5..a842d70a2f94f294b005a8d711989cbf48115956 100644 --- a/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt +++ b/ets2panda/test/parser/ets/MathSpectralNorm-expected.txt @@ -5019,7 +5019,7 @@ }, "accessibility": "private", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/Morph3d-expected.txt b/ets2panda/test/parser/ets/Morph3d-expected.txt index c9daaacefa3274327acf87470836160e111c0794..d9f848ecd46d7227165daa73d256a717c79b5b9b 100644 --- a/ets2panda/test/parser/ets/Morph3d-expected.txt +++ b/ets2panda/test/parser/ets/Morph3d-expected.txt @@ -127,7 +127,7 @@ }, "accessibility": "private", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -190,7 +190,7 @@ }, "accessibility": "private", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/StringBase64-expected.txt b/ets2panda/test/parser/ets/StringBase64-expected.txt index 8c46d0b051dc9c43280450d70fd95e1580d8baa7..e5f329790ba2147befc230629ea18f7abf51ac56 100644 --- a/ets2panda/test/parser/ets/StringBase64-expected.txt +++ b/ets2panda/test/parser/ets/StringBase64-expected.txt @@ -83,7 +83,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -174,7 +174,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -2975,7 +2975,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/anonymous_class-expected.txt b/ets2panda/test/parser/ets/anonymous_class-expected.txt index 50ae27c56d966cb933f6afca166aab99479e3c12..08d3e48272184b1396e8f6c98db7d82c047995cf 100644 --- a/ets2panda/test/parser/ets/anonymous_class-expected.txt +++ b/ets2panda/test/parser/ets/anonymous_class-expected.txt @@ -175,7 +175,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/field_decl-expected.txt b/ets2panda/test/parser/ets/field_decl-expected.txt index 25bfd9129a170d6fae7fa85d26d9c532dc07f18c..e2781c3382ac206c2956772eae547ed6726acafd 100644 --- a/ets2panda/test/parser/ets/field_decl-expected.txt +++ b/ets2panda/test/parser/ets/field_decl-expected.txt @@ -517,7 +517,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -580,7 +580,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -643,7 +643,7 @@ }, "accessibility": "private", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/global_const_vars3-expected.txt b/ets2panda/test/parser/ets/global_const_vars3-expected.txt index 04e9ad0cdb7ab9fb9c4bc762124e9ac0b03443a0..7532f6f6601bc82453c1ec89826e937c19de5d27 100644 --- a/ets2panda/test/parser/ets/global_const_vars3-expected.txt +++ b/ets2panda/test/parser/ets/global_const_vars3-expected.txt @@ -41,7 +41,7 @@ }, "accessibility": "public", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/global_const_vars4-expected.txt b/ets2panda/test/parser/ets/global_const_vars4-expected.txt index effa949d28357cc36a655306c0c70371a274f42d..5438e4192b3d8fd72ece8289774a8a4f28bec07b 100644 --- a/ets2panda/test/parser/ets/global_const_vars4-expected.txt +++ b/ets2panda/test/parser/ets/global_const_vars4-expected.txt @@ -96,7 +96,7 @@ }, "accessibility": "public", "static": false, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt index a0429f6a7db7e3a089173aa136253133094a590e..3760dd6005ce8fbb82f3241895e367e5ea825107 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -242,7 +242,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt index 04b54186be83e3fcdd5aeaf816dea2c58e7b2b34..d6525647ada4b6e221a343452568b2d606c9876c 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -242,7 +242,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt index 0f99422e115d451281e74d7b5b26e20b74623338..724b9f8ae331c69ac361afe908632dcff18e9a47 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_compare_char_2-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -242,7 +242,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_different_enum-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_different_enum-expected.txt index 8ce637786ed4b25f6795d7702a6ff7bbf84107ff..214c91a16d78a78cfff1d53af2aed20fe0b56b94 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_different_enum-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_different_enum-expected.txt @@ -400,7 +400,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -618,7 +618,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_different_enum_2-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_different_enum_2-expected.txt index 5891ffb6e13f852b8cc5f8a4a7e84a53ebbba50b..d363c874fe884e1e8e2e24cc912444f4b6a780e4 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_different_enum_2-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_different_enum_2-expected.txt @@ -400,7 +400,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -618,7 +618,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_enum-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_enum-expected.txt index cc9db9fc4a73b6404a9f3e753ccfc0c0c81514cb..19bfeb11dd1b76c19afaf942c82da17e68839f1c 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_enum-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_enum-expected.txt @@ -400,7 +400,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -618,7 +618,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_enum_duplicate-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_enum_duplicate-expected.txt index c37cacffebdfd380c90cdc1ad55f41fe2d790157..0dd7585512b0fbcd77b0132d9ecdd84786ecf004 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_enum_duplicate-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_enum_duplicate-expected.txt @@ -400,7 +400,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -618,7 +618,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/parser/ets/switch_readonly_member_number_duplicate-expected.txt b/ets2panda/test/parser/ets/switch_readonly_member_number_duplicate-expected.txt index 2ce1ff962ac981cf80603be3f45e0c24c4a9b352..a40d0941047fd0dd0adf50036ebf405b1b437d38 100644 --- a/ets2panda/test/parser/ets/switch_readonly_member_number_duplicate-expected.txt +++ b/ets2panda/test/parser/ets/switch_readonly_member_number_duplicate-expected.txt @@ -55,7 +55,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, @@ -242,7 +242,7 @@ }, "accessibility": "public", "static": true, - "readonly": false, + "readonly": true, "declare": false, "optional": false, "computed": false, diff --git a/ets2panda/test/runtime/ets/readonlyField_ObjectLiteral.ets b/ets2panda/test/runtime/ets/readonlyField_ObjectLiteral.ets new file mode 100644 index 0000000000000000000000000000000000000000..59a922655fc75ea37c672afefddbb10f38097a95 --- /dev/null +++ b/ets2panda/test/runtime/ets/readonlyField_ObjectLiteral.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + readonly fld: Number = 2; +} + +function main(): void { + let a: A = {fld: 3}; + assert(a.fld == 3); +} diff --git a/ets2panda/test/runtime/ets/readonlyObjectLiteral.ets b/ets2panda/test/runtime/ets/readonlyObjectLiteral.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ae629fe0877cea1973c3a1f5f53b74bf625391c --- /dev/null +++ b/ets2panda/test/runtime/ets/readonlyObjectLiteral.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class A { + readonly fld: number = 2; +} +function main(): void { + let a: A = {fld: 3}; + assert(a.fld == 3); +} diff --git a/ets2panda/test/runtime/ets/readonlyObjectLiteral_2.ets b/ets2panda/test/runtime/ets/readonlyObjectLiteral_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..255f8b7a94e842e2ecad9c41438c36471ac7c927 --- /dev/null +++ b/ets2panda/test/runtime/ets/readonlyObjectLiteral_2.ets @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class A { + readonly fld: number = 2; + fld2: number = 3; +} +function main(): void { + let a: A = {fld: 3, fld2: 4}; + a.fld2 = 5; + assert(a.fld == 3); + assert(a.fld2 == 5); +} diff --git a/ets2panda/test/runtime/ets/readonlyTypeRuntime.ets b/ets2panda/test/runtime/ets/readonlyTypeRuntime.ets new file mode 100644 index 0000000000000000000000000000000000000000..a67514182623ae43f48e94448445f669470cfcea --- /dev/null +++ b/ets2panda/test/runtime/ets/readonlyTypeRuntime.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +type readonly_A = Readonly; + +class A { + num_mem: Number + str_mem: String + b_mem: B +} + +class B {fld: Number = 6} + +class C {c_num_mem: Number} + +class D extends C {d_num_mem: Number} + + +function main(): void { + let readonly_a: Readonly = { + num_mem: 1, + str_mem: "readonly_a", + b_mem: new B() + } + + assert(readonly_a.num_mem == 1) + assert(readonly_a.str_mem == "readonly_a") + assert(readonly_a.b_mem.fld == 6) + + let readonly_d: Readonly = { + c_num_mem: 2, + d_num_mem: 3 + } + assert(readonly_d.c_num_mem == 2) + assert(readonly_d.d_num_mem == 3) + + let readonly_a2: readonly_A = { + num_mem: 4, + str_mem: "readonly_a2", + b_mem: new B() + } + assert(readonly_a2.num_mem == 4) + assert(readonly_a2.str_mem == "readonly_a2") + assert(readonly_a2.b_mem.fld == 6) + +} diff --git a/ets2panda/test/runtime/ets/readonlyTypeRuntime_2.ets b/ets2panda/test/runtime/ets/readonlyTypeRuntime_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..75f5d5f7ced72c6b31f47d3e553793c3167c8d74 --- /dev/null +++ b/ets2panda/test/runtime/ets/readonlyTypeRuntime_2.ets @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +class A { + fld: Number = 2; + foo2() { + this.fld = 5 + } +} + +function main() { + let readonly_a: Readonly = {fld: 6}; + let plain_a: A = new A(); + + plain_a.fld = 3; + assert(plain_a.fld == 3); + + plain_a.foo2(); + assert(plain_a.fld == 5); + + assert(readonly_a.fld == 6); + +} diff --git a/ets2panda/varbinder/ETSBinder.cpp b/ets2panda/varbinder/ETSBinder.cpp index e659bb3f11d353bd9759987a8f65d19fe2a1f51e..f49e7d8c626a9064b54039bc4e034270660732c5 100644 --- a/ets2panda/varbinder/ETSBinder.cpp +++ b/ets2panda/varbinder/ETSBinder.cpp @@ -96,7 +96,8 @@ void ETSBinder::LookupTypeArgumentReferences(ir::ETSTypeReference *typeRef) void ETSBinder::LookupTypeReference(ir::Identifier *ident, bool allowDynamicNamespaces) { const auto &name = ident->Name(); - if (name == compiler::Signatures::UNDEFINED || name == compiler::Signatures::NULL_LITERAL) { + if (name == compiler::Signatures::UNDEFINED || name == compiler::Signatures::NULL_LITERAL || + name == compiler::Signatures::READONLY_TYPE_NAME) { return; } auto *iter = GetScope();