Package com.redhat.ceylon.compiler.java.codegen

Source Code of com.redhat.ceylon.compiler.java.codegen.Decl

/*
* Copyright Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the authors tag. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*
* This particular file is subject to the "Classpath" exception as provided in the
* LICENSE file that accompanied this code.
*
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE.  See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License,
* along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*/

package com.redhat.ceylon.compiler.java.codegen;

import java.util.List;

import com.redhat.ceylon.compiler.java.util.Util;
import com.redhat.ceylon.compiler.loader.model.FieldValue;
import com.redhat.ceylon.compiler.loader.model.LazyClass;
import com.redhat.ceylon.compiler.loader.model.LazyInterface;
import com.redhat.ceylon.compiler.typechecker.model.Annotation;
import com.redhat.ceylon.compiler.typechecker.model.Class;
import com.redhat.ceylon.compiler.typechecker.model.ClassOrInterface;
import com.redhat.ceylon.compiler.typechecker.model.ConditionScope;
import com.redhat.ceylon.compiler.typechecker.model.ControlBlock;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.Element;
import com.redhat.ceylon.compiler.typechecker.model.Functional;
import com.redhat.ceylon.compiler.typechecker.model.Interface;
import com.redhat.ceylon.compiler.typechecker.model.IntersectionType;
import com.redhat.ceylon.compiler.typechecker.model.Method;
import com.redhat.ceylon.compiler.typechecker.model.MethodOrValue;
import com.redhat.ceylon.compiler.typechecker.model.Module;
import com.redhat.ceylon.compiler.typechecker.model.NamedArgumentList;
import com.redhat.ceylon.compiler.typechecker.model.Package;
import com.redhat.ceylon.compiler.typechecker.model.Parameter;
import com.redhat.ceylon.compiler.typechecker.model.ProducedType;
import com.redhat.ceylon.compiler.typechecker.model.Scope;
import com.redhat.ceylon.compiler.typechecker.model.Setter;
import com.redhat.ceylon.compiler.typechecker.model.Specification;
import com.redhat.ceylon.compiler.typechecker.model.TypeDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration;
import com.redhat.ceylon.compiler.typechecker.model.UnionType;
import com.redhat.ceylon.compiler.typechecker.model.Value;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;

/**
* Utility functions telling you about Ceylon declarations
* @see Strategy
*/
public class Decl {
    private Decl() {
    }

    private static boolean eq(Object decl, Object other) {
        if (decl == null) {
            return other == null;
        } else {
            return decl.equals(other);
        }
    }
   
    public static boolean equal(Declaration decl, Declaration other) {
        if (decl instanceof UnionType || decl instanceof IntersectionType
                || other instanceof UnionType || other instanceof IntersectionType) {
            return false;
        }
        return eq(decl, other);
    }
   
    public static boolean equal(Parameter decl, Parameter other) {
        return eq(decl, other);
    }
   
    public static boolean equalScopes(Scope scope, Scope other) {
        return eq(scope, other);
    }
   
    public static boolean equalScopeDecl(Scope scope, Declaration other) {
        return eq(scope, other);
    }
   
    public static boolean equalModules(Module scope, Module other) {
        return eq(scope, other);
    }
   
    /**
     * Returns the declaration's container
     * @param decl The declaration
     * @return the declaration's container
     */
    public static Scope container(Tree.Declaration decl) {
        return container(decl.getDeclarationModel());
    }

    /**
     * Returns the declaration's container
     * @param decl The declaration
     * @return the declaration's container
     */
    public static Scope container(Declaration decl) {
        return decl.getContainer();
    }
   
    /**
     * Determines whether the declaration is a getter (a transient value
     * that is not a parameter)
     * @param decl The declaration
     * @return true if the declaration is a getter
     */
    public static boolean isGetter(Declaration decl) {
        return (decl instanceof Value)
                && !((Value)decl).isParameter()
                && ((Value)decl).isTransient();
    }

    public static boolean isNonTransientValue(Declaration decl) {
        return (decl instanceof Value)
                && !((Value)decl).isTransient();
    }
   
