Java Code Examples for org.eclipse.xtext.xbase.compiler.output.ITreeAppendable#increaseIndentation()

The following examples show how to use org.eclipse.xtext.xbase.compiler.output.ITreeAppendable#increaseIndentation() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FeatureCallCompiler.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected void appendArgument(XExpression argument, ITreeAppendable b, boolean doLineWrappingIfSourceWasWrapped) {
	final String referenceName = getReferenceName(argument, b);
	/*
	 * This is done to support better debugging experience.
	 * Consider the following xbase expression:
	 * 
	 * foo(
	 *   new String())
	 *   
	 *  The compiler could translate that to a single line, but then the two lines in the source would map
	 *  to the same line in the Java code, so it's not possible to have two steps. 
	 *  Therefore we add a newline in the Java if the user had one the expression defined in a new line.
	 */
	final boolean needsNewLine = doLineWrappingIfSourceWasWrapped && referenceName == null && isDeclaredInNewLine(argument);
	if (needsNewLine) {
		b.increaseIndentation();
		b.newLine();
	}
	if (referenceName == null && isVariableDeclarationRequired(argument, b, true)) {
		if (canCompileToJavaExpression(argument, b)) {
			internalToJavaExpression(argument, b);
		} else {
			LightweightTypeReference type = getLightweightExpectedType(argument);
			if (type == null)
				type = getLightweightType(argument);
			compileAsJavaExpression(argument, b, type);
		}
	} else {
		internalToJavaExpression(argument, b);
	}
	if (needsNewLine) {
		b.decreaseIndentation();
	}
}
 
Example 2
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * @since 2.18
 */
protected void appendFinallyWithResources(XTryCatchFinallyExpression expr, ITreeAppendable b) {
	final String throwablesStore = b.getName(Tuples.pair(expr, "_caughtThrowables"));
	List<XVariableDeclaration> resources = expr.getResources();
	if (!resources.isEmpty()) {
		for (int i = resources.size() - 1; i >= 0; i--) {
			b.openPseudoScope();
			XVariableDeclaration res = resources.get(i);
			String resName = getVarName(res, b);
			b.newLine().append("if (" + resName + " != null) {");
			b.increaseIndentation();
			b.newLine().append("try {");
			b.increaseIndentation();
			b.newLine().append(resName + ".close();");
			// close inner try
			closeBlock(b);
			String throwable = b.declareSyntheticVariable(Tuples.pair(res, "_caughtThrowable"), "_t");
			b.append(" catch (").append(Throwable.class).append(" " + throwable + ") {");
			b.increaseIndentation();
			b.newLine().append(throwablesStore);
			b.append(".add(" + throwable + ");");
			// close inner catch
			closeBlock(b);
			// close if != null check
			closeBlock(b);
			b.closeScope();
		}
		b.newLine().append("if(!");
		b.append(throwablesStore);
		b.append(".isEmpty()) ");
		appendSneakyThrow(expr, b, throwablesStore + ".get(0)");
	}
}
 
Example 3
Source File: JvmModelGenerator.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected ITreeAppendable _generateBody(final JvmAnnotationType it, final ITreeAppendable appendable, final GeneratorConfig config) {
  ITreeAppendable _xblockexpression = null;
  {
    this.generateJavaDoc(it, appendable, config);
    final ITreeAppendable childAppendable = appendable.trace(it);
    this.generateAnnotations(it.getAnnotations(), childAppendable, true, config);
    this.generateModifier(it, childAppendable, config);
    childAppendable.append("@interface ");
    this._treeAppendableUtil.traceSignificant(childAppendable, it).append(this.makeJavaIdentifier(it.getSimpleName()));
    childAppendable.append(" {");
    Iterable<JvmDeclaredType> _filter = Iterables.<JvmDeclaredType>filter(this.getMembersToBeCompiled(it), JvmDeclaredType.class);
    for (final JvmDeclaredType innerType : _filter) {
      {
        final ITreeAppendable innerTypeAppendable = childAppendable.trace(innerType);
        innerTypeAppendable.increaseIndentation();
        this.generateMember(innerType, innerTypeAppendable, config);
        innerTypeAppendable.decreaseIndentation();
      }
    }
    Iterable<JvmOperation> _filter_1 = Iterables.<JvmOperation>filter(this.getMembersToBeCompiled(it), JvmOperation.class);
    for (final JvmOperation operation : _filter_1) {
      this.generateAnnotationMethod(operation, childAppendable, config);
    }
    childAppendable.newLine().append("}");
    ITreeAppendable _xifexpression = null;
    EObject _eContainer = it.eContainer();
    boolean _not = (!(_eContainer instanceof JvmType));
    if (_not) {
      _xifexpression = appendable.newLine();
    }
    _xblockexpression = _xifexpression;
  }
  return _xblockexpression;
}
 
