/******************************************************************************* * Copyright (c) 2009, 2014 Google, Inc and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Sergey Prigogin (Google) - initial API and implementation * Thomas Corbat (IFS) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.ast2; import static org.eclipse.cdt.core.parser.tests.VisibilityAsserts.assertVisibility; import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.AccessContext; import org.eclipse.cdt.internal.core.parser.ParserException; public class AccessControlTests extends AST2TestBase { protected class AccessAssertionHelper extends BindingAssertionHelper { AccessAssertionHelper(String contents) throws ParserException { super(contents, true); } void assertAccessible(String section, int len) { IASTName name = findName(section, len); IBinding binding = name.resolveBinding(); assertNotNull(binding); assertTrue(AccessContext.isAccessible(binding, name)); } void assertNotAccessible(String section, int len) { IASTName name = findName(section, len); IBinding binding = name.resolveBinding(); assertNotNull(binding); assertFalse(AccessContext.isAccessible(binding, name)); } } public AccessControlTests() { } public AccessControlTests(String name) { super(name); } public static TestSuite suite() { return suite(AccessControlTests.class); } private AccessAssertionHelper getAssertionHelper() throws Exception { final String code = getAboveComment(); parseAndCheckBindings(code, ParserLanguage.CPP); return new AccessAssertionHelper(code); } // class A { // public: // int a; // typedef char E; // }; // class B : private A { // friend void test(); // int b; // typedef char* F; // }; // class C : protected B { // }; // void test() { // class D : public C { // void m() { // a; //1 // b; //1 // E(); //1 // F(); //1 // } // }; // B b; // b.a; //2 // b.b; //2 // B::E(); //2 // B::F(); //2 // C c; // c.a; //3 // c.b; //3 // C::E(); //3 // C::F(); //3 // } public void testFriends() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertAccessible("a; //1", 1); ah.assertAccessible("b; //1", 1); ah.assertAccessible("E(); //1", 1); ah.assertAccessible("F(); //1", 1); ah.assertAccessible("a; //2", 1); ah.assertAccessible("b; //2", 1); ah.assertAccessible("E(); //2", 1); ah.assertAccessible("F(); //2", 1); ah.assertNotAccessible("a; //3", 1); ah.assertNotAccessible("b; //3", 1); ah.assertNotAccessible("E(); //3", 1); ah.assertNotAccessible("F(); //3", 1); } // class A { // public: // int a; // }; // // class B : public A { // private: // int a; // }; // // void test(B x) { // x.a = 0; // } public void testHiddenMember() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertNotAccessible("a = 0", 1); } // class A0 { // public: // enum Ex {e1}; // }; // // class A : public A0 { // class B { // void test() { // Ex a; // we compute 'B' as the naming type, whereas it should be 'A' // } // }; // }; public void testEnclosingAsNamingClass_292232() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertAccessible("Ex a;", 2); } // // Example from C++-specification 11.2-3 // class B { // public: // int mi; // static int si; // }; // class D : private B {}; // class DD : public D { // void f(); // }; // // void DD::f() { // mi=3; // private // si=3; // private // B b; // b.mi=4; // b.si=4; // B* bp; // bp->mi=5; // } public void testEnclosingAsNamingClass_292232a() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertNotAccessible("mi=3;", 2); ah.assertNotAccessible("si=3;", 2); ah.assertAccessible("mi=4;", 2); ah.assertAccessible("si=4;", 2); ah.assertAccessible("mi=5;", 2); } // class A { // private: // typedef int Waldo; // }; // A::Waldo waldo; public void testPrivateTypedef_427730() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertNotAccessible("Waldo waldo", 5); } // class A { // private: // class B {}; // public: // typedef B Waldo; // }; // A::Waldo waldo; public void testPublicTypedefForPrivateMemberClass_427730() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertAccessible("Waldo waldo", 5); } // class A { // private: // class B {}; // friend class C; // }; // class C { // public: // typedef A::B Waldo; // }; // C::Waldo waldo; public void testPublicTypedefForFriendClass_427730() throws Exception { AccessAssertionHelper ah = getAssertionHelper(); ah.assertAccessible("Waldo waldo", 5); } // class Outer { // class Inner {}; // protected: // using AliasInner = Inner; // typedef Inner TypedefInner; // }; public void testAccessibilityForAliasedTypeInSameClass_427730() throws Exception { BindingAssertionHelper bh = getAssertionHelper(); ICPPClassType outerClass = bh.assertNonProblem("Outer"); IBinding aliasInner = bh.assertNonProblem("AliasInner"); assertVisibility(ICPPClassType.v_protected, outerClass.getVisibility(aliasInner)); IBinding typedefInner = bh.assertNonProblem("TypedefInner"); assertVisibility(ICPPClassType.v_protected, outerClass.getVisibility(typedefInner)); } }