/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.template; import gw.internal.gosu.parser.*; import gw.lang.reflect.gs.ClassType; import gw.lang.reflect.gs.ISourceFileHandle; import gw.lang.reflect.*; import gw.lang.GosuShop; import gw.lang.parser.ISymbol; import gw.lang.parser.ISymbolTable; import gw.lang.parser.ITypeUsesMap; import gw.lang.parser.template.ITemplateGenerator; import gw.lang.reflect.IFunctionType; import gw.lang.reflect.IMethodInfo; import gw.lang.reflect.IRelativeTypeInfo; import gw.lang.reflect.IType; import gw.lang.reflect.Modifier; import gw.lang.reflect.TypeSystem; import gw.lang.reflect.gs.GosuClassTypeLoader; import gw.lang.reflect.java.IJavaType; import gw.lang.reflect.java.JavaTypes; import java.io.StringReader; import java.io.Writer; import java.util.ArrayList; import java.util.List; public class GosuTemplateType extends GosuProgram implements IGosuTemplateInternal { private TemplateGenerator _gen; private ModifierInfo _modifierInfo; public GosuTemplateType( String strNamespace, String strRelativeName, GosuClassTypeLoader classTypeLoader, ISourceFileHandle sourceFile, ITypeUsesMap typeUsesMap, ISymbolTable symTable ) { super( strNamespace, strRelativeName, classTypeLoader, sourceFile, typeUsesMap, symTable ); _modifierInfo = new ModifierInfo( Modifier.PUBLIC ); } @Override protected void addProgramInterfaces() { } public IType getArrayType() { return TypeSystem.getOrCreateTypeReference(new DefaultArrayType(TypeSystem.getOrCreateTypeReference(this), TypeSystem.getJavaClassInfo(Object.class), getTypeLoader())); } public IType getSupertype() { if( getTemplateGenerator().getSuperType() != null ) { return getTemplateGenerator().getSuperType(); } return JavaTypes.OBJECT(); } @Override public boolean isFinal() { return true; } @Override public boolean isGenericType() { return false; } @Override public ModifierInfo getModifierInfo() { return _modifierInfo; } public TemplateGenerator getTemplateGenerator() { if( _gen == null ) { _gen = (TemplateGenerator)GosuShop.createSimpleTemplateHost().getTemplate( new StringReader( getSource() ), getName() ); } return _gen; } @Override protected GosuParser getOrCreateParser(CompiledGosuClassSymbolTable symbolTable) { GosuParser parser = super.getOrCreateParser(symbolTable); if( parser.getTokenizerInstructor() == null ) { setTokenizerInstructor( new TemplateTokenizerInstructor( parser.getTokenizer() ) ); } return parser; } @Override public void addTemplateEntryPoints( ISymbolTable symTable, GosuClassParser parser ) { IGosuClassInternal pThis = (IGosuClassInternal)getOrCreateTypeReference(); IJavaType iface = JavaTypes.getGosuType(TemplateRenderer.class); IGosuClassInternal gsInterface = Util.getGosuClassFrom( iface ); if( gsInterface != null ) { for( IMethodInfo mi : gsInterface.getTypeInfo().getDeclaredMethods() ) { if( mi.getDisplayName().startsWith( "render" ) ) { GosuMethodInfo gmi = (GosuMethodInfo)mi; ReducedDynamicFunctionSymbol dfs = gmi.getDfs(); mi = (IMethodInfo)dfs.getMethodOrConstructorInfo(); String strMethodName = mi.getDisplayName(); mi = ((IRelativeTypeInfo)iface.getTypeInfo()).getMethod( iface, strMethodName, ((IFunctionType)dfs.getType()).getParameterTypes() ); symTable.pushScope(); TemplateRenderFunctionSymbol forwardFs; try { forwardFs = new TemplateRenderFunctionSymbol( pThis, symTable, dfs, mi, this, getParameterTypes( "render".equals( strMethodName ) ) ); } finally { symTable.popScope(); } forwardFs.setModifiers( Modifier.setStatic( forwardFs.getModifiers(), true ) ); parser.processFunctionSymbol( forwardFs, pThis ); } } } } public IType[] getParameterTypes( boolean bWithWriter ) { ITemplateGenerator templateGenerator = getTemplateGenerator(); List<ISymbol> params = templateGenerator.getParameters(); List<IType> paramTypes = new ArrayList<IType>(); if( bWithWriter ) { paramTypes.add( JavaTypes.getJreType( Writer.class ) ); } for( int i = 0; i < params.size(); i++ ) { ISymbol symbol = params.get( i ); paramTypes.add( symbol.getType() ); } return paramTypes.toArray( new IType[paramTypes.size()] ); } @Override public ClassType getClassType() { return ClassType.Template; } }