/* * Copyright 2013. Guidewire Software, Inc. */ package gw.lang.reflect.java.asm; import gw.internal.ext.org.objectweb.asm.signature.SignatureVisitor; /** */ class TypeDeclarationSignatureVisitor implements SignatureVisitor { private boolean _bOverride; private int _iInterfacesVisited; private final AsmType _currentType; private AsmType _typeArg; private int _iDims; private IGeneric _asmGenericType; TypeDeclarationSignatureVisitor( IGeneric asmGenericType, AsmType type ) { _asmGenericType = asmGenericType; _currentType = type; } TypeDeclarationSignatureVisitor( IGeneric asmGenericType, AsmType type, boolean bOverride ) { _asmGenericType = asmGenericType; _currentType = type; _bOverride = bOverride; } IGeneric getGenericType() { return _asmGenericType; } @Override public void visitFormalTypeParameter( String tv ) { AsmType typeVar = AsmUtil.makeTypeVariable( tv ); _currentType.addTypeParameter( typeVar ); _asmGenericType.setGeneric(); } @Override public SignatureVisitor visitClassBound() { return new TypeDeclarationSignatureVisitor( _asmGenericType, _currentType.getTypeParameters().get( _currentType.getTypeParameters().size() - 1 ) ); } @Override public SignatureVisitor visitInterfaceBound() { return new TypeDeclarationSignatureVisitor( _asmGenericType, _currentType.getTypeParameters().get( _currentType.getTypeParameters().size() - 1 ) ); } @Override public SignatureVisitor visitSuperclass() { return new TypeDeclarationSignatureVisitor( _asmGenericType, ((AsmClass)_asmGenericType).getSuperClass(), true ); } @Override public SignatureVisitor visitInterface() { return new TypeDeclarationSignatureVisitor( _asmGenericType, ((AsmClass)_asmGenericType).getInterfaces().get( _iInterfacesVisited++ ), true ); } @Override public SignatureVisitor visitParameterType() { // For method only return null; } @Override public SignatureVisitor visitReturnType() { // For method only return null; } @Override public SignatureVisitor visitExceptionType() { // For method only return null; } @Override public void visitBaseType( char c ) { if( _currentType == null ) { return; } if( _iDims == 0 ) { throw new IllegalStateException( "Primitive types are only allowed as array components in a type declaration signature" ); } _typeArg = new AsmType( AsmPrimitiveType.findPrimitive( String.valueOf( c ) ).getName(), _iDims ); _currentType.addTypeParameter( _typeArg ); } @Override public void visitTypeVariable( String tv ) { if( _bOverride ) { throw new IllegalStateException( "Should never have a type var as an override type i.e., type var can't be a superclass or interface" ); } else { _typeArg = AsmUtil.makeTypeVariable( tv ); _currentType.addTypeParameter( _typeArg ); } } @Override public SignatureVisitor visitArrayType() { TypeDeclarationSignatureVisitor visitor = new TypeDeclarationSignatureVisitor( _asmGenericType, _currentType ); visitor._typeArg = _typeArg; visitor._iDims = _iDims + 1; return visitor; } @Override public void visitClassType( String name ) { if( _currentType == null ) { return; } if( _bOverride ) { if( !_currentType.getName().startsWith( AsmUtil.makeDotName( name ) ) ) { throw new IllegalStateException( "Name should match current type" ); } _typeArg = _currentType; } else { _typeArg = AsmUtil.makeType( name ); _currentType.addTypeParameter( _typeArg ); } } @Override public void visitInnerClassType( String name ) { if( _bOverride ) { if( !_currentType.getName().contains( '$' + AsmUtil.makeDotName( name ) ) ) { throw new IllegalStateException( "Name should match current type" ); } _typeArg = _currentType; } else { _typeArg = AsmUtil.makeType( name ); _currentType.addTypeParameter( _typeArg ); } } @Override public void visitTypeArgument() { } @Override public SignatureVisitor visitTypeArgument( char c ) { return new TypeDeclarationSignatureVisitor( _asmGenericType, _typeArg ); } @Override public void visitEnd() { if( _iDims > 0 ) { if( _typeArg.isPrimitive() || _typeArg.isArray() && AsmPrimitiveType.findPrimitive( _typeArg.getName() ) != null ) { throw new IllegalStateException( "Not expected " ); } _typeArg.incArrayDims(); } } }