use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class StaticWriteAccessFilterScope method isAccepted.
@Override
protected boolean isAccepted(IEObjectDescription description) {
EObject proxyOrInstance = description.getEObjectOrProxy();
if (proxyOrInstance instanceof TMember && !proxyOrInstance.eIsProxy()) {
TMember member = (TMember) proxyOrInstance;
// this particular message to hide the better one.
if (member.isStatic() && member.isWriteable() && /* i.e. (member.isField(), not const || member.isSetter()) */
isWriteAccess()) {
ContainerType<?> memberType = member.getContainingType();
memberTypeName = memberType.getName();
// Access only allowed for Direct access, so AST must be IdentifierRef.
final boolean isTargetGivenByIdentifier = getTarget() instanceof IdentifierRef;
if (!isTargetGivenByIdentifier) {
// Not an IdentifierRef --> disallowed for write access.
return false;
}
IdentifierRef idref = (IdentifierRef) getTarget();
// this also covers aliased imports:
if (idref.getId().getName().equals(memberTypeName)) {
// correct name.
return true;
} else {
// wrong name, disallowed
// search for alias, for better error reporting.
Script sc = EcoreUtil2.getContainerOfType(context, Script.class);
Optional<NamedImportSpecifier> namedImport = sc.getScriptElements().stream().filter(se -> se instanceof ImportDeclaration).map(se -> (ImportDeclaration) se).flatMap(idecl -> {
return idecl.getImportSpecifiers().stream().filter(is -> is instanceof NamedImportSpecifier).map(is -> (NamedImportSpecifier) is);
}).filter(s -> s.getImportedElement() == memberType).findFirst();
if (namedImport.isPresent()) {
// if alias is present assign, otherwise null will be passed through
memberTypeAlias = namedImport.get().getAlias();
}
return false;
}
}
}
return true;
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class ComposedMemberInfo method initMemberAggregate.
// ///////////////////////// Init Methods ///////////////////////////
private synchronized void initMemberAggregate() {
if (isInitialized)
return;
this.isSiblingMissing = siblings.contains(null);
MemberType lastMType = null;
for (Pair<TMember, RuleEnvironment> pair : siblings) {
if (pair == null)
continue;
this.isEmpty = false;
TMember member = pair.getKey();
RuleEnvironment G = pair.getValue();
lastMType = handleMemberTypes(lastMType, member);
handleReadOnlyField(member);
handleAccessibility(member);
handleTypeRefLists(member, G);
handleFParameters(member, G);
}
// init: fParameters
List<TypeRef> currVariadicAccumulated = new LinkedList<>();
for (ComposedFParInfo fpAggr : fParameters) {
initFParAggregate(fpAggr);
// handle: typeRefsVariadicAccumulated
currVariadicAccumulated.addAll(fpAggr.typeRefsVariadic);
fpAggr.typeRefsVariadicAccumulated.addAll(currVariadicAccumulated);
}
handleIsVariadicButLastFParIsDifferent();
handleValidationProblems();
this.isInitialized = true;
}
use of org.eclipse.n4js.ts.types.TMember 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.n4js.ts.types.TMember in project n4js by eclipse.
the class AbstractMemberScope method getSingleLocalElementByName.
@Override
protected IEObjectDescription getSingleLocalElementByName(QualifiedName name) {
if (name.getSegmentCount() != 1) {
return null;
}
final String nameAsString = name.getFirstSegment();
// both read/write required
if (ExpressionExtensions.isBothReadFromAndWrittenTo(context)) {
TMember reader = findMember(nameAsString, false, staticAccess);
TMember writer = findMember(nameAsString, true, staticAccess);
if (null == reader && null == writer) {
// will be caught as error "Could not resolve reference"
return null;
}
if (null == reader) {
return new UnsatisfiedRWAccessDescription(EObjectDescription.create(writer.getName(), writer), true);
}
if (null == writer) {
return new UnsatisfiedRWAccessDescription(EObjectDescription.create(reader.getName(), reader), false);
}
// pick arbitrarily the setter
return createSingleElementDescription(writer);
}
// either read or write requirement that moreover is satisfied
final boolean accessForWriteOperation = ExpressionExtensions.isLeftHandSide(context);
TMember existingMember = findMember(nameAsString, accessForWriteOperation, staticAccess);
if (existingMember != null) {
return createSingleElementDescription(existingMember);
}
// wrong read/write
existingMember = findMember(nameAsString, !accessForWriteOperation, staticAccess);
if (existingMember != null) {
// allowed special case: writing in the ctor to a final field that lacks init value
final boolean isAssOfFinalInCtor = N4JSASTUtils.isSemiLegalAssignmentToFinalFieldInCtor(context.eContainer(), existingMember);
final boolean isLegalAssOfFinalInCtor = isAssOfFinalInCtor && !((TField) existingMember).isHasExpression();
if (isLegalAssOfFinalInCtor) {
return createSingleElementDescription(existingMember);
}
// allowed special case: wrong read/write in a mode other than N4JS
if (jsVariantHelper.allowWrongReadWrite(context)) {
// cf. sec. 13.1
return createSingleElementDescription(existingMember);
}
return new WrongWriteAccessDescription(EObjectDescription.create(existingMember.getName(), existingMember), accessForWriteOperation, isAssOfFinalInCtor);
}
// wrong static / non-static
existingMember = findMember(nameAsString, accessForWriteOperation, !staticAccess);
if (existingMember == null) {
// if both read/write access and static access are wrong, we want to
// complain (only) about "wrong static access" -> so include this case here
existingMember = findMember(nameAsString, !accessForWriteOperation, !staticAccess);
}
if (existingMember != null) {
return new WrongStaticAccessDescription(EObjectDescription.create(existingMember.getName(), existingMember), staticAccess);
}
return null;
}
use of org.eclipse.n4js.ts.types.TMember in project n4js by eclipse.
the class AbstractMemberScope method getLocalElementsByEObject.
@Override
protected Iterable<IEObjectDescription> getLocalElementsByEObject(EObject object, URI uri) {
if (object instanceof TMember) {
final TMember tMember = (TMember) object;
final String name = tMember.getName();
final TMember existing = findMember(name, tMember.isWriteable(), staticAccess);
if (existing == object) {
return Collections.singletonList(EObjectDescription.create(existing.getName(), existing));
}
}
return Collections.emptyList();
}
Aggregations