Java Code Examples for org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference#isArray()

The following examples show how to use org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference#isArray() . 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: XbaseValidator.java    From xtext-extras with Eclipse Public License 2.0 6 votes vote down vote up
@Check
public void checkOperandTypesForTripleEquals(XBinaryOperation binaryOperation) {
	if(isTripleEqualsOperation(binaryOperation)){
		LightweightTypeReference left = getActualType(binaryOperation.getLeftOperand());
		LightweightTypeReference right = getActualType(binaryOperation.getRightOperand());
		if(left.isArray() != right.isArray()) {
			if (left.isArray()) {
				if (right.isAny() || right.isType(Object.class) || right.isType(Serializable.class) || right.isType(Cloneable.class)) {
					return;
				}
			} else {
				if (left.isAny() || left.isType(Object.class) || left.isType(Serializable.class) || left.isType(Cloneable.class)) {
					return;
				}
			}
			error("Incompatible operand types " + left.getHumanReadableName() + " and " + right.getHumanReadableName(), null, INVALID_OPERAND_TYPES);
		}
	}
}
 
Example 2
Source File: CollectionLiteralsTypeComputer.java    From xtext-extras with Eclipse Public License 2.0 6 votes vote down vote up
protected void computeType(XListLiteral literal, JvmGenericType listType, ITypeExpectation expectation,
		ITypeComputationState state) {
	LightweightTypeReference elementTypeExpectation = null;
	final LightweightTypeReference expectedType = expectation.getExpectedType();
	if(expectedType != null) {
		if(expectedType.isArray()) {
			computeArrayLiteralType(literal, expectedType, expectation, state);
			return; 
		} 
		elementTypeExpectation = getElementOrComponentType(expectedType, state);
	}
	List<LightweightTypeReference> listTypeCandidates = computeCollectionTypeCandidates(literal, listType, elementTypeExpectation, state);
	LightweightTypeReference commonListType = getCommonSuperType(listTypeCandidates, state);
	if (commonListType != null) {
		LightweightTypeReference commonElementType = getElementOrComponentType(commonListType, state);
		ITypeReferenceOwner owner = state.getReferenceOwner();
		commonElementType = normalizeElementType(commonElementType, expectedType, owner);
		if (expectedType != null) {
			commonListType = createCollectionTypeReference(listType, commonElementType, expectedType, owner);
		}
		expectation.acceptActualType(commonListType, ConformanceFlags.UNCHECKED);
		refineElementTypeExpectation(literal, commonElementType, state);
	} else {
		setUnboundCollectionType(literal, listType, expectation, elementTypeExpectation, state);
	}
}
 
Example 3
Source File: XbaseInterpreter.java    From xtext-extras with Eclipse Public License 2.0 6 votes vote down vote up
protected Object _doEvaluate(XListLiteral literal, IEvaluationContext context, CancelIndicator indicator) {
	IResolvedTypes resolveTypes = typeResolver.resolveTypes(literal);
	LightweightTypeReference type = resolveTypes.getActualType(literal);
	List<Object> list = newArrayList();
	for(XExpression element: literal.getElements()) {
		if (indicator.isCanceled())
			throw new InterpreterCanceledException();
		list.add(internalEvaluate(element, context, indicator));
	}
	if(type != null && type.isArray()) {
		try {
			LightweightTypeReference componentType = type.getComponentType();
			return Conversions.unwrapArray(list, getJavaType(componentType.getType()));
		} catch (ClassNotFoundException e) {
		}
	}
	return Collections.unmodifiableList(list);
}
 
Example 4
Source File: ExtensionScopeHelper.java    From xtext-extras with Eclipse Public License 2.0 6 votes vote down vote up
private boolean isArrayTypeMismatch(LightweightTypeReference receiverType, LightweightTypeReference parameterType) {
	if (receiverType.isArray()) {
		if (parameterType.isArray()) {
			LightweightTypeReference componentType = parameterType.getComponentType();
			if (isArrayTypeMismatch(receiverType.getComponentType(), componentType)) {
				return true;
			}
			return false;
		}
		return true;
	} else {
		if (!parameterType.isArray() && parameterType.isPrimitive()) {
			return true;
		}
	}
	return false;
}
 
Example 5
Source File: XbaseValidator.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected boolean isFinal(LightweightTypeReference expressionTypeRef) {
	if (expressionTypeRef.isArray()) {
		return isFinal(expressionTypeRef.getComponentType());
	}
	if (expressionTypeRef.isPrimitive())
		return true;
	return expressionTypeRef.getType() instanceof JvmDeclaredType
			&& ((JvmDeclaredType) expressionTypeRef.getType()).isFinal();
}
 
