| 632 | // TypeDecl |
| 633 | |
| 634 | string TypeDecl::describe ( DescribeExtra extra, DescribeContracts contracts, DescribeModule dmodule, AliasDefs * aliasDefs, bool topAlias ) const { |
| 635 | TextWriter stream; |
| 636 | if ( autoToAlias ) { |
| 637 | stream << "type<"; |
| 638 | } |
| 639 | if ( aliasDefs && topAlias && extra==DescribeExtra::yes && baseType!=Type::alias |
| 640 | && baseType!=Type::autoinfer && !alias.empty() ) { |
| 641 | bool known = false; |
| 642 | for ( auto & kv : *aliasDefs ) { if ( kv.first==alias ) { known = true; break; } } |
| 643 | if ( !known ) { |
| 644 | aliasDefs->emplace_back(alias, string()); // reserve slot, break recursion cycles |
| 645 | string def = describe(extra, contracts, dmodule, aliasDefs, false); // expand this node structurally |
| 646 | for ( auto & kv : *aliasDefs ) { if ( kv.first==alias ) { kv.second = def; break; } } |
| 647 | } |
| 648 | stream << alias; |
| 649 | } else if ( baseType==Type::alias ) { |
| 650 | if ( isTag ) { |
| 651 | if ( firstType) { |
| 652 | stream << "$$("; |
| 653 | if ( firstType->dimExpr.size()==1 ) { |
| 654 | stream << *(firstType->dimExpr[0]); |
| 655 | } |
| 656 | stream << ")"; |
| 657 | } else { |
| 658 | stream << "$$()"; |
| 659 | } |
| 660 | } else { |
| 661 | stream << alias; |
| 662 | } |
| 663 | } else if ( baseType==Type::autoinfer ) { |
| 664 | stream << "auto"; |
| 665 | if ( !alias.empty() ) { |
| 666 | stream << "(" << alias << ")"; |
| 667 | } |
| 668 | } else if ( baseType==Type::option ) { |
| 669 | for ( auto & argT : argTypes ) { |
| 670 | stream << argT->describe(extra, contracts, dmodule, aliasDefs); |
| 671 | if ( argT != argTypes.back() ) { |
| 672 | stream << "|"; |
| 673 | } |
| 674 | } |
| 675 | } else if ( baseType==Type::typeDecl ) { |
| 676 | if ( dimExpr.size()==1 ) { |
| 677 | stream << "typedecl(" << (*dimExpr[0]) << ")"; |
| 678 | } else { |
| 679 | stream << "typedecl(/*invalid expression*/)"; |
| 680 | } |
| 681 | } else if ( baseType==Type::typeMacro ) { |
| 682 | stream << "$" << typeMacroName() << "("; |
| 683 | for ( size_t i=1; i!=dimExpr.size(); ++i ) { |
| 684 | if ( i!=1 ) stream << ","; |
| 685 | if ( dimExpr[i] ) { |
| 686 | stream << *(dimExpr[i]); |
| 687 | } else { |
| 688 | stream << "/*invalid expression*/"; |
| 689 | } |
| 690 | } |
| 691 | stream << ")"; |
no test coverage detected