/* * Copyright 2013 Guidewire Software, Inc. */ package gw.internal.gosu.ir.transform; import gw.internal.gosu.ir.nodes.GosuClassIRType; import gw.internal.gosu.ir.transform.util.RequiresReflectionDeterminer; import gw.internal.gosu.parser.IGosuClassInternal; import gw.lang.ir.IRExpression; import gw.lang.ir.IRStatement; import gw.lang.ir.IRType; import gw.lang.parser.IBlockClass; import gw.lang.parser.Keyword; import gw.lang.reflect.IRelativeTypeInfo; import gw.lang.reflect.IType; import gw.lang.reflect.gs.ISourceFileHandle; import java.util.ArrayList; import java.util.List; public class GosuClassTransformationContext extends TransformationContextBase { private GosuClassTransformer _classTransformer; private IGosuClassInternal _gsClass; private List<String> _sourceLines; private static final boolean INCLUDE_SOURCE_COMMENTS = false; public GosuClassTransformationContext( GosuClassTransformer classTransformer, IGosuClassInternal gsClass ) { super(gsClass ); _classTransformer = classTransformer; _gsClass = gsClass; maybeIndexSourceCode(); } @Override public void maybeAssignOuterRef(List<IRStatement> statements) { _classTransformer.maybeAssignOuterRef( statements ); } @Override public void maybePushSupersEnclosingThisRef(List<IRExpression> arguments) { _classTransformer.maybePushSupersEnclosingThisRef( arguments ); } @Override public void pushEnumNameAndOrdinal(IType type, List<IRExpression> args) { _classTransformer.pushEnumNameAndOrdinal( type, args ); } @Override public void initCapturedSymbolFields(List<IRStatement> statements) { _classTransformer.initCapturedSymbolFields( statements ); } @Override public void initTypeVarFields(List<IRStatement> statements) { _classTransformer.initTypeVarFields( statements ); } @Override public void initializeInstanceFields(List<IRStatement> statements) { _classTransformer.initializeInstanceFields( statements ); } public void addAssertionsStaticField() { _classTransformer.setHasAsserts(); } // --------------- Methods implemented directly here @Override public String getOuterThisParamName() { return getOuterThisFieldName() + "$$arg"; } @Override public String getSourceFileRef() { // Try to find the outermost class that's a Gosu class, so that inner classes get the // source file name of the outermost class IGosuClassInternal outermostClass = _gsClass; while (outermostClass.getEnclosingType() != null && outermostClass.getEnclosingType() instanceof IGosuClassInternal) { outermostClass = (IGosuClassInternal) outermostClass.getEnclosingType(); } ISourceFileHandle sfh = outermostClass.getSourceFileHandle(); return sfh == null ? null : sfh.getFileName(); } @Override public String getSourceLine(int lineNumber) { if (_sourceLines != null) { return _sourceLines.get(lineNumber - 1); } else { return null; } } @Override public String getOuterThisFieldName() { return Keyword.KW_this + "$" + (_gsClass.getDepth()-1); } @Override public IRType getIRTypeForCurrentClass() { return GosuClassIRType.get( _gsClass ); } @Override public boolean isExternalSymbol(String name) { return _gsClass.getExternalSymbol( name ) != null; } @Override public boolean isFragmentEvaluation() { return false; } // ---------------------------------- Private helper methods private void maybeIndexSourceCode() { if (INCLUDE_SOURCE_COMMENTS) { String source = _gsClass.getSource(); _sourceLines = split(source); } } private List<String> split(String source) { List<String> results = new ArrayList<String>(); int start = 0; int lineIndex = source.indexOf('\n'); while (lineIndex != -1) { results.add(source.substring(start, lineIndex)); start = lineIndex + 1; lineIndex = source.indexOf('\n', start); } results.add(source.substring(start)); return results; } public boolean shouldUseReflection( IType declaringClass, IRelativeTypeInfo.Accessibility accessibility ) { return RequiresReflectionDeterminer.shouldUseReflection( declaringClass, _gsClass, accessibility ); } @Override public boolean currentlyCompilingBlock() { return getGosuClass() instanceof IBlockClass; } }