Example 6
Source File: Utils.java    From sarl with Apache License 2.0 5 votes vote down vote up
/** Replies if the given reference is referencing a final type.
 *
 * @param expressionTypeRef - the type reference to test.
 * @return {@code true} if the given type is final.
 */
public static boolean isFinal(LightweightTypeReference expressionTypeRef) {
	if (expressionTypeRef.isArray()) {
		return isFinal(expressionTypeRef.getComponentType());
	}
	if (expressionTypeRef.isPrimitive()) {
		return true;
	}
	return expressionTypeRef.getType() instanceof JvmDeclaredType
			&& ((JvmDeclaredType) expressionTypeRef.getType()).isFinal();
}
 
Example 7
Source File: XbaseInterpreter.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected Object wrapOrUnwrapArray(Object result, LightweightTypeReference expectedType) {
	if (expectedType.isArray() && !(result instanceof Object[])) {
		Class<?> arrayType;
		try {
			arrayType = getJavaType(expectedType.getComponentType().getType());
			return Conversions.unwrapArray(result, arrayType);
		} catch (ClassNotFoundException e) {
			return result;
		}
	} else if (!expectedType.isArray() && expectedType.isSubtypeOf(Iterable.class)) {
		return Conversions.doWrapArray(result);
	}
	return result;
}
 
Example 8
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected LightweightTypeReference getCollectionElementType(XCollectionLiteral literal) {
	LightweightTypeReference type = getLightweightType(literal);
	if (type == null)
		throw new IllegalStateException();
	if(type.isArray()) {
		LightweightTypeReference result = type.getComponentType();
		if (result == null)
			throw new IllegalStateException();
		return result;
	}
	else if(type.isSubtypeOf(Collection.class) && type.hasTypeArguments()) {
		return type.getTypeArguments().get(0).getInvariantBoundSubstitute();
	}
	return type.getOwner().newReferenceToObject();
}
 
Example 9
Source File: TypeConvertingCompiler.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected void doConversion(final LightweightTypeReference left, final LightweightTypeReference right,
		final ITreeAppendable appendable, XExpression context, final Later expression) {
	if(left.isPrimitive() && !right.isPrimitive()) {
		if (right.isAny()) {
			convertWrapperToPrimitive(left, left, context, appendable, expression);
		} else {
			convertWrapperToPrimitive(right, right.getPrimitiveIfWrapperType(), context, appendable, expression);
		}
	} else if (right.isPrimitive() && !left.isPrimitive()) {
		convertPrimitiveToWrapper(right, right.getWrapperTypeIfPrimitive(), appendable, expression);
	} else if (right.isMultiType()) {
		convertMultiType(left, (CompoundTypeReference) right, context, appendable, expression);
	} else if (right.isArray() && !left.isArray() && left.isSubtypeOf(Iterable.class)) {
		convertArrayToList(left, appendable, context, expression);
	} else if (isJavaConformant(left, right)) {
		if (mustInsertTypeCast(context, left)) {
			doCastConversion(left, appendable, expression);
		} else {
			expression.exec(appendable);
		}
	} else if (left.isArray() && !right.isArray() && right.isSubtypeOf(Iterable.class)) {
		convertListToArray(left, appendable, expression);
	} else if ((isFunction(left) && isFunction(right) || isProcedure(left) && isProcedure(right)) && left.getType() == right.getType()) {
		doCastConversion(left, appendable, expression);
	} else if (isFunction(right) || (isFunction(left) && findImplementingOperation(right) != null)) {
		convertFunctionType(left, right, appendable, expression);
	} else if (isProcedure(right) || (isProcedure(left) && findImplementingOperation(right) != null)) {
		convertFunctionType(left, right, appendable, expression);
	} else if (mustInsertTypeCast(context, left)) {
		doCastConversion(left, appendable, expression);
	} else {
		expression.exec(appendable);
	}
}
 
Example 10
Source File: ExtensionScopeHelper.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
private boolean isArrayTypeMismatch(LightweightTypeReference rawReceiverType, JvmType rawParameterType) {
	if (rawReceiverType.isArray()) {
		LightweightTypeReference parameterTypeReference = rawReceiverType.getOwner().toPlainTypeReference(rawParameterType);
		if (parameterTypeReference.getSuperType(Iterable.class) == null && isArrayTypeMismatch(rawReceiverType, parameterTypeReference)) {
			return true;
		}
	}
	return false;
}
 
