def testIsReadyFull(self): """ Три класса и интерфейс A<-B<-C=>D. Порядок загрузки C, A, D, B """ module = TaxonModule('module') classA = module.addNamedItem(TaxonClass('A')) classB = module.addNamedItem(TaxonClass('B')) classB.parent = Ref('A') classC = module.addNamedItem(TaxonClass('C')) classC.parent = Ref('B') intD = module.addNamedItem(TaxonInterface('D')) classC.implements.append(Ref('D')) self.assertTrue(classA.isReady()) # True, because A have no parent self.assertTrue(classA.isReadyFull()) self.assertFalse( classB.isReady()) # False, because not init ref to parent A self.assertFalse(classB.isReadyFull()) self.assertFalse(classC.isReady()) self.assertTrue(intD.isReady()) # True, because D have no parent classC.update( ) # Не fullUpdate, т.к. запустится задача, которая будет ждать готовность класса, но она не выполнится self.assertTrue(classC.isReady()) # Must init refs to B and D self.assertFalse(classB.isReady()) self.assertFalse( classC.isReadyFull()) # But B is not ready => C is not ready full classB.update() self.assertTrue(classB.isReady()) self.assertTrue(classC.isReadyFull()) # All classes are ready
def testUpcastTo(self): module = TaxonModule('module') classA = module.addNamedItem(TaxonClass('A')) classB = module.addNamedItem(TaxonClass('B')) classB.parent = Ref('A', classA) classC = module.addNamedItem(TaxonClass('C')) classC.parent = Ref('B', classB) intAx = module.addNamedItem(TaxonInterface('Ax')) intBx = module.addNamedItem(TaxonInterface('Bx')) intBx.parent = Ref('Ax', intAx) intCx = module.addNamedItem(TaxonInterface('Cx')) classC.implements.append(Ref('Bx', intBx)) classC.implements.append(Ref('Cx', intCx)) self.assertTrue(classC.canUpcastTo(classC)) self.assertTrue(classC.canUpcastTo(classB)) self.assertTrue(classC.canUpcastTo(classA)) self.assertTrue(classB.canUpcastTo(classB)) self.assertFalse(classA.canUpcastTo(classB)) self.assertFalse(classA.canUpcastTo(intAx)) self.assertFalse(classB.canUpcastTo(intBx)) self.assertTrue(intAx.canUpcastTo(intAx)) self.assertTrue(intBx.canUpcastTo(intAx)) self.assertFalse(intCx.canUpcastTo(intAx)) self.assertTrue(classC.canUpcastTo(intCx)) self.assertTrue(classC.canUpcastTo(intBx)) self.assertTrue(classC.canUpcastTo(intAx))
def testParent(self): root = TaxonPackage('root') moduleA = root.addNamedItem(TaxonModule('A')) classA = moduleA.addNamedItem(TaxonClass('A')) classA.attrs.add('public') moduleB = root.addNamedItem(TaxonModule('B')) classB = moduleB.addNamedItem(TaxonClass('B')) classB.parent = Ref('A') root.fullUpdate() self.assertEqual(classB.getParent(), classA)
def exportMethod(method, lexems, style): # access level accessLevel = TaxonClass.getAccessLevelFor(method) if accessLevel: lexems += [Lex.keyword(accessLevel), Lex.space] isConstructor = method.type == 'constructor' # static if method.isStatic(): lexems += [Lex.keyword('static'), Lex.space] isConstructor = False if isConstructor: lexems.append(Lex.keyword('constructor')) else: lexems.append(Lex.funcName(method.getName())) lexems.append(Lex.paramsBegin) for param in method.getParamsList(): param.exportLexems(lexems, style) lexems.append(Lex.paramDiv) if lexems[-1] == Lex.paramDiv: lexems[-1] = Lex.paramDivLast lexems.append(Lex.paramsEnd) if not isConstructor: lexems.append(Lex.colon) typeExpr = method.getResultTypeExpr() if typeExpr: typeExpr.exportLexems(lexems, style) else: lexems.append(Lex.typeName('void')) method.getBody().exportLexems(lexems, style)
def testImplements(self): class MyMember(Taxon): pass module = TaxonModule('Module') iFar = module.addNamedItem(TaxonInterface('IFar')) txFar = iFar.addNamedItem(MyMember('far')) txMulti1 = iFar.addNamedItem(MyMember('multi')) iNear = module.addNamedItem(TaxonInterface('INear')) iNear.parent = Ref('IFar') txNear = iNear.addNamedItem(MyMember('near')) iSecond = module.addNamedItem(TaxonInterface('ISecond')) txSecond = iSecond.addNamedItem(MyMember('second')) txMulti2 = iSecond.addNamedItem(MyMember('multi')) classA = module.addNamedItem(TaxonClass('A')) classA.implements = [Ref('INear'), Ref('ISecond')] txBlock = classA.addNamedItem(MyMember('block')) module.fullUpdate() self.assertEqual(txBlock.findUpPath('ISecond'), iSecond) self.assertEqual(txBlock.findUpPath('second'), txSecond) self.assertEqual(txBlock.findUpPath('far'), txFar) with self.assertRaises(RuntimeError) as cm: txBlock.findUpPath('multi') self.assertEqual( str(cm.exception), '*Error* Multiple definition of "multi" in [Module.IFar.multi, Module.ISecond.multi]' )
def checkMemberAccess(source, target): """ Проверка возможности доступа к члену класса source представлен таксоном типа WppNamed target - член класса """ # Нужно найти метод, в котором находится source sourceMethod = source.owner while not (sourceMethod.owner.isClass() and isinstance(sourceMethod, TaxonFunc)): if sourceMethod.isModule(): sourceMethod = None break sourceMethod = sourceMethod.owner # Если target не является статическим, а source принадлежит статическому члену, это ошибка if not target.isStatic() and sourceMethod and sourceMethod.isStatic(): source.throwError('Non-static %s "%s" cannot be referenced from the static "%s"' % (target.type, target.getName(), sourceMethod.getName())) TaxonClass.checkAccess(source, target)
def exportLexems(self, lexems, rules): self.exportComment(lexems, rules) # access level accessLevel = TaxonClass.getAccessLevelFor(self) if accessLevel: lexems += [Lex.keyword(accessLevel), Lex.space] # static if 'static' in self.attrs: lexems += [Lex.keyword('static'), Lex.space] exportVar(self, lexems, rules) lexems.append(Lex.instrDiv)
def exec(self): TaxonClass.checkAccess(self.taxon, self.member)