Search in sources :

Example 6 with RuleEnvironment

use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.

the class InternalTypeSystem method applyRuleExpectedTypeInJSXPropertyAttribute.

protected Result<TypeRef> applyRuleExpectedTypeInJSXPropertyAttribute(final RuleEnvironment G, final RuleApplicationTrace _trace_, final JSXPropertyAttribute container, final Expression expr) throws RuleFailedException {
    // output parameter
    TypeRef T = null;
    T = TypeRefsFactory.eINSTANCE.createUnknownTypeRef();
    final EObject jsxElem = container.eContainer();
    if ((jsxElem instanceof JSXElement)) {
        final TypeRef propsTypeRef = this.reactHelper.getPropsType(((JSXElement) jsxElem));
        if ((propsTypeRef != null)) {
            final RuleEnvironment G2 = RuleEnvironmentExtensions.wrap(G);
            this.typeSystemHelper.addSubstitutions(G2, propsTypeRef);
            RuleEnvironmentExtensions.addThisType(G2, propsTypeRef);
            /* G2 |- container.getProperty() : var TypeRef propertyTypeRef */
            IdentifiableElement _property = container.getProperty();
            TypeRef propertyTypeRef = null;
            Result<TypeRef> result = typeInternal(G2, _trace_, _property);
            checkAssignableTo(result.getFirst(), TypeRef.class);
            propertyTypeRef = (TypeRef) result.getFirst();
            /* G2 |- propertyTypeRef ~> T */
            Result<TypeArgument> result_1 = substTypeVariablesInternal(G2, _trace_, propertyTypeRef);
            checkAssignableTo(result_1.getFirst(), TypeRef.class);
            T = (TypeRef) result_1.getFirst();
        }
    }
    return new Result<TypeRef>(T);
}
Also used : JSXElement(org.eclipse.n4js.n4JS.JSXElement) ThisTypeRef(org.eclipse.n4js.ts.typeRefs.ThisTypeRef) ParameterizedTypeRef(org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef) BaseTypeRef(org.eclipse.n4js.ts.typeRefs.BaseTypeRef) FunctionTypeRef(org.eclipse.n4js.ts.typeRefs.FunctionTypeRef) ExistentialTypeRef(org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef) BoundThisTypeRef(org.eclipse.n4js.ts.typeRefs.BoundThisTypeRef) StructuralTypeRef(org.eclipse.n4js.ts.typeRefs.StructuralTypeRef) TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) TypeTypeRef(org.eclipse.n4js.ts.typeRefs.TypeTypeRef) StaticBaseTypeRef(org.eclipse.n4js.ts.typeRefs.StaticBaseTypeRef) ComposedTypeRef(org.eclipse.n4js.ts.typeRefs.ComposedTypeRef) UnknownTypeRef(org.eclipse.n4js.ts.typeRefs.UnknownTypeRef) EObject(org.eclipse.emf.ecore.EObject) IdentifiableElement(org.eclipse.n4js.ts.types.IdentifiableElement) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) TypeArgument(org.eclipse.n4js.ts.typeRefs.TypeArgument) Result(org.eclipse.xsemantics.runtime.Result) StructuralTypingResult(org.eclipse.n4js.typesystem.StructuralTypingResult)

Example 7 with RuleEnvironment

use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.

the class ExceptionAnalyser method getScriptErrors.

@Override
protected List<Diagnostic> getScriptErrors(Script script) {
    EcoreUtil.resolveAll(script.eResource());
    List<Diagnostic> diagnostics = super.getScriptErrors(script);
    Iterator<Expression> expressions = Iterators.filter(EcoreUtil2.eAll(script), Expression.class);
    List<Diagnostic> result = Lists.<Diagnostic>newArrayList(Iterables.filter(diagnostics, ExceptionDiagnostic.class));
    while (expressions.hasNext()) {
        Expression expression = expressions.next();
        RuleEnvironment ruleEnvironment = RuleEnvironmentExtensions.newRuleEnvironment(expression);
        Result<TypeRef> type = typeSystem.type(ruleEnvironment, expression);
        if (type.getRuleFailedException() != null) {
            Throwable cause = Throwables.getRootCause(type.getRuleFailedException());
            if (!(cause instanceof RuleFailedException)) {
                if (cause instanceof Exception) {
                    result.add(new ExceptionDiagnostic((Exception) cause));
                } else {
                    throw new RuntimeException(cause);
                }
            }
        }
    }
    validator.validate(script.eResource(), CheckMode.ALL, CancelIndicator.NullImpl);
    return result;
}
Also used : Expression(org.eclipse.n4js.n4JS.Expression) TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) ExceptionDiagnostic(org.eclipse.xtext.diagnostics.ExceptionDiagnostic) Diagnostic(org.eclipse.emf.ecore.resource.Resource.Diagnostic) ExceptionDiagnostic(org.eclipse.xtext.diagnostics.ExceptionDiagnostic) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) RuleFailedException(org.eclipse.xsemantics.runtime.RuleFailedException) RuleFailedException(org.eclipse.xsemantics.runtime.RuleFailedException)