    public static boolean isSharedParameter(Declaration decl) {
        return decl instanceof Value
                && ((Value)decl).isParameter()
                && decl.isShared();
    }
   
   
    /**
     * Determines whether the declaration is a non-transient non-parameter value
     * (not a getter)
     * @param decl The declaration
     * @return true if the declaration is a value
     */
    public static boolean isValue(Declaration decl) {
        return (decl instanceof Value)
                && !((Value)decl).isParameter()
                && !((Value)decl).isTransient();
    }

    /**
     * Determines whether the declaration's is a value or a shared value parameter
     * @param decl The declaration
     * @return true if the declaration is a value or a shared value parameter
     */
    public static boolean isValueOrSharedParam(Declaration decl) {
        return isValue(decl)
                || decl instanceof Value
                    && ((Value)decl).isParameter()
                    && decl.isShared();
    }
   
    public static boolean isValueOrSharedOrCapturedParam(Declaration decl) {
        return isValue(decl)
                || decl instanceof Value
                    && ((Value)decl).isParameter()
                    && (decl.isShared() || decl.isCaptured());
    }
   
    public static boolean isMethodOrSharedOrCapturedParam(Declaration decl) {
        return decl instanceof Method
                    && (!((Method)decl).isParameter() || decl.isShared() || decl.isCaptured());
    }

    /**
     * Determines whether the declaration's is a method
     * @param decl The declaration
     * @return true if the declaration is a method
     */
    public static boolean isMethod(Declaration decl) {
        return (decl instanceof Method)
                && !((Method)decl).isParameter();
    }

    /**
     * Determines whether the declaration's containing scope is a method
     * @param decl The declaration
     * @return true if the declaration is within a method
     */
    public static boolean withinMethod(Tree.Declaration decl) {
        return withinMethod(decl.getDeclarationModel());
    }
   
    /**
     * Determines whether the declaration's containing scope is a getter
     * @param decl The declaration
     * @return true if the declaration is within a getter
     */
    public static boolean withinGetter(Tree.Declaration decl) {
        return withinGetter(decl.getDeclarationModel());
    }
   
    /**
     * Determines whether the declaration's containing scope is a setter
     * @param decl The declaration
     * @return true if the declaration is within a setter
     */
    public static boolean withinSetter(Tree.Declaration decl) {
        return withinSetter(decl.getDeclarationModel());
    }

    /**
     * Determines whether the declaration's containing scope is a method
     * @param decl The declaration
     * @return true if the declaration is within a method
     */
    public static boolean withinMethod(Declaration decl) {
        return container(decl) instanceof Method;
    }
   
    /**
     * Determines whether the declaration's containing scope is a getter
     * @param decl The declaration
     * @return true if the declaration is within a getter
     */
    public static boolean withinGetter(Declaration decl) {
        Scope s = container(decl);
        return isGetter((Declaration)s);
    }
   
    /**
     * Determines whether the declaration's containing scope is a setter
     * @param decl The declaration
     * @return true if the declaration is within a setter
     */
    public static boolean withinSetter(Declaration decl) {
        return container(decl) instanceof Setter;
    }
   
    /**
     * Determines whether the declaration's containing scope is a package
     * @param decl The declaration
     * @return true if the declaration is within a package
     */
    public static boolean withinPackage(Tree.Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.Package;
    }
   
    /**
     * Determines whether the declaration's containing scope is a class
     * @param decl The declaration
     * @return true if the declaration is within a class
     */
    public static boolean withinClass(Tree.Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.Class;
    }
   
    public static boolean withinClass(Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.Class;
    }
   
    /**
     * Determines whether the declaration's containing scope is an interface
     * @param decl The declaration
     * @return true if the declaration is within an interface
     */
    public static boolean withinInterface(Tree.Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.Interface;
    }
   
    public static boolean withinInterface(Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.Interface;
    }
   
    /**
     * Determines whether the declaration's containing scope is a class or interface
     * @param decl The declaration
     * @return true if the declaration is within a class or interface
     */
    public static boolean withinClassOrInterface(Tree.Declaration decl) {
        return withinClassOrInterface(decl.getDeclarationModel());
    }
   
