int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember) { if (smember) { AggregateDeclaration *cd = NULL; Dsymbol *smemberparent = smember->toParent(); if (smemberparent) cd = smemberparent->isAggregateDeclaration(); #if LOG printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n", toChars(), smember->toChars()); #endif if (this == cd) // smember is a member of this class { #if LOG printf("\tyes 1\n"); #endif return 1; // so we get private access } // If both are members of the same module, grant access while (1) { Dsymbol *sp = smember->toParent(); if (sp->isFuncDeclaration() && smember->isFuncDeclaration()) smember = sp; else break; } if (!cd && toParent() == smember->toParent()) { #if LOG printf("\tyes 2\n"); #endif return 1; } if (!cd && getAccessModule() == smember->getAccessModule()) { #if LOG printf("\tyes 3\n"); #endif return 1; } } #if LOG printf("\tno\n"); #endif return 0; }
void Dsymbol::jsonProperties(JsonOut *json) { if (!isTemplateDeclaration()) // TemplateDeclaration::kind() acts weird sometimes { json->property("name", toChars()); json->property("kind", kind()); } if (prot() != PROTpublic) json->property("protection", Pprotectionnames[prot()]); json->property("comment", (const char *)comment); json->property("line", &loc); #if 0 if (!isModule()) { Module *module = getModule(); if (module) { json->propertyStart("module"); json->objectStart(); module->jsonProperties(json); json->objectEnd(); } Module *accessModule = getAccessModule(); if (accessModule && accessModule != module) { json->propertyStart("accessModule"); json->objectStart(); accessModule->jsonProperties(json); json->objectEnd(); } } #endif }
int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd) { #if LOG printf("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd->toChars() : "null"); #endif if (this == cd) return 1; // Friends if both are in the same module //if (toParent() == cd->toParent()) if (cd && getAccessModule() == cd->getAccessModule()) { #if LOG printf("\tin same module\n"); #endif return 1; } #if LOG printf("\tnot friend\n"); #endif return 0; }
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember) { int result; FuncDeclaration *f = sc->func; AggregateDeclaration *cdscope = sc->getStructClassScope(); PROT access; #if LOG printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n", toChars(), smember->toChars(), f ? f->toChars() : NULL, cdscope ? cdscope->toChars() : NULL); #endif Dsymbol *smemberparent = smember->toParent(); if (!smemberparent || !smemberparent->isAggregateDeclaration()) { #if LOG printf("not an aggregate member\n"); #endif return; // then it is accessible } // BUG: should enable this check //assert(smember->parent->isBaseOf(this, NULL)); if (smemberparent == this) { PROT access2 = smember->prot(); result = access2 >= PROTpublic || hasPrivateAccess(f) || isFriendOf(cdscope) || (access2 == PROTpackage && hasPackageAccess(sc, this)) || getAccessModule() == sc->module; #if LOG printf("result1 = %d\n", result); #endif } else if ((access = this->getAccess(smember)) >= PROTpublic) { result = 1; #if LOG printf("result2 = %d\n", result); #endif } else if (access == PROTpackage && hasPackageAccess(sc, this)) { result = 1; #if LOG printf("result3 = %d\n", result); #endif } else { result = accessCheckX(smember, f, this, cdscope); #if LOG printf("result4 = %d\n", result); #endif } if (!result) { error(loc, "member %s is not accessible", smember->toChars()); } }