Example 8 with RuleEnvironment

use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.

the class ProjectCompareHelper method internalCompareApiImpl.

private ProjectCompareResult internalCompareApiImpl(ProjectComparisonEntry entry, int implIdx) {
    if (!entry.isElementEntry())
        // not an entry for an EObject element -> never report differences
        return ProjectCompareResult.equal();
    final int implCount = entry.getImplCount();
    if (implIdx < 0 || implIdx >= implCount)
        // implementation index out of range -> never report differences
        return ProjectCompareResult.equal();
    // compare implementation to API
    final EObject api = entry.getElementAPI();
    final EObject impl = entry.getElementImpl()[implIdx];
    // special case: no API
    if (api == null) {
        if (impl != null)
            return ProjectCompareResult.compliant();
        else
            return ProjectCompareResult.equal();
    }
    // special case: no impl
    if (impl == null) {
        // note: we know api!=null because of above check
        return ProjectCompareResult.error("missing implementation");
    }
    // accessibility-based compare:
    if (api instanceof TMember && impl instanceof TMember) {
        // order important: check for member before type!
        if (AccessModifiers.less((TMember) impl, (TMember) api))
            return ProjectCompareResult.error("reduced visibility");
    } else if (api instanceof Type && impl instanceof Type) {
        final MemberAccessModifier apiAcc = AccessModifiers.toMemberModifier((Type) api);
        final MemberAccessModifier implAcc = AccessModifiers.toMemberModifier((Type) impl);
        if (AccessModifiers.less(implAcc, apiAcc))
            return ProjectCompareResult.error("reduced visibility");
    }
    ImplToApiReplacementProvider typeReplacementProvider = new ImplToApiReplacementProvider(entry.getRoot());
    // subtype-based compare:
    if (api instanceof TMember && impl instanceof TMember) {
        final TMember apiMember = (TMember) api;
        final TMember implMember = (TMember) impl;
        if (apiMember instanceof TField) {
            boolean bAPIProvidesInitializer = PROVIDES_INITIALZER.hasAnnotation(apiMember);
            if (bAPIProvidesInitializer && !hasInitializer(impl)) {
                if (bAPIProvidesInitializer) {
                    return ProjectCompareResult.error("no initializer in implementation but @" + PROVIDES_INITIALZER.name + " in API");
                } else {
                    return ProjectCompareResult.error("initializer in implementation but no @" + PROVIDES_INITIALZER.name + " in API)");
                }
            }
        } else {
            // Method or accessor
            boolean bAPIProvidesDefImpl = PROVIDES_DEFAULT_IMPLEMENTATION.hasAnnotation(apiMember);
            if ((bAPIProvidesDefImpl != hasBody(impl)) && apiMember.eContainer() instanceof TInterface) {
                if (bAPIProvidesDefImpl) {
                    return ProjectCompareResult.error("no body in implementation but @" + PROVIDES_DEFAULT_IMPLEMENTATION.name + " in API");
                } else {
                    return ProjectCompareResult.error("body in implementation but no @" + PROVIDES_DEFAULT_IMPLEMENTATION.name + " in API");
                }
            }
        }
        final TypeRef context = TypeUtils.createTypeRef((Type) api.eContainer());
        final TypeRef typeApi = typeSystem.tau(apiMember, context);
        final TypeRef typeImpl = typeSystem.tau(implMember, context);
        final RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(api);
        RuleEnvironmentExtensions.setTypeReplacement(G, typeReplacementProvider);
        final Result<Boolean> implSubtypeApi = typeSystem.subtype(G, typeImpl, typeApi);
        final Result<Boolean> apiSubtypeImpl = typeSystem.subtype(G, typeApi, typeImpl);
        final boolean isImplSubtypeApi = !implSubtypeApi.failed();
        final boolean isApiSubtypeImpl = !apiSubtypeImpl.failed();
        final boolean isEqualType = isImplSubtypeApi && isApiSubtypeImpl;
        if (!isEqualType) {
            if (isImplSubtypeApi)
                // not equal but at least compliant
                return ProjectCompareResult.compliant();
            else {
                final String msg = implSubtypeApi.getRuleFailedException().getLocalizedMessage();
                // not even compliant
                return ProjectCompareResult.error(msg);
            }
        }
        if (isSpecialCaseOfHiddenMethodDiff(api, impl)) {
            // not equal but at least compliant
            return ProjectCompareResult.compliant();
        }
        // all fine
        return ProjectCompareResult.equal();
    }
    // classifier compare
    if (api instanceof TClassifier && impl instanceof TClassifier) {
        TClassifier apiClassifier = (TClassifier) api;
        TClassifier implClassifier = (TClassifier) impl;
        EList<TypeVariable> apiTypeVars = apiClassifier.getTypeVars();
        EList<TypeVariable> implTypeVars = implClassifier.getTypeVars();
        // check for number of type variables
        if (apiTypeVars.size() != implTypeVars.size()) {
            return ProjectCompareResult.error("the number of type variables doesn't match");
        }
        final RuleEnvironment ruleEnvironment = RuleEnvironmentExtensions.newRuleEnvironment(api);
        RuleEnvironmentExtensions.setTypeReplacement(ruleEnvironment, typeReplacementProvider);
        // check for upper bound compatibility
        for (int i = 0; i < apiTypeVars.size(); i++) {
            TypeVariable apiTypeVar = apiTypeVars.get(i);
            TypeVariable implTypeVar = implTypeVars.get(i);
            TypeRef apiDeclaredUpperBound = apiTypeVar.getDeclaredUpperBound();
            TypeRef implDeclaredUpperBound = implTypeVar.getDeclaredUpperBound();
            if ((apiDeclaredUpperBound != null) != (implDeclaredUpperBound != null) || (apiDeclaredUpperBound != null && implDeclaredUpperBound != null && !typeSystem.equaltypeSucceeded(ruleEnvironment, apiDeclaredUpperBound, implDeclaredUpperBound))) {
                return ProjectCompareResult.error(String.format("the upper bound of type variable %s isn't compatible with the API", implTypeVar.getName()));
            }
        }
        return ProjectCompareResult.equal();
    }
    // text-based compare:
    // always compare with API
    final String textApi = entry.getTextAPI();
    final String textImpl = entry.getTextImpl(implIdx);
    final boolean isEqual = textApi != null ? textApi.equals(textImpl) : textImpl == null;
    if (!isEqual)
        return ProjectCompareResult.error(textImpl + " is not equal to " + textApi);
    return ProjectCompareResult.equal();
}
Also used : TClassifier(org.eclipse.n4js.ts.types.TClassifier) TField(org.eclipse.n4js.ts.types.TField) TInterface(org.eclipse.n4js.ts.types.TInterface) TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) MemberAccessModifier(org.eclipse.n4js.ts.types.MemberAccessModifier) ContainerType(org.eclipse.n4js.ts.types.ContainerType) Type(org.eclipse.n4js.ts.types.Type) TypeVariable(org.eclipse.n4js.ts.types.TypeVariable) EObject(org.eclipse.emf.ecore.EObject) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) TMember(org.eclipse.n4js.ts.types.TMember)