    /**
     * Determines whether the declaration's containing scope is a class or interface
     * @param decl The declaration
     * @return true if the declaration is within a class or interface
     */
    public static boolean withinClassOrInterface(Declaration decl) {
        return container(decl) instanceof com.redhat.ceylon.compiler.typechecker.model.ClassOrInterface;
    }
   
    public static boolean isShared(Tree.Declaration decl) {
        return isShared(decl.getDeclarationModel());
    }
   
    public static boolean isShared(Declaration decl) {
        return decl.isShared();
    }
   
    public static boolean isCaptured(Tree.Declaration decl) {
        return isCaptured(decl.getDeclarationModel());
    }
   
    public static boolean isCaptured(Declaration decl) {
        // Shared elements are implicitely captured although the typechecker doesn't mark them that way
        return decl.isCaptured() || decl.isShared();
    }

    public static boolean isAbstract(Tree.ClassOrInterface decl) {
        return decl.getDeclarationModel().isAbstract();
    }

    public static boolean isDefault(Tree.Declaration decl) {
        return decl.getDeclarationModel().isDefault();
    }

    public static boolean isFormal(Tree.Declaration decl) {
        return decl.getDeclarationModel().isFormal();
    }

    public static boolean isActual(Tree.Declaration decl) {
        return isActual(decl.getDeclarationModel());
    }
   
    public static boolean isActual(Declaration decl) {
        return decl.isActual();
    }

    public static boolean isTransient(Tree.AttributeDeclaration decl) {
        return decl.getDeclarationModel().isTransient();
    }

    public static boolean isTransient(Declaration decl) {
        if (decl instanceof MethodOrValue) {
            return ((MethodOrValue)decl).isTransient();
        } else {
            return false;
        }
    }

    public static boolean isVariable(Tree.AttributeDeclaration decl) {
        return decl.getDeclarationModel().isVariable() && !hasSetter(decl);
    }
   
    public static boolean hasSetter(Tree.AttributeDeclaration decl) {
        return decl.getDeclarationModel().getSetter() != null;
    }
   
    public static boolean isLate(Tree.AttributeDeclaration decl) {
        return isLate(decl.getDeclarationModel());
    }

    public static boolean isLate(Value model) {
        return model.isLate();
    }
   
    public static boolean isIndirect(Tree.AttributeDeclaration decl) {
        return decl.getDeclarationModel().isTransient() && decl.getSpecifierOrInitializerExpression() == null;
    }

    public static boolean isToplevel(Tree.Declaration decl) {
        return isToplevel(decl.getDeclarationModel());
    }
   
    public static boolean isToplevel(Declaration decl) {
        return decl.isToplevel();
    }
   
    public static boolean isNative(Tree.Declaration decl) {
        return isNative(decl.getDeclarationModel());
    }
   
    public static boolean isNative(Declaration decl) {
        return decl.isNative();
    }
   
    public static boolean isDeferred(Tree.Declaration decl) {
        return isDeferred(decl.getDeclarationModel());
    }
   
    public static boolean isDeferred(Declaration decl) {
        return (decl instanceof Method) && ((Method)decl).isDeferred();
    }
   
    /**
     * Determines whether the declaration is local to a method,
     * getter or setter, but <strong>returns {@code false} for a declaration
     * local to a Class initializer.</strong>
     * @param decl The declaration
     * @return true if the declaration is local
     */
    public static boolean isLocalNotInitializer(Tree.Declaration decl) {
        return isLocalNotInitializer(decl.getDeclarationModel());
    }

    /**
     * Determines whether the declaration is local to a method,
     * getter or setter, but <strong>returns {@code false} for a declaration
     * local to a Class initializer.</strong>
     * @param decl The declaration
     * @return true if the declaration is local
     */
    public static boolean isLocalNotInitializer(Declaration decl) {
        return isLocalNotInitializerScope(decl.getContainer());
    }
   
