/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.parser; import gw.internal.gosu.parser.expressions.AnnotationExpression; import gw.lang.reflect.IAnnotationInfo; import gw.lang.reflect.IType; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.gs.ICompilableType; import gw.lang.reflect.java.JavaTypes; import java.io.Serializable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; /** * Holds annotation information for a feature */ public class GosuAnnotation implements Serializable, IGosuAnnotation { private ICompilableTypeInternal _enclosingType; private IType _type; private Expression _expression; private int _start; private int _end; public GosuAnnotation( ICompilableTypeInternal enclosingType, IType type, Expression expression, int iOffset, int end ) { _enclosingType = enclosingType; _type = type; _expression = expression; _start = iOffset; _end = end; } public String getName() { return getType().getRelativeName(); } public IType getType() { return _type; } @Override public String getNewExpressionAsString() { // what, you were expecting something more sophisictated? if (_start > _end) { return ""; } String typeName = _enclosingType.getSource().substring( _start, _end ); if( typeName.startsWith( "@" ) ) { typeName = typeName.substring( 1 ); } String s = "new " + typeName; if( !s.contains( "(" ) ) // I'll just rub some contains on it... { s += "()"; } return s; } public Expression getExpression() { return _expression; } @Override public void clearExpression() { _expression = null; } public boolean shouldPersistToClass() { return isJavaAnnotation() && !hasRetentionPolicy(RetentionPolicy.SOURCE) && !hasBadArgs(); } @Override public boolean shouldRetainAtRuntime() { return isJavaAnnotation() && hasRetentionPolicy(RetentionPolicy.RUNTIME) && !hasBadArgs(); } private boolean isJavaAnnotation() { return JavaTypes.ANNOTATION().isAssignableFrom( getType() ); } private boolean hasRetentionPolicy(RetentionPolicy policy) { List<IAnnotationInfo> annotation = _type.getTypeInfo().getAnnotationsOfType( TypeSystem.get(Retention.class) ); if( annotation != null ) { for( IAnnotationInfo annotationInfo : annotation ) { String value = (String) annotationInfo.getFieldValue("value"); if( value.equals(policy.name()) ) { return true; } } } return false; } private boolean isSourceAnnotation() { List<IAnnotationInfo> annotations = _type.getTypeInfo().getAnnotationsOfType( JavaTypes.getJreType(Retention.class) ); if( annotations != null ) { for( IAnnotationInfo annotationInfo : annotations ) { String fieldValue = (String) annotationInfo.getFieldValue( "value" ); if( fieldValue.equals( RetentionPolicy.SOURCE.name() ) ) { return true; } } } return false; } private boolean hasBadArgs() { if(_expression instanceof AnnotationExpression ){ if( ((AnnotationExpression)_expression).getArgs() != null ) { for( Expression expr : ((AnnotationExpression)_expression).getArgs() ) { if( !expr.isCompileTimeConstant() ) { return true; } } } } return false; } @Override public ICompilableType getOwnersType() { return _enclosingType; } public void clearDebugInfo() { if (_expression != null) { _expression.clearParseTreeInformation(); } } }