Example 9 with RuleEnvironment

use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.

the class ComposedMemberInfo method handleValidationProblems.

private void handleValidationProblems() {
    for (Pair<TMember, RuleEnvironment> pair : siblings) {
        if (pair == null)
            continue;
        TMember member = pair.getKey();
        if (member instanceof TMethod) {
            TMethod tMethod = (TMethod) member;
            for (int i = 0; i < tMethod.getFpars().size(); i++) {
                TFormalParameter currFP = tMethod.getFpars().get(i);
                if (currFP.isVariadic() && tMethod.getFpars().size() > i + 1) {
                    ComposedFParInfo currFPA = fParameters.get(i);
                    currFPA.hasValidationProblem = true;
                    return;
                }
            }
        }
    }
}
Also used : TFormalParameter(org.eclipse.n4js.ts.types.TFormalParameter) TMethod(org.eclipse.n4js.ts.types.TMethod) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment) TMember(org.eclipse.n4js.ts.types.TMember)

Example 10 with RuleEnvironment

use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.

the class ComposedMemberInfo method initFParAggregate.

private void initFParAggregate(ComposedFParInfo fpAggr) {
    for (Pair<TFormalParameter, RuleEnvironment> fpPair : fpAggr.fpSiblings) {
        TFormalParameter tFpar = fpPair.getKey();
        RuleEnvironment G = fpPair.getValue();
        // handle: name
        final String nextName = tFpar.getName();
        if (nextName != null && !fpAggr.names.contains(nextName)) {
            fpAggr.names.add(nextName);
        }
        // handle: typeRef lists
        TypeRef typeRefSubst = ts.substTypeVariablesInTypeRef(G, tFpar.getTypeRef());
        if (typeRefSubst != null && !(typeRefSubst instanceof UnknownTypeRef)) {
            TypeRef typeRefCopy = TypeUtils.copyIfContained(typeRefSubst);
            fpAggr.typeRefs.add(typeRefCopy);
            if (tFpar.isVariadic()) {
                fpAggr.typeRefsVariadic.add(typeRefCopy);
            }
        }
        // handle: optional
        fpAggr.allOptional &= tFpar.isOptional();
        fpAggr.allNonOptional &= !tFpar.isOptional();
    }
}
Also used : TFormalParameter(org.eclipse.n4js.ts.types.TFormalParameter) UnknownTypeRef(org.eclipse.n4js.ts.typeRefs.UnknownTypeRef) TypeRef(org.eclipse.n4js.ts.typeRefs.TypeRef) UnknownTypeRef(org.eclipse.n4js.ts.typeRefs.UnknownTypeRef) RuleEnvironment(org.eclipse.xsemantics.runtime.RuleEnvironment)

