diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 166 | ||||
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-language-server-completion.cpp | 29 | ||||
| -rw-r--r-- | source/slang/slang-language-server-completion.h | 5 |
4 files changed, 101 insertions, 117 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index b249bb343..b730069b6 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -4136,12 +4136,6 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( IntegerLiteralValue baseElementRowCount, IntegerLiteralValue baseElementColCount) { - MatrixSwizzleExpr* swizExpr = m_astBuilder->create<MatrixSwizzleExpr>(); - swizExpr->loc = memberRefExpr->loc; - swizExpr->base = memberRefExpr->baseExpression; - swizExpr->memberOpLoc = memberRefExpr->memberOperatorLoc; - swizExpr->checked = true; - // We can have up to 4 swizzles of two elements each MatrixCoord elementCoords[4]; int elementCount = 0; @@ -4170,24 +4164,14 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( // Throw out swizzling with more than 4 output elements if (elementCount >= 4) { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } MatrixCoord elementCoord = {0, 0}; // Check for the preceding underscore if (*cursor++ != '_') { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } // Check for one or zero indexing @@ -4196,12 +4180,7 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( // Can't mix one and zero indexing if (zeroIndexOffset == 1) { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } zeroIndexOffset = 0; // Increment the index since we saw 'm' @@ -4212,12 +4191,7 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( // Can't mix one and zero indexing if (zeroIndexOffset == 0) { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } zeroIndexOffset = 1; } @@ -4229,13 +4203,7 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( if (ch < '0' || ch > '4') { - // An invalid character in the swizzle is an error - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } const int subIndex = ch - '0' - zeroIndexOffset; @@ -4255,12 +4223,7 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( // Account for off-by-one and reject 0 if oneIndexed if (subIndex >= elementLimit || subIndex < 0) { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } } // Check if we've seen this index before @@ -4275,6 +4238,12 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( elementCount++; } + MatrixSwizzleExpr* swizExpr = m_astBuilder->create<MatrixSwizzleExpr>(); + swizExpr->loc = memberRefExpr->loc; + swizExpr->base = memberRefExpr->baseExpression; + swizExpr->memberOpLoc = memberRefExpr->memberOperatorLoc; + swizExpr->checked = true; + // Store our list in the actual AST node for (int ee = 0; ee < elementCount; ++ee) { @@ -4324,11 +4293,7 @@ Expr* SemanticsVisitor::CheckMatrixSwizzleExpr( constantColCount->getValue()); } } - getSink()->diagnose( - memberRefExpr, - Diagnostics::unimplemented, - "swizzle on matrix of unknown size"); - return CreateErrorExpr(memberRefExpr); + return nullptr; } Expr* SemanticsVisitor::checkTupleSwizzleExpr(MemberExpr* memberExpr, TupleType* baseTupleType) @@ -4439,26 +4404,13 @@ Expr* SemanticsVisitor::CheckSwizzleExpr( Type* baseElementType, IntegerLiteralValue baseElementCount) { - SwizzleExpr* swizExpr = m_astBuilder->create<SwizzleExpr>(); - swizExpr->loc = memberRefExpr->loc; - swizExpr->base = memberRefExpr->baseExpression; - swizExpr->memberOpLoc = memberRefExpr->memberOperatorLoc; IntegerLiteralValue limitElement = baseElementCount; ShortList<uint32_t, 4> elementIndices; bool anyDuplicates = false; bool anyError = false; - if (memberRefExpr->name == getSession()->getCompletionRequestTokenName()) - { - auto& suggestions = getLinkage()->contentAssistInfo.completionSuggestions; - suggestions.clear(); - suggestions.scopeKind = CompletionSuggestions::ScopeKind::Swizzle; - suggestions.swizzleBaseType = - memberRefExpr->baseExpression ? memberRefExpr->baseExpression->type : nullptr; - suggestions.elementCount[0] = baseElementCount; - suggestions.elementCount[1] = 0; - } + auto swizzleText = getText(memberRefExpr->name); for (Index i = 0; i < swizzleText.getLength(); i++) @@ -4518,18 +4470,18 @@ Expr* SemanticsVisitor::CheckSwizzleExpr( elementIndices.add(elementIndex); } - swizExpr->elementIndices = _Move(elementIndices); - if (anyError) { - getSink()->diagnose( - swizExpr, - Diagnostics::invalidSwizzleExpr, - swizzleText, - baseElementType->toString()); - return CreateErrorExpr(memberRefExpr); + return nullptr; } - else if (swizExpr->elementIndices.getCount() == 1) + + SwizzleExpr* swizExpr = m_astBuilder->create<SwizzleExpr>(); + swizExpr->loc = memberRefExpr->loc; + swizExpr->base = memberRefExpr->baseExpression; + swizExpr->memberOpLoc = memberRefExpr->memberOperatorLoc; + swizExpr->elementIndices = _Move(elementIndices); + + if (swizExpr->elementIndices.getCount() == 1) { // single-component swizzle produces a scalar // @@ -4568,11 +4520,7 @@ Expr* SemanticsVisitor::CheckSwizzleExpr( } else { - getSink()->diagnose( - memberRefExpr, - Diagnostics::unimplemented, - "swizzle on vector of unknown size"); - return CreateErrorExpr(memberRefExpr); + return nullptr; } } @@ -4914,6 +4862,28 @@ Expr* SemanticsVisitor::checkGeneralMemberLookupExpr(MemberExpr* expr, Type* bas if (expr->name == getSession()->getCompletionRequestTokenName()) { suggestCompletionItems(CompletionSuggestions::ScopeKind::Member, lookupResult); + if (expr->baseExpression) + { + if (auto vectorType = as<VectorExpressionType>(expr->baseExpression->type)) + { + auto& suggestions = getLinkage()->contentAssistInfo.completionSuggestions; + suggestions.scopeKind = CompletionSuggestions::ScopeKind::Swizzle; + suggestions.elementCount[1] = 0; + suggestions.swizzleBaseType = vectorType; + if (auto elementCount = as<ConstantIntVal>(vectorType->getElementCount())) + suggestions.elementCount[0] = elementCount->getValue(); + else + suggestions.elementCount[0] = 1; + } + else if (auto scalarType = as<BasicExpressionType>(expr->baseExpression->type)) + { + auto& suggestions = getLinkage()->contentAssistInfo.completionSuggestions; + suggestions.scopeKind = CompletionSuggestions::ScopeKind::Swizzle; + suggestions.elementCount[1] = 0; + suggestions.elementCount[0] = 1; + suggestions.swizzleBaseType = scalarType; + } + } } return createLookupResultExpr(expr->name, lookupResult, expr->baseExpression, expr->loc, expr); } @@ -4942,34 +4912,36 @@ Expr* SemanticsExprVisitor::visitMemberExpr(MemberExpr* expr) if (auto modifiedType = as<ModifiedType>(baseType)) baseType = modifiedType->getBase(); - // Note: Checking for vector types before declaration-reference types, - // because vectors are also declaration reference types... + // Try handle swizzle-able types (scalar,vector,matrix) first. + // If checking as a swizzle failed for these types, + // we will fallback to normal member lookup. // - // Also note: the way this is done right now means that the ability - // to swizzle vectors interferes with any chance of looking up - // members via extension, for vector or scalar types. - // - if (auto baseMatrixType = as<MatrixExpressionType>(baseType)) + if (auto baseScalarType = as<BasicExpressionType>(baseType)) { - return CheckMatrixSwizzleExpr( - expr, - baseMatrixType->getElementType(), - baseMatrixType->getRowCount(), - baseMatrixType->getColumnCount()); + // Treat scalar like a 1-element vector when swizzling + auto swizzle = CheckSwizzleExpr(expr, baseScalarType, 1); + if (swizzle) + return swizzle; } - if (auto baseVecType = as<VectorExpressionType>(baseType)) + else if (auto baseVecType = as<VectorExpressionType>(baseType)) { - return CheckSwizzleExpr( - expr, - baseVecType->getElementType(), - baseVecType->getElementCount()); + auto swizzle = + CheckSwizzleExpr(expr, baseVecType->getElementType(), baseVecType->getElementCount()); + if (swizzle) + return swizzle; } - else if (auto baseScalarType = as<BasicExpressionType>(baseType)) + else if (auto baseMatrixType = as<MatrixExpressionType>(baseType)) { - // Treat scalar like a 1-element vector when swizzling - return CheckSwizzleExpr(expr, baseScalarType, 1); + auto swizzle = CheckMatrixSwizzleExpr( + expr, + baseMatrixType->getElementType(), + baseMatrixType->getRowCount(), + baseMatrixType->getColumnCount()); + if (swizzle) + return swizzle; } - else if (as<NamespaceType>(baseType)) + + if (as<NamespaceType>(baseType)) { return _lookupStaticMember(expr, expr->baseExpression); } diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index 5e55eb70f..21fc21df6 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -1316,15 +1316,17 @@ int SemanticsVisitor::CompareLookupResultItems( // Add a special case for constructors, where we prefer the one that is not synthesized, if (auto leftCtor = as<ConstructorDecl>(left.declRef.getDecl())) { - auto rightCtor = as<ConstructorDecl>(right.declRef.getDecl()); - bool leftIsSynthesized = - leftCtor->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault); - bool rightIsSynthesized = - rightCtor->containsFlavor(ConstructorDecl::ConstructorFlavor::SynthesizedDefault); - - if (leftIsSynthesized != rightIsSynthesized) + if (auto rightCtor = as<ConstructorDecl>(right.declRef.getDecl())) { - return int(leftIsSynthesized) - int(rightIsSynthesized); + bool leftIsSynthesized = leftCtor->containsFlavor( + ConstructorDecl::ConstructorFlavor::SynthesizedDefault); + bool rightIsSynthesized = rightCtor->containsFlavor( + ConstructorDecl::ConstructorFlavor::SynthesizedDefault); + + if (leftIsSynthesized != rightIsSynthesized) + { + return int(leftIsSynthesized) - int(rightIsSynthesized); + } } } diff --git a/source/slang/slang-language-server-completion.cpp b/source/slang/slang-language-server-completion.cpp index 77ed33002..1e5bae4b0 100644 --- a/source/slang/slang-language-server-completion.cpp +++ b/source/slang/slang-language-server-completion.cpp @@ -512,11 +512,14 @@ LanguageServerResult<CompletionResult> CompletionContext::tryCompleteMemberAndSy CompletionResult CompletionContext::collectMembersAndSymbols() { + List<LanguageServerProtocol::CompletionItem> result; + auto linkage = version->linkage; if (linkage->contentAssistInfo.completionSuggestions.scopeKind == CompletionSuggestions::ScopeKind::Swizzle) { - return createSwizzleCandidates( + createSwizzleCandidates( + result, linkage->contentAssistInfo.completionSuggestions.swizzleBaseType, linkage->contentAssistInfo.completionSuggestions.elementCount); } @@ -526,12 +529,12 @@ CompletionResult CompletionContext::collectMembersAndSymbols() { return createCapabilityCandidates(); } - List<LanguageServerProtocol::CompletionItem> result; bool useCommitChars = true; bool addKeywords = false; switch (linkage->contentAssistInfo.completionSuggestions.scopeKind) { case CompletionSuggestions::ScopeKind::Member: + case CompletionSuggestions::ScopeKind::Swizzle: useCommitChars = (commitCharacterBehavior == CommitCharacterBehavior::MembersOnly || commitCharacterBehavior == CommitCharacterBehavior::All); @@ -698,13 +701,12 @@ CompletionResult CompletionContext::createCapabilityCandidates() return result; } -CompletionResult CompletionContext::createSwizzleCandidates( +void CompletionContext::createSwizzleCandidates( + List<LanguageServerProtocol::CompletionItem>& result, Type* type, IntegerLiteralValue elementCount[2]) { - List<LanguageServerProtocol::CompletionItem> result; // Hard code members for vector and matrix types. - result.clear(); if (auto vectorType = as<VectorExpressionType>(type)) { const char* memberNames[4] = {"x", "y", "z", "w"}; @@ -724,6 +726,17 @@ CompletionResult CompletionContext::createSwizzleCandidates( result.add(item); } } + else if (auto scalarType = as<BasicExpressionType>(type)) + { + String typeStr; + typeStr = scalarType->toString(); + LanguageServerProtocol::CompletionItem item; + item.data = 0; + item.detail = typeStr; + item.kind = LanguageServerProtocol::kCompletionItemKindVariable; + item.label = "x"; + result.add(item); + } else if (auto matrixType = as<MatrixExpressionType>(type)) { Type* elementType = nullptr; @@ -769,12 +782,6 @@ CompletionResult CompletionContext::createSwizzleCandidates( result.add(item); } } - for (auto& item : result) - { - for (auto ch : getCommitChars()) - item.commitCharacters.add(ch); - } - return result; } LanguageServerProtocol::CompletionItem CompletionContext::generateGUIDCompletionItem() diff --git a/source/slang/slang-language-server-completion.h b/source/slang/slang-language-server-completion.h index 560702dea..fab1c8a75 100644 --- a/source/slang/slang-language-server-completion.h +++ b/source/slang/slang-language-server-completion.h @@ -55,7 +55,10 @@ struct CompletionContext CompletionResult collectMembersAndSymbols(); - CompletionResult createSwizzleCandidates(Type* baseType, IntegerLiteralValue elementCount[2]); + void createSwizzleCandidates( + List<LanguageServerProtocol::CompletionItem>& result, + Type* type, + IntegerLiteralValue elementCount[2]); CompletionResult createCapabilityCandidates(); CompletionResult collectAttributes(); LanguageServerProtocol::CompletionItem generateGUIDCompletionItem(); |
