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); } }
@Override public IModifierInfo getModifierInfo() { return symbol.getModifierInfo(); }
@Override public boolean isWritable() { return symbol.isWritable(); }
@Override public void setDefaultValueExpression(IExpression defaultValue) { symbol.setDefaultValueExpression(defaultValue); }
@Override public boolean hasDynamicSymbolTable() { return symbol.hasDynamicSymbolTable(); }
@Override public void setType(IType type) { symbol.setType(type); }
@Override public void setValue(Object value) { symbol.setValue(value); }
@Override public boolean isInternal() { return symbol.isInternal(); }
@Override public boolean isProtected() { return symbol.isProtected(); }
@Override public String getFullDescription() { return symbol.getFullDescription(); }
@Override public boolean isPrivate() { return symbol.isPrivate(); }
@Override public List<IGosuAnnotation> getAnnotations() { return symbol.getAnnotations(); }
@Override public int getModifiers() { return symbol.getModifiers(); }
@Override public IReducedSymbol createReducedSymbol() { return symbol.createReducedSymbol(); }
@Override public String getDisplayName() { return symbol.getDisplayName(); }
@Override public boolean isPublic() { return symbol.isPublic(); }
@Override public IType getType() { return symbol.getType(); }
@Override public boolean isAbstract() { return symbol.isAbstract(); }
@Override public Object getValue() { return symbol.getValue(); }
@Override public boolean isFinal() { return symbol.isFinal(); }
@Override public IExpression getDefaultValueExpression() { return symbol.getDefaultValueExpression(); }
@Override public IScriptPartId getScriptPart() { return symbol.getScriptPart(); }
@Override public void setDynamicSymbolTable(ISymbolTable symTable) { symbol.setDynamicSymbolTable(symTable); }
@Override public IGosuClass getGosuClass() { return symbol.getGosuClass(); }
@Override public ISymbolTable getDynamicSymbolTable() { return symbol.getDynamicSymbolTable(); }
@Override public boolean hasTypeVariables() { return symbol.hasTypeVariables(); }
@Override public void setValueIsBoxed(boolean b) { symbol.setValueIsBoxed(b); }
@Override public Class<?> getSymbolClass() { return symbol.getSymbolClass(); }
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()); } }
@Override public boolean isValueBoxed() { return symbol.isValueBoxed(); }