    /**
     * Determines whether the declaration is local to a method,
     * getter, setter or Class initializer.
     * @param decl The declaration
     * @return true if the declaration is local
     */
    public static boolean isLocal(Tree.Declaration decl) {
        return isLocal(decl.getDeclarationModel());
    }

    /**
     * Determines whether the declaration is local to a method,
     * getter, setter or Class initializer.
     * @param decl The declaration
     * @return true if the declaration is local
     */
    public static boolean isLocal(Declaration decl) {
        return isLocalNotInitializer(decl) || isLocalToInitializer(decl);
    }
   
    /**
     * Is the given scope a local scope but not an initializer scope?
     */
    public static boolean isLocalNotInitializerScope(Scope scope) {
        return scope instanceof MethodOrValue
                || scope instanceof ControlBlock
                || scope instanceof NamedArgumentList
                || scope instanceof Specification;
    }
   
    /**
     * Determines whether the declaration is local or a descendant of a
     * local.
     * @param decl The declaration
     * @return true if the decl is local or descendant from a local
     */
    public static boolean isAncestorLocal(Tree.Declaration decl) {
        return isAncestorLocal(decl.getDeclarationModel());
    }
   
    /**
     * Determines whether the declaration is local or a descendant of a
     * local.
     * @param decl The declaration
     * @return true if the decl is local or descendant from a local
     */
    public static boolean isAncestorLocal(Declaration decl) {
        Scope container = decl.getContainer();
        while (container != null) {
            if (container instanceof MethodOrValue
                    || container instanceof ControlBlock
                    || container instanceof NamedArgumentList) {
                return true;
            }
            container = container.getContainer();
        }
        return false;
    }
       
    public static boolean isClassAttribute(Declaration decl) {
        return (withinClassOrInterface(decl))
                && (Decl.isValue(decl) || decl instanceof Setter)
                && (decl.isCaptured() || decl.isShared());
    }

    public static boolean isClassParameter(Declaration decl) {
        return (withinClassOrInterface(decl))
                && (decl instanceof Value)
                && ((Value)decl).isParameter()
                && (decl.isCaptured() || decl.isShared());
    }

    public static boolean isLocalToInitializer(Tree.Declaration decl) {
        return isLocalToInitializer(decl.getDeclarationModel());
    }
   
    public static boolean isLocalToInitializer(Declaration decl) {
        return withinClass(decl) && !Decl.isCaptured(decl);
    }
   
    public static boolean isOverloaded(Declaration decl) {
        if (decl instanceof Functional) {
            return ((Functional)decl).isOverloaded();
        }
        return false;
    }

    public static boolean isJavaField(Declaration decl) {
        return decl instanceof FieldValue;
    }

    public static boolean isStatic(TypeDeclaration declaration) {
        if(declaration instanceof LazyClass){
            return ((LazyClass)declaration).isStatic();
        }
        if(declaration instanceof LazyInterface){
            return ((LazyInterface)declaration).isStatic();
        }
        return false;
    }

    public static boolean isCeylon(TypeDeclaration declaration) {
        if(declaration instanceof LazyClass){
            return ((LazyClass)declaration).isCeylon();
        }
        if(declaration instanceof LazyInterface){
            return ((LazyInterface)declaration).isCeylon();
        }
        // if it's not one of those it must be from source (Ceylon)
        return true;
    }

    /**
     * Is the declaration a method declared to return {@code void}
     * (as opposed to a {@code Anything})
     */
    public static boolean isUnboxedVoid(Declaration decl) {
        return Util.isUnboxedVoid(decl);
    }
   
    public static boolean isMpl(Functional decl) {
        return decl.getParameterLists().size() > 1;
    }
   
    public static ClassOrInterface getClassOrInterfaceContainer(Element decl){
        return getClassOrInterfaceContainer(decl, true);
    }
   
    public static ClassOrInterface getClassOrInterfaceContainer(Element decl, boolean includingDecl){
        if (!includingDecl) {
            decl = (Element) decl.getContainer();
        }
        // stop when null or when it's a ClassOrInterface
        while(decl != null
                && !(decl instanceof ClassOrInterface)){
            // stop if the container is not an Element
            if(!(decl.getContainer() instanceof Element))
                return null;
            decl = (Element) decl.getContainer();
        }
        return (ClassOrInterface) decl;
    }