Example 11
Source File: ExtensionScopeHelper.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected boolean isMatchingFirstParameter(JvmOperation feature) {
	List<JvmFormalParameter> parameters = feature.getParameters();
	JvmFormalParameter firstParameter = parameters.get(0);
	JvmTypeReference type = firstParameter.getParameterType();
	if (type == null)
		return false;
	JvmType rawParameterType = type.getType();
	if (rawParameterType == null || rawParameterType.eIsProxy())
		return false;
	if (!(rawParameterType instanceof JvmTypeParameter)) {
		if (rawArgumentType.isResolved()) {
			// short circuit - limit extension scope entries to real candidates
			LightweightTypeReference parameterTypeReference = rawArgumentType.getOwner().toPlainTypeReference(rawParameterType);
			if (parameterTypeReference.isResolved() && !parameterTypeReference.isAssignableFrom(rawArgumentType)) {
				if (parameterTypeReference.isArray() && !rawArgumentType.isArray() && rawArgumentType.isSubtypeOf(Iterable.class)) {
					return true;
				}
				return false;
			}
			if (parameterTypeReference.isArray() && !rawArgumentType.isArray() && !rawArgumentType.isSubtypeOf(Iterable.class)) {
				return false;
			}
		} else if (isArrayTypeMismatch(rawArgumentType, rawParameterType)) {
			return false;
		}
	}
	return true;
}
 
Example 12
Source File: AnnotationValueTypeComputationState.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
@Override
/* @Nullable */
protected LightweightTypeReference getExpectedType() {
	JvmOperation operation = annotationValue.getOperation();
	LightweightTypeReference result = getResolvedTypes().getActualType(operation);
	if (result != null && result.isArray()) {
		return result.getComponentType();
	}
	return result;
}
 
Example 13
Source File: FeatureLinkingCandidate.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
@Override
protected void resolveAgainstActualType(LightweightTypeReference declaredType, LightweightTypeReference actualType, final AbstractTypeComputationState state) {
	super.resolveAgainstActualType(declaredType, actualType, state);
	if (!isStatic() || ((actualType.hasTypeArguments() || actualType.isArray()) && getDeclaredTypeParameters().isEmpty())) {
		DeferredTypeParameterHintCollector collector = new DeferredTypeParameterHintCollector(state.getReferenceOwner());
		collector.processPairedReferences(declaredType, actualType);
	}
}
 
Example 14
Source File: TypeConformanceComputer.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected void addComponentType(LightweightTypeReference reference, List<LightweightTypeReference> result) {
	if (reference.isArray()) {
		result.add(((ArrayTypeReference) reference).getComponentType());
	} else {
		result.add(reference);
	}
}
 
Example 15
Source File: XbaseValidator.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
@Check
public void checkInstanceOf(XInstanceOfExpression instanceOfExpression) {
	LightweightTypeReference leftType = getActualType(instanceOfExpression.getExpression());
	final LightweightTypeReference rightType = toLightweightTypeReference(instanceOfExpression.getType(), true);
	if (leftType == null || rightType == null || rightType.getType() == null || rightType.getType().eIsProxy()) {
		return;
	}
	if (containsTypeArgs(rightType)) {
		error("Cannot perform instanceof check against parameterized type " + getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF);
		return;
	}
	if (leftType.isAny() || leftType.isUnknown()) {
		return; // null / unknown is ok
	}
	if (rightType.isPrimitive()) {
		error("Cannot perform instanceof check against primitive type " + this.getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF);
		return;
	}
	if (leftType.isPrimitive() 
		|| rightType.isArray() && !(leftType.isArray() || leftType.isType(Object.class) || leftType.isType(Cloneable.class) || leftType.isType(Serializable.class))
		|| isFinal(rightType) && !memberOfTypeHierarchy(rightType, leftType)
		|| isFinal(leftType) && !memberOfTypeHierarchy(leftType, rightType)) {
		error("Incompatible conditional operand types " + this.getNameOfTypes(leftType)+" and "+this.getNameOfTypes(rightType), null, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, INVALID_INSTANCEOF);
		return;
	}
	if (!isIgnored(OBSOLETE_INSTANCEOF) && rightType.isAssignableFrom(leftType, new TypeConformanceComputationArgument(false, false, true, true, false, false))) {
		// check that we do not have a type parameter usage on the rhs of the instanceof 
		if (rightType.getConstraintSubstitute() == rightType) {
			addIssueToState(OBSOLETE_INSTANCEOF, "The expression of type " + getNameOfTypes(leftType) + " is already of type " + canonicalName(rightType), null);	
		}
	}
}
 
