<commit_before>package com.redhat.ceylon.eclipse.code.correct;

import static com.redhat.ceylon.compiler.typechecker.model.Util.intersectionType;
import static com.redhat.ceylon.compiler.typechecker.model.Util.isTypeUnknown;
import static com.redhat.ceylon.compiler.typechecker.model.Util.unionType;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Interface;
import com.redhat.ceylon.compiler.typechecker.model.NothingType;
import com.redhat.ceylon.compiler.typechecker.model.Parameter;
import com.redhat.ceylon.compiler.typechecker.model.ProducedReference;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.Unit;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Term;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;

class InferredType {
    
    private Unit unit;

    InferredType(Unit unit) {
        this.unit = unit;
        
    }
    
    ProducedType inferredType;
    ProducedType generalizedType;
    
    void intersect(ProducedType pt) {
        if (!isTypeUnknown(pt)) {
            if (generalizedType==null) {
                generalizedType = pt;
            }
            else {
                ProducedType it = intersectionType(generalizedType, pt, unit);
                if (!(it.getDeclaration() instanceof NothingType)) {
                    generalizedType = it;
                }
            }
        }
    }
    
    void union(ProducedType pt) {
        if (!isTypeUnknown(pt)) {
            if (inferredType==null) {
                inferredType = pt;
            }
            else {
                inferredType = unionType(inferredType, unit.denotableType(pt), unit);
            }
        }
    }
    
}

class InferTypeVisitor extends Visitor {
    
    Unit unit;
    Declaration dec;
    InferredType result;
    
    InferTypeVisitor(Unit unit) {
        this.unit = unit;
        result = new InferredType(unit);
    }
    
    @Override public void visit(Tree.AttributeDeclaration that) {
        super.visit(that);
        Term term = that.getSpecifierOrInitializerExpression()==null ? 
                null : that.getSpecifierOrInitializerExpression().getExpression().getTerm();
        if (term instanceof Tree.BaseMemberExpression) {
            Declaration d = ((Tree.BaseMemberExpression) term).getDeclaration();
            if (d!=null && d.equals(dec)) {
                result.intersect(that.getType().getTypeModel());
            }
        }
        else if (term!=null) {
            if (that.getDeclarationModel().equals(dec)) {
                result.union(term.getTypeModel());
            }
        }
    }
    
    @Override public void visit(Tree.MethodDeclaration that) {
        super.visit(that);
        Term term = that.getSpecifierExpression()==null ? 
                null : that.getSpecifierExpression().getExpression().getTerm();
        if (term instanceof Tree.BaseMemberExpression) {
            Declaration d = ((Tree.BaseMemberExpression) term).getDeclaration();
            if (d!=null && d.equals(dec)) {
                result.intersect(that.getType().getTypeModel());
            }
        }
        else if (term!=null) {
            if (that.getDeclarationModel().equals(dec)) {
                result.union(term.getTypeModel());
            }
        }
    }
    
    @Override public void visit(Tree.SpecifierStatement that) {
        super.visit(that);
        Tree.Term bme = that.getBaseMemberExpression();
        Term term = that.getSpecifierExpression()==null ? 
                null : that.getSpecifierExpression().getExpression().getTerm();
        if (bme instanceof Tree.BaseMemberExpression) {
            Declaration d = ((Tree.BaseMemberExpression) bme).getDeclaration();<commit_msg>add TODOs<commit_after>package com.redhat.ceylon.eclipse.code.correct;

import static com.redhat.ceylon.compiler.typechecker.model.Util.intersectionType;
import static com.redhat.ceylon.compiler.typechecker.model.Util.isTypeUnknown;
import static com.redhat.ceylon.compiler.typechecker.model.Util.unionType;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Interface;
import com.redhat.ceylon.compiler.typechecker.model.NothingType;
import com.redhat.ceylon.compiler.typechecker.model.Parameter;
import com.redhat.ceylon.compiler.typechecker.model.ProducedReference;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.Unit;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Term;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;

class InferredType {
    
    private Unit unit;

    InferredType(Unit unit) {
        this.unit = unit;
        
    }
    
    ProducedType inferredType;
    ProducedType generalizedType;
    
    void intersect(ProducedType pt) {
        if (!isTypeUnknown(pt)) {
            if (generalizedType==null) {
                generalizedType = pt;
            }
            else {
                ProducedType it = intersectionType(generalizedType, pt, unit);
                if (!(it.getDeclaration() instanceof NothingType)) {
                    generalizedType = it;
                }
            }
        }
    }
    
    void union(ProducedType pt) {
        if (!isTypeUnknown(pt)) {
            if (inferredType==null) {
                inferredType = pt;
            }
            else {
                inferredType = unionType(inferredType, unit.denotableType(pt), unit);
            }
        }
    }
    
}

class InferTypeVisitor extends Visitor {
    
    Unit unit;
    Declaration dec;
    InferredType result;
    
    InferTypeVisitor(Unit unit) {
        this.unit = unit;
        result = new InferredType(unit);
    }
    
    @Override public void visit(Tree.AttributeDeclaration that) {
        super.visit(that);
        //TODO: an assignment to something with an inferred
        //      type doesn't _directly_ constrain the type
        //      ... but _indirectly_ it can!
//        if (!(that.getType() instanceof Tree.LocalModifier)) {
            Term term = that.getSpecifierOrInitializerExpression()==null ? 
                    null : that.getSpecifierOrInitializerExpression().getExpression().getTerm();
            if (term instanceof Tree.BaseMemberExpression) {
                Declaration d = ((Tree.BaseMemberExpression) term).getDeclaration();
                if (d!=null && d.equals(dec)) {
                    result.intersect(that.getType().getTypeModel());
                }
            }
            else if (term!=null) {
                if (that.getDeclarationModel().equals(dec)) {
                    result.union(term.getTypeModel());
                }
            }
//        }
    }
    
    @Override public void visit(Tree.MethodDeclaration that) {
        super.visit(that);
        //TODO: an assignment to something with an inferred
        //      type doesn't _directly_ constrain the type
        //      ... but _indirectly_ it can!
//        if (!(that.getType() instanceof Tree.LocalModifier)) {
            Term term = that.getSpecifierExpression()==null ? 
                    null : that.getSpecifierExpression().getExpression().getTerm();
            if (term instanceof Tree.BaseMemberExpression) {
                Declaration d = ((Tree.BaseMemberExpression) term).getDeclaration();
                if (d!=null && d.equals(dec)) {
                    result.intersect(that.getType().getTypeModel());
                }
            }
            else if (term!=null) {
                if (that.getDeclarationModel().equals(dec)) {
                    result.union(term.getTypeModel());
                }
            }
//        }
    }
    
    @Override public void visit(Tree.SpecifierStatement that) {
        super.visit(that);
        Tree.Term bme = that.getBaseMemberExpression();
        Term term = that.getSpecifierExpression()==null ? 
                null : that.getSpecifierExpression().getExpression().getTerm();
        if (bme instanceof Tree.BaseMemberExpression) {
            Declaration d = ((Tree.BaseMemberExpression) bme).getDeclaration();
{'fraction_non_alphanumeric': 0.10696920583468396, 'fraction_numerical': 0.0, 'mean_word_length': 2.26, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3234133', 'n_tokens_mistral': 2397, 'n_tokens_neox': 2356, 'n_words': 404}