Search in sources :

Example 1 with ITypeComputationResult

use of org.eclipse.xtext.xbase.typesystem.computation.ITypeComputationResult in project xtext-xtend by eclipse.

the class XtendReentrantTypeResolver method _computeTypes.

@Override
protected void _computeTypes(Map<JvmIdentifiableElement, ResolvedTypes> preparedResolvedTypes, ResolvedTypes resolvedTypes, IFeatureScopeSession featureScopeSession, JvmOperation operation) {
    ResolvedTypes childResolvedTypes = preparedResolvedTypes.get(operation);
    if (childResolvedTypes == null) {
        if (preparedResolvedTypes.containsKey(operation))
            return;
        throw new IllegalStateException("No resolved type found. Type was: " + operation.getIdentifier());
    }
    if (dispatchHelper.isDispatcherFunction(operation)) {
        // no associated expression, we just resolve it to the common super type of all associated cases
        // see #createTypeProvider and #_doPrepare
        preparedResolvedTypes.put(operation, null);
        computeAnnotationTypes(childResolvedTypes, featureScopeSession, operation);
        mergeChildTypes(childResolvedTypes);
    } else if (dispatchHelper.isDispatchFunction(operation) && InferredTypeIndicator.isInferred(operation.getReturnType())) {
        JvmOperation dispatcher = dispatchHelper.getDispatcherOperation(operation);
        if (dispatcher == null) {
            super._computeTypes(preparedResolvedTypes, resolvedTypes, featureScopeSession, operation);
            return;
        }
        List<JvmOperation> dispatchCasesWithDeclaredReturnType = new ArrayList<JvmOperation>();
        List<JvmOperation> dispatchCasesWithInferredReturnType = new ArrayList<JvmOperation>();
        List<JvmOperation> dispatchCases = dispatchHelper.getLocalDispatchCases(dispatcher);
        for (JvmOperation dispatchCase : dispatchCases) {
            if (InferredTypeIndicator.isInferred(dispatchCase.getReturnType())) {
                dispatchCasesWithInferredReturnType.add(dispatchCase);
            } else {
                dispatchCasesWithDeclaredReturnType.add(dispatchCase);
            }
        }
        try {
            markComputing(dispatcher.getReturnType());
            LightweightTypeReference declaredDispatcherType = getReturnTypeOfOverriddenOperation(dispatcher, childResolvedTypes, featureScopeSession);
            List<LightweightTypeReference> dispatchCaseResults = Lists.newArrayListWithCapacity(dispatchCases.size());
            LightweightTypeReference implicitVoid = null;
            LightweightTypeReference thrownVoid = null;
            for (JvmOperation dispatchCase : dispatchCasesWithDeclaredReturnType) {
                ResolvedTypes dispatchCaseResolvedTypes = preparedResolvedTypes.get(dispatchCase);
                if (dispatchCaseResolvedTypes == null) {
                    if (preparedResolvedTypes.containsKey(dispatchCase)) {
                        dispatchCaseResolvedTypes = childResolvedTypes;
                    }
                }
                if (dispatchCaseResolvedTypes == null) {
                    throw new IllegalStateException("No resolved type found. Type was: " + dispatchCase.getIdentifier());
                }
                dispatchCaseResults.add(dispatchCaseResolvedTypes.getActualType(dispatchCase));
            }
            List<ResolvedTypes> mergeUs = Lists.newArrayList();
            for (JvmOperation dispatchCase : dispatchCasesWithInferredReturnType) {
                ResolvedTypes dispatchCaseResolvedTypes = dispatchCase == operation ? childResolvedTypes : preparedResolvedTypes.get(dispatchCase);
                if (dispatchCaseResolvedTypes == null) {
                    if (preparedResolvedTypes.containsKey(dispatchCase)) {
                        if (InferredTypeIndicator.isInferred(dispatchCase.getReturnType())) {
                            if (declaredDispatcherType == null) {
                                dispatchCaseResults.add(childResolvedTypes.getActualType(dispatchCase));
                            }
                        } else {
                            dispatchCaseResults.add(childResolvedTypes.getActualType(dispatchCase));
                        }
                    } else {
                        throw new IllegalStateException("No resolved type found. Type was: " + dispatchCase.getIdentifier());
                    }
                } else {
                    mergeUs.add(dispatchCaseResolvedTypes);
                    preparedResolvedTypes.put(dispatchCase, null);
                    OperationBodyComputationState state = new DispatchOperationBodyComputationState(dispatchCaseResolvedTypes, dispatchCase.isStatic() ? featureScopeSession : featureScopeSession.toInstanceContext(), dispatchCase, dispatcher, declaredDispatcherType);
                    addExtensionProviders(state, dispatchCase.getParameters());
                    ITypeComputationResult dispatchCaseResult = null;
                    try {
                        markComputing(dispatchCase.getReturnType());
                        dispatchCaseResult = state.computeTypes();
                    } finally {
                        unmarkComputing(dispatchCase.getReturnType());
                    }
                    if (InferredTypeIndicator.isInferred(dispatchCase.getReturnType())) {
                        if (declaredDispatcherType == null) {
                            LightweightTypeReference returnType = dispatchCaseResult.getReturnType();
                            if (returnType != null) {
                                if (returnType.isPrimitiveVoid()) {
                                    int conformanceFlags = dispatchCaseResult.getConformanceFlags();
                                    if ((conformanceFlags & ConformanceFlags.THROWN_EXCEPTION) == 0) {
                                        if ((conformanceFlags & ConformanceFlags.NO_IMPLICIT_RETURN) != 0) {
                                            dispatchCaseResults.add(returnType);
                                        } else {
                                            implicitVoid = returnType;
                                        }
                                    } else {
                                        thrownVoid = returnType;
                                    }
                                } else {
                                    dispatchCaseResults.add(returnType);
                                }
                            }
                        }
                    } else {
                        LightweightTypeReference explicitType = dispatchCaseResolvedTypes.getActualType(dispatchCase);
                        dispatchCaseResults.add(explicitType);
                    }
                    computeAnnotationTypes(dispatchCaseResolvedTypes, featureScopeSession, dispatchCase);
                    computeLocalTypes(preparedResolvedTypes, dispatchCaseResolvedTypes, featureScopeSession, dispatchCase);
                }
            }
            LightweightTypeReference commonDispatchType = normalizeDispatchReturnType(declaredDispatcherType, dispatchCaseResults, implicitVoid, thrownVoid, childResolvedTypes);
            if (commonDispatchType != null) {
                resolveDispatchCaseTypes(dispatcher, dispatchCasesWithInferredReturnType, commonDispatchType, featureScopeSession);
            }
            // deferred merge since #normalizeDispatchReturnType may add more hints to the different dispatch cases
            for (ResolvedTypes mergeMe : mergeUs) {
                mergeChildTypes(mergeMe);
            }
        } finally {
            unmarkComputing(dispatcher.getReturnType());
        }
    } else {
        super._computeTypes(preparedResolvedTypes, resolvedTypes, featureScopeSession, operation);
    }
}
Also used : JvmOperation(org.eclipse.xtext.common.types.JvmOperation) OperationBodyComputationState(org.eclipse.xtext.xbase.typesystem.internal.OperationBodyComputationState) LightweightTypeReference(org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference) ITypeComputationResult(org.eclipse.xtext.xbase.typesystem.computation.ITypeComputationResult) List(java.util.List) ArrayList(java.util.ArrayList) ResolvedTypes(org.eclipse.xtext.xbase.typesystem.internal.ResolvedTypes) IResolvedTypes(org.eclipse.xtext.xbase.typesystem.IResolvedTypes)

Aggregations

ArrayList (java.util.ArrayList)1 List (java.util.List)1 JvmOperation (org.eclipse.xtext.common.types.JvmOperation)1 IResolvedTypes (org.eclipse.xtext.xbase.typesystem.IResolvedTypes)1 ITypeComputationResult (org.eclipse.xtext.xbase.typesystem.computation.ITypeComputationResult)1 OperationBodyComputationState (org.eclipse.xtext.xbase.typesystem.internal.OperationBodyComputationState)1 ResolvedTypes (org.eclipse.xtext.xbase.typesystem.internal.ResolvedTypes)1 LightweightTypeReference (org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference)1