Example 4
Source File: JvmModelGenerator.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
public ITreeAppendable generateBodyWithIssues(final ITreeAppendable appendable, final Iterable<Issue> errors) {
  ITreeAppendable _xblockexpression = null;
  {
    appendable.append("{").increaseIndentation().newLine().append("throw new Error(\"Unresolved compilation problems:\"");
    appendable.increaseIndentation();
    final Consumer<Issue> _function = (Issue it) -> {
      appendable.newLine().append("+ \"\\n").append(this.doConvertToJavaString(it.getMessage())).append("\"");
    };
    errors.forEach(_function);
    _xblockexpression = appendable.append(");").decreaseIndentation().decreaseIndentation().newLine().append("}");
  }
  return _xblockexpression;
}
 
Example 5
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
protected void appendCatchClause(XCatchClause catchClause, boolean parentIsReferenced, String parentVariable,
		ITreeAppendable appendable) {
	JvmTypeReference type = catchClause.getDeclaredParam().getParameterType();
	final String declaredParamName = makeJavaIdentifier(catchClause.getDeclaredParam().getName());
	final String name = appendable.declareVariable(catchClause.getDeclaredParam(), declaredParamName);
	appendable.append("if (");
	JvmTypeReference typeToUse = type;
	if (type instanceof JvmSynonymTypeReference) {
		List<JvmTypeReference> references = ((JvmSynonymTypeReference) type).getReferences();
		Iterator<JvmTypeReference> iter = references.iterator();
		while(iter.hasNext()) {
			appendable.append(parentVariable).append(" instanceof ");
			serialize(iter.next(), catchClause, appendable);
			if (iter.hasNext()) {
				appendable.append(" || ");
			}
		}
		typeToUse = resolveSynonymType((JvmSynonymTypeReference) type, catchClause);
	} else {
		appendable.append(parentVariable).append(" instanceof ");
		serialize(type, catchClause, appendable);			
	}
	appendable.append(") ").append("{");
	appendable.increaseIndentation();
	ITreeAppendable withDebugging = appendable.trace(catchClause, true);
	if (!XbaseUsageCrossReferencer.find(catchClause.getDeclaredParam(), catchClause.getExpression()).isEmpty()) {
		ITreeAppendable parameterAppendable = withDebugging.trace(catchClause.getDeclaredParam());
		appendCatchClauseParameter(catchClause, typeToUse, name, parameterAppendable.newLine());
		withDebugging.append(" = (");
		serialize(typeToUse, catchClause, withDebugging);
		withDebugging.append(")").append(parentVariable).append(";");
	}
	final boolean canBeReferenced = parentIsReferenced && ! isPrimitiveVoid(catchClause.getExpression());
	internalToJavaStatement(catchClause.getExpression(), withDebugging, canBeReferenced);
	if (canBeReferenced) {
		appendable.newLine().append(getVarName(catchClause.eContainer(), appendable)).append(" = ");
		internalToConvertedExpression(catchClause.getExpression(), appendable, getLightweightType((XExpression) catchClause.eContainer()));
		appendable.append(";");
	}
	closeBlock(appendable);
}
 
