use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.
the class ComposedMemberScope method createComposedMember.
/**
* Key method of entire scoping for composed types e.g. union/intersection types. This creates a new TMember as a
* combination of all members of the given name in the type's contained types. If those members cannot be combined
* into a single valid member, this method creates a dummy placeholder.
*/
private TMember createComposedMember(String memberName) {
// check all subScopes for a member of the given name and
// merge the properties of the existing members into 'composedMember'
final Resource resource = EcoreUtilN4.getResource(request.context, composedTypeRef);
ComposedMemberInfoBuilder cmiBuilder = new ComposedMemberInfoBuilder();
cmiBuilder.init(writeAccess, resource, ts);
for (int idx = 0; idx < subScopes.length; idx++) {
final IScope subScope = subScopes[idx];
final TypeRef typeRef = composedTypeRef.getTypeRefs().get(idx);
final Resource res = EcoreUtilN4.getResource(request.context, composedTypeRef);
final RuleEnvironment GwithSubstitutions = ts.createRuleEnvironmentForContext(typeRef, res);
final TMember member = findMemberInSubScope(subScope, memberName);
cmiBuilder.addMember(member, GwithSubstitutions);
}
// produce result
ComposedMemberInfo cmi = cmiBuilder.get();
ComposedMemberFactory cmf = getComposedMemberFactory(cmi);
if (!cmf.isEmpty()) {
// at least one of the subScopes had an element of that name
final TMember result;
if (cmf.isValid()) {
// success case: The element for that name can be merged into a valid composed member
result = cmf.create(memberName);
} else {
// some of the subScopes do not have an element for that name OR
// they do not form a valid composed member (e.g. they are of different kind)
// -> produce a specific error message explaining the incompatibility
// (this error placeholder will be wrapped with a UncommonMemberDescription
// in #getSingleLocalElementByName(QualifiedName) above)
result = createErrorPlaceholder(memberName);
}
// add composed member to ComposedTypeRef's cache (without notifications to avoid cache-clear)
final ComposedMemberCache cache = getOrCreateComposedMemberCache();
if (cache != null) {
EcoreUtilN4.doWithDeliver(false, () -> {
cache.getCachedComposedMembers().add(result);
}, cache);
}
// if cache==null: simply do not cache the composed member (i.e. member won't be contained in a resource!)
return result;
} else {
// -> produce the ordinary "Cannot resolve reference ..." error by returning 'null'
return null;
}
}
use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.
the class ComposedMemberFactory method allTypeRefAreEqual.
/**
* Compares the return types of the new {@link TMember}.
* <p>
* Returns true iff no new composition type is created. That is, all return {@link TypeRef}s of the siblings are
* equal.
*/
protected boolean allTypeRefAreEqual() {
N4JSTypeSystem ts = cmi.getTypeSystem();
List<TypeRef> allTypeRefs = cmi.getTypeRefsOfMemberType(METHOD, FIELD, GETTER, SETTER);
TypeRef siTypeRef = ts.createSimplifiedIntersection(allTypeRefs, cmi.getResource());
Iterator<TypeRef> typeRefIt = allTypeRefs.iterator();
while (typeRefIt.hasNext()) {
TypeRef firstNonNullTypeRef = typeRefIt.next();
if (firstNonNullTypeRef != null) {
RuleEnvironment G = cmi.getRuleEnvironmentForTypeRef(firstNonNullTypeRef);
boolean equalTypeRefs = ts.equaltypeSucceeded(G, firstNonNullTypeRef, siTypeRef);
return equalTypeRefs;
}
}
return true;
}
use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method changeReturnTypeToVoid.
/**
* Returns a copy of the given {@link FunctionTypeExprOrRef} with its return type changed to <code>void</code>.
*/
private FunctionTypeExpression changeReturnTypeToVoid(RuleEnvironment G, FunctionTypeExprOrRef typeRef) {
final RuleEnvironment G_empty = RuleEnvironmentExtensions.newRuleEnvironment(G);
final FunctionTypeExpression result = tsh.createSubstitutionOfFunctionTypeExprOrRef(G_empty, typeRef);
// TODO use RuleEnvironmentExtensions.voidTypeRef(G) here
result.setReturnTypeRef(null);
return result;
}
use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.
the class N4JSMemberRedefinitionValidator method checkMemberRedefinitions.
/**
* Checks constraints defined in chapter 5.4. Redefinition of Members.
*/
@Check
public void checkMemberRedefinitions(N4ClassifierDefinition n4ClassifierDefinition) {
if (!(n4ClassifierDefinition.getDefinedType() instanceof TClassifier)) {
// wrongly parsed
return;
}
TClassifier tClassifier = (TClassifier) n4ClassifierDefinition.getDefinedType();
getContext().put(TClassifier.class, tClassifier);
RuleEnvironment g = RuleEnvironmentExtensions.newRuleEnvironment(tClassifier);
getContext().put(RuleEnvironment.class, g);
// the context for type variables
ParameterizedTypeRef classTypeRef = TypeUtils.createTypeRef(tClassifier);
getContext().put(TYPE_VAR_CONTEXT, classTypeRef);
MemberCube memberCube = createMemberValidationList();
final boolean isClass = tClassifier instanceof TClass;
final Map<ParameterizedTypeRef, MemberList<TMember>> nonAccessibleAbstractMembersBySuperTypeRef = new HashMap<>();
for (Entry<NameStaticPair, MemberMatrix> entry : memberCube.entrySet()) {
MemberMatrix mm = entry.getValue();
// Set to collect all owned members that are lacking an override annotation.
Collection<TMember> membersMissingOverrideAnnotation = new HashSet<>();
if (isClass) {
constraints_67_MemberOverride_checkEntry(mm, membersMissingOverrideAnnotation);
}
if (mm.hasImplemented()) {
// first mix in
if (holdConstraints_68_Consumption(mm)) {
// then check if everything is implemented
constraints_69_Implementation(mm, membersMissingOverrideAnnotation);
}
}
constraints_60_InheritedConsumedCovariantSpecConstructor(tClassifier, mm);
constraints_66_NonOverride(mm);
constraints_42_45_46_AbstractMember(mm, nonAccessibleAbstractMembersBySuperTypeRef);
unusedGenericTypeVariable(mm);
checkUnpairedAccessorConsumption(mm, n4ClassifierDefinition);
checkUnpairedAccessorFilling(mm, n4ClassifierDefinition);
messageMissingOverrideAnnotation(mm, membersMissingOverrideAnnotation);
}
final boolean foundImpossibleExtendsImplements = !nonAccessibleAbstractMembersBySuperTypeRef.isEmpty();
if (foundImpossibleExtendsImplements) {
messageImpossibleExtendsImplements(n4ClassifierDefinition, nonAccessibleAbstractMembersBySuperTypeRef);
}
if (!foundImpossibleExtendsImplements) {
// avoid consequential errors
constraints_41_AbstractClass(tClassifier, memberCube);
}
}
use of org.eclipse.xsemantics.runtime.RuleEnvironment in project n4js by eclipse.
the class N4JSStatementValidator method checkForInLoop.
/**
* 9.1.4 Iteration Statements, Constraints 118 (For-In-Statement Constraints) Variable declaration must be a string
*/
@Check
public void checkForInLoop(ForStatement forStatement) {
if (forStatement.isForIn()) {
TypeRef loopVarType = null;
EObject location = null;
RuleEnvironment G = (RuleEnvironment) getContext().get(RuleEnvironment.class);
if (G == null)
// wrongly configured test
return;
if (!forStatement.getVarDeclsOrBindings().isEmpty()) {
VariableDeclarationOrBinding varDeclOrBinding = forStatement.getVarDeclsOrBindings().iterator().next();
location = varDeclOrBinding;
if (varDeclOrBinding instanceof VariableDeclaration) {
loopVarType = ((VariableDeclaration) varDeclOrBinding).getDeclaredTypeRef();
} else {
VariableBinding varBinding = (VariableBinding) varDeclOrBinding;
Result<TypeRef> res = typeSystem.type(G, varBinding.getExpression());
if (!res.failed()) {
loopVarType = res.getFirst();
}
}
} else if (forStatement.getInitExpr() != null) {
location = forStatement.getInitExpr();
Result<TypeRef> res = typeSystem.type(G, forStatement.getInitExpr());
if (!res.failed()) {
loopVarType = res.getFirst();
}
}
if (loopVarType != null) {
Result<Boolean> res = typeSystem.subtype(G, RuleEnvironmentExtensions.stringTypeRef(G), loopVarType);
if (res.failed() || !res.getFirst()) {
addIssue(getMessageForTYS_FOR_IN_VAR_STRING(loopVarType.getTypeRefAsString()), location, TYS_FOR_IN_VAR_STRING);
}
}
}
}
Aggregations