<commit_before>/*
 * This file is part of the Polyglot extensible compiler framework.
 *
 * Copyright (c) 2000-2006 Polyglot project group, Cornell University
 * 
 */

package polyglot.types;

import polyglot.util.*;
import polyglot.main.Report;
import java.util.*;

/**
 * A <code>ClassContextResolver</code> looks up type names qualified with a class name.
 * For example, if the class is "A.B", the class context will return the class
 * for member class "A.B.C" (if it exists) when asked for "C".
 */
public class ClassContextResolver extends AbstractAccessControlResolver {
    protected ClassType type;
    
    /**
     * Construct a resolver.
     * @param ts The type system.
     * @param type The type in whose context we search for member types.
     */
    public ClassContextResolver(TypeSystem ts, ClassType type) {
        super(ts);
        this.type = type;
    }
    
    public String toString() {
        return "(class-context " + type + ")";
    }
    
    /**
     * Find a type object in the context of the class.
     * @param name The name to search for.
     */
    public Named find(String name, ClassType accessor) throws SemanticException {
        if (Report.should_report(TOPICS, 2))
	    Report.report(2, "Looking for " + name + " in " + this);

        if (! StringUtil.isNameShort(name)) {
            throw new InternalCompilerError(
                "Cannot lookup qualified name " + name);
        }

        // Check if the name is for a member class.
        ClassType mt = null;

        Named m;

        String fullName = type.fullName() + "." + name;
        String rawName = ts.getTransformedClassName(type) + "$" + name;

        // First check the system resolver.
        m = ts.systemResolver().check(fullName);

        // Try the raw class file name.
        if (m == null) {
            m = ts.systemResolver().check(rawName);
        }

        // Check if the member was explicitly declared.
        if (m == null) {
            m = type.memberClassNamed(name);
        }

        // Go to disk, but only if there is no job for the type.
        // If there is a job, all members should be in the resolver
        // already.
        boolean useLoadedResolver = true;

        if (type instanceof ParsedTypeObject) {
            ParsedTypeObject pto = (ParsedTypeObject) type;
            if (pto.job() != null) {
                useLoadedResolver = false;
            }
        }

        if (m == null && useLoadedResolver) {
            try {
                m = ts.systemResolver().find(rawName);
            }
            catch (SemanticException e) {
                // Not found; will fall through to error handling code
            }
        }

        if (m instanceof ClassType) {
            mt = (ClassType) m;

            if (! mt.isMember()) {
                throw new SemanticException("Class " + mt +
                                            " is not a member class, " +
                                            " but was found in " + type + ".");
            }
            
            if (mt.outer() != type) {
                throw new SemanticException("Class " + mt +
                                            " is not a member class, " +
                                            " of " + type + ".");
            }
            
            if (! canAccess(mt, accessor)) {
                throw new SemanticException("Cannot access member type \"" + mt + "\".");<commit_msg>Use typeEquals() instead of reference equality<commit_after>/*
 * This file is part of the Polyglot extensible compiler framework.
 *
 * Copyright (c) 2000-2006 Polyglot project group, Cornell University
 * 
 */

package polyglot.types;

import polyglot.util.*;
import polyglot.main.Report;
import java.util.*;

/**
 * A <code>ClassContextResolver</code> looks up type names qualified with a class name.
 * For example, if the class is "A.B", the class context will return the class
 * for member class "A.B.C" (if it exists) when asked for "C".
 */
public class ClassContextResolver extends AbstractAccessControlResolver {
    protected ClassType type;
    
    /**
     * Construct a resolver.
     * @param ts The type system.
     * @param type The type in whose context we search for member types.
     */
    public ClassContextResolver(TypeSystem ts, ClassType type) {
        super(ts);
        this.type = type;
    }
    
    public String toString() {
        return "(class-context " + type + ")";
    }
    
    /**
     * Find a type object in the context of the class.
     * @param name The name to search for.
     */
    public Named find(String name, ClassType accessor) throws SemanticException {
        if (Report.should_report(TOPICS, 2))
	    Report.report(2, "Looking for " + name + " in " + this);

        if (! StringUtil.isNameShort(name)) {
            throw new InternalCompilerError(
                "Cannot lookup qualified name " + name);
        }

        // Check if the name is for a member class.
        ClassType mt = null;

        Named m;

        String fullName = type.fullName() + "." + name;
        String rawName = ts.getTransformedClassName(type) + "$" + name;

        // First check the system resolver.
        m = ts.systemResolver().check(fullName);

        // Try the raw class file name.
        if (m == null) {
            m = ts.systemResolver().check(rawName);
        }

        // Check if the member was explicitly declared.
        if (m == null) {
            m = type.memberClassNamed(name);
        }

        // Go to disk, but only if there is no job for the type.
        // If there is a job, all members should be in the resolver
        // already.
        boolean useLoadedResolver = true;

        if (type instanceof ParsedTypeObject) {
            ParsedTypeObject pto = (ParsedTypeObject) type;
            if (pto.job() != null) {
                useLoadedResolver = false;
            }
        }

        if (m == null && useLoadedResolver) {
            try {
                m = ts.systemResolver().find(rawName);
            }
            catch (SemanticException e) {
                // Not found; will fall through to error handling code
            }
        }

        if (m instanceof ClassType) {
            mt = (ClassType) m;

            if (! mt.isMember()) {
                throw new SemanticException("Class " + mt +
                                            " is not a member class, " +
                                            " but was found in " + type + ".");
            }
            
            if (!ts.typeEquals(mt.outer(), type)) {
                throw new SemanticException("Class " + mt +
                                            " is not a member class " +
                                            " of " + type + ".");
            }
            
            if (! canAccess(mt, accessor)) {
                throw new SemanticException("Cannot access member type \"" + mt + "\".");
{'fraction_non_alphanumeric': 0.10040160642570281, 'fraction_numerical': 0.002868617326448652, 'mean_word_length': 1.5902674591381871, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5553918', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1764, 'n_words': 625}