protected IRExpression compile_impl() { ISymbol symbol = _expr().getSymbol(); ICompilableType gsClass = getGosuClass(); if ((Keyword.KW_this.equals(symbol.getName()) || Keyword.KW_super.equals(symbol.getName())) && // 'this' must be an external symbol when in a program e.g., studio debugger expression (!(gsClass instanceof IGosuProgram) || gsClass.isAnonymous())) { if (_cc().isBlockInvoke() && _cc().currentlyCompilingBlock()) { while (gsClass instanceof IBlockClass) { gsClass = gsClass.getEnclosingType(); } return pushOuter(gsClass); } else { return pushThis(); } } else if (symbol instanceof DynamicPropertySymbol && ((DynamicPropertySymbol) symbol).getGetterDfs() instanceof OuterFunctionSymbol) { // 'outer' return pushOuterForOuterSymbol(); } else { return pushSymbolValue(symbol); } }
public IRExpression pushSymbolValue(ISymbol symbol) { IType type = symbol.getType(); Class symClass; IReducedSymbol reducedSym; if (symbol instanceof ReducedSymbol.SyntheticSymbol) { reducedSym = ((ReducedSymbol.SyntheticSymbol) symbol).getReducedSymbol(); symClass = reducedSym.getSymbolClass(); } else { reducedSym = symbol; symClass = symbol.getClass(); } if (_cc().isExternalSymbol(reducedSym.getName())) { // unbox( symbols.getValue( name ) ) return unboxValueToType( reducedSym.getType(), callMethod( IExternalSymbolMap.class, "getValue", new Class[] {String.class, int.class}, pushExternalSymbolsMap(), Arrays.asList( pushConstant(reducedSym.getName()), pushConstant(getArrayDims(reducedSym))))); } else if (DynamicSymbol.class.isAssignableFrom(symClass)) { // Instance or Static field IRProperty irProp = IRPropertyFactory.createIRProperty(reducedSym); if (!irProp.isStatic()) { if (isMemberOnEnclosingType(reducedSym) != null) { // Instance field from 'outer' return getField_new( irProp, pushOuter(reducedSym.getGosuClass()), getDescriptor(reducedSym.getType())); } else { // Instance field from 'this' return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType())); } } else { // Static field return getField_new(irProp, null, getDescriptor(reducedSym.getType())); } } else if (CapturedSymbol.class.isAssignableFrom(symClass)) { // Captured symbol is stored as a Field on an anonymous inner class (one elem array of // symbol's type) // e.g., val$myFiield[0] = value. Note a captured symbol is duplicated in all nested classes. IRProperty irProp = IRPropertyFactory.createIRProperty(getGosuClass(), reducedSym); return getField_new(irProp, pushThis(), getDescriptor(reducedSym.getType())); } else if (reducedSym.getIndex() >= 0) { // Local var if (reducedSym.isValueBoxed()) { // Local var is captured in an anonymous inner class. // Symbol's value maintained as a one elem array of symbol's type. return buildArrayLoad( identifier(_cc().getSymbol(reducedSym.getName())), 0, getDescriptor(type)); } else { // Simple local var return identifier(_cc().getSymbol(reducedSym.getName())); } } else if (DynamicPropertySymbol.class.isAssignableFrom(symClass)) { IRProperty irProp; if (reducedSym instanceof DynamicPropertySymbol) { irProp = IRPropertyFactory.createIRProperty((DynamicPropertySymbol) reducedSym); } else { irProp = IRPropertyFactory.createIRProperty((ReducedDynamicPropertySymbol) reducedSym); } IRExpression root; if (irProp.isStatic()) { root = null; } else { ICompilableType targetType = isMemberOnEnclosingType(reducedSym); if (targetType != null) { root = pushOuter(targetType); } else { root = pushThis(); } } IRExpression getterCall = callMethod(irProp.getGetterMethod(), root, Collections.<IRExpression>emptyList()); return castResultingTypeIfNecessary( getDescriptor(reducedSym.getType()), irProp.getType(), getterCall); } else { throw new UnsupportedOperationException( "Don't know how to compile symbol: " + reducedSym.getClass().getSimpleName() + ": " + reducedSym.getName() + ": " + reducedSym.getType()); } }