Example 16
Source File: XbaseCompiler.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
protected void _toJavaExpression(XListLiteral literal, ITreeAppendable b) {
	LightweightTypeReference literalType = batchTypeResolver.resolveTypes(literal).getActualType(literal);
	if (literalType == null) {
		b.append("error - couldn't compute type for literal : "+literal);
		return;
	} 
	if (literalType.isArray()) {
		LightweightTypeReference expectedType = batchTypeResolver.resolveTypes(literal).getExpectedType(literal);
		boolean skipTypeName = false;
		if (expectedType != null && expectedType.isArray()) {
			if (canUseArrayInitializer(literal, b)) {
				skipTypeName = true;
			}
		}
		if (!skipTypeName) {
			if (literalType instanceof CompoundTypeReference) {
				for (LightweightTypeReference c : literalType.getMultiTypeComponents()) {
					if (c.isArray()) {
						b.append("new ")
						.append(c.getType()) // append raw type since we cannot create generic arrays
						.append(" ");
						break;
					}
				}
			} else {
				b.append("new ")
					.append(literalType.getType()) // append raw type since we cannot create generic arrays
					.append(" ");
			}
		}
		if (literal.getElements().isEmpty()) {
			b.append("{}");
		} else {
			b.append("{ ");
			boolean isFirst = true;
			for(XExpression element: literal.getElements())  {
				if(!isFirst)
					b.append(", ");
				isFirst = false;
				internalToJavaExpression(element, b);
			}
			b.append(" }");
		}
		return;
	} else {
		appendImmutableCollectionExpression(literal, b, "unmodifiableList", CollectionLiterals.class, "newArrayList");
	}
}
 
Example 17
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 18
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 19
Source File: AbstractAssignabilityTest.java    From xtext-xtend with Eclipse Public License 2.0 4 votes vote down vote up
public void isAssignableFrom(final Pair<String, String> lhsAndParams, final String rhs, final boolean expectation) {
  try {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("def ");
    {
      boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(lhsAndParams.getValue());
      boolean _not = (!_isNullOrEmpty);
      if (_not) {
        _builder.append("<");
        String _value = lhsAndParams.getValue();
        _builder.append(_value);
        _builder.append("> ");
      }
    }
    _builder.append("void method(");
    String _fixup = this.fixup(lhsAndParams.getKey());
    _builder.append(_fixup);
    _builder.append(" lhs, ");
    String _fixup_1 = this.fixup(rhs);
    _builder.append(_fixup_1);
    _builder.append(" rhs) {}");
    final String signature = _builder.toString();
    final XtendFunction function = this.function(signature.toString());
    final JvmOperation operation = this._iXtendJvmAssociations.getDirectlyInferredOperation(function);
    LightweightTypeReference _xifexpression = null;
    String _key = lhsAndParams.getKey();
    boolean _tripleNotEquals = (_key != null);
    if (_tripleNotEquals) {
      _xifexpression = this.toLightweightTypeReference(IterableExtensions.<JvmFormalParameter>head(operation.getParameters()).getParameterType());
    } else {
      _xifexpression = this.getOwner().newAnyTypeReference();
    }
    final LightweightTypeReference lhsType = _xifexpression;
    LightweightTypeReference _xifexpression_1 = null;
    if ((rhs != null)) {
      _xifexpression_1 = this.toLightweightTypeReference(IterableExtensions.<JvmFormalParameter>last(operation.getParameters()).getParameterType());
    } else {
      _xifexpression_1 = this.getOwner().newAnyTypeReference();
    }
    final LightweightTypeReference rhsType = _xifexpression_1;
    String _simpleName = lhsType.getSimpleName();
    String _plus = (_simpleName + " := ");
    String _simpleName_1 = rhsType.getSimpleName();
    String _plus_1 = (_plus + _simpleName_1);
    Assert.assertEquals(_plus_1, Boolean.valueOf(expectation), Boolean.valueOf(this.testIsAssignable(lhsType, rhsType)));
    if (expectation) {
      List<LightweightTypeReference> _allSuperTypes = lhsType.getAllSuperTypes();
      for (final LightweightTypeReference superType : _allSuperTypes) {
        if (((superType.isArray() == lhsType.isArray()) || (lhsType.isArray() == rhsType.isArray()))) {
          Assert.assertEquals(superType.toString(), Boolean.valueOf(expectation), Boolean.valueOf(this.testIsAssignable(superType, rhsType)));
        }
      }
    }
  } catch (Throwable _e) {
    throw Exceptions.sneakyThrow(_e);
  }
}
 
Example 20
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;
}