@@ -1984,141 +1984,6 @@ static void diagAvailability(TypeChecker &TC, const Expr *E,
1984
1984
const_cast <Expr*>(E)->walk (walker);
1985
1985
}
1986
1986
1987
- namespace {
1988
-
1989
- static ClosureExpr* getLastArgAsClosure (Expr* Arg) {
1990
- if (auto Paren = dyn_cast<ParenExpr>(Arg)) {
1991
-
1992
- // If the argument is paren expression, get the sub expression as closure.
1993
- if (!Paren->hasTrailingClosure ())
1994
- return dyn_cast_or_null<ClosureExpr>(Paren->getSubExpr ());
1995
- } else if (auto Tuple = dyn_cast<TupleExpr>(Arg)) {
1996
-
1997
- // If the argument is tuple expression, get the last expression in the tuple
1998
- // as closure.
1999
- if (!Tuple->hasTrailingClosure () && Tuple->getNumElements () > 0 )
2000
- return dyn_cast<ClosureExpr>(Tuple->getElement (Tuple->getNumElements () - 1 ));
2001
- }
2002
- return nullptr ;
2003
- }
2004
-
2005
- static bool areIdentifiersSame (Identifier Left, Identifier Right) {
2006
-
2007
- // If both are anonymous, returns true.
2008
- if (Left.empty () && Right.empty ())
2009
- return true ;
2010
-
2011
- // If one is anonymous and the other is not, returns false.
2012
- if (Left.empty () || Right.empty ())
2013
- return false ;
2014
-
2015
- // If both are not anonymous, compare the content.
2016
- return Left.str () == Right.str ();
2017
- }
2018
-
2019
- static bool willCauseAmbiguity (TypeChecker &TC, FuncDecl *SelectedFD) {
2020
- auto SelectedArgNames = SelectedFD->getEffectiveFullName ().getArgumentNames ();
2021
- auto SelectedArgNameExcludingClosure = SelectedArgNames.slice (0 ,
2022
- SelectedArgNames.size () - 1 );
2023
-
2024
- // Consider all decls from the same context with the simple
2025
- // identifier with SelectedFD.
2026
- for (ValueDecl *VD : TC.lookupUnqualified (SelectedFD->getDeclContext (),
2027
- SelectedFD->getName (), SourceLoc ())) {
2028
-
2029
- // Make sure the overload is not the selected function.
2030
- if (VD == SelectedFD)
2031
- continue ;
2032
-
2033
- // Make sure the overload is a function.
2034
- FuncDecl *FD = dyn_cast<FuncDecl>(VD);
2035
- if (!FD)
2036
- continue ;
2037
- auto ArgNames = FD->getEffectiveFullName ().getArgumentNames ();
2038
-
2039
- // If the overload requires more arguments than the selected; there are no
2040
- // chance of conflicts.
2041
- if (ArgNames.size () < SelectedArgNames.size ())
2042
- continue ;
2043
-
2044
- // Assuming there is a conflict.
2045
- bool Conflict = true ;
2046
- for (unsigned I = 0 ; I < SelectedArgNameExcludingClosure.size (); I ++) {
2047
- if (!areIdentifiersSame (ArgNames[I], SelectedArgNameExcludingClosure[I])) {
2048
- // Different argument names disprove our assumption.
2049
- Conflict = false ;
2050
- }
2051
- }
2052
- if (Conflict)
2053
- return true ;
2054
- }
2055
- return false ;
2056
- }
2057
-
2058
- static FuncDecl* digForFuncDecl (Expr *Fn) {
2059
- auto FD = dyn_cast_or_null<FuncDecl>(Fn->getReferencedDecl ().getDecl ());
2060
- if (FD)
2061
- return FD;
2062
- if (auto DE = dyn_cast<DotSyntaxCallExpr>(Fn)) {
2063
- return digForFuncDecl (DE->getFn ());
2064
- }
2065
- return nullptr ;
2066
- }
2067
-
2068
- static void
2069
- applyConvertToTrailingClosureFixit (TypeChecker &TC, SourceManager &SM,
2070
- ClosureExpr *Closure, Expr *Arg) {
2071
- if (auto *Paren = dyn_cast<ParenExpr>(Arg)) {
2072
- SourceRange LRemove (Paren->getLParenLoc (),
2073
- Paren->getLParenLoc ().getAdvancedLoc (1 ));
2074
- SourceRange RRemove (Paren->getRParenLoc (),
2075
- Paren->getRParenLoc ().getAdvancedLoc (1 ));
2076
-
2077
- // Remove the left and right paren.
2078
- TC.diagnose (Closure->getStartLoc (), diag::convert_to_trailing_closure).
2079
- fixItRemove (LRemove).fixItRemove (RRemove);
2080
- } else if (auto *Tuple = dyn_cast<TupleExpr>(Arg)) {
2081
- if (Tuple->getNumElements () > 1 ) {
2082
- SourceLoc ReplaceStart = Lexer::getLocForEndOfToken (SM,
2083
- Tuple->getElement (Tuple->getNumElements () - 2 )->getEndLoc ());
2084
- SourceRange Replace (ReplaceStart, Closure->getStartLoc ());
2085
- SourceRange ToRemove (Tuple->getRParenLoc (),
2086
- Tuple->getRParenLoc ().getAdvancedLoc (1 ));
2087
-
2088
- // Closing the tuple before the closure; and remove the right paren after the
2089
- // closure.
2090
- TC.diagnose (Closure->getStartLoc (), diag::convert_to_trailing_closure).
2091
- fixItReplace (Replace, " ) " ).fixItRemove (ToRemove);
2092
- } else {
2093
- SourceRange LRemove (Tuple->getLParenLoc (), Closure->getStartLoc ());
2094
- SourceRange RRemove (Lexer::getLocForEndOfToken (SM,Closure->getEndLoc ()),
2095
- Lexer::getLocForEndOfToken (SM, Tuple->getEndLoc ()));
2096
- TC.diagnose (Closure->getStartLoc (), diag::convert_to_trailing_closure).
2097
- fixItRemove (LRemove).fixItRemove (RRemove);
2098
- }
2099
- }
2100
- }
2101
- }
2102
-
2103
- static void diagConvertToTrailingClosure (TypeChecker &TC, const Expr *E,
2104
- DeclContext *DC) {
2105
- auto * AE = dyn_cast<ApplyExpr>(E);
2106
- if (!AE)
2107
- return ;
2108
-
2109
- auto * Closure = getLastArgAsClosure (AE->getArg ());
2110
- if (!Closure)
2111
- return ;
2112
- if (auto * FD = digForFuncDecl (AE->getFn ())) {
2113
- // Check the condition whether converting will cause ambiguity.
2114
- if (!willCauseAmbiguity (TC, FD))
2115
- // Without ambiguity, we can proceed to fix.
2116
- applyConvertToTrailingClosureFixit (TC, DC->getASTContext ().SourceMgr ,
2117
- Closure, AE->getArg ());
2118
- }
2119
- }
2120
-
2121
-
2122
1987
// ===----------------------------------------------------------------------===//
2123
1988
// Per func/init diagnostics
2124
1989
// ===----------------------------------------------------------------------===//
@@ -3345,7 +3210,6 @@ void swift::performSyntacticExprDiagnostics(TypeChecker &TC, const Expr *E,
3345
3210
diagRecursivePropertyAccess (TC, E, DC);
3346
3211
diagnoseImplicitSelfUseInClosure (TC, E, DC);
3347
3212
diagAvailability (TC, E, const_cast <DeclContext*>(DC));
3348
- diagConvertToTrailingClosure (TC, E, const_cast <DeclContext*>(DC));
3349
3213
if (TC.Context .LangOpts .EnableObjCInterop )
3350
3214
diagDeprecatedObjCSelectors (TC, DC, E);
3351
3215
}
0 commit comments