/* * Copyright 2013. Guidewire Software, Inc. */ package gw.lang.reflect.java.asm; import gw.internal.ext.org.objectweb.asm.signature.SignatureVisitor; /** */ public class MethodPartSignatureVisitor implements SignatureVisitor { private AsmType _currentType; private AsmType _typeArg; private int _iDims; private Boolean _variance; // null = none, true = covariant, false = contravariant MethodPartSignatureVisitor( AsmType type ) { _currentType = type; } MethodPartSignatureVisitor( AsmType type, char wildcardVariance ) { _currentType = type; _typeArg = type; _variance = wildcardVariance == '=' ? null : wildcardVariance == '+'; } @Override public void visitFormalTypeParameter( String tv ) { throw new IllegalStateException(); } @Override public SignatureVisitor visitClassBound() { throw new IllegalStateException(); } @Override public SignatureVisitor visitInterfaceBound() { throw new IllegalStateException(); } @Override public SignatureVisitor visitSuperclass() { return this; } @Override public SignatureVisitor visitInterface() { throw new IllegalStateException(); } @Override public SignatureVisitor visitParameterType() { // For method only throw new IllegalStateException(); } @Override public SignatureVisitor visitReturnType() { // For method only throw new IllegalStateException(); } @Override public SignatureVisitor visitExceptionType() { // For method only throw new IllegalStateException(); } @Override public void visitBaseType( char c ) { if( _currentType == null ) { return; } if( _iDims == 0 ) { return; } if( _currentType instanceof AsmPrimitiveType ) { throw new IllegalStateException( "Current type should not be a cached Primitive type" ); } String name = String.valueOf( c ); AsmPrimitiveType primitive = AsmPrimitiveType.findPrimitive( name ); if( !primitive.equals( _currentType ) ) { _typeArg = AsmUtil.makeType( primitive.getName() ); if( _variance != null ) { _typeArg = new AsmWildcardType( _typeArg, _variance ); } _currentType.addTypeParameter( _typeArg ); _currentType = _typeArg; } for( int i = 0; i < _iDims; i++ ) { _currentType.incArrayDims(); } } @Override public void visitTypeVariable( String tv ) { if( _typeArg == null ) { _currentType.setName( tv ); _currentType.setTypeVariable(); if( !AsmUtil.makeDotName( tv ).equals( _currentType.getName() ) ) { throw new IllegalStateException( "Name should match current type" ); } if( _iDims > 0 ) { for( int i = 0; i < _iDims; i++ ) { _currentType.incArrayDims(); } } _typeArg = _currentType; } else { _typeArg = AsmUtil.makeTypeVariable( tv ); if( _variance != null ) { _typeArg = new AsmWildcardType( _typeArg, _variance ); } _currentType.addTypeParameter( _typeArg ); } } @Override public SignatureVisitor visitArrayType() { MethodPartSignatureVisitor visitor = new MethodPartSignatureVisitor( _currentType ); visitor._typeArg = _typeArg; visitor._iDims = _iDims + 1; return visitor; } @Override public void visitClassType( String name ) { if( _typeArg == null ) { if( !_currentType.getName().startsWith( AsmUtil.makeDotName( name ) ) ) { throw new IllegalStateException( "Name should match current type" ); } _typeArg = _currentType; } else { _typeArg = AsmUtil.makeType( name ); if( _variance != null ) { _typeArg = new AsmWildcardType( _typeArg, _variance ); } _currentType.addTypeParameter( _typeArg ); } } @Override public void visitInnerClassType( String name ) { if( _typeArg == null ) { if( !_currentType.getName().contains( '$' + AsmUtil.makeDotName( name ) ) ) { throw new IllegalStateException( "Name should match current type" ); } _typeArg = _currentType; } else { _typeArg = AsmUtil.makeType( name ); if( _variance != null ) { _typeArg = new AsmWildcardType( _typeArg, _variance ); } _currentType.addTypeParameter( _typeArg ); } } @Override public void visitTypeArgument() { _typeArg.addTypeParameter( new AsmWildcardType( null, true ) ); } @Override public SignatureVisitor visitTypeArgument( char wildcard ) { return new MethodPartSignatureVisitor( _typeArg, wildcard ); } @Override public void visitEnd() { if( _iDims > 0 ) { if( _typeArg.isPrimitive() || _typeArg.isArray() && AsmPrimitiveType.findPrimitive( _typeArg.getName() ) != null ) { throw new IllegalStateException( "Not expected " ); } for( int i = 0; i < _iDims; i++ ) { _typeArg.incArrayDims(); } } } }