    public static Package getPackage(Declaration decl){
        if (decl instanceof Scope) {
            return getPackageContainer((Scope)decl);
        } else {
            return getPackageContainer(decl.getContainer());
        }
    }

    public static Package getPackageContainer(Scope scope){
        // stop when null or when it's a Package
        while(scope != null
                && !(scope instanceof Package)){
            // stop if the container is not a Scope
            if(!(scope.getContainer() instanceof Scope))
                return null;
            scope = (Scope) scope.getContainer();
        }
        return (Package) scope;
    }

    public static Module getModule(Declaration decl){
        if (decl instanceof Scope) {
            return getModuleContainer((Scope)decl);
        } else {
            return getModuleContainer(decl.getContainer());
        }
    }

    public static Module getModuleContainer(Scope scope) {
        Package pkg = Decl.getPackageContainer(scope);
        return pkg != null ? pkg.getModule() : null;
    }

    public static boolean isValueTypeDecl(Tree.Term decl) {
        if (decl != null){
            return isValueTypeDecl(decl.getTypeModel());
        }
        return false;
    }
   
    public static boolean isValueTypeDecl(TypedDeclaration decl) {
        if (decl != null){
            return isValueTypeDecl(decl.getType());
        }
        return false;
    }

    public static boolean isValueTypeDecl(ProducedType type) {
        if(type == null)
            return false;
        type = type.resolveAliases();
        if ((type != null) && type.getDeclaration() instanceof LazyClass) {
            return ((LazyClass)type.getDeclaration()).isValueType();
        }
        return false;
    }

    static boolean isRefinableMemberClass(Declaration model) {
        return model instanceof Class
                && model.isMember()
                && (model.isFormal() || model.isDefault())
                && !model.isAnonymous()
                && isCeylon((Class)model);
    }
   
    /**
     * WARNING: this only works for Ceylon declarations!!!
     */
    public static String className(Declaration decl) {
        String name = decl.getQualifiedNameString().replace("::", ".");
        if (Naming.isLowerCase(decl.getName())) {
            name += "_";
        }
        return name;
    }

    public static Tree.Term unwrapExpressionsUntilTerm(Tree.Term term) {
        while (term instanceof Tree.Expression) {
            term = ((Tree.Expression)term).getTerm();
        }
        return term;
    }
   
    /**
     * Determines whether the given attribute should be accessed and assigned
     * via a {@code VariableBox}
     */
    public static boolean isBoxedVariable(Tree.AttributeDeclaration attr) {
        return isBoxedVariable(attr.getDeclarationModel());
    }
   
    /**
     * Determines whether the given attribute should be accessed and assigned
     * via a {@code VariableBox}
     */
    public static boolean isBoxedVariable(TypedDeclaration attr) {
        return isNonTransientValue(attr)
                && isLocalNotInitializer(attr)
                && ((attr.isVariable() && attr.isCaptured())
                        // self-captured objects must also be boxed like variables
                        || attr.isSelfCaptured());
    }

    public static boolean isObjectValue(TypedDeclaration attr) {
        ProducedType type = attr.getType();
        // Check type because in case of compile errors it can be null
        if (type != null) {
            TypeDeclaration typeDecl = type.getDeclaration();
            return typeDecl.isAnonymous();
        }
        return false;
    }

    public static boolean isAnnotationConstructor(Tree.AnyMethod def) {
        return isAnnotationConstructor(def.getDeclarationModel());
    }
   
    public static boolean isAnnotationConstructor(Declaration def) {
        return def.isToplevel()
                && def instanceof Method
                && containsAnnotationAnnotation(def);
    }

    private static boolean containsAnnotationAnnotation(
            Declaration decl) {
        List<Annotation> annotations = decl.getAnnotations();
        if (annotations != null) {
            for (Annotation ann : annotations) {
                if ("annotation".equals(ann.getName())) {
                    return true;
                }
            }
        }
        return false;
    }

