1 /** 2 Copyright: Copyright (c) 2015-2017, Joakim Brännström. All rights reserved. 3 License: MPL-2 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 6 This Source Code Form is subject to the terms of the Mozilla Public License, 7 v.2.0. If a copy of the MPL was not distributed with this file, You can obtain 8 one at http://mozilla.org/MPL/2.0/. 9 */ 10 module cpptooling.generator.classes; 11 12 import std.typecons : Yes, No, Flag; 13 14 import dsrcgen.cpp : CppModule; 15 16 import cpptooling.data : CppClass, LocationTag; 17 import cpptooling.data.symbol : USRType; 18 19 @safe: 20 21 // for now this function is only used at one place but genCtor, genDtor and 22 // genOp is expected to use it in the future. 23 private string genLocationComment(LookupT)(USRType usr, LookupT lookup) { 24 import std.algorithm : map, joiner; 25 26 foreach (loc; lookup(usr).map!(a => a.any).joiner) { 27 return "Origin " ~ loc.toString; 28 } 29 30 return "Unknown origin for USR " ~ cast(string) usr; 31 } 32 33 /** Generate code for a C++ class from a CppClass specification. 34 * 35 * Params: 36 * lookup = expecting same signature and behavior as Container.find!LocationTag 37 */ 38 void generateHdr(LookupT)(CppClass in_c, CppModule hdr, Flag!"locationAsComment" loc_as_comment, 39 LookupT lookup, Flag!"inlineDtor" inline_dtor = No.inlineDtor) { 40 import std.array : array; 41 import std.algorithm : each, map, joiner; 42 import std.variant : visit; 43 import std.utf : byChar; 44 import cpptooling.data.representation; 45 import cpptooling.utility.sort : indexSort; 46 47 static void genCtor(const ref CppCtor m, CppModule hdr) { 48 string params = m.paramRange().joinParams(); 49 hdr.ctor(m.name, params); 50 } 51 52 static void genDtor(const ref CppDtor m, CppModule hdr, Flag!"inlineDtor" inline_dtor) { 53 if (inline_dtor) { 54 hdr.dtor(m.isVirtual() ? Yes.isVirtual : No.isVirtual, m.name)[$.end = " {}"]; 55 } else { 56 hdr.dtor(m.isVirtual() ? Yes.isVirtual : No.isVirtual, m.name); 57 } 58 } 59 60 static void genMethod(const ref CppMethod m, CppModule hdr, 61 Flag!"locationAsComment" loc_as_comment, LookupT lookup) { 62 import cpptooling.data; 63 64 if (loc_as_comment) { 65 hdr.comment(genLocationComment(m.usr, lookup))[$.begin = "/// "]; 66 } 67 68 foreach (comment; m.comments) { 69 hdr.comment(comment)[$.begin = "/// "]; 70 } 71 72 string params = m.paramRange().joinParams(); 73 auto o = hdr.method(cast(Flag!"isVirtual") m.isVirtual(), 74 m.returnType.toStringDecl, m.name, cast(Flag!"isConst") m.isConst, params); 75 if (m.isPure) { 76 o[$.end = " = 0;"]; 77 } 78 } 79 80 //TODO not implemented 81 static void genOp(const ref CppMethodOp m, CppModule hdr) { 82 } 83 84 in_c.commentRange().each!(a => hdr.comment(a)[$.begin = "/// "]); 85 auto c = hdr.class_(in_c.name, in_c.inherits.map!(a => a.toString) 86 .joiner(", ").byChar.array().idup); 87 auto pub = c.public_(); 88 89 // dfmt off 90 foreach (m; in_c.methodPublicRange 91 .array() 92 .indexSort!((ref a, ref b) => getName(a) < getName(b)) 93 ) { 94 () @trusted { 95 m.visit!( 96 (const CppMethod m) => genMethod(m, pub, loc_as_comment, lookup), 97 (const CppMethodOp m) => genOp(m, pub), 98 (const CppCtor m) => genCtor(m, pub), 99 (const CppDtor m) => genDtor(m, pub, inline_dtor)); 100 }(); 101 } 102 // dfmt on 103 hdr.sep(2); 104 }