Aggregations

RuleEnvironment (org.eclipse.xsemantics.runtime.RuleEnvironment)31 TypeRef (org.eclipse.n4js.ts.typeRefs.TypeRef)22 ParameterizedTypeRef (org.eclipse.n4js.ts.typeRefs.ParameterizedTypeRef)14 ComposedTypeRef (org.eclipse.n4js.ts.typeRefs.ComposedTypeRef)12 TypeArgument (org.eclipse.n4js.ts.typeRefs.TypeArgument)12 TypeTypeRef (org.eclipse.n4js.ts.typeRefs.TypeTypeRef)12 UnknownTypeRef (org.eclipse.n4js.ts.typeRefs.UnknownTypeRef)12 ExistentialTypeRef (org.eclipse.n4js.ts.typeRefs.ExistentialTypeRef)11 EObject (org.eclipse.emf.ecore.EObject)10 ThisTypeRef (org.eclipse.n4js.ts.typeRefs.ThisTypeRef)10 Result (org.eclipse.xsemantics.runtime.Result)10 BaseTypeRef (org.eclipse.n4js.ts.typeRefs.BaseTypeRef)9 BoundThisTypeRef (org.eclipse.n4js.ts.typeRefs.BoundThisTypeRef)9 FunctionTypeRef (org.eclipse.n4js.ts.typeRefs.FunctionTypeRef)9 StaticBaseTypeRef (org.eclipse.n4js.ts.typeRefs.StaticBaseTypeRef)9 StructuralTypeRef (org.eclipse.n4js.ts.typeRefs.StructuralTypeRef)9 ContainerType (org.eclipse.n4js.ts.types.ContainerType)9 Type (org.eclipse.n4js.ts.types.Type)9 StructuralTypingResult (org.eclipse.n4js.typesystem.StructuralTypingResult)9 PrimitiveType (org.eclipse.n4js.ts.types.PrimitiveType)8