    public static boolean isAnnotationClass(Tree.ClassOrInterface def) {
        return isAnnotationClass(def.getDeclarationModel());
    }

    public static boolean isAnnotationClass(Declaration declarationModel) {
        return (declarationModel instanceof Class)
                && containsAnnotationAnnotation(declarationModel);
    }

    /**
     * Determines whether the given annotation class is a synthetic "proxy"
     * created by LazyPackage
     */
    public static boolean isInteropAnnotationClass(
            ClassOrInterface annotationClass) {  
        return annotationClass.getName().endsWith("$Proxy");
    }
   
    public static boolean isJavaArray(TypeDeclaration decl) {
        if(decl instanceof Class == false)
            return false;
        Class c = (Class) decl;
        String name = c.getQualifiedNameString();
        return name.equals("java.lang::ObjectArray")
                || name.equals("java.lang::ByteArray")
                || name.equals("java.lang::ShortArray")
                || name.equals("java.lang::IntArray")
                || name.equals("java.lang::LongArray")
                || name.equals("java.lang::FloatArray")
                || name.equals("java.lang::DoubleArray")
                || name.equals("java.lang::BooleanArray")
                || name.equals("java.lang::CharArray");
    }

    public static boolean isJavaObjectArray(TypeDeclaration decl) {
        if(decl instanceof Class == false)
            return false;
        Class c = (Class) decl;
        String name = c.getQualifiedNameString();
        return name.equals("java.lang::ObjectArray");
    }

    public static boolean isAnnotationClassOrConstructor(Declaration container) {
        return isAnnotationClass(container) || isAnnotationConstructor(container);
    }
   
    public static Tree.SpecifierOrInitializerExpression getDefaultArgument(Tree.Parameter parameter) {
        if (parameter instanceof Tree.InitializerParameter) {
            return ((Tree.InitializerParameter)parameter).getSpecifierExpression();
        } else if (parameter instanceof Tree.ValueParameterDeclaration) {
            Tree.TypedDeclaration typedDeclaration = ((Tree.ValueParameterDeclaration)parameter).getTypedDeclaration();
            if (typedDeclaration != null) {
                return ((Tree.AttributeDeclaration)typedDeclaration).getSpecifierOrInitializerExpression();
            }
        } else if (parameter instanceof Tree.FunctionalParameterDeclaration) {
            Tree.TypedDeclaration typedDeclaration = ((Tree.FunctionalParameterDeclaration)parameter).getTypedDeclaration();
            if (typedDeclaration != null) {
                return ((Tree.MethodDeclaration)typedDeclaration).getSpecifierExpression();
            }
        }
        return null;
    }
   
    public static Tree.TypedDeclaration getMemberDeclaration(Tree.AnyClass def, final Tree.Parameter parameter) {
        if (parameter instanceof Tree.ParameterDeclaration) {
            return ((Tree.ParameterDeclaration)parameter).getTypedDeclaration();
        } else if (parameter instanceof Tree.InitializerParameter) {
            final Tree.TypedDeclaration[] annotationList = new Tree.TypedDeclaration[]{null};
            def.visit(new Visitor() {
                public void visit(Tree.MethodDeclaration that) {
                    if (that.getDeclarationModel().equals(parameter.getParameterModel().getModel())) {
                        annotationList[0] = that;
                    }
                }
                public void visit(Tree.AttributeDeclaration that) {
                    if (that.getDeclarationModel().equals(parameter.getParameterModel().getModel())) {
                        annotationList[0] = that;
                    }
                }
            });
            return annotationList[0];
        }
        return null;
    }
   
    public static Tree.AnnotationList getAnnotations(Tree.AnyClass def, final Tree.Parameter parameter) {
        return getMemberDeclaration(def, parameter).getAnnotationList();
    }
   
    public static boolean isParameter(Declaration decl) {
        return decl instanceof MethodOrValue
                && ((MethodOrValue)decl).isParameter();
    }
   