Example 6
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
protected ITreeAppendable appendOpenIfStatement(XCasePart casePart, ITreeAppendable b, String matchedVariable, String variableName, XSwitchExpressionCompilationState state) {
	ITreeAppendable caseAppendable = b.trace(casePart, true);
	if (state.caseNeedsIfNotMatchedCheck()) {
		caseAppendable.newLine().append("if (!").append(matchedVariable).append(") {");
		caseAppendable.increaseIndentation();
	}
	JvmTypeReference typeGuard = casePart.getTypeGuard();
	if (typeGuard != null) {
		ITreeAppendable typeGuardAppendable = caseAppendable.trace(typeGuard, true);
		typeGuardAppendable.newLine().append("if (");
		if (typeGuard instanceof JvmSynonymTypeReference) {
			Iterator<JvmTypeReference> iter = ((JvmSynonymTypeReference) typeGuard).getReferences().iterator();
			while(iter.hasNext()) {
				typeGuardAppendable.append(variableName);
				typeGuardAppendable.append(" instanceof ");
				typeGuardAppendable.trace(typeGuard).append(iter.next().getType());
				if (iter.hasNext()) {
					typeGuardAppendable.append(" || ");
				}
			}
		} else {
			typeGuardAppendable.append(variableName);
			typeGuardAppendable.append(" instanceof ");
			typeGuardAppendable.trace(typeGuard).append(typeGuard.getType());
		}
		typeGuardAppendable.append(") {");
		typeGuardAppendable.increaseIndentation();
		typeGuardAppendable.openPseudoScope();
	}
	if (casePart.getCase() != null) {
		ITreeAppendable conditionAppendable = caseAppendable.trace(casePart.getCase(), true);
		internalToJavaStatement(casePart.getCase(), conditionAppendable, true);
		conditionAppendable.newLine().append("if (");
		LightweightTypeReference convertedType = getLightweightType(casePart.getCase());
		if (convertedType.isType(Boolean.TYPE) || convertedType.isType(Boolean.class)) {
			internalToJavaExpression(casePart.getCase(), conditionAppendable);
		} else {
			JvmType objectsType = findKnownType(Objects.class, casePart);
			if (objectsType != null) {
				conditionAppendable.append(objectsType);
				conditionAppendable.append(".equal(").append(variableName).append(", ");
				internalToJavaExpression(casePart.getCase(), conditionAppendable);
				conditionAppendable.append(")");
			} else {
				// use ObjectExtensions rather than a == b || a != null && a.equals(b) since
				// that won't work with primitive types and other incompatible conditional operands
				conditionAppendable.append(ObjectExtensions.class);
				conditionAppendable.append(".operator_equals(").append(variableName).append(", ");
				internalToJavaExpression(casePart.getCase(), conditionAppendable);
				conditionAppendable.append(")");
			}
		}
		conditionAppendable.append(")");
		caseAppendable.append(" {");
		caseAppendable.increaseIndentation();
	}
	// set matched to true
	return caseAppendable.newLine().append(matchedVariable).append("=true;");
}
 
