Search in sources :

Example 36 with TypedDeclaration

use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.

the class SelfReferenceVisitor method checkSelfReference.

private void checkSelfReference(Node that, Tree.Term term) {
    Tree.Term t = eliminateParensAndWidening(term);
    if (directlyInBody() && t instanceof Tree.Super) {
        that.addError("leaks 'super' reference: '" + typeDeclaration.getName() + "'");
    }
    if (mayNotLeakThis() && t instanceof Tree.This) {
        that.addError("leaks 'this' reference in initializer: '" + typeDeclaration.getName() + "'");
    }
    if (mayNotLeakOuter() && t instanceof Tree.Outer) {
        that.addError("leaks 'outer' reference in initializer: '" + typeDeclaration.getName() + "'");
    }
    if (typeDeclaration.isObjectClass() && mayNotLeakAnonymousClass() && t instanceof Tree.BaseMemberExpression) {
        Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) t;
        Declaration declaration = bme.getDeclaration();
        if (declaration instanceof TypedDeclaration) {
            TypedDeclaration td = (TypedDeclaration) declaration;
            if (td.getTypeDeclaration() == typeDeclaration) {
                that.addError("anonymous class leaks self reference in initializer: '" + typeDeclaration.getName() + "'");
            }
        }
    }
    if (typeDeclaration.isObjectClass() && mayNotLeakAnonymousClass() && t instanceof Tree.QualifiedMemberExpression) {
        Tree.QualifiedMemberExpression qme = (Tree.QualifiedMemberExpression) t;
        if (qme.getPrimary() instanceof Tree.Outer) {
            Declaration declaration = qme.getDeclaration();
            if (declaration instanceof TypedDeclaration) {
                TypedDeclaration td = (TypedDeclaration) declaration;
                if (td.getTypeDeclaration() == typeDeclaration) {
                    that.addError("anonymous class leaks self reference in initializer: '" + typeDeclaration.getName() + "'");
                }
            }
        }
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Super(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Super)

Example 37 with TypedDeclaration

use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.

the class ExpressionVisitor method visitInvocationPrimary.

private void visitInvocationPrimary(Tree.InvocationExpression that, Tree.StaticMemberOrTypeExpression reference) {
    if (reference instanceof Tree.QualifiedMemberOrTypeExpression) {
        Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) reference;
        Tree.Term term = unwrapExpressionUntilTerm(qmte.getPrimary());
        if (term instanceof Tree.StaticMemberOrTypeExpression) {
            Tree.StaticMemberOrTypeExpression pmte = (Tree.StaticMemberOrTypeExpression) term;
            visitInvocationPrimary(that, pmte);
        }
    }
    Tree.TypeArguments tas = reference.getTypeArguments();
    if (reference instanceof Tree.BaseTypeExpression) {
        Tree.BaseTypeExpression bte = (Tree.BaseTypeExpression) reference;
        TypeDeclaration type = resolveBaseTypeExpression(bte, true);
        if (type != null) {
            setArgumentParameters(that, type);
            Type receivingType = getBaseReceivingType(that, type);
            List<Type> typeArgs = getOrInferTypeArguments(that, type, reference, receivingType);
            if (typeArgs != null) {
                tas.setTypeModels(typeArgs);
            } else {
                typeArgs = tas.getTypeModels();
            }
            visitBaseTypeExpression(bte, type, typeArgs, tas, receivingType);
        }
    } else if (reference instanceof Tree.QualifiedTypeExpression) {
        Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) reference;
        TypeDeclaration type = resolveQualifiedTypeExpression(qte, true);
        if (type != null) {
            setArgumentParameters(that, type);
            Type receivingType = getReceivingType(qte);
            List<Type> typeArgs = getOrInferTypeArguments(that, type, reference, unwrap(receivingType, qte));
            if (typeArgs != null) {
                tas.setTypeModels(typeArgs);
            } else {
                typeArgs = tas.getTypeModels();
            }
            Tree.Primary primary = qte.getPrimary();
            if (primary instanceof Tree.Package) {
                visitBaseTypeExpression(qte, type, typeArgs, tas, null);
            } else {
                visitQualifiedTypeExpression(qte, receivingType, type, typeArgs, tas);
            }
        }
    } else if (reference instanceof Tree.BaseMemberExpression) {
        Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) reference;
        TypedDeclaration base = resolveBaseMemberExpression(bme, true);
        if (base != null) {
            setArgumentParameters(that, base);
            Type receivingType = getBaseReceivingType(that, base);
            List<Type> typeArgs = getOrInferTypeArguments(that, base, reference, receivingType);
            if (typeArgs != null) {
                tas.setTypeModels(typeArgs);
            } else {
                typeArgs = tas.getTypeModels();
            }
            visitBaseMemberExpression(bme, base, typeArgs, tas, receivingType);
        }
    } else if (reference instanceof Tree.QualifiedMemberExpression) {
        Tree.QualifiedMemberExpression qme = (Tree.QualifiedMemberExpression) reference;
        TypedDeclaration member = resolveQualifiedMemberExpression(qme, true);
        if (member != null) {
            setArgumentParameters(that, member);
            Type receivingType = getReceivingType(qme);
            List<Type> typeArgs = getOrInferTypeArguments(that, member, reference, unwrap(receivingType, qme));
            if (typeArgs != null) {
                tas.setTypeModels(typeArgs);
            } else {
                typeArgs = tas.getTypeModels();
            }
            Tree.Primary primary = qme.getPrimary();
            if (primary instanceof Tree.Package) {
                visitBaseMemberExpression(qme, member, typeArgs, tas, null);
            } else {
                visitQualifiedMemberExpression(qme, receivingType, member, typeArgs, tas);
            }
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) ModelUtil.typeParametersAsArgList(org.eclipse.ceylon.model.typechecker.model.ModelUtil.typeParametersAsArgList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) TreeUtil.isEffectivelyBaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.isEffectivelyBaseMemberExpression) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 38 with TypedDeclaration

