yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
eaa8dcfcc
master
1#pragma once 2 3#include "compiler-core/slang-doc-extractor.h" 4#include "diagnostics.h" 5 6namespace CppParse 7{ 8using namespace Slang ; 9 10enum class ReflectionType :uint8_t 11{ 12NotReflected , 13Reflected , 14}; 15 16// Pre-declare 17class TypeSet ; 18class SourceOrigin ; 19 20struct ScopeNode ; 21 22class Node :public RefObject 23{ 24public : 25enum class Kind :uint8_t 26 { 27Invalid , 28 29StructType , 30ClassType , 31 32Enum , 33EnumClass , 34 35Namespace , 36AnonymousNamespace , 37 38Field , 39EnumCase , 40 41TypeDef , 42 43Callable ,///< Functions/methods 44 45Other ,///< Used 'other' parsing like for TYPE 46Unknown ,///< Used for marking tokens consumed but usage is not known 47 48CountOf , 49 }; 50 51enum class KindRange 52 { 53ScopeStart = int (Kind ::StructType ), 54ScopeEnd = int (Kind ::AnonymousNamespace ), 55 56ClassLikeStart = int (Kind ::StructType ), 57ClassLikeEnd = int (Kind ::ClassType ), 58 59ScopeTypeStart = int (Kind ::StructType ), 60ScopeTypeEnd = int (Kind ::EnumClass ), 61 62OtherTypeStart = int (Kind ::TypeDef ), 63OtherTypeEnd = int (Kind ::TypeDef ), 64 65EnumStart = int (Kind ::Enum ), 66EnumEnd = int (Kind ::EnumClass ), 67 }; 68 69/// Returns true if kind can cast to this type 70/// Used for implementing as<T> casting 71static bool isOfKind (Kind kind ) 72 { 73SLANG_UNUSED (kind ); 74return true; 75 } 76 77static bool isKindScope (Kind kind ) 78 { 79return int (kind ) >=int (KindRange ::ScopeStart )&& int (kind ) <=int (KindRange ::ScopeEnd ); 80 } 81static bool isKindClassLike (Kind kind ) 82 { 83return int (kind ) >=int (KindRange ::ClassLikeStart )&& 84int (kind ) <=int (KindRange ::ClassLikeEnd ); 85 } 86static bool isKindEnumLike (Kind kind ) 87 { 88return int (kind ) >=int (KindRange ::EnumStart )&& int (kind ) <=int (KindRange ::EnumEnd ); 89 } 90 91/// It a type, but doesn't have a scope 92static bool isKindOtherType (Kind kind ) 93 { 94return int (kind ) >=int (KindRange ::OtherTypeStart )&& 95int (kind ) <=int (KindRange ::OtherTypeEnd ); 96 } 97/// Is a type and has a scope 98static bool isKindScopeType (Kind kind ) 99 { 100return int (kind ) >=int (KindRange ::ScopeTypeStart )&& 101int (kind ) <=int (KindRange ::ScopeTypeEnd ); 102 } 103 104/// True if the kind is any type 105static bool isKindType (Kind kind ) {return isKindOtherType (kind )|| isKindScopeType (kind ); } 106 107/// True if the kind can accept contained types 108static bool canKindContainTypes (Kind type ) 109 { 110switch (type ) 111 { 112case Kind ::StructType : 113case Kind ::ClassType : 114case Kind ::Namespace : 115case Kind ::AnonymousNamespace : 116 { 117return true; 118 } 119default : 120break ; 121 } 122return false; 123 } 124 125bool isNamespace ()const {return m_kind == Kind ::Namespace ; } 126bool isClassLike ()const {return isKindClassLike (m_kind ); } 127bool isScope ()const {return isKindScope (m_kind ); } 128bool isEnumLike ()const {return isKindEnumLike (m_kind ); } 129 130/// These are useful for the filter 131static bool isClassLikeAndReflected (Node * node ) 132 { 133return node -> isClassLike ()&& node -> isReflected (); 134 } 135static bool isClassLike (Node * node ) {return isKindClassLike (node -> m_kind ); } 136 137virtual void dump (int indent ,StringBuilder & out )= 0 ; 138 139/// Do depth first traversal of nodes in scopes 140virtual void calcScopeDepthFirst (List < Node *>& outNodes ); 141 142/// Calculate the absolute name for this namespace/type 143void calcAbsoluteName (StringBuilder & outName )const ; 144 145/// Get the absolute name 146String getAbsoluteName ()const 147 { 148StringBuilder buf ; 149calcAbsoluteName (buf ); 150return buf .produceString (); 151 } 152 153/// Calculate the scope path to this node, from the root 154void calcScopePath (List < Node *>& outPath ) {calcScopePath (this ,outPath ); } 155 156/// True if reflected 157bool isReflected ()const {return m_reflectionType == ReflectionType ::Reflected ; } 158 159SourceLoc getSourceLoc ()const {return m_name .getLoc (); } 160 161ScopeNode * getRootScope (); 162 163typedef bool (* Filter )(Node * node ); 164 165template < typename T > 166static void filter (Filter filter ,List < T *>& io ) 167 { 168const Node * _isNodeDerived = (T * )nullptr ; 169SLANG_UNUSED (_isNodeDerived ); 170filterImpl (filter ,reinterpret_cast < List < Node *>& >(io)); 171} 172 173static void filterImpl ( Filter filter, List < Node *>& io); 174 175static void calcScopePath ( Node * node, List < Node *>& outPath); 176 177/// Lookup a name in just the specified scope 178/// Handles anonymous namespaces, or name lookups that are in the parents space 179static Node * lookupNameInScope ( ScopeNode * scope, const UnownedStringSlice & name); 180 181/// Lookup from a path 182static Node * lookupFromScope ( ScopeNode * scope, const UnownedStringSlice * path, Index pathCount); 183/// Looks up *just* from the specified scope. 184static Node * lookupFromScope ( ScopeNode * scope, const UnownedStringSlice & slice); 185 186/// Look up name (which can contain ::) 187static Node * lookup ( ScopeNode * scope, const UnownedStringSlice & name); 188 189static void splitPath ( const UnownedStringSlice & slice, List < UnownedStringSlice >& outSplitPath); 190 191/// If markup is specified dump it 192void dumpMarkup ( int indent, StringBuilder & out); 193 194Node( Kind type) 195: m_kind ( type ), m_parentScope ( nullptr ), m_reflectionType ( ReflectionType ::NotReflected) 196{ 197} 198 199Kind m_kind; ///< The kind of node this is 200ReflectionType m_reflectionType; ///< Classes can be traversed, but not reflected. To be 201///< reflected they have to contain the marker 202 203MarkupVisibility m_markupVisibility = 204MarkupVisibility::Public; ///< The visibility of the markup 205String m_markup; ///< Documentation associated with this node 206 207Token m_name; ///< The name of this scope/type 208 209ScopeNode * m_parentScope; ///< The scope this type/scope is defined in 210}; 211 212struct ScopeNode : public Node 213{ 214typedef Node Super ; 215 216static bool isOfKind ( Kind kind) { return isKindScope (kind); } 217 218virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 219virtual void calcScopeDepthFirst (List < Node *>& outNodes) SLANG_OVERRIDE ; 220 221/// True if can contain callable entries 222bool canContainCallable () const { return isClassLike () || isNamespace (); } 223 224/// True if can accept fields (class like types can) 225bool canContainFields () const { return isClassLike (); } 226 227/// True if the scope can accept types 228bool canContainTypes () const { return canKindContainTypes (m_kind); } 229 230/// Gets the reflection for any contained types 231ReflectionType getContainedReflectionType () const 232{ 233return m_reflectionType == ReflectionType::NotReflected ? ReflectionType::NotReflected 234: m_reflectionOverride; 235} 236 237/// Add a child node to this nodes scope 238void addChild ( Node * child); 239/// Adds the child but does not add the name to the map 240void addChildIgnoringName ( Node * child); 241 242/// Find a child node in this scope with the specified name. Return nullptr if not found 243Node * findChild ( const UnownedStringSlice & name) const; 244 245/// Gets the anonymous namespace associated with this scope 246ScopeNode * getAnonymousNamespace (); 247 248ScopeNode( Kind kind) 249: Super ( kind ) 250, m_reflectionOverride ( ReflectionType ::Reflected) 251, m_anonymousNamespace ( nullptr ) 252{ 253} 254 255/// For child types, fields, how reflection is handled. If this type is not reflected 256ReflectionType m_reflectionOverride; 257 258/// All of the types and namespaces in this *scope* 259List < RefPtr < Node>> m_children; 260 261/// Map from a name (in this scope) to the Node 262Dictionary < UnownedStringSlice, Node *> m_childMap; 263 264/// There can only be one anonymousNamespace for a scope. If there is one it's held here 265ScopeNode * m_anonymousNamespace; 266}; 267 268struct FieldNode : public Node 269{ 270typedef Node Super ; 271 272static bool isOfKind ( Kind kind) { return kind == Kind::Field; } 273 274virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 275 276FieldNode () 277: Super( Kind :: Field ) 278{ 279} 280 281UnownedStringSlice m_fieldType; 282 283bool m_isStatic = false; 284 285/// TODO(JS): We may want to add initializer tokens 286}; 287 288struct ClassLikeNode : public ScopeNode 289{ 290typedef ScopeNode Super ; 291 292static bool isOfKind ( Kind kind) { return isKindClassLike (kind); } 293 294/// Add a node that is derived from this 295void addDerived ( ClassLikeNode * derived); 296 297/// Dump all of the derived types 298void dumpDerived ( int indentCount, StringBuilder & out); 299 300/// Calculates the derived depth 301Index calcDerivedDepth () const ; 302 303/// Find the last (reflected) derived type 304ClassLikeNode * findLastDerived (); 305 306/// Traverse the hierarchy of derived nodes, in depth first order 307void calcDerivedDepthFirst ( List < ClassLikeNode *>& outNodes); 308 309/// True if has a derived type that is reflected 310bool hasReflectedDerivedType () const; 311 312/// Stores in out any reflected derived types 313void getReflectedDerivedTypes ( List < ClassLikeNode *>& out) const; 314 315// Node Impl 316virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 317 318ClassLikeNode ( Kind kind) 319: Super (kind), m_origin ( nullptr ), m_typeSet ( nullptr ), m_superNode ( nullptr ) 320{ 321SLANG_ASSERT ( kind == Kind::ClassType || kind == Kind::StructType); 322} 323 324SourceOrigin * m_origin; ///< Defines where this was uniquely defined. 325 326Token m_marker; ///< The marker associated with this scope (typically the marker is SLANG_CLASS 327///< etc, that is used to identify reflectedType) 328 329List < RefPtr < ClassLikeNode>> m_derivedTypes; ///< All of the types derived from this type 330 331TypeSet * m_typeSet; ///< The typeset this type belongs to. 332 333Token m_super; ///< Super class name 334ClassLikeNode * m_superNode; ///< If this is a class/struct, the type it is derived from (or 335///< nullptr if base) 336}; 337 338struct CallableNode : public Node 339{ 340typedef Node Super ; 341 342static bool isOfKind ( Kind kind) { return kind == Kind::Callable; } 343 344virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 345 346CallableNode () 347: Super( Kind :: Callable ) 348{ 349} 350 351struct Param 352{ 353UnownedStringSlice m_type ; 354Token m_name ; 355}; 356 357UnownedStringSlice m_returnType; 358 359CallableNode * m_nextOverload = nullptr ; 360 361List < Param > m_params; 362 363bool m_isStatic = false; 364bool m_isVirtual = false; 365bool m_isPure = false; 366}; 367 368struct EnumCaseNode : public Node 369{ 370typedef Node Super ; 371 372static bool isOfKind ( Kind kind) { return kind == Kind::EnumCase; } 373 374virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 375 376EnumCaseNode () 377: Super( Kind :: EnumCase ) 378{ 379} 380 381// Tokens that make up the value. If not defined will be empty 382List < Token > m_valueTokens; 383}; 384 385struct EnumNode : public ScopeNode 386{ 387typedef ScopeNode Super ; 388static bool isOfKind ( Kind kind) { return isKindEnumLike (kind); } 389 390virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 391 392EnumNode ( Kind kind) 393: Super (kind) 394{ 395SLANG_ASSERT ( isKindEnumLike (kind)); 396} 397 398List < Token > m_backingTokens; 399}; 400 401struct TypeDefNode : public Node 402{ 403typedef Node Super ; 404static bool isOfKind ( Kind kind) { return kind == Kind::TypeDef; } 405 406virtual void dump ( int indent, StringBuilder & out) SLANG_OVERRIDE ; 407 408TypeDefNode () 409: Super( Kind :: TypeDef ) 410{ 411} 412 413List < Token > m_targetTypeTokens; 414}; 415 416template < typename T > 417T * as (Node * node) 418{ 419return (node && T :: isOfKind (node -> m_kind )) ? static_cast < T *> (node) : nullptr ; 420} 421 422} // namespace CppParse