Example 7
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
protected ITreeAppendable toAnonymousClass(final XClosure closure, final ITreeAppendable b, LightweightTypeReference type,
		JvmOperation operation) {
	b.append("new ");
	b.append(type);
	b.append("() {");
	b.increaseIndentation();
	try {
		b.openScope();
		String selfVariable = null;
		if (needSyntheticSelfVariable(closure, type)) {
			b.newLine().append("final ");
			b.append(type).append(" ");
			selfVariable = b.declareVariable(type.getType(), "_self");
			b.append(selfVariable);
			b.append(" = this;");
		}
		final LightweightTypeReference returnType = getClosureOperationReturnType(type, operation);
		appendOperationVisibility(b, operation);
		if (!operation.getTypeParameters().isEmpty()) {
			appendTypeParameters(b, operation, type);
		}
		b.append(returnType);
		b.append(" ").append(operation.getSimpleName());
		b.append("(");
		List<JvmFormalParameter> closureParams = closure.getFormalParameters();
		boolean isVarArgs = operation.isVarArgs();
		for (int i = 0; i < closureParams.size(); i++) {
			JvmFormalParameter closureParam = closureParams.get(i);
			LightweightTypeReference parameterType = getClosureOperationParameterType(type, operation, i);
			if (isVarArgs && i == closureParams.size()-1 && parameterType.isArray()) {
				appendClosureParameterVarArgs(closureParam, parameterType.getComponentType(), b);
			} else {					
				appendClosureParameter(closureParam, parameterType, b);
			}
			if (i != closureParams.size() - 1)
				b.append(", ");
		}
		b.append(")");
		if(!operation.getExceptions().isEmpty()) {
			b.append(" throws ");
			for (int i = 0; i < operation.getExceptions().size(); ++i) {
				serialize(operation.getExceptions().get(i), closure, b, false, false, false, false);
				if(i != operation.getExceptions().size() -1)
					b.append(", ");
			}
		}
		b.append(" {");
		b.increaseIndentation();
		if (selfVariable == null) {
			reassignThisInClosure(b, type.getType());
		} else {
			// We have already assigned the closure type to _self, so don't assign it again
			reassignThisInClosure(b, null);
		}
		compile(closure.getExpression(), b, returnType, newHashSet(operation.getExceptions()));
		closeBlock(b);
	} finally {
		b.closeScope();
	}
	return b.decreaseIndentation().newLine().append("}");
}
 
Example 8
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
protected ITreeAppendable toLambda(XClosure closure, ITreeAppendable b, LightweightTypeReference type,
		JvmOperation operation, boolean writeExplicitTargetType) {
	if (writeExplicitTargetType) {
		b.append("((");
		b.append(type);
		b.append(") ");
	}
	try {
		b.openPseudoScope();
		b.append("(");
		List<JvmFormalParameter> closureParams = closure.getFormalParameters();
		boolean isVarArgs = operation.isVarArgs();
		for (int i = 0; i < closureParams.size(); i++) {
			JvmFormalParameter closureParam = closureParams.get(i);
			LightweightTypeReference parameterType = getClosureOperationParameterType(type, operation, i);
			if (isVarArgs && i == closureParams.size()-1 && parameterType.isArray()) {
				b.append(parameterType.getComponentType());
				b.append("...");
			} else {
				b.append(parameterType);
			}
			b.append(" ");
			String proposedParamName = makeJavaIdentifier(closureParam.getName());	
			// Usually a normal variable would suffice here. The 'unique name' variable is a workaround for
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=445949
			String name = b.declareUniqueNameVariable(closureParam, proposedParamName);
			b.append(name);
			if (i != closureParams.size() - 1)
				b.append(", ");
		}
		b.append(") -> {");
		b.increaseIndentation();
		LightweightTypeReference returnType = getClosureOperationReturnType(type, operation);
		compile(closure.getExpression(), b, returnType, newHashSet(operation.getExceptions()));
		closeBlock(b);
	} finally {
		b.closeScope();
	}
	if (writeExplicitTargetType) {
		b.append(")");
	}
	return b;
}
 