use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.

the class ExpressionVisitor method visit.

@Override
public void visit(Tree.QualifiedMemberExpression that) {
    super.visit(that);
    boolean notIndirectlyInvoked = !that.getIndirectlyInvoked();
    boolean notDirectlyInvoked = !that.getDirectlyInvoked();
    TypedDeclaration member = resolveQualifiedMemberExpression(that, notIndirectlyInvoked);
    boolean inferrableAnyway = !notDirectlyInvoked && inferrableAnyway(member);
    if (member != null && notDirectlyInvoked || inferrableAnyway) {
        Tree.Primary primary = that.getPrimary();
        Tree.TypeArguments tal = that.getTypeArguments();
        Type receiverType = primary.getTypeModel().resolveAliases();
        if (receiverType.isTypeConstructor()) {
            that.addError("missing type arguments in reference to member of generic type: the type '" + receiverType.asString(unit) + "' is a type constructor (specify explicit type arguments)");
        }
        List<Type> typeArgs;
        if (typeConstructorArgumentsInferrable(member, that)) {
            typeArgs = new TypeArgumentInference(unit).getInferredTypeArgsForFunctionRef(that, receiverType, inferrableAnyway);
        } else if (explicitTypeArguments(member, tal)) {
            typeArgs = getTypeArguments(tal, receiverType, member.getTypeParameters());
        } else {
            typeArgs = new TypeArgumentInference(unit).getInferredTypeArgsForFunctionRef(that, receiverType, inferrableAnyway);
        }
        if (typeArgs != null) {
            tal.setTypeModels(typeArgs);
            if (primary instanceof Tree.Package) {
                visitBaseMemberExpression(that, member, typeArgs, tal, null);
            } else {
                visitQualifiedMemberExpression(that, receiverType, member, typeArgs, tal);
            }
        } else if (notDirectlyInvoked) {
            if (primary instanceof Tree.Package) {
                visitGenericBaseMemberReference(that, member);
            } else {
                visitGenericQualifiedMemberReference(that, receiverType, member);
            }
        }
        if (that.getStaticMethodReference()) {
            handleStaticReferenceImplicitTypeArguments(that);
        }
    // otherwise infer type arguments later
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.declaredInPackage(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.declaredInPackage) Package(org.eclipse.ceylon.model.typechecker.model.Package) AnalyzerUtil.importedPackage(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.importedPackage)

Example 39 with TypedDeclaration

use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.

the class InheritanceVisitor method visit.

@Override
public void visit(Tree.Enumerated that) {
    super.visit(that);
    Value v = that.getDeclarationModel();
    Scope container = v.getContainer();
    if (container instanceof Class) {
        Class cl = (Class) container;
        List<TypedDeclaration> caseValues = cl.getCaseValues();
        if (caseValues != null && !caseValues.contains(v) && !cl.isAbstract()) {
            that.addError("value constructor is not a case of enumerated class: '" + v.getName() + "' is not listed in the 'of' clause of '" + cl.getName() + "'");
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Value(org.eclipse.ceylon.model.typechecker.model.Value) Class(org.eclipse.ceylon.model.typechecker.model.Class)

Example 40 with TypedDeclaration

use of org.eclipse.ceylon.model.typechecker.model.TypedDeclaration in project ceylon by eclipse.

the class InheritanceVisitor method collectCaseValues.

void collectCaseValues(Tree.CaseTypes that, TypeDeclaration td) {
    Unit unit = that.getUnit();
    Set<Declaration> valueSet = new HashSet<Declaration>();
    for (Tree.StaticMemberOrTypeExpression bme : that.getBaseMemberExpressions()) {
        String name = name(bme.getIdentifier());
        TypedDeclaration value = bme instanceof Tree.BaseMemberExpression ? getTypedDeclaration(bme.getScope(), name, null, false, unit) : getPackageTypedDeclaration(name, null, false, unit);
        if (value != null) {
            if (value != null && !valueSet.add(value)) {
                // this error is not really truly necessary
                bme.addError("duplicate case: '" + value.getName(unit) + "' of '" + td.getName() + "'");
            }
            Type type = value.getType();
            if (type != null) {
                TypeDeclaration caseDec = type.getDeclaration();
                if (caseDec instanceof Constructor) {
                    Scope scope = caseDec.getContainer();
                    if (scope instanceof Class) {
                        // enumerated singleton constructors
                        Constructor cons = (Constructor) caseDec;
                        Class c = (Class) scope;
                        if (!c.isToplevel() && !c.isStatic()) {
                            bme.addError("case must be a value constructor of a toplevel or static class: '" + c.getName(unit) + "' is not toplevel");
                        } else if (!cons.getParameterLists().isEmpty()) {
                            bme.addError("case must be a value constructor of a toplevel or static class: '" + cons.getName(unit) + "' is not a value constructor");
                        }
                    /*else if (!c.inherits(unit.getIdentifiableDeclaration())) {
                                bme.addError("case must be a value constructor of an identifiable class: '" + 
                                        c.getName(unit) + 
                                        "' is not a subtype of 'Identifiable'");
                            }*/
                    }
                } else {
                    // enumerated anonymous subclasses
                    if (!caseDec.isObjectClass()) {
                        bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is not an anonymous class");
                    } else if (!value.isToplevel() && !value.isStatic()) {
                        bme.addError("case must be a toplevel or static anonymous class: '" + value.getName(unit) + "' is neither static nor toplevel");
                    }
                }
                if (checkDirectSubtype(td, bme, type)) {
                    checkAssignable(type, td.getType(), bme, getCaseTypeExplanation(td, type));
                }
            }
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Aggregations

TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)110 Type (org.eclipse.ceylon.model.typechecker.model.Type)58 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)51 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)50 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Function (org.eclipse.ceylon.model.typechecker.model.Function)34 Value (org.eclipse.ceylon.model.typechecker.model.Value)28 Class (org.eclipse.ceylon.model.typechecker.model.Class)26 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)25 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)20 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)19 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)17 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)15