Package org.codehaus.groovy.control

Source Code of org.codehaus.groovy.control.AnnotationConstantsVisitor

/*
* Copyright 2003-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.codehaus.groovy.control;

import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.expr.CastExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.classgen.Verifier;

import java.math.BigDecimal;

/**
* Visitor to resolve constants in annotation definitions.
*
* @author Paul King
*/
public class AnnotationConstantsVisitor extends ClassCodeVisitorSupport {
    private SourceUnit source;
    private boolean inAnnotationDef;

    public void visitClass(ClassNode node, SourceUnit source) {
        this.source = source;
        this.inAnnotationDef = node.isAnnotationDefinition();
        super.visitClass(node);
        this.inAnnotationDef = false;
    }

    @Override
    protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
        if (!inAnnotationDef) return;
        visitStatement(node.getFirstStatement(), node.getReturnType());
    }

    private void visitStatement(Statement statement, ClassNode returnType) {
        if (statement instanceof ReturnStatement) {
            // normal path
            ReturnStatement rs = (ReturnStatement) statement;
            rs.setExpression(transformConstantExpression(rs.getExpression(), returnType));
        } else if (statement instanceof ExpressionStatement) {
            // path for JavaStubGenerator
            ExpressionStatement es = (ExpressionStatement) statement;
            es.setExpression(transformConstantExpression(es.getExpression(), returnType));
        }
    }

    private Expression transformConstantExpression(Expression val, ClassNode returnType) {
        ClassNode returnWrapperType = ClassHelper.getWrapper(returnType);
        if (val instanceof ConstantExpression) {
            Expression result = revertType(val, returnWrapperType);
            if (result != null) {
                return result;
            }
            return val;
        }
        if (val instanceof CastExpression) {
            CastExpression castExp = (CastExpression) val;
            Expression castee = castExp.getExpression();
            if (castee instanceof ConstantExpression) {
                if (ClassHelper.getWrapper(castee.getType()).isDerivedFrom(returnWrapperType)) {
                    return castee;
                }
                Expression result = revertType(castee, returnWrapperType);
                if (result != null) {
                    return result;
                }
                return castee;
            }
        }
        return val;
    }

    private Expression revertType(Expression val, ClassNode returnWrapperType) {
        ConstantExpression ce = (ConstantExpression) val;
        if (ClassHelper.Character_TYPE.equals(returnWrapperType) && ClassHelper.STRING_TYPE.equals(val.getType())) {
            return configure(val, Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) val));
        }
        ClassNode valWrapperType = ClassHelper.getWrapper(val.getType());
        if (ClassHelper.Integer_TYPE.equals(valWrapperType)) {
            Integer i = (Integer) ce.getValue();
            if (ClassHelper.Character_TYPE.equals(returnWrapperType)) {
                return configure(val, new ConstantExpression((char) i.intValue(), true));
            }
            if (ClassHelper.Short_TYPE.equals(returnWrapperType)) {
                return configure(val, new ConstantExpression(i.shortValue(), true));
            }
            if (ClassHelper.Byte_TYPE.equals(returnWrapperType)) {
                return configure(val, new ConstantExpression(i.byteValue(), true));
            }
        }
        if (ClassHelper.BigDecimal_TYPE.equals(valWrapperType)) {
            BigDecimal bd = (BigDecimal) ce.getValue();
            if (ClassHelper.Float_TYPE.equals(returnWrapperType)) {
                return configure(val, new ConstantExpression(bd.floatValue(), true));
            }
            if (ClassHelper.Double_TYPE.equals(returnWrapperType)) {
                return configure(val, new ConstantExpression(bd.doubleValue(), true));
            }
        }
        return null;
    }

    private Expression configure(Expression orig, Expression result) {
        result.setSourcePosition(orig);
        return result;
    }

    protected SourceUnit getSourceUnit() {
        return source;
    }
}
TOP

Related Classes of org.codehaus.groovy.control.AnnotationConstantsVisitor

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.