    public static boolean isFunctionalParameter(Declaration decl) {
        return decl instanceof Method
                && ((Method)decl).isParameter();
    }
   
    public static boolean isValueParameter(Declaration decl) {
        return decl instanceof Value
                && ((Value)decl).isParameter();
    }
   

   
   
    public static boolean isEnumeratedTypeWithAnonCases(ProducedType parameterType) {
        TypeDeclaration decl = parameterType.getDeclaration();
        if (decl.equals(decl.getUnit().getBooleanDeclaration())) {
            return false;
        }
        if (decl.getCaseTypeDeclarations() == null) {
            return false;
        }
        for (TypeDeclaration td : decl.getCaseTypeDeclarations()) {
            if (!td.isAnonymous()) {
                return false;
            }
        }
        return true;
    }
   
    public static boolean isAnonCaseOfEnumeratedType(Tree.BaseMemberExpression term) {
        Declaration decl = term.getDeclaration();
        return isAnonCaseOfEnumeratedType(decl);
    }
    public static boolean isAnonCaseOfEnumeratedType(Declaration decl) {
   
        if (com.redhat.ceylon.compiler.typechecker.analyzer.Util.isBooleanTrue(decl)
                || com.redhat.ceylon.compiler.typechecker.analyzer.Util.isBooleanFalse(decl)) {
            return false;
        }
        if (decl instanceof Value) {
            TypeDeclaration type = ((Value) decl).getType().getDeclaration();
            if (type.isAnonymous()) {
                if (isEnumeratedTypeWithAnonCases(type.getExtendedType())) {
                    return true;
                }
                for (ProducedType s : type.getSatisfiedTypes()) {
                    if (isEnumeratedTypeWithAnonCases(s)) {
                        return true;
                    }
                }
            }
        }
        return false;
       
    }
   
    public static boolean isJavaStaticPrimary(Tree.Term term) {
        return term instanceof Tree.QualifiedMemberOrTypeExpression
                && ((Tree.QualifiedMemberOrTypeExpression)term).getDeclaration() != null
                && ((Tree.QualifiedMemberOrTypeExpression)term).getDeclaration().isStaticallyImportable();
    }
   
    /**
     * Is the member private and not visible from the primary (i.e. is an
     * upcast required to be able to see that member)
     */
    public static boolean isPrivateAccessRequiringUpcast(Tree.StaticMemberOrTypeExpression qual) {
        if (qual instanceof Tree.QualifiedMemberOrTypeExpression) {
            Tree.Primary primary = ((Tree.QualifiedMemberOrTypeExpression)qual).getPrimary();
            Declaration decl = qual.getDeclaration();
            return decl.isMember()
                    && !decl.isShared()
                    && decl.getContainer() instanceof Class
                    && !Decl.equalScopeDecl(decl.getContainer(), primary.getTypeModel().getDeclaration());
        }
        return false;
    }
   
    public static boolean isPrivateAccessRequiringCompanion(Tree.StaticMemberOrTypeExpression qual) {
        if (qual instanceof Tree.QualifiedMemberOrTypeExpression) {
            Tree.Primary primary = ((Tree.QualifiedMemberOrTypeExpression)qual).getPrimary();
            Declaration decl = qual.getDeclaration();
            return decl.isMember()
                    && !decl.isShared()
                    && decl.getContainer() instanceof Interface
                    && !Decl.equalScopeDecl(decl.getContainer(), primary.getTypeModel().getDeclaration());
        }
        return false;
    }
   
    public static ProducedType getPrivateAccessType(Tree.StaticMemberOrTypeExpression qmte) {
        return ((TypeDeclaration)qmte.getDeclaration().getRefinedDeclaration().getContainer()).getType();
    }

    /**
     * Finds the first containing scope of the given scope which is not a ConditionScope.
     * @param scope
     * @return
     */
    public static Scope getNonConditionScope(Scope scope) {
        while (scope != null &&
                scope instanceof ConditionScope) {
            scope = scope.getContainer();
        }
        return scope;
    }
}
TOP

Related Classes of com.redhat.ceylon.compiler.java.codegen.Decl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.