Search in sources :

Example 1 with Later

use of org.eclipse.xtext.xbase.compiler.Later in project xtext-xtend by eclipse.

the class XtendCompiler method _toJavaStatement.

@Override
protected void _toJavaStatement(final XConstructorCall expr, ITreeAppendable b, final boolean isReferenced) {
    for (XExpression arg : expr.getArguments()) {
        prepareExpression(arg, b);
    }
    if (!isReferenced) {
        b.newLine();
        constructorCallToJavaExpression(expr, b);
        if (expr.eContainer() instanceof AnonymousClass) {
            JvmConstructor constructor = expr.getConstructor();
            JvmDeclaredType declaringType = constructor.getDeclaringType();
            compileAnonymousClassBody((AnonymousClass) expr.eContainer(), declaringType, b);
        }
        b.append(";");
    } else if (isVariableDeclarationRequired(expr, b, true)) {
        Later later = new Later() {

            @Override
            public void exec(ITreeAppendable appendable) {
                constructorCallToJavaExpression(expr, appendable);
                if (expr.eContainer() instanceof AnonymousClass) {
                    JvmConstructor constructor = expr.getConstructor();
                    JvmDeclaredType declaringType = constructor.getDeclaringType();
                    compileAnonymousClassBody((AnonymousClass) expr.eContainer(), declaringType, appendable);
                }
            }
        };
        declareFreshLocalVariable(expr, b, later);
    }
}
Also used : Later(org.eclipse.xtext.xbase.compiler.Later) AnonymousClass(org.eclipse.xtend.core.xtend.AnonymousClass) JvmConstructor(org.eclipse.xtext.common.types.JvmConstructor) JvmDeclaredType(org.eclipse.xtext.common.types.JvmDeclaredType) XExpression(org.eclipse.xtext.xbase.XExpression) ITreeAppendable(org.eclipse.xtext.xbase.compiler.output.ITreeAppendable)

Example 2 with Later

use of org.eclipse.xtext.xbase.compiler.Later in project xtext-xtend by eclipse.

the class DispatchMethodCompileStrategy method apply.

