/** * Creates a list of collection type references from the element types of a collection literal. */ protected List<LightweightTypeReference> computeCollectionTypeCandidates(XCollectionLiteral literal, JvmGenericType collectionType, LightweightTypeReference elementTypeExpectation, ITypeComputationState state) { List<XExpression> elements = literal.getElements(); if(!elements.isEmpty()) { List<LightweightTypeReference> elementTypes = Lists.newArrayListWithCapacity(elements.size()); for(XExpression element: elements) { ITypeComputationResult elementType = computeTypes(element, elementTypeExpectation, state); LightweightTypeReference actualType = elementType.getActualExpressionType(); if(actualType != null && !actualType.isAny()) { ParameterizedTypeReference collectionTypeCandidate = state.getReferenceOwner().newParameterizedTypeReference(collectionType); collectionTypeCandidate.addTypeArgument(actualType.getWrapperTypeIfPrimitive()); elementTypes.add(collectionTypeCandidate); } } return elementTypes; } return Collections.emptyList(); }
protected void appendImmutableCollectionExpression(XCollectionLiteral literal, ITreeAppendable b, String collectionsMethod, Class<?> guavaHelper, String guavaHelperMethod) { LightweightTypeReference collectionElementType = getCollectionElementType(literal); b.append(Collections.class); b.append(".<").append(collectionElementType).append(">").append(collectionsMethod).append("("); b.append(guavaHelper).append(".<").append(collectionElementType).append(">").append(guavaHelperMethod).append("("); boolean isFirst = true; for(XExpression element: literal.getElements()) { if(!isFirst) b.append(", "); isFirst = false; if(element instanceof XNullLiteral) { b.append("(").append(collectionElementType).append(")"); } internalToJavaExpression(element, b); } b.append("))"); return; }
protected void _format(final XCollectionLiteral literal, @Extension final IFormattableDocument document) { final Procedure1<IHiddenRegionFormatter> _function = (IHiddenRegionFormatter it) -> { it.noSpace(); }; document.append(this.textRegionExtensions.regionFor(literal).keyword("#"), _function); ISemanticRegion _elvis = null; ISemanticRegion _keyword = this.textRegionExtensions.regionFor(literal).keyword("["); if (_keyword != null) { _elvis = _keyword; } else { ISemanticRegion _keyword_1 = this.textRegionExtensions.regionFor(literal).keyword("{"); _elvis = _keyword_1; } final ISemanticRegion open = _elvis; ISemanticRegion _elvis_1 = null; ISemanticRegion _keyword_2 = this.textRegionExtensions.regionFor(literal).keyword("]"); if (_keyword_2 != null) { _elvis_1 = _keyword_2; } else { ISemanticRegion _keyword_3 = this.textRegionExtensions.regionFor(literal).keyword("}"); _elvis_1 = _keyword_3; } final ISemanticRegion close = _elvis_1; this.formatCommaSeparatedList(literal.getElements(), open, close, document); }
protected void _format(final XCollectionLiteral literal, final FormattableDocument document) { final Procedure1<FormattingDataInit> _function = (FormattingDataInit it) -> { it.noSpace(); }; Function1<? super FormattableDocument, ? extends Iterable<FormattingData>> _append = this._formattingDataFactory.append(this._nodeModelAccess.nodeForKeyword(literal, "#"), _function); document.operator_add(_append); ILeafNode _elvis = null; ILeafNode _nodeForKeyword = this._nodeModelAccess.nodeForKeyword(literal, "["); if (_nodeForKeyword != null) { _elvis = _nodeForKeyword; } else { ILeafNode _nodeForKeyword_1 = this._nodeModelAccess.nodeForKeyword(literal, "{"); _elvis = _nodeForKeyword_1; } final ILeafNode open = _elvis; ILeafNode _elvis_1 = null; ILeafNode _nodeForKeyword_2 = this._nodeModelAccess.nodeForKeyword(literal, "]"); if (_nodeForKeyword_2 != null) { _elvis_1 = _nodeForKeyword_2; } else { ILeafNode _nodeForKeyword_3 = this._nodeModelAccess.nodeForKeyword(literal, "}"); _elvis_1 = _nodeForKeyword_3; } final ILeafNode close = _elvis_1; this.formatCommaSeparatedList(literal.getElements(), open, close, document); }
@Override protected void appendImmutableCollectionExpression(final XCollectionLiteral literal, final ITreeAppendable b, final String collectionsMethod, final Class<?> guavaHelper, final String guavaHelperMethod) { // This is a work-around for a bug in the xbase compiler, which always constructs empty list literals #[] as List<Object>, // which then cannot be assigned (without cast) to any typed list. Note that this is not a problem in check; it also occurs // in plain xtend. if (literal.getElements().isEmpty()) { JvmType collectionsClass = findKnownTopLevelType(Collections.class, literal); if (collectionsClass != null) { if (literal instanceof XListLiteral) { b.append(collectionsClass).append(".emptyList()"); return; } else if (literal instanceof XSetLiteral) { b.append(collectionsClass).append(".emptySet()"); return; } } } super.appendImmutableCollectionExpression(literal, b, collectionsMethod, guavaHelper, guavaHelperMethod); }
protected void setUnboundCollectionType(XCollectionLiteral literal, JvmGenericType collectionType, ITypeExpectation expectation, LightweightTypeReference elementTypeExpectation, ITypeComputationState state) { ParameterizedTypeReference unboundCollectionType = state.getReferenceOwner().newParameterizedTypeReference(collectionType); if (elementTypeExpectation != null) { unboundCollectionType.addTypeArgument(elementTypeExpectation); } else { UnboundTypeReference unboundTypeArgument = expectation.createUnboundTypeReference(literal, collectionType.getTypeParameters().get(0)); unboundCollectionType.addTypeArgument(unboundTypeArgument); } expectation.acceptActualType(unboundCollectionType, ConformanceFlags.UNCHECKED); }
/** * Process all children and assign an unknown type to the literal. */ protected void handleCollectionTypeNotAvailable(XCollectionLiteral literal, ITypeComputationState state, Class<?> clazz) { for(XExpression element: literal.getElements()) { state.withNonVoidExpectation().computeTypes(element); } state.acceptActualType(state.getReferenceOwner().newUnknownTypeReference(clazz.getName())); }
/** * @return whether the expression itself (not its children) possibly causes a side-effect */ public boolean hasSideEffects(XExpression expr) { if (expr instanceof XClosure || expr instanceof XStringLiteral || expr instanceof XTypeLiteral || expr instanceof XBooleanLiteral || expr instanceof XNumberLiteral || expr instanceof XNullLiteral || expr instanceof XAnnotation ) return false; if(expr instanceof XCollectionLiteral) { for(XExpression element: ((XCollectionLiteral)expr).getElements()) { if(hasSideEffects(element)) return true; } return false; } if (expr instanceof XAbstractFeatureCall) { XAbstractFeatureCall featureCall = (XAbstractFeatureCall) expr; return hasSideEffects(featureCall, true); } if (expr instanceof XConstructorCall) { XConstructorCall constrCall = (XConstructorCall) expr; return findPureAnnotation(constrCall.getConstructor()) == null; } return true; }
protected LightweightTypeReference getCollectionElementType(XCollectionLiteral literal) { LightweightTypeReference type = getLightweightType(literal); if (type == null) throw new IllegalStateException(); if(type.isArray()) { LightweightTypeReference result = type.getComponentType(); if (result == null) throw new IllegalStateException(); return result; } else if(type.isSubtypeOf(Collection.class) && type.hasTypeArguments()) { return type.getTypeArguments().get(0).getInvariantBoundSubstitute(); } return type.getOwner().newReferenceToObject(); }
protected void refineElementTypeExpectation(XCollectionLiteral literal, LightweightTypeReference expectation, ITypeComputationState state) { for (XExpression element : literal.getElements()) { state.refineExpectedType(element, expectation); } }
protected void _findImplicitReturns(final XCollectionLiteral expression, final ImplicitReturnFinder.Acceptor acceptor) { acceptor.accept(expression); }
public void findImplicitReturns(final XExpression expression, final ImplicitReturnFinder.Acceptor acceptor) { if (expression instanceof XAbstractFeatureCall) { _findImplicitReturns((XAbstractFeatureCall)expression, acceptor); return; } else if (expression instanceof XBlockExpression) { _findImplicitReturns((XBlockExpression)expression, acceptor); return; } else if (expression instanceof XBooleanLiteral) { _findImplicitReturns((XBooleanLiteral)expression, acceptor); return; } else if (expression instanceof XCastedExpression) { _findImplicitReturns((XCastedExpression)expression, acceptor); return; } else if (expression instanceof XClosure) { _findImplicitReturns((XClosure)expression, acceptor); return; } else if (expression instanceof XCollectionLiteral) { _findImplicitReturns((XCollectionLiteral)expression, acceptor); return; } else if (expression instanceof XConstructorCall) { _findImplicitReturns((XConstructorCall)expression, acceptor); return; } else if (expression instanceof XIfExpression) { _findImplicitReturns((XIfExpression)expression, acceptor); return; } else if (expression instanceof XInstanceOfExpression) { _findImplicitReturns((XInstanceOfExpression)expression, acceptor); return; } else if (expression instanceof XNullLiteral) { _findImplicitReturns((XNullLiteral)expression, acceptor); return; } else if (expression instanceof XNumberLiteral) { _findImplicitReturns((XNumberLiteral)expression, acceptor); return; } else if (expression instanceof XStringLiteral) { _findImplicitReturns((XStringLiteral)expression, acceptor); return; } else if (expression instanceof XSwitchExpression) { _findImplicitReturns((XSwitchExpression)expression, acceptor); return; } else if (expression instanceof XSynchronizedExpression) { _findImplicitReturns((XSynchronizedExpression)expression, acceptor); return; } else if (expression instanceof XTryCatchFinallyExpression) { _findImplicitReturns((XTryCatchFinallyExpression)expression, acceptor); return; } else if (expression instanceof XTypeLiteral) { _findImplicitReturns((XTypeLiteral)expression, acceptor); return; } else if (expression != null) { _findImplicitReturns(expression, acceptor); return; } else if (expression == null) { _findImplicitReturns((Void)null, acceptor); return; } else { throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object>asList(expression, acceptor).toString()); } }