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 my.sumtype; 15 16 import dsrcgen.cpp : CppModule; 17 18 import cpptooling.data : CppClass, LocationTag; 19 import cpptooling.data.symbol : USRType; 20 21 @safe: 22 23 // for now this function is only used at one place but genCtor, genDtor and 24 // genOp is expected to use it in the future. 25 private string genLocationComment(LookupT)(USRType usr, LookupT lookup) { 26 import std.algorithm : map, joiner; 27 28 foreach (loc; lookup(usr).map!(a => a.any).joiner) { 29 return "Origin " ~ loc.toString; 30 } 31 32 return "Unknown origin for USR " ~ cast(string) usr; 33 } 34 35 /** Generate code for a C++ class from a CppClass specification. 36 * 37 * Params: 38 * lookup = expecting same signature and behavior as Container.find!LocationTag 39 */ 40 void generateHdr(LookupT)(CppClass in_c, CppModule hdr, Flag!"locationAsComment" loc_as_comment, 41 LookupT lookup, Flag!"inlineDtor" inline_dtor = No.inlineDtor) @trusted { 42 import std.array : array; 43 import std.algorithm : each, map, joiner; 44 import std.variant : visit; 45 import std.utf : byChar; 46 import cpptooling.data.representation; 47 import cpptooling.utility.sort : indexSort; 48 49 static void genCtor(ref CppCtor m, CppModule hdr) { 50 string params = m.paramRange().joinParams(); 51 hdr.ctor(m.name.get, params); 52 } 53 54 static void genDtor(ref CppDtor m, CppModule hdr, Flag!"inlineDtor" inline_dtor) { 55 if (inline_dtor) { 56 hdr.dtor(m.isVirtual() ? Yes.isVirtual : No.isVirtual, m.name)[$.end = " {}"]; 57 } else { 58 hdr.dtor(m.isVirtual() ? Yes.isVirtual : No.isVirtual, m.name); 59 } 60 } 61 62 static void genMethod(ref CppMethod m, CppModule hdr, 63 Flag!"locationAsComment" loc_as_comment, LookupT lookup) { 64 import cpptooling.data; 65 66 if (loc_as_comment) { 67 hdr.comment(genLocationComment(m.usr.get, lookup))[$.begin = "/// "]; 68 } 69 70 foreach (comment; m.comments) { 71 hdr.comment(comment)[$.begin = "/// "]; 72 } 73 74 string params = m.paramRange().joinParams(); 75 auto o = hdr.method(cast(Flag!"isVirtual") m.isVirtual(), 76 m.returnType.toStringDecl, m.name, cast(Flag!"isConst") m.isConst, params); 77 if (m.isPure) { 78 o[$.end = " = 0;"]; 79 } 80 } 81 82 //TODO not implemented 83 static void genOp(ref CppMethodOp m, CppModule hdr) { 84 } 85 86 in_c.commentRange().each!(a => hdr.comment(a)[$.begin = "/// "]); 87 auto c = hdr.class_(in_c.name, in_c.inherits.map!(a => a.toString) 88 .joiner(", ").byChar.array().idup); 89 auto pub = c.public_(); 90 91 // dfmt off 92 foreach (m; in_c.methodPublicRange 93 .array 94 .indexSort!((ref a, ref b) => getName(a) < getName(b)) 95 ) { 96 m.match!( 97 (CppMethod m) => genMethod(m, pub, loc_as_comment, lookup), 98 (CppMethodOp m) => genOp(m, pub), 99 (CppCtor m) => genCtor(m, pub), 100 (CppDtor m) => genDtor(m, pub, inline_dtor)); 101 } 102 // dfmt on 103 hdr.sep(2); 104 }