use of org.eclipse.n4js.ts.types.IdentifiableElement in project n4js by eclipse.
the class N4JSEnumValidator method checkUsageOfStringBasedEnum.
/**
* See N4JS Specification, Req. IDE-41, Nr. 6.
*/
@Check
public void checkUsageOfStringBasedEnum(IdentifierRef identRef) {
final IdentifiableElement id = identRef.getId();
if (id == null || id.eIsProxy()) {
return;
}
if (!(id instanceof TEnum)) {
return;
}
final TEnum tEnum = (TEnum) id;
if (!AnnotationDefinition.STRING_BASED.hasAnnotation(tEnum)) {
return;
}
// we now have an IdentifierRef pointing to a string-based enum ...
final EObject parent = N4JSASTUtils.skipParenExpressionUpward(identRef.eContainer());
final ParameterizedPropertyAccessExpression parentPAE = parent instanceof ParameterizedPropertyAccessExpression ? (ParameterizedPropertyAccessExpression) parent : null;
final IdentifiableElement prop = parentPAE != null ? parentPAE.getProperty() : null;
if (prop != null) {
if (prop.eIsProxy()) {
// unnecessary duplicate error
return;
}
if (tEnum.getLiterals().contains(prop)) {
// reference to one of tEnum's literals -> valid usage!
return;
}
final RuleEnvironment G = RuleEnvironmentExtensions.newRuleEnvironment(identRef);
final TMember getterLiterals = RuleEnvironmentExtensions.n4StringBasedEnumType(G).findOwnedMember("literals", false, true);
if (prop == getterLiterals) {
// reference to static getter 'literals' in N4StringBasedEnum -> valid usage!
return;
}
}
// invalid usage!
addIssue(getMessageForENM_INVALID_USE_OF_STRINGBASED_ENUM(), identRef, ENM_INVALID_USE_OF_STRINGBASED_ENUM);
}
use of org.eclipse.n4js.ts.types.IdentifiableElement in project n4js by eclipse.
the class N4JSSyntaxValidator method checkClassDefinition.
/**
* Checks that no "with" is used and that list of implemented interfaces is separated with commas and not with
* keywords. These checks (with some warnings created instead of errors) should help the transition from roles to
* interfaces. However, they may be useful later on as well, e.g., if an interface is manually refactored into a
* class or vice versa.
* <p>
* Note that "with" is used in Dart for roles, so maybe it is useful to have a user-friendly message instead of a
* parser error.
*/
@Check
public void checkClassDefinition(N4ClassDefinition n4ClassDefinition) {
holdsCorrectOrderOfExtendsImplements(n4ClassDefinition);
ICompositeNode node = NodeModelUtils.findActualNodeFor(n4ClassDefinition);
ILeafNode keywordNode = findSecondLeafWithKeyword(n4ClassDefinition, "{", node, EXTENDS_KEYWORD, false);
if (keywordNode != null) {
TClass tclass = n4ClassDefinition.getDefinedTypeAsClass();
if (tclass == null) {
// avoid consequential errors
return;
}
if (StreamSupport.stream(tclass.getImplementedInterfaceRefs().spliterator(), false).allMatch(superTypeRef -> superTypeRef.getDeclaredType() instanceof TInterface)) {
List<? extends IdentifiableElement> interfaces = StreamSupport.stream(tclass.getImplementedInterfaceRefs().spliterator(), false).map(ref -> (TInterface) (ref.getDeclaredType())).collect(Collectors.toList());
String message = getMessageForSYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP(validatorMessageHelper.description(tclass), "extend", "interface" + (interfaces.size() > 1 ? "s " : " ") + validatorMessageHelper.names(interfaces), IMPLEMENTS_KEYWORD);
addIssue(message, n4ClassDefinition, keywordNode.getTotalOffset(), keywordNode.getLength(), SYN_KW_EXTENDS_IMPLEMENTS_MIXED_UP);
}
}
}
use of org.eclipse.n4js.ts.types.IdentifiableElement in project n4js by eclipse.
the class AmbiguousImportDescription method getMessage.
@Override
public String getMessage() {
StringBuilder typeListStr = new StringBuilder();
IdentifiableElement first = (IdentifiableElement) EcoreUtil.resolve(getEObjectOrProxy(), context);
String typeIdent = first instanceof Type ? "type" : "variable";
TModule module = (TModule) first.eContainer();
typeListStr.append(module.getQualifiedName());
Set<IdentifiableElement> uniqueTypes = Sets.newLinkedHashSet(elements);
uniqueTypes.remove(first);
Iterator<IdentifiableElement> iter = uniqueTypes.iterator();
while (iter.hasNext()) {
IdentifiableElement type = iter.next();
if (iter.hasNext()) {
typeListStr.append(", ");
} else {
typeListStr.append(" and ");
}
typeListStr.append(((TModule) type.eContainer()).getQualifiedName());
}
if (this.issueCode == IssueCodes.IMP_AMBIGUOUS_WILDCARD) {
return IssueCodes.getMessageForIMP_AMBIGUOUS_WILDCARD(typeIdent, getName(), typeListStr.toString());
} else if (this.issueCode == IssueCodes.IMP_AMBIGUOUS) {
return IssueCodes.getMessageForIMP_AMBIGUOUS(typeIdent, getName(), typeListStr.toString());
} else if (this.issueCode == IssueCodes.IMP_DUPLICATE_NAMESPACE) {
return IssueCodes.getMessageForIMP_DUPLICATE_NAMESPACE(getName(), "stub");
}
return "Unknown ambiguous import issue: " + this.issueCode + " for " + context + ".";
}
use of org.eclipse.n4js.ts.types.IdentifiableElement in project n4js by eclipse.
the class InternalTypeSystem method applyRuleTypeIdentifierRef.
protected Result<TypeRef> applyRuleTypeIdentifierRef(final RuleEnvironment G, final RuleApplicationTrace _trace_, final IdentifierRef idref) throws RuleFailedException {
// output parameter
TypeRef T = null;
/* G |- idref.id : T */
IdentifiableElement _id = idref.getId();
Result<TypeRef> result = typeInternal(G, _trace_, _id);
checkAssignableTo(result.getFirst(), TypeRef.class);
T = (TypeRef) result.getFirst();
T = this.versionResolver.<TypeRef, IdentifierRef>resolveVersion(T, idref);
if (((idref.eContainer() instanceof ParameterizedCallExpression) && (idref.eContainmentFeature() == N4JSPackage.eINSTANCE.getParameterizedCallExpression_Target()))) {
final TMethod callableCtorFunction = this.typeSystemHelper.getCallableClassConstructorFunction(G, T);
if ((callableCtorFunction != null)) {
T = TypeExtensions.ref(callableCtorFunction);
}
}
return new Result<TypeRef>(T);
}
use of org.eclipse.n4js.ts.types.IdentifiableElement 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);
}
Aggregations