<commit_before>package com.redhat.ceylon.compiler.typechecker.analyzer;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;

/**
 * Validates that the initializer of a class does
 * not leak self-references to the instance being
 * initialized.
 * 
 * @author <NAME>
 *
 */
public class SelfReferenceVisitor extends Visitor {
        
    private Tree.Statement lastExecutableStatement;
    private Boolean declarationSection = null;
    private Boolean outerDeclarationSection = null;

    @Override
    public void visit(Tree.AnnotationList that) {}

    @Override
    public void visit(Tree.ExtendedTypeExpression that) {
        super.visit(that);
        Declaration member  = that.getDeclaration();
        if (member!=null && !inOuterDeclarationSection() && 
                !member.isToplevel() && 
                !member.isDefinedInScope(that.getScope().getContainer())) {
            //then it must be an inherited member class?
            //TODO: is that logic exactly correct?
            that.addError("inherited member class may not be extended in initializer: " + 
                            member.getName());
        }
    }

    @Override
    public void visit(Tree.BaseMemberExpression that) {
        super.visit(that);
        visitReference(that);
    }

    @Override
    public void visit(Tree.BaseTypeExpression that) {
        super.visit(that);
        visitReference(that);
    }

    @Override
    public void visit(Tree.QualifiedMemberExpression that) {
        super.visit(that);
        if (isSelfReference(that.getPrimary())) {
            visitReference(that);
        }
    }

    @Override
    public void visit(Tree.QualifiedTypeExpression that) {
        super.visit(that);
        if (isSelfReference(that.getPrimary())) {
            visitReference(that);
        }
    }

    private boolean isSelfReference(Tree.Term that) {
        return that instanceof Tree.This || 
            that instanceof Tree.Outer || 
            that instanceof Tree.Super;
    }

    private void visitReference(Tree.Primary that) {
        Declaration member  = that.getDeclaration();
        if (member!=null && !inDeclarationSection() && 
                !member.isToplevel() && 
                !member.isDefinedInScope(that.getScope())) {
            //then it must be an inherited member?
            //TODO: is that logic exactly correct?
            that.addError("inherited member may not be used in initializer: " + 
                            member.getName());
        }
    }
    
    @Override
    public void visit(Tree.IsCondition that) {
        super.visit(that);
        if (that.getVariable().getSpecifierExpression()!=null) {
            Tree.Term term = that.getVariable().getSpecifierExpression().getExpression().getTerm();
            if ( isSelfReference(term) ) {
                if (term instanceof Tree.Super ) {
                    term.addError("cannot narrow super");<commit_msg>move code<commit_after>package com.redhat.ceylon.compiler.typechecker.analyzer;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;

/**
 * Validates that the initializer of a class does
 * not leak self-references to the instance being
 * initialized.
 * 
 * @author <NAME>
 *
 */
public class SelfReferenceVisitor extends Visitor {
        
    private Tree.Statement lastExecutableStatement;
    private Boolean declarationSection = null;
    private Boolean outerDeclarationSection = null;

    private void visitExtendedType(Tree.ExtendedTypeExpression that) {
        Declaration member  = that.getDeclaration();
        if (member!=null && !inOuterDeclarationSection() && 
                !member.isToplevel() && 
                !member.isDefinedInScope(that.getScope().getContainer())) {
            //then it must be an inherited member class?
            //TODO: this logic is broken!
            that.addError("inherited member class may not be extended in initializer: " + 
                            member.getName());
        }
    }

    private void visitReference(Tree.Primary that) {
        Declaration member  = that.getDeclaration();
        if (member!=null && !inDeclarationSection() && 
                !member.isToplevel() && 
                !member.isDefinedInScope(that.getScope())) {
            //then it must be an inherited member?
            //TODO: this logic is broken!
            that.addError("inherited member may not be used in initializer: " + 
                            member.getName());
        }
    }
    
    @Override
    public void visit(Tree.AnnotationList that) {}

    @Override
    public void visit(Tree.ExtendedTypeExpression that) {
        super.visit(that);
        visitExtendedType(that);
    }

    @Override
    public void visit(Tree.BaseMemberExpression that) {
        super.visit(that);
        visitReference(that);
    }

    @Override
    public void visit(Tree.BaseTypeExpression that) {
        super.visit(that);
        visitReference(that);
    }

    @Override
    public void visit(Tree.QualifiedMemberExpression that) {
        super.visit(that);
        if (isSelfReference(that.getPrimary())) {
            visitReference(that);
        }
    }

    @Override
    public void visit(Tree.QualifiedTypeExpression that) {
        super.visit(that);
        if (isSelfReference(that.getPrimary())) {
            visitReference(that);
        }
    }

    private boolean isSelfReference(Tree.Term that) {
        return that instanceof Tree.This || 
            that instanceof Tree.Outer || 
            that instanceof Tree.Super;
    }

    @Override
    public void visit(Tree.IsCondition that) {
        super.visit(that);
        if (that.getVariable().getSpecifierExpression()!=null) {
            Tree.Term term = that.getVariable().getSpecifierExpression().getExpression().getTerm();
            if ( isSelfReference(term) ) {
                if (term instanceof Tree.Super ) {
                    term.addError("cannot narrow super");
{'fraction_non_alphanumeric': 0.1003606711619884, 'fraction_numerical': 0.0, 'mean_word_length': 2.372818614489688, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5328292', 'n_tokens_mistral': 1691, 'n_tokens_neox': 1632, 'n_words': 377}