Example 9
Source File: JvmModelGenerator.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
public void generateDefaultExpression(final JvmOperation it, final ITreeAppendable appendable, final GeneratorConfig config) {
  Procedure1<? super ITreeAppendable> _compilationStrategy = this._jvmTypeExtensions.getCompilationStrategy(it);
  boolean _tripleNotEquals = (_compilationStrategy != null);
  if (_tripleNotEquals) {
    appendable.append(" default ");
    appendable.increaseIndentation();
    this._jvmTypeExtensions.getCompilationStrategy(it).apply(appendable);
    appendable.decreaseIndentation();
  } else {
    StringConcatenationClient _compilationTemplate = this._jvmTypeExtensions.getCompilationTemplate(it);
    boolean _tripleNotEquals_1 = (_compilationTemplate != null);
    if (_tripleNotEquals_1) {
      appendable.append(" default ").increaseIndentation();
      this.appendCompilationTemplate(appendable, it);
      appendable.decreaseIndentation();
    } else {
      boolean _isGenerateExpressions = config.isGenerateExpressions();
      if (_isGenerateExpressions) {
        final XExpression body = this._iLogicalContainerProvider.getAssociatedExpression(it);
        if ((body != null)) {
          boolean _hasErrors = this._errorSafeExtensions.hasErrors(body);
          if (_hasErrors) {
            appendable.append("/* skipped default expression with errors */");
          } else {
            appendable.append(" default ");
            this.compiler.compileAsJavaExpression(body, appendable, it.getReturnType());
          }
        } else {
          JvmAnnotationValue _defaultValue = it.getDefaultValue();
          boolean _tripleNotEquals_2 = (_defaultValue != null);
          if (_tripleNotEquals_2) {
            boolean _hasErrors_1 = this._errorSafeExtensions.hasErrors(it.getDefaultValue());
            if (_hasErrors_1) {
              appendable.append("/* skipped default expression with errors */");
            } else {
              appendable.append(" default ");
              this.toJavaLiteral(it.getDefaultValue(), appendable, config);
            }
          }
        }
      }
    }
  }
}
 
Example 10
Source File: JvmModelGenerator.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
public void generateInitialization(final JvmField it, final ITreeAppendable appendable, final GeneratorConfig config) {
  Procedure1<? super ITreeAppendable> _compilationStrategy = this._jvmTypeExtensions.getCompilationStrategy(it);
  boolean _tripleNotEquals = (_compilationStrategy != null);
  if (_tripleNotEquals) {
    final Iterable<Issue> errors = this.getDirectErrorsOrLogicallyContainedErrors(it);
    boolean _isEmpty = IterableExtensions.isEmpty(errors);
    if (_isEmpty) {
      appendable.append(" = ");
      appendable.increaseIndentation();
      this._jvmTypeExtensions.getCompilationStrategy(it).apply(appendable);
      appendable.decreaseIndentation();
    } else {
      appendable.append(" /* Skipped initializer because of errors */");
    }
  } else {
    StringConcatenationClient _compilationTemplate = this._jvmTypeExtensions.getCompilationTemplate(it);
    boolean _tripleNotEquals_1 = (_compilationTemplate != null);
    if (_tripleNotEquals_1) {
      final Iterable<Issue> errors_1 = this.getDirectErrorsOrLogicallyContainedErrors(it);
      boolean _isEmpty_1 = IterableExtensions.isEmpty(errors_1);
      if (_isEmpty_1) {
        appendable.append(" = ").increaseIndentation();
        this.appendCompilationTemplate(appendable, it);
        appendable.decreaseIndentation();
      } else {
        appendable.append(" /* Skipped initializer because of errors */");
      }
    } else {
      final XExpression expression = this._iLogicalContainerProvider.getAssociatedExpression(it);
      if (((expression != null) && config.isGenerateExpressions())) {
        boolean _hasErrors = this._errorSafeExtensions.hasErrors(expression);
        if (_hasErrors) {
          appendable.append(" /* Skipped initializer because of errors */");
        } else {
          appendable.append(" = ");
          this.compiler.compileAsJavaExpression(expression, appendable, it.getType());
        }
      }
    }
  }
}
 
