1*a9ac8606Spatrick#!/usr/bin/env python3 2*a9ac8606Spatrick# -*- coding: utf-8 -*- 3*a9ac8606Spatrick 4*a9ac8606Spatrickimport os 5*a9ac8606Spatrickimport sys 6*a9ac8606Spatrickimport json 7*a9ac8606Spatrickimport filecmp 8*a9ac8606Spatrickimport shutil 9*a9ac8606Spatrickimport argparse 10*a9ac8606Spatrick 11*a9ac8606Spatrickclass Generator(object): 12*a9ac8606Spatrick 13*a9ac8606Spatrick implementationContent = '' 14*a9ac8606Spatrick 15*a9ac8606Spatrick RefClades = {"DeclarationNameInfo", 16*a9ac8606Spatrick "NestedNameSpecifierLoc", 17*a9ac8606Spatrick "TemplateArgumentLoc", 18*a9ac8606Spatrick "TypeLoc"} 19*a9ac8606Spatrick 20*a9ac8606Spatrick def __init__(self, templateClasses): 21*a9ac8606Spatrick self.templateClasses = templateClasses 22*a9ac8606Spatrick 23*a9ac8606Spatrick def GeneratePrologue(self): 24*a9ac8606Spatrick 25*a9ac8606Spatrick self.implementationContent += \ 26*a9ac8606Spatrick """ 27*a9ac8606Spatrick/*===- Generated file -------------------------------------------*- C++ -*-===*\ 28*a9ac8606Spatrick|* *| 29*a9ac8606Spatrick|* Introspection of available AST node SourceLocations *| 30*a9ac8606Spatrick|* *| 31*a9ac8606Spatrick|* Automatically generated file, do not edit! *| 32*a9ac8606Spatrick|* *| 33*a9ac8606Spatrick\*===----------------------------------------------------------------------===*/ 34*a9ac8606Spatrick 35*a9ac8606Spatricknamespace clang { 36*a9ac8606Spatricknamespace tooling { 37*a9ac8606Spatrick 38*a9ac8606Spatrickusing LocationAndString = SourceLocationMap::value_type; 39*a9ac8606Spatrickusing RangeAndString = SourceRangeMap::value_type; 40*a9ac8606Spatrick 41*a9ac8606Spatrickbool NodeIntrospection::hasIntrospectionSupport() { return true; } 42*a9ac8606Spatrick 43*a9ac8606Spatrickstruct RecursionPopper 44*a9ac8606Spatrick{ 45*a9ac8606Spatrick RecursionPopper(std::vector<clang::TypeLoc> &TypeLocRecursionGuard) 46*a9ac8606Spatrick : TLRG(TypeLocRecursionGuard) 47*a9ac8606Spatrick { 48*a9ac8606Spatrick 49*a9ac8606Spatrick } 50*a9ac8606Spatrick 51*a9ac8606Spatrick ~RecursionPopper() 52*a9ac8606Spatrick { 53*a9ac8606Spatrick TLRG.pop_back(); 54*a9ac8606Spatrick } 55*a9ac8606Spatrick 56*a9ac8606Spatrickprivate: 57*a9ac8606Spatrickstd::vector<clang::TypeLoc> &TLRG; 58*a9ac8606Spatrick}; 59*a9ac8606Spatrick""" 60*a9ac8606Spatrick 61*a9ac8606Spatrick def GenerateBaseGetLocationsDeclaration(self, CladeName): 62*a9ac8606Spatrick InstanceDecoration = "*" 63*a9ac8606Spatrick if CladeName in self.RefClades: 64*a9ac8606Spatrick InstanceDecoration = "&" 65*a9ac8606Spatrick 66*a9ac8606Spatrick self.implementationContent += \ 67*a9ac8606Spatrick """ 68*a9ac8606Spatrickvoid GetLocationsImpl(SharedLocationCall const& Prefix, 69*a9ac8606Spatrick clang::{0} const {1}Object, SourceLocationMap &Locs, 70*a9ac8606Spatrick SourceRangeMap &Rngs, 71*a9ac8606Spatrick std::vector<clang::TypeLoc> &TypeLocRecursionGuard); 72*a9ac8606Spatrick""".format(CladeName, InstanceDecoration) 73*a9ac8606Spatrick 74*a9ac8606Spatrick def GenerateSrcLocMethod(self, 75*a9ac8606Spatrick ClassName, ClassData, CreateLocalRecursionGuard): 76*a9ac8606Spatrick 77*a9ac8606Spatrick NormalClassName = ClassName 78*a9ac8606Spatrick RecursionGuardParam = ('' if CreateLocalRecursionGuard else \ 79*a9ac8606Spatrick ', std::vector<clang::TypeLoc>& TypeLocRecursionGuard') 80*a9ac8606Spatrick 81*a9ac8606Spatrick if "templateParms" in ClassData: 82*a9ac8606Spatrick TemplatePreamble = "template <typename " 83*a9ac8606Spatrick ClassName += "<" 84*a9ac8606Spatrick First = True 85*a9ac8606Spatrick for TA in ClassData["templateParms"]: 86*a9ac8606Spatrick if not First: 87*a9ac8606Spatrick ClassName += ", " 88*a9ac8606Spatrick TemplatePreamble += ", typename " 89*a9ac8606Spatrick 90*a9ac8606Spatrick First = False 91*a9ac8606Spatrick ClassName += TA 92*a9ac8606Spatrick TemplatePreamble += TA 93*a9ac8606Spatrick 94*a9ac8606Spatrick ClassName += ">" 95*a9ac8606Spatrick TemplatePreamble += ">\n"; 96*a9ac8606Spatrick self.implementationContent += TemplatePreamble 97*a9ac8606Spatrick 98*a9ac8606Spatrick self.implementationContent += \ 99*a9ac8606Spatrick """ 100*a9ac8606Spatrickstatic void GetLocations{0}(SharedLocationCall const& Prefix, 101*a9ac8606Spatrick clang::{1} const &Object, 102*a9ac8606Spatrick SourceLocationMap &Locs, SourceRangeMap &Rngs {2}) 103*a9ac8606Spatrick{{ 104*a9ac8606Spatrick""".format(NormalClassName, ClassName, RecursionGuardParam) 105*a9ac8606Spatrick 106*a9ac8606Spatrick if 'sourceLocations' in ClassData: 107*a9ac8606Spatrick for locName in ClassData['sourceLocations']: 108*a9ac8606Spatrick self.implementationContent += \ 109*a9ac8606Spatrick """ 110*a9ac8606Spatrick Locs.insert(LocationAndString(Object.{0}(), 111*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"))); 112*a9ac8606Spatrick""".format(locName) 113*a9ac8606Spatrick 114*a9ac8606Spatrick self.implementationContent += '\n' 115*a9ac8606Spatrick 116*a9ac8606Spatrick if 'sourceRanges' in ClassData: 117*a9ac8606Spatrick for rngName in ClassData['sourceRanges']: 118*a9ac8606Spatrick self.implementationContent += \ 119*a9ac8606Spatrick """ 120*a9ac8606Spatrick Rngs.insert(RangeAndString(Object.{0}(), 121*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"))); 122*a9ac8606Spatrick""".format(rngName) 123*a9ac8606Spatrick 124*a9ac8606Spatrick self.implementationContent += '\n' 125*a9ac8606Spatrick 126*a9ac8606Spatrick if 'typeLocs' in ClassData or 'typeSourceInfos' in ClassData \ 127*a9ac8606Spatrick or 'nestedNameLocs' in ClassData \ 128*a9ac8606Spatrick or 'declNameInfos' in ClassData: 129*a9ac8606Spatrick if CreateLocalRecursionGuard: 130*a9ac8606Spatrick self.implementationContent += \ 131*a9ac8606Spatrick 'std::vector<clang::TypeLoc> TypeLocRecursionGuard;\n' 132*a9ac8606Spatrick 133*a9ac8606Spatrick self.implementationContent += '\n' 134*a9ac8606Spatrick 135*a9ac8606Spatrick if 'typeLocs' in ClassData: 136*a9ac8606Spatrick for typeLoc in ClassData['typeLocs']: 137*a9ac8606Spatrick 138*a9ac8606Spatrick self.implementationContent += \ 139*a9ac8606Spatrick """ 140*a9ac8606Spatrick if (Object.{0}()) {{ 141*a9ac8606Spatrick GetLocationsImpl( 142*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"), 143*a9ac8606Spatrick Object.{0}(), Locs, Rngs, TypeLocRecursionGuard); 144*a9ac8606Spatrick }} 145*a9ac8606Spatrick """.format(typeLoc) 146*a9ac8606Spatrick 147*a9ac8606Spatrick self.implementationContent += '\n' 148*a9ac8606Spatrick if 'typeSourceInfos' in ClassData: 149*a9ac8606Spatrick for tsi in ClassData['typeSourceInfos']: 150*a9ac8606Spatrick self.implementationContent += \ 151*a9ac8606Spatrick """ 152*a9ac8606Spatrick if (Object.{0}()) {{ 153*a9ac8606Spatrick GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>( 154*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}", 155*a9ac8606Spatrick LocationCall::ReturnsPointer), "getTypeLoc"), 156*a9ac8606Spatrick Object.{0}()->getTypeLoc(), Locs, Rngs, TypeLocRecursionGuard); 157*a9ac8606Spatrick }} 158*a9ac8606Spatrick """.format(tsi) 159*a9ac8606Spatrick 160*a9ac8606Spatrick self.implementationContent += '\n' 161*a9ac8606Spatrick 162*a9ac8606Spatrick if 'nestedNameLocs' in ClassData: 163*a9ac8606Spatrick for NN in ClassData['nestedNameLocs']: 164*a9ac8606Spatrick self.implementationContent += \ 165*a9ac8606Spatrick """ 166*a9ac8606Spatrick if (Object.{0}()) 167*a9ac8606Spatrick GetLocationsImpl( 168*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"), 169*a9ac8606Spatrick Object.{0}(), Locs, Rngs, TypeLocRecursionGuard); 170*a9ac8606Spatrick """.format(NN) 171*a9ac8606Spatrick 172*a9ac8606Spatrick if 'declNameInfos' in ClassData: 173*a9ac8606Spatrick for declName in ClassData['declNameInfos']: 174*a9ac8606Spatrick 175*a9ac8606Spatrick self.implementationContent += \ 176*a9ac8606Spatrick """ 177*a9ac8606Spatrick GetLocationsImpl( 178*a9ac8606Spatrick llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "{0}"), 179*a9ac8606Spatrick Object.{0}(), Locs, Rngs, TypeLocRecursionGuard); 180*a9ac8606Spatrick """.format(declName) 181*a9ac8606Spatrick 182*a9ac8606Spatrick self.implementationContent += '}\n' 183*a9ac8606Spatrick 184*a9ac8606Spatrick def GenerateFiles(self, OutputFile): 185*a9ac8606Spatrick with open(os.path.join(os.getcwd(), 186*a9ac8606Spatrick OutputFile), 'w') as f: 187*a9ac8606Spatrick f.write(self.implementationContent) 188*a9ac8606Spatrick 189*a9ac8606Spatrick def GenerateBaseGetLocationsFunction(self, ASTClassNames, 190*a9ac8606Spatrick ClassEntries, CladeName, InheritanceMap, 191*a9ac8606Spatrick CreateLocalRecursionGuard): 192*a9ac8606Spatrick 193*a9ac8606Spatrick MethodReturnType = 'NodeLocationAccessors' 194*a9ac8606Spatrick InstanceDecoration = "*" 195*a9ac8606Spatrick if CladeName in self.RefClades: 196*a9ac8606Spatrick InstanceDecoration = "&" 197*a9ac8606Spatrick 198*a9ac8606Spatrick Signature = \ 199*a9ac8606Spatrick 'GetLocations(clang::{0} const {1}Object)'.format( 200*a9ac8606Spatrick CladeName, InstanceDecoration) 201*a9ac8606Spatrick ImplSignature = \ 202*a9ac8606Spatrick """ 203*a9ac8606Spatrick GetLocationsImpl(SharedLocationCall const& Prefix, 204*a9ac8606Spatrick clang::{0} const {1}Object, SourceLocationMap &Locs, 205*a9ac8606Spatrick SourceRangeMap &Rngs, 206*a9ac8606Spatrick std::vector<clang::TypeLoc> &TypeLocRecursionGuard) 207*a9ac8606Spatrick """.format(CladeName, InstanceDecoration) 208*a9ac8606Spatrick 209*a9ac8606Spatrick self.implementationContent += 'void {0} {{ '.format(ImplSignature) 210*a9ac8606Spatrick 211*a9ac8606Spatrick if CladeName == "TypeLoc": 212*a9ac8606Spatrick self.implementationContent += 'if (Object.isNull()) return;' 213*a9ac8606Spatrick 214*a9ac8606Spatrick self.implementationContent += \ 215*a9ac8606Spatrick """ 216*a9ac8606Spatrick if (llvm::find(TypeLocRecursionGuard, Object) != TypeLocRecursionGuard.end()) 217*a9ac8606Spatrick return; 218*a9ac8606Spatrick TypeLocRecursionGuard.push_back(Object); 219*a9ac8606Spatrick RecursionPopper RAII(TypeLocRecursionGuard); 220*a9ac8606Spatrick """ 221*a9ac8606Spatrick 222*a9ac8606Spatrick RecursionGuardParam = '' 223*a9ac8606Spatrick if not CreateLocalRecursionGuard: 224*a9ac8606Spatrick RecursionGuardParam = ', TypeLocRecursionGuard' 225*a9ac8606Spatrick 226*a9ac8606Spatrick ArgPrefix = '*' 227*a9ac8606Spatrick if CladeName in self.RefClades: 228*a9ac8606Spatrick ArgPrefix = '' 229*a9ac8606Spatrick self.implementationContent += \ 230*a9ac8606Spatrick 'GetLocations{0}(Prefix, {1}Object, Locs, Rngs {2});'.format( 231*a9ac8606Spatrick CladeName, ArgPrefix, RecursionGuardParam) 232*a9ac8606Spatrick 233*a9ac8606Spatrick if CladeName == "TypeLoc": 234*a9ac8606Spatrick self.implementationContent += \ 235*a9ac8606Spatrick ''' 236*a9ac8606Spatrick if (auto QTL = Object.getAs<clang::QualifiedTypeLoc>()) { 237*a9ac8606Spatrick auto Dequalified = QTL.getNextTypeLoc(); 238*a9ac8606Spatrick return GetLocationsImpl(llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getNextTypeLoc"), 239*a9ac8606Spatrick Dequalified, 240*a9ac8606Spatrick Locs, 241*a9ac8606Spatrick Rngs, 242*a9ac8606Spatrick TypeLocRecursionGuard); 243*a9ac8606Spatrick }''' 244*a9ac8606Spatrick 245*a9ac8606Spatrick for ASTClassName in ASTClassNames: 246*a9ac8606Spatrick if ASTClassName in self.templateClasses: 247*a9ac8606Spatrick continue 248*a9ac8606Spatrick if ASTClassName == CladeName: 249*a9ac8606Spatrick continue 250*a9ac8606Spatrick if CladeName != "TypeLoc": 251*a9ac8606Spatrick self.implementationContent += \ 252*a9ac8606Spatrick """ 253*a9ac8606Spatrickif (auto Derived = llvm::dyn_cast<clang::{0}>(Object)) {{ 254*a9ac8606Spatrick GetLocations{0}(Prefix, *Derived, Locs, Rngs {1}); 255*a9ac8606Spatrick}} 256*a9ac8606Spatrick""".format(ASTClassName, RecursionGuardParam) 257*a9ac8606Spatrick continue 258*a9ac8606Spatrick 259*a9ac8606Spatrick self.GenerateBaseTypeLocVisit(ASTClassName, ClassEntries, 260*a9ac8606Spatrick RecursionGuardParam, InheritanceMap) 261*a9ac8606Spatrick 262*a9ac8606Spatrick self.implementationContent += '}' 263*a9ac8606Spatrick 264*a9ac8606Spatrick self.implementationContent += \ 265*a9ac8606Spatrick """ 266*a9ac8606Spatrick{0} NodeIntrospection::{1} {{ 267*a9ac8606Spatrick NodeLocationAccessors Result; 268*a9ac8606Spatrick SharedLocationCall Prefix; 269*a9ac8606Spatrick std::vector<clang::TypeLoc> TypeLocRecursionGuard; 270*a9ac8606Spatrick 271*a9ac8606Spatrick GetLocationsImpl(Prefix, Object, Result.LocationAccessors, 272*a9ac8606Spatrick Result.RangeAccessors, TypeLocRecursionGuard); 273*a9ac8606Spatrick""".format(MethodReturnType, Signature) 274*a9ac8606Spatrick 275*a9ac8606Spatrick self.implementationContent += 'return Result; }' 276*a9ac8606Spatrick 277*a9ac8606Spatrick def GenerateBaseTypeLocVisit(self, ASTClassName, ClassEntries, 278*a9ac8606Spatrick RecursionGuardParam, InheritanceMap): 279*a9ac8606Spatrick CallPrefix = 'Prefix' 280*a9ac8606Spatrick if ASTClassName != 'TypeLoc': 281*a9ac8606Spatrick CallPrefix = \ 282*a9ac8606Spatrick '''llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, 283*a9ac8606Spatrick "getAs<clang::{0}>", LocationCall::IsCast) 284*a9ac8606Spatrick '''.format(ASTClassName) 285*a9ac8606Spatrick 286*a9ac8606Spatrick if ASTClassName in ClassEntries: 287*a9ac8606Spatrick 288*a9ac8606Spatrick self.implementationContent += \ 289*a9ac8606Spatrick """ 290*a9ac8606Spatrick if (auto ConcreteTL = Object.getAs<clang::{0}>()) 291*a9ac8606Spatrick GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3}); 292*a9ac8606Spatrick """.format(ASTClassName, ASTClassName, 293*a9ac8606Spatrick CallPrefix, RecursionGuardParam) 294*a9ac8606Spatrick 295*a9ac8606Spatrick if ASTClassName in InheritanceMap: 296*a9ac8606Spatrick for baseTemplate in self.templateClasses: 297*a9ac8606Spatrick if baseTemplate in InheritanceMap[ASTClassName]: 298*a9ac8606Spatrick self.implementationContent += \ 299*a9ac8606Spatrick """ 300*a9ac8606Spatrick if (auto ConcreteTL = Object.getAs<clang::{0}>()) 301*a9ac8606Spatrick GetLocations{1}({2}, ConcreteTL, Locs, Rngs {3}); 302*a9ac8606Spatrick """.format(InheritanceMap[ASTClassName], baseTemplate, 303*a9ac8606Spatrick CallPrefix, RecursionGuardParam) 304*a9ac8606Spatrick 305*a9ac8606Spatrick 306*a9ac8606Spatrick def GenerateDynNodeVisitor(self, CladeNames): 307*a9ac8606Spatrick MethodReturnType = 'NodeLocationAccessors' 308*a9ac8606Spatrick 309*a9ac8606Spatrick Signature = \ 310*a9ac8606Spatrick 'GetLocations(clang::DynTypedNode const &Node)' 311*a9ac8606Spatrick 312*a9ac8606Spatrick self.implementationContent += MethodReturnType \ 313*a9ac8606Spatrick + ' NodeIntrospection::' + Signature + '{' 314*a9ac8606Spatrick 315*a9ac8606Spatrick for CladeName in CladeNames: 316*a9ac8606Spatrick if CladeName == "DeclarationNameInfo": 317*a9ac8606Spatrick continue 318*a9ac8606Spatrick self.implementationContent += \ 319*a9ac8606Spatrick """ 320*a9ac8606Spatrick if (const auto *N = Node.get<{0}>()) 321*a9ac8606Spatrick """.format(CladeName) 322*a9ac8606Spatrick ArgPrefix = "" 323*a9ac8606Spatrick if CladeName in self.RefClades: 324*a9ac8606Spatrick ArgPrefix = "*" 325*a9ac8606Spatrick self.implementationContent += \ 326*a9ac8606Spatrick """ 327*a9ac8606Spatrick return GetLocations({0}const_cast<{1} *>(N));""".format(ArgPrefix, CladeName) 328*a9ac8606Spatrick 329*a9ac8606Spatrick self.implementationContent += '\nreturn {}; }' 330*a9ac8606Spatrick 331*a9ac8606Spatrick def GenerateEpilogue(self): 332*a9ac8606Spatrick 333*a9ac8606Spatrick self.implementationContent += ''' 334*a9ac8606Spatrick } 335*a9ac8606Spatrick} 336*a9ac8606Spatrick''' 337*a9ac8606Spatrick 338*a9ac8606Spatrickdef main(): 339*a9ac8606Spatrick 340*a9ac8606Spatrick parser = argparse.ArgumentParser() 341*a9ac8606Spatrick parser.add_argument('--json-input-path', 342*a9ac8606Spatrick help='Read API description from FILE', metavar='FILE') 343*a9ac8606Spatrick parser.add_argument('--output-file', help='Generate output in FILEPATH', 344*a9ac8606Spatrick metavar='FILEPATH') 345*a9ac8606Spatrick parser.add_argument('--use-empty-implementation', 346*a9ac8606Spatrick help='Generate empty implementation', 347*a9ac8606Spatrick action="store", type=int) 348*a9ac8606Spatrick parser.add_argument('--empty-implementation', 349*a9ac8606Spatrick help='Copy empty implementation from FILEPATH', 350*a9ac8606Spatrick action="store", metavar='FILEPATH') 351*a9ac8606Spatrick 352*a9ac8606Spatrick options = parser.parse_args() 353*a9ac8606Spatrick 354*a9ac8606Spatrick use_empty_implementation = options.use_empty_implementation 355*a9ac8606Spatrick 356*a9ac8606Spatrick if (not use_empty_implementation 357*a9ac8606Spatrick and not os.path.exists(options.json_input_path)): 358*a9ac8606Spatrick use_empty_implementation = True 359*a9ac8606Spatrick 360*a9ac8606Spatrick if not use_empty_implementation: 361*a9ac8606Spatrick with open(options.json_input_path) as f: 362*a9ac8606Spatrick jsonData = json.load(f) 363*a9ac8606Spatrick 364*a9ac8606Spatrick if not 'classesInClade' in jsonData or not jsonData["classesInClade"]: 365*a9ac8606Spatrick use_empty_implementation = True 366*a9ac8606Spatrick 367*a9ac8606Spatrick if use_empty_implementation: 368*a9ac8606Spatrick if not os.path.exists(options.output_file) or \ 369*a9ac8606Spatrick not filecmp.cmp(options.empty_implementation, options.output_file): 370*a9ac8606Spatrick shutil.copyfile(options.empty_implementation, options.output_file) 371*a9ac8606Spatrick sys.exit(0) 372*a9ac8606Spatrick 373*a9ac8606Spatrick templateClasses = [] 374*a9ac8606Spatrick for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): 375*a9ac8606Spatrick if "templateParms" in ClassAccessors: 376*a9ac8606Spatrick templateClasses.append(ClassName) 377*a9ac8606Spatrick 378*a9ac8606Spatrick g = Generator(templateClasses) 379*a9ac8606Spatrick 380*a9ac8606Spatrick g.GeneratePrologue() 381*a9ac8606Spatrick 382*a9ac8606Spatrick for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): 383*a9ac8606Spatrick g.GenerateBaseGetLocationsDeclaration(CladeName) 384*a9ac8606Spatrick 385*a9ac8606Spatrick def getCladeName(ClassName): 386*a9ac8606Spatrick for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): 387*a9ac8606Spatrick if ClassName in ClassNameData: 388*a9ac8606Spatrick return CladeName 389*a9ac8606Spatrick 390*a9ac8606Spatrick for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): 391*a9ac8606Spatrick cladeName = getCladeName(ClassName) 392*a9ac8606Spatrick g.GenerateSrcLocMethod( 393*a9ac8606Spatrick ClassName, ClassAccessors, 394*a9ac8606Spatrick cladeName not in Generator.RefClades) 395*a9ac8606Spatrick 396*a9ac8606Spatrick for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): 397*a9ac8606Spatrick g.GenerateBaseGetLocationsFunction( 398*a9ac8606Spatrick ClassNameData, 399*a9ac8606Spatrick jsonData['classEntries'], 400*a9ac8606Spatrick CladeName, 401*a9ac8606Spatrick jsonData["classInheritance"], 402*a9ac8606Spatrick CladeName not in Generator.RefClades) 403*a9ac8606Spatrick 404*a9ac8606Spatrick g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys()) 405*a9ac8606Spatrick 406*a9ac8606Spatrick g.GenerateEpilogue() 407*a9ac8606Spatrick 408*a9ac8606Spatrick g.GenerateFiles(options.output_file) 409*a9ac8606Spatrick 410*a9ac8606Spatrickif __name__ == '__main__': 411*a9ac8606Spatrick main() 412