@Override
public void apply(/* @Nullable */
ITreeAppendable a) {
    if (a == null)
        throw new IllegalArgumentException("a is never null");
    int parameterCount = dispatchOperation.getParameters().size();
    List<JvmOperation> sortedDispatchOperations = sorter.getAllDispatchCases(dispatchOperation);
    ITypeReferenceOwner owner = new StandardTypeReferenceOwner(services, dispatchOperation);
    boolean[] allCasesSameType = new boolean[parameterCount];
    boolean[] voidIncluded = new boolean[parameterCount];
    boolean[] notNullIncluded = new boolean[parameterCount];
    for (int i = 0; i < parameterCount; i++) {
        allCasesSameType[i] = true;
        voidIncluded[i] = false;
        notNullIncluded[i] = false;
        JvmFormalParameter dispatchParam = dispatchOperation.getParameters().get(i);
        LightweightTypeReference dispatchParamType = owner.toLightweightTypeReference(dispatchParam.getParameterType());
        for (JvmOperation operation : sortedDispatchOperations) {
            JvmFormalParameter caseParam = operation.getParameters().get(i);
            LightweightTypeReference caseParamType = owner.toLightweightTypeReference(caseParam.getParameterType());
            if (!Strings.equal(dispatchParamType.getIdentifier(), caseParamType.getIdentifier())) {
                allCasesSameType[i] = false;
            }
            if (caseParamType.isType(Void.class)) {
                voidIncluded[i] = true;
            }
            if (isSameType(dispatchParamType, caseParamType) && !dispatchParamType.isPrimitive()) {
                notNullIncluded[i] = true;
            }
        }
    }
    boolean needsElse = anyFalse(notNullIncluded) || (anyFalse(voidIncluded) && sortedDispatchOperations.size() != 1);
    for (JvmOperation operation : sortedDispatchOperations) {
        ITreeAppendable operationAppendable = treeAppendableUtil.traceSignificant(a, operation, true);
        final List<Later> laters = newArrayList();
        for (int i = 0; i < parameterCount; i++) {
            final JvmFormalParameter dispatchParam = dispatchOperation.getParameters().get(i);
            final LightweightTypeReference dispatchParamType = owner.toLightweightTypeReference(dispatchParam.getParameterType());
            final JvmFormalParameter caseParam = operation.getParameters().get(i);
            final LightweightTypeReference caseParamType = owner.toLightweightTypeReference(caseParam.getParameterType());
            final String name = getVarName(dispatchParam, operationAppendable);
            if (caseParamType.isType(Void.class)) {
                laters.add(new Later() {

                    @Override
                    public void exec(ITreeAppendable appendable) {
                        appendable.append(name).append(" == null");
                    }
                });
            } else if (!allCasesSameType[i]) {
                laters.add(new Later() {

                    @Override
                    public void exec(ITreeAppendable appendable) {
                        if (isSameType(dispatchParamType, caseParamType) && !dispatchParamType.isPrimitive()) {
                            appendable.append(name).append(" != null");
                        } else {
                            appendable.append(name).append(" instanceof ");
                            JvmType type = caseParamType.getWrapperTypeIfPrimitive().getType();
                            if (type == null) {
                                throw new IllegalStateException(String.valueOf(caseParamType));
                            }
                            appendable.append(type);
                        }
                    }
                });
            }
        }
        boolean isLast = sortedDispatchOperations.get(sortedDispatchOperations.size() - 1) == operation;
        // if it's not the first if append an 'else'
        if (sortedDispatchOperations.get(0) != operation) {
            operationAppendable.append(" else ");
        }
        if (laters.isEmpty()) {
            if (sortedDispatchOperations.size() != 1) {
                operationAppendable.append("{").increaseIndentation();
                operationAppendable.newLine();
            }
        } else {
            if (!isLast || needsElse) {
                operationAppendable.append("if (");
                operationAppendable.increaseIndentation().increaseIndentation();
                Iterator<Later> iterator = laters.iterator();
                while (iterator.hasNext()) {
                    iterator.next().exec(operationAppendable);
                    if (iterator.hasNext()) {
                        operationAppendable.newLine().append(" && ");
                    }
                }
                operationAppendable.decreaseIndentation().decreaseIndentation();
                operationAppendable.append(") {").increaseIndentation();
                operationAppendable.newLine();
            } else {
                operationAppendable.append("{").increaseIndentation().newLine();
            }
        }
        final boolean isCurrentVoid = typeReferences.is(operation.getReturnType(), Void.TYPE);
        final boolean isDispatchVoid = typeReferences.is(dispatchOperation.getReturnType(), Void.TYPE);
        if (isDispatchVoid) {
            generateActualDispatchCall(dispatchOperation, operation, operationAppendable, owner);
            operationAppendable.append(";");
            // we generate a redundant return statement here to get a better debugging experience
            operationAppendable.newLine().append("return;");
        } else {
            if (isCurrentVoid) {
                generateActualDispatchCall(dispatchOperation, operation, operationAppendable, owner);
                operationAppendable.append(";").newLine().append("return null");
            } else {
                operationAppendable.append("return ");
                generateActualDispatchCall(dispatchOperation, operation, operationAppendable, owner);
            }
            operationAppendable.append(";");
        }
        if (sortedDispatchOperations.size() != 1 || anyTrue(voidIncluded)) {
            operationAppendable.decreaseIndentation();
            a.newLine().append("}");
        }
    }
    if (needsElse) {
        a.append(" else {").increaseIndentation();
        a.newLine();
        a.increaseIndentation();
        a.append("throw new IllegalArgumentException(\"Unhandled parameter types: \" +").newLine();
        JvmType jvmType = typeReferences.findDeclaredType("java.util.Arrays", dispatchOperation);
        if (jvmType != null) {
            a.append(jvmType);
        } else {
            a.append(Arrays.class.getSimpleName());
        }
        a.append(".<Object>asList(");
        Iterator<JvmFormalParameter> iterator = dispatchOperation.getParameters().iterator();
        while (iterator.hasNext()) {
            JvmFormalParameter parameter = iterator.next();
            final String name = getVarName(parameter, a);
            a.append(name);
            if (iterator.hasNext()) {
                a.append(", ");
            }
        }
        a.append(").toString());");
        a.decreaseIndentation();
        a.decreaseIndentation().newLine().append("}");
    }
}
Also used : LightweightTypeReference(org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference) JvmType(org.eclipse.xtext.common.types.JvmType) ITypeReferenceOwner(org.eclipse.xtext.xbase.typesystem.references.ITypeReferenceOwner) ITreeAppendable(org.eclipse.xtext.xbase.compiler.output.ITreeAppendable) JvmOperation(org.eclipse.xtext.common.types.JvmOperation) Later(org.eclipse.xtext.xbase.compiler.Later) JvmFormalParameter(org.eclipse.xtext.common.types.JvmFormalParameter) Arrays(java.util.Arrays) StandardTypeReferenceOwner(org.eclipse.xtext.xbase.typesystem.references.StandardTypeReferenceOwner)

Aggregations

Later (org.eclipse.xtext.xbase.compiler.Later)2 ITreeAppendable (org.eclipse.xtext.xbase.compiler.output.ITreeAppendable)2 Arrays (java.util.Arrays)1 AnonymousClass (org.eclipse.xtend.core.xtend.AnonymousClass)1 JvmConstructor (org.eclipse.xtext.common.types.JvmConstructor)1 JvmDeclaredType (org.eclipse.xtext.common.types.JvmDeclaredType)1 JvmFormalParameter (org.eclipse.xtext.common.types.JvmFormalParameter)1 JvmOperation (org.eclipse.xtext.common.types.JvmOperation)1 JvmType (org.eclipse.xtext.common.types.JvmType)1 XExpression (org.eclipse.xtext.xbase.XExpression)1 ITypeReferenceOwner (org.eclipse.xtext.xbase.typesystem.references.ITypeReferenceOwner)1 LightweightTypeReference (org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference)1 StandardTypeReferenceOwner (org.eclipse.xtext.xbase.typesystem.references.StandardTypeReferenceOwner)1