Example 11
Source File: CacheMethodCompileStrategy.java    From xtext-xtend with Eclipse Public License 2.0 4 votes vote down vote up
@Override
public void apply(ITreeAppendable appendable) {
	JvmOperation cacheMethod = (JvmOperation) logicalContainerProvider.getLogicalContainer(createExtensionInfo.getCreateExpression());
	JvmDeclaredType containerType = cacheMethod.getDeclaringType();
	IResolvedTypes resolvedTypes = typeResolver.resolveTypes(containerType);
	final ITypeReferenceOwner owner = new StandardTypeReferenceOwner(services, containerType);
	LightweightTypeReference listType = owner.newReferenceTo(ArrayList.class, new TypeReferenceInitializer<ParameterizedTypeReference>() {
		@Override
		public LightweightTypeReference enhance(ParameterizedTypeReference reference) {
			reference.addTypeArgument(owner.newWildcardTypeReference());
			return reference;
		}
	});
	String cacheVarName = cacheField.getSimpleName();
	String cacheKeyVarName = appendable.declareSyntheticVariable("CacheKey", "_cacheKey");
	appendable.append("final ").append(listType).append(" ").append(cacheKeyVarName)
		.append(" = ").append(CollectionLiterals.class).append(".newArrayList(");
	List<JvmFormalParameter> list = cacheMethod.getParameters();
	for (Iterator<JvmFormalParameter> iterator = list.iterator(); iterator.hasNext();) {
		JvmFormalParameter jvmFormalParameter = iterator.next();
		appendable.append(getVarName(jvmFormalParameter));
		if (iterator.hasNext()) {
			appendable.append(", ");
		}
	}
	appendable.append(");");
	// declare result variable
	LightweightTypeReference returnType = resolvedTypes.getActualType(initializerMethod.getParameters().get(0));
	if (returnType != null) {
		appendable.newLine().append("final ").append(returnType);
	} else {
		appendable.newLine().append("final Object");
	}
	String resultVarName = "_result";
	appendable.append(" ").append(resultVarName).append(";");
	// open synchronize block
	appendable.newLine().append("synchronized (").append(cacheVarName).append(") {");
	appendable.increaseIndentation();
	// if the cache contains the key return the previously created object.
	appendable.newLine().append("if (").append(cacheVarName).append(".containsKey(").append(cacheKeyVarName)
			.append(")) {");
	appendable.increaseIndentation();
	appendable.newLine().append("return ").append(cacheVarName).append(".get(").append(cacheKeyVarName).append(");");
	appendable.decreaseIndentation().newLine().append("}");
	
	// execute the creation
	compiler.toJavaStatement(createExtensionInfo.getCreateExpression(), appendable, true);
	appendable.newLine();
	appendable.append(resultVarName).append(" = ");
	compiler.toJavaExpression(createExtensionInfo.getCreateExpression(), appendable);
	appendable.append(";");

	// store the newly created object in the cache
	appendable.newLine().append(cacheVarName).append(".put(").append(cacheKeyVarName).append(", ");
	LightweightTypeReference fieldType = resolvedTypes.getActualType(cacheField);
	LightweightTypeReference declaredResultType = fieldType.getTypeArguments().get(1);
	boolean castRequired = false;
	if (!declaredResultType.isAssignableFrom(returnType)) {
		castRequired = true;
		appendable.append("(").append(declaredResultType).append(")");
	}
	appendable.append(resultVarName).append(");");

	// close synchronize block
	appendable.decreaseIndentation();
	appendable.newLine().append("}");
	appendable.newLine().append(initializerMethod.getSimpleName()).append("(").append(resultVarName);
	for (JvmFormalParameter parameter : cacheMethod.getParameters()) {
		appendable.append(", ").append(parameter.getName());
	}
	appendable.append(");");
	// return the result
	appendable.newLine().append("return ");
	if (castRequired) {
		appendable.append("(").append(declaredResultType).append(")");
	}
	appendable.append(resultVarName).append(";");
}
 
Example 12
Source File: SarlCompiler.java    From sarl with Apache License 2.0 4 votes vote down vote up
@SuppressWarnings("checkstyle:npathcomplexity")
private ITreeAppendable toSerializableAnonymousClass(XClosure closure, ITreeAppendable appendable,
		LightweightTypeReference type, JvmOperation operation) {
	// This function is implemented in order to generate static inner class when the closure
	// cannot be represented neither by a Java 8 lambda nor a not-static inner class.
	// It solves the issues related to the serialization and deserialization of the closures.
	final List<JvmFormalParameter> closureParams = closure.getFormalParameters();
	appendable.openPseudoScope();
	try {
		final List<XAbstractFeatureCall> localReferences = getReferencedExternalCalls(
				closure.getExpression(), closureParams, false, appendable);
		final LightweightTypeReference returnType = getClosureOperationReturnType(type, operation);
		appendable.append("new ").append(type).append("() {"); //$NON-NLS-1$ //$NON-NLS-2$
		appendable.increaseIndentation();
		String selfVariable = null;
		try {
			appendable.openScope();
			if (needSyntheticSelfVariable(closure, type)) {
				appendable.newLine().append("final "); //$NON-NLS-1$
				appendable.append(type).append(" "); //$NON-NLS-1$
				selfVariable = appendable.declareVariable(type.getType(), "_self"); //$NON-NLS-1$
				appendable.append(selfVariable);
				appendable.append(" = this;"); //$NON-NLS-1$
			}
			appendOperationVisibility(appendable, operation);
			if (!operation.getTypeParameters().isEmpty()) {
				appendTypeParameters(appendable, operation, type);
			}
			appendable.append(returnType);
			appendable.append(" ").append(operation.getSimpleName()); //$NON-NLS-1$
			appendable.append("("); //$NON-NLS-1$
			final boolean isVarArgs = operation.isVarArgs();
			for (int i = 0; i < closureParams.size(); i++) {
				final JvmFormalParameter closureParam = closureParams.get(i);
				final LightweightTypeReference parameterType = getClosureOperationParameterType(type, operation, i);
				if (isVarArgs && i == closureParams.size() - 1 && parameterType.isArray()) {
					appendClosureParameterVarArgs(closureParam, parameterType.getComponentType(), appendable);
				} else {
					appendClosureParameter(closureParam, parameterType, appendable);
				}
				if (i != closureParams.size() - 1) {
					appendable.append(", "); //$NON-NLS-1$
				}
			}
			appendable.append(")"); //$NON-NLS-1$
			if (!operation.getExceptions().isEmpty()) {
				appendable.append(" throws "); //$NON-NLS-1$
				for (int i = 0; i < operation.getExceptions().size(); ++i) {
					serialize(operation.getExceptions().get(i), closure, appendable, false, false, false, false);
					if (i != operation.getExceptions().size() - 1) {
						appendable.append(", "); //$NON-NLS-1$
					}
				}
			}
			appendable.append(" {"); //$NON-NLS-1$
			appendable.increaseIndentation();
			if (selfVariable == null) {
				reassignThisInClosure(appendable, type.getType());
			} else {
				// We have already assigned the closure type to _self, so don't assign it again
				reassignThisInClosure(appendable, null);
			}
			compile(closure.getExpression(), appendable, returnType, newHashSet(operation.getExceptions()));
			closeBlock(appendable);
		} catch (Exception exception) {
			throw new RuntimeException(exception);
		} finally {
			appendable.closeScope();
		}
		appendable.newLine().append("private ").append(Object.class).append(" writeReplace() throws ");  //$NON-NLS-1$//$NON-NLS-2$
		appendable.append(ObjectStreamException.class).append(" {").increaseIndentation().newLine(); //$NON-NLS-1$
		if (selfVariable == null) {
			reassignThisInClosure(appendable, type.getType());
		} else {
			// We have already assigned the closure type to _self, so don't assign it again
			reassignThisInClosure(appendable, null);
		}
		appendable.append("return new ").append(SerializableProxy.class); //$NON-NLS-1$
		appendable.append("(").append(appendable.getName(type)).append(".class"); //$NON-NLS-1$ //$NON-NLS-2$
		for (final XAbstractFeatureCall call : localReferences) {
			appendable.append(", "); //$NON-NLS-1$
			compileAsJavaExpression(call, appendable, returnType);
		}

		appendable.append(");").decreaseIndentation().newLine().append("}"); //$NON-NLS-1$ //$NON-NLS-2$
		appendable.decreaseIndentation().newLine().append("}"); //$NON-NLS-1$
	} finally {
		appendable.closeScope();
	}
	return appendable;
}