本文整理汇总了C++中TypePtr::canAssignTo方法的典型用法代码示例。如果您正苦于以下问题:C++ TypePtr::canAssignTo方法的具体用法?C++ TypePtr::canAssignTo怎么用?C++ TypePtr::canAssignTo使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TypePtr
的用法示例。
在下文中一共展示了TypePtr::canAssignTo方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: isLiteralTypeForEnum
static bool isLiteralTypeForEnum(GlobalScope* global, const TypePtr& type)
{
if(type->canAssignTo(global->IntegerLiteralConvertible()))
return true;
if(type->canAssignTo(global->StringLiteralConvertible()))
return true;
if(type->canAssignTo(global->FloatLiteralConvertible()))
return true;
//if(type->canAssignTo(global->BooleanLiteralConvertible))
// return true;
if(type->canAssignTo(global->UnicodeScalarLiteralConvertible()))
return true;
if(type->canAssignTo(global->ExtendedGraphemeClusterLiteralConvertible()))
return true;
//nil, array, dictionary literal is not working for enum
return false;
}
示例2: defineType
//.........这里部分代码省略.........
assert(type != nullptr);
assert(type->getCategory() == category);
//prepare for generic
if(!type->getGenericDefinition() && node->getGenericParametersDef())
{
GenericParametersDefPtr genericParams = node->getGenericParametersDef();
GenericDefinitionPtr generic = prepareGenericTypes(genericParams);
generic->registerTo(type->getScope());
type->setGenericDefinition(generic);
}
if(node->hasModifier(DeclarationModifiers::Final))
type->setFlags(SymbolFlagFinal, true);
static_pointer_cast<TypeBuilder>(type)->setModuleName(ctx->currentModule->getName());
ctx->allTypes.push_back(type);
//check inheritance clause
{
TypePtr parent = nullptr;
bool first = true;
ScopeGuard scope(symbolRegistry, type->getScope());
SCOPED_SET(ctx->currentType, type);
for(const TypeIdentifierPtr& parentType : node->getParents())
{
parentType->accept(this);
if(first)
declareImmediately(parentType->getName());
TypePtr ptr = resolveType(parentType, true);
Type::Category pcategory = ptr->getCategory();
if(pcategory == Type::Specialized)
pcategory = ptr->getInnerType()->getCategory();
if(pcategory == Type::Class && category == Type::Class)
{
if(!first)
{
//only the first type can be class type
error(parentType, Errors::E_SUPERCLASS_MUST_APPEAR_FIRST_IN_INHERITANCE_CLAUSE_1, toString(parentType));
return nullptr;
}
parent = ptr;
if(parent->hasFlags(SymbolFlagFinal))
{
error(parentType, Errors::E_INHERITANCE_FROM_A_FINAL_CLASS_A_1, parentType->getName());
return nullptr;
}
}
else if(category == Type::Enum && pcategory != Type::Protocol)
{
if(parent)//already has a raw type
{
error(parentType, Errors::E_MULTIPLE_ENUM_RAW_TYPES_A_AND_B_2, parent->toString(), ptr->toString());
return nullptr;
}
if(!first)
{
error(parentType, Errors::E_RAW_TYPE_A_MUST_APPEAR_FIRST_IN_THE_ENUM_INHERITANCE_CLAUSE_1, ptr->toString());
return nullptr;
}
//check if the raw type is literal convertible
if(!isLiteralTypeForEnum(symbolRegistry->getGlobalScope(), ptr))
{
error(parentType, Errors::E_RAW_TYPE_A_IS_NOT_CONVERTIBLE_FROM_ANY_LITERAL_1, ptr->toString());
return nullptr;
}
if(!ptr->canAssignTo(symbolRegistry->getGlobalScope()->Equatable()))
{
error(parentType, Errors::E_RAWREPRESENTABLE_INIT_CANNOT_BE_SYNTHESIZED_BECAUSE_RAW_TYPE_A_IS_NOT_EQUATABLE_1, ptr->toString());
return nullptr;
}
parent = ptr;
}
else if(pcategory == Type::Protocol)
{
type->addProtocol(ptr);
}
else
{
if(category == Type::Class)
error(parentType, Errors::E_INHERITANCE_FROM_NONE_PROTOCOL_NON_CLASS_TYPE_1, toString(parentType));
else
error(parentType, Errors::E_INHERITANCE_FROM_NONE_PROTOCOL_TYPE_1, toString(parentType));
return nullptr;
}
first = false;
}
type->setParentType(parent);
if(parent && parent->getAccessLevel() == AccessLevelPublic && (node->getModifiers() & DeclarationModifiers::AccessModifiers) == 0)
type->setAccessLevel(AccessLevelPublic);//when access level is undefined, try to inherit base's access level
else
type->setAccessLevel(parseAccessLevel(node->getModifiers()));
}
declarationFinished(type->getName(), type, node);
return type;
}
示例3: visitEnum
void DeclarationAnalyzer::visitEnum(const EnumDefPtr& node)
{
if(isLazyDeclared(node))
return;
TypeBuilderPtr type = static_pointer_cast<TypeBuilder>(getOrDefineType(node));
ScopeGuard scope(symbolRegistry, type->getScope());
SCOPED_SET(ctx->currentType, type);
SCOPED_SET(ctx->currentExtension, nullptr);
SCOPED_SET(ctx->currentFunction, nullptr);
GlobalScope* global = symbolRegistry->getGlobalScope();
SymbolScope* local = symbolRegistry->getCurrentScope();
//check if it's raw value enum
bool isRawValues = false;
if(node->numParents() > 0)
{
TypePtr firstParent = lookupType(node->getParent(0));
if(firstParent)
{
Type::Category category = firstParent->getCategory();
isRawValues = category == Type::Struct || category == Type::Enum || category == Type::Aggregate || category == Type::Class;
if(isRawValues)
type->setParentType(firstParent);
}
}
//initialize enum's cases
if(isRawValues)
{
if(!node->numCases())
{
error(node, Errors::E_ENUM_WITH_NO_CASES_CANNOT_DECLARE_A_RAW_TYPE);
return;
}
//Add RawRepresentable protocol if it's not implemented
if(!type->canAssignTo(global->RawRepresentable()))
{
makeRawRepresentable(type, global);
}
TypePtr rawType = type->getParentType();
assert(rawType != nullptr);
bool integerConvertible = rawType->canAssignTo(global->IntegerLiteralConvertible());
for(auto c : node->getCases())
{
if(!c.value && !integerConvertible)
{
//Enum cases require explicit raw values when the raw type is not integer literal convertible
error(node, Errors::E_ENUM_CASES_REQUIRE_EXPLICIT_RAW_VALUES_WHEN_THE_RAW_TYPE_IS_NOT_INTEGER_LITERAL_CONVERTIBLE);
return;
}
if(c.value)
{
if(dynamic_pointer_cast<TupleType>(c.value))
{
error(node, Errors::E_ENUM_WITH_RAW_TYPE_CANNOT_HAVE_CASES_WITH_ARGUMENTS);
return;
}
}
type->addEnumCase(c.name, global->Void());
//register it to scope
local->addSymbol(SymbolPlaceHolderPtr(new SymbolPlaceHolder(c.name, type, SymbolPlaceHolder::R_PARAMETER, SymbolFlagReadable | SymbolFlagMember | SymbolFlagStatic | SymbolFlagInitialized)));
}
}
else
{
//it's an associated-values enum
for(auto c : node->getCases())
{
TypePtr associatedType = global->Void();
if(c.value)
{
TypeNodePtr typeNode = dynamic_pointer_cast<TypeNode>(c.value);
if(!typeNode)
{
error(node, Errors::E_ENUM_CASE_CANNOT_HAVE_A_RAW_VALUE_IF_THE_ENUM_DOES_NOT_HAVE_A_RAW_TYPE);
return;
}
assert(typeNode != nullptr);
associatedType = resolveType(typeNode, true);
}
type->addEnumCase(c.name, associatedType);
if(associatedType == global->Void())
local->addSymbol(SymbolPlaceHolderPtr(new SymbolPlaceHolder(c.name, type, SymbolPlaceHolder::R_PARAMETER, SymbolFlagReadable | SymbolFlagMember | SymbolFlagStatic | SymbolFlagInitialized)));
}
}
//check member declaration of enum
{
SCOPED_SET(ctx->flags, (ctx->flags & (~SemanticContext::FLAG_PROCESS_IMPLEMENTATION)) | SemanticContext::FLAG_PROCESS_DECLARATION);
for (const DeclarationPtr &decl : *node)
{
bool isStatic = decl->hasModifier(DeclarationModifiers::Class) || decl->hasModifier(DeclarationModifiers::Static);
if (!isStatic && (decl->getNodeType() == NodeType::ValueBindings))
{
error(node, Errors::E_ENUMS_MAY_NOT_CONTAIN_STORED_PROPERTIES);
continue;
}
decl->accept(this);
}
//.........这里部分代码省略.........
示例4: defineType
//.........这里部分代码省略.........
//check if it's defined as a nested type
if(ctx->currentType)
{
if(genericParams)
{
error(node, Errors::E_GENERIC_TYPE_A_NESTED_IN_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
return nullptr;
}
if(ctx->currentType->isGenericType())
{
error(node, Errors::E_TYPE_A_NESTED_IN_GENERIC_TYPE_B_IS_NOT_ALLOWED_2, id->getName(), ctx->currentType->getName());
return nullptr;
}
}
if(genericParams)
{
generic = prepareGenericTypes(genericParams);
generic->registerTo(typeScope);
}
//check inheritance clause
TypePtr parent = nullptr;
std::vector<TypePtr> protocols;
bool first = true;
for(const TypeIdentifierPtr& parentType : node->getParents())
{
parentType->accept(semanticAnalyzer);
TypePtr ptr = this->lookupType(parentType);
if(ptr->getCategory() == Type::Class && category == Type::Class)
{
if(!first)
{
//only the first type can be class type
error(parentType, Errors::E_SUPERCLASS_MUST_APPEAR_FIRST_IN_INHERITANCE_CLAUSE_1, toString(parentType));
return nullptr;
}
parent = ptr;
if(parent->hasFlags(SymbolFlagFinal))
{
error(parentType, Errors::E_INHERITANCE_FROM_A_FINAL_CLASS_A_1, parentType->getName());
return nullptr;
}
}
else if(category == Type::Enum && ptr->getCategory() != Type::Protocol)
{
if(parent)//already has a raw type
{
error(parentType, Errors::E_MULTIPLE_ENUM_RAW_TYPES_A_AND_B_2, parent->toString(), ptr->toString());
return nullptr;
}
if(!first)
{
error(parentType, Errors::E_RAW_TYPE_A_MUST_APPEAR_FIRST_IN_THE_ENUM_INHERITANCE_CLAUSE_1, ptr->toString());
return nullptr;
}
//check if the raw type is literal convertible
if(!isLiteralTypeForEnum(symbolRegistry->getGlobalScope(), ptr))
{
error(parentType, Errors::E_RAW_TYPE_A_IS_NOT_CONVERTIBLE_FROM_ANY_LITERAL_1, ptr->toString());
return nullptr;
}
if(!ptr->canAssignTo(symbolRegistry->getGlobalScope()->Equatable()))
{
error(parentType, Errors::E_RAWREPRESENTABLE_INIT_CANNOT_BE_SYNTHESIZED_BECAUSE_RAW_TYPE_A_IS_NOT_EQUATABLE_1, ptr->toString());
return nullptr;
}
parent = ptr;
}
else if(ptr->getCategory() == Type::Protocol)
{
protocols.push_back(ptr);
}
else
{
if(category == Type::Class)
error(parentType, Errors::E_INHERITANCE_FROM_NONE_PROTOCOL_NON_CLASS_TYPE_1, toString(parentType));
else
error(parentType, Errors::E_INHERITANCE_FROM_NONE_PROTOCOL_TYPE_1, toString(parentType));
return nullptr;
}
first = false;
}
//register this type
type = Type::newType(node->getIdentifier()->getName(), category, node, parent, protocols, generic);
node->setType(type);
if(parent && parent->getAccessLevel() == AccessLevelPublic && (node->getModifiers() & DeclarationModifiers::AccessModifiers) == 0)
type->setAccessLevel(AccessLevelPublic);//when access level is undefined, try to inherit base's access level
else
type->setAccessLevel(parseAccessLevel(node->getModifiers()));
currentScope->addSymbol(type);
if(node->hasModifier(DeclarationModifiers::Final))
type->setFlags(SymbolFlagFinal, true);
declarationFinished(type->getName(), type, node);
return type;
}
示例5: visitValueBinding
void SemanticAnalyzer::visitValueBinding(const ValueBindingPtr& node)
{
PatternPtr name = node->getName();
//tuple was already exploded in declaration analyzer
if(name->getNodeType() == NodeType::Tuple)
{
validateTupleTypeDeclaration(node);
}
if (name->getNodeType() != NodeType::Identifier)
return;
if(node->getOwner()->isReadOnly() && !node->getInitializer() && ctx->currentType == nullptr)
{
error(node, Errors::E_LET_REQUIRES_INITIALIZER);
return;
}
//handle type inference for temporary variable
if(node->isTemporary() && node->getInitializer())
{
//temporary variable always has an initializer
TypePtr initializerType;
TypePtr declaredType = node->getType();
SCOPED_SET(ctx->contextualType, declaredType);
node->getInitializer()->accept(this);
initializerType = node->getInitializer()->getType();
assert(initializerType != nullptr);
if(declaredType)
{
//it has both type definition and initializer, then we need to check if the initializer expression matches the type annotation
if(!initializerType->canAssignTo(declaredType))
{
error(node, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, initializerType->toString(), declaredType->toString());
return;
}
}
else
{
node->setType(initializerType);
}
}
//add implicitly constructor for Optional
IdentifierPtr id = static_pointer_cast<Identifier>(node->getName());
SymbolScope* currentScope = symbolRegistry->getCurrentScope();
TypePtr declaredType = node->getType() ? node->getType() : lookupType(node->getDeclaredType());
SCOPED_SET(ctx->contextualType, declaredType);
if(!declaredType && !node->getInitializer())
{
error(node, Errors::E_TYPE_ANNOTATION_MISSING_IN_PATTERN);
return;
}
SymbolPtr sym = currentScope->lookup(id->getIdentifier());
assert(sym != nullptr);
SymbolPlaceHolderPtr placeholder = std::dynamic_pointer_cast<SymbolPlaceHolder>(sym);
assert(placeholder != nullptr);
if(declaredType)
{
placeholder->setType(declaredType);
}
ExpressionPtr initializer = node->getInitializer();
if(initializer)
{
placeholder->setFlags(SymbolFlagInitializing, true);
ExpressionPtr initializer = transformExpression(declaredType, node->getInitializer());
node->setInitializer(initializer);
TypePtr actualType = initializer->getType();
assert(actualType != nullptr);
if(declaredType)
{
if(!Type::equals(actualType, declaredType) && !canConvertTo(initializer, declaredType))
{
error(initializer, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, actualType->toString(), declaredType->toString());
return;
}
}
if(!declaredType)
placeholder->setType(actualType);
}
assert(placeholder->getType() != nullptr);
placeholder->setFlags(SymbolFlagInitializing, false);
//optional type always considered initialized, compiler will make it has a default value nil
TypePtr symbolType = sym->getType();
GlobalScope* global = symbolRegistry->getGlobalScope();
if(initializer || global->isOptional(symbolType) || global->isImplicitlyUnwrappedOptional(symbolType))
markInitialized(placeholder);
if (initializer)
placeholder->setFlags(SymbolFlagHasInitializer, true);
if(node->isTemporary())
{
placeholder->setFlags(SymbolFlagTemporary, true);
markInitialized(placeholder);
}
if(!node->isTemporary())
//.........这里部分代码省略.........
示例6: validateTupleTypeDeclaration
void SemanticAnalyzer::validateTupleTypeDeclaration(const PatternPtr& name, const TypePtr& declType, const TypePtr& initType)
{
switch(name->getNodeType())
{
case NodeType::Identifier:
{
if(initType && declType && !initType->canAssignTo(declType))
{
error(name, Errors::E_CANNOT_CONVERT_EXPRESSION_TYPE_2, initType->toString(), declType->toString());
}
break;
}
case NodeType::TypedPattern:
{
TypedPatternPtr pat = static_pointer_cast<TypedPattern>(name);
assert(pat->getDeclaredType());
TypePtr nameType = lookupType(pat->getDeclaredType());
assert(nameType != nullptr);
if(declType && !Type::equals(nameType, declType))
{
error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
abort();
return;
}
break;
}
case NodeType::Tuple:
{
TuplePtr tuple = static_pointer_cast<Tuple>(name);
if(declType)
{
if((declType->getCategory() != Type::Tuple) || (tuple->numElements() != declType->numElementTypes()))
{
error(name, Errors::E_TYPE_ANNOTATION_DOES_NOT_MATCH_CONTEXTUAL_TYPE_A_1, declType->toString());
abort();
return;
}
}
int elements = tuple->numElements();
for(int i = 0; i < elements; i++)
{
PatternPtr element = tuple->getElement(i);
TypePtr elementDecl = declType ? declType->getElementType(i) : nullptr;
TypePtr elementInit = initType ? initType->getElementType(i) : nullptr;
validateTupleTypeDeclaration(element, elementDecl, elementInit);
}
break;
}
case NodeType::ValueBindingPattern:
break;
case NodeType::EnumCasePattern:
{
break;
}
case NodeType::TypeCase:
case NodeType::TypeCheck:
default:
error(name, Errors::E_EXPECT_TUPLE_OR_IDENTIFIER);
break;
}
}