157 lines
5.0 KiB
C++
157 lines
5.0 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "uLang/Semantics/Definition.h"
|
|
#include "uLang/Semantics/DataDefinition.h"
|
|
#include "uLang/Common/Text/UTF8String.h"
|
|
#include "uLang/Semantics/SemanticProgram.h"
|
|
#include "uLang/Semantics/SemanticScope.h"
|
|
#include "uLang/Semantics/SemanticTypes.h"
|
|
|
|
namespace uLang
|
|
{
|
|
CDefinition::CDefinition(EKind Kind, CScope& EnclosingScope, const CSymbol& Name)
|
|
: CNamed(Name)
|
|
, _EnclosingScope(EnclosingScope)
|
|
, _ParentScopeOrdinal(EnclosingScope.GetLogicalScope().AllocateNextDefinitionOrdinal())
|
|
, _Qualifier{SQualifier::Unknown()}
|
|
, _Kind(Kind)
|
|
{}
|
|
|
|
CDefinition::~CDefinition()
|
|
{
|
|
// Hack to allow CDefinition to reference a default expression for a non CExprDataDefinition named argument.
|
|
// @JIRA SOL-2695 Named parameter needs to detach double link with AST
|
|
//ULANG_ASSERTF(!GetAstNode(), "Expected %s definition AST node link to be cleared before definition is destroyed", DefinitionKindAsCString(GetKind()));
|
|
//ULANG_ASSERTF(!GetIrNode(true), "Expected %s definition IR node link to be cleared before definition is destroyed", DefinitionKindAsCString(GetKind()));
|
|
}
|
|
|
|
const CDefinition& CDefinition::GetBaseClassOverriddenDefinition() const
|
|
{
|
|
const CDefinition* BaseOverriddenDefinition = this;
|
|
while (BaseOverriddenDefinition->GetOverriddenDefinition() != nullptr && BaseOverriddenDefinition->GetOverriddenDefinition()->_EnclosingScope.GetKind() != CScope::EKind::Interface)
|
|
{
|
|
BaseOverriddenDefinition = BaseOverriddenDefinition->GetOverriddenDefinition();
|
|
}
|
|
return *BaseOverriddenDefinition;
|
|
}
|
|
|
|
SAccessLevel CDefinition::DerivedAccessLevel() const
|
|
{
|
|
const CDefinition& DefinitionAccessibilityRoot = GetDefinitionAccessibilityRoot();
|
|
if (DefinitionAccessibilityRoot._AccessLevel.IsSet())
|
|
{
|
|
return DefinitionAccessibilityRoot._AccessLevel.GetValue();
|
|
}
|
|
else
|
|
{
|
|
return DefinitionAccessibilityRoot._EnclosingScope.GetDefaultDefinitionAccessLevel();
|
|
}
|
|
}
|
|
|
|
bool CDefinition::IsInstanceMember() const
|
|
{
|
|
return _EnclosingScope.GetKind() == CScope::EKind::Class
|
|
|| _EnclosingScope.GetKind() == CScope::EKind::Interface;
|
|
}
|
|
|
|
bool CDefinition::IsDeprecated() const
|
|
{
|
|
return HasAttributeClass(_EnclosingScope.GetProgram()._deprecatedClass, _EnclosingScope.GetProgram());
|
|
}
|
|
|
|
bool CDefinition::IsExperimental() const
|
|
{
|
|
return HasAttributeClass(_EnclosingScope.GetProgram()._experimentalClass, _EnclosingScope.GetProgram());
|
|
}
|
|
|
|
bool CDefinition::IsFinal() const
|
|
{
|
|
return HasAttributeClass(_EnclosingScope.GetProgram()._finalClass, _EnclosingScope.GetProgram());
|
|
}
|
|
|
|
const CExpressionBase* CDefinition::GetNativeSpecifierExpression() const
|
|
{
|
|
return FindAttributeExpr(_EnclosingScope.GetProgram()._nativeClass, _EnclosingScope.GetProgram());
|
|
}
|
|
|
|
bool CDefinition::IsNative() const
|
|
{
|
|
return GetNativeSpecifierExpression() != nullptr;
|
|
}
|
|
|
|
bool CDefinition::IsBuiltIn() const
|
|
{
|
|
return _EnclosingScope.IsBuiltInScope();
|
|
}
|
|
|
|
CUTF8String GetQualifiedNameString(const CDefinition& Definition)
|
|
{
|
|
return CUTF8String("(%s:)%s", Definition._EnclosingScope.GetScopePath('/', CScope::EPathMode::PrefixSeparator).AsCString(), Definition.AsNameCString());
|
|
}
|
|
|
|
CUTF8String GetCrcNameString(const CDefinition& Definition)
|
|
{
|
|
if (Definition.GetKind() == CDefinition::EKind::Data && Definition._EnclosingScope.GetKind() == uLang::CScope::EKind::Interface)
|
|
{
|
|
return GetQualifiedNameString(Definition);
|
|
}
|
|
else
|
|
{
|
|
return Definition.AsNameCString();
|
|
}
|
|
}
|
|
|
|
const char* DefinitionKindAsCString(CDefinition::EKind Kind)
|
|
{
|
|
switch(Kind)
|
|
{
|
|
#define VISIT_KIND(Name, String) case CDefinition::EKind::Name: return String;
|
|
VERSE_ENUM_DEFINITION_KINDS(VISIT_KIND)
|
|
#undef VISIT_KIND
|
|
default: ULANG_UNREACHABLE();
|
|
};
|
|
}
|
|
|
|
bool CDefinition::IsAccessibleFrom(const CScope& Scope) const
|
|
{
|
|
const CDefinition& Definition = GetDefinitionAccessibilityRoot();
|
|
return Scope.CanAccess(Definition, Definition.DerivedAccessLevel());
|
|
}
|
|
|
|
const CDefinition* CDefinition::GetEnclosingDefinition() const
|
|
{
|
|
for (const CScope* Scope = &_EnclosingScope; Scope; Scope = Scope->GetParentScope())
|
|
{
|
|
if (const CDefinition* EnclosingScopeDefinition = Scope->ScopeAsDefinition())
|
|
{
|
|
return EnclosingScopeDefinition;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
bool CDefinition::IsExplicitlyLocallyQualified() const
|
|
{
|
|
return _Qualifier._Type == SQualifier::EType::Local;
|
|
}
|
|
|
|
bool CDefinition::IsLocallyQualified() const
|
|
{
|
|
// If it's explicitly `(local:)`-qualified, it's still local.
|
|
if (IsExplicitlyLocallyQualified())
|
|
{
|
|
return true;
|
|
}
|
|
// Anything within a function local-scope and which isn't explicitly-qualified
|
|
// is implicitly `(local:)`.
|
|
return _Qualifier._Type == SQualifier::EType::Unknown && _EnclosingScope.GetScopeOfKind(CScope::EKind::Function) != nullptr;
|
|
}
|
|
|
|
SQualifier CDefinition::GetImplicitQualifier() const
|
|
{
|
|
const CDefinition& BaseDefinition = GetBaseOverriddenDefinition();
|
|
return BaseDefinition._EnclosingScope.GetLogicalScope().AsQualifier();
|
|
}
|
|
|
|
} // namespace uLang
|