Skip to content

Follow-up for fixing IDE/SourceKit tests after changes for [SE-0111] #4195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4253,6 +4253,9 @@ class VarDecl : public AbstractStorageDecl {
setType(Ty);
}

/// This is the type specified, including location information.
TypeLoc typeLoc;

public:
VarDecl(bool IsStatic, bool IsLet, SourceLoc NameLoc, Identifier Name,
Type Ty, DeclContext *DC)
Expand All @@ -4267,6 +4270,9 @@ class VarDecl : public AbstractStorageDecl {
bool isUserAccessible() const {
return VarDeclBits.IsUserAccessible;
}

TypeLoc &getTypeLoc() { return typeLoc; }
TypeLoc getTypeLoc() const { return typeLoc; }

/// Retrieve the source range of the variable type, or an invalid range if the
/// variable's type is not explicitly written in the source.
Expand Down Expand Up @@ -4398,9 +4404,6 @@ class ParamDecl : public VarDecl {
SourceLoc ArgumentNameLoc;
SourceLoc LetVarInOutLoc;

/// This is the type specified, including location information.
TypeLoc typeLoc;

/// The default value, if any, along with whether this is varargs.
llvm::PointerIntPair<ExprHandle *, 1, bool> DefaultValueAndIsVariadic;

Expand Down Expand Up @@ -4434,9 +4437,6 @@ class ParamDecl : public VarDecl {
SourceLoc getArgumentNameLoc() const { return ArgumentNameLoc; }

SourceLoc getLetVarInOutLoc() const { return LetVarInOutLoc; }

TypeLoc &getTypeLoc() { return typeLoc; }
TypeLoc getTypeLoc() const { return typeLoc; }

bool isTypeLocImplicit() const { return IsTypeLocImplicit; }
void setIsTypeLocImplicit(bool val) { IsTypeLocImplicit = val; }
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/PrintOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ struct PrintOptions {
result.AbstractAccessors = false;
result.PrintForSIL = true;
result.PrintInSILBody = true;
result.PreferTypeRepr = false;
return result;
}

Expand Down
21 changes: 18 additions & 3 deletions include/swift/AST/TypeRepr.h
Original file line number Diff line number Diff line change
Expand Up @@ -580,32 +580,47 @@ class TupleTypeRepr : public TypeRepr {
friend class TypeRepr;
};

/// \brief A named element of a tuple type.
/// \brief A named element of a tuple type or a named parameter of a function
/// type.
/// \code
/// (x: Foo = 0)
/// (x: Foo)
/// (_ x: Foo) -> ()
/// \endcode
class NamedTypeRepr : public TypeRepr {
Identifier Id;
TypeRepr *Ty;
SourceLoc IdLoc;
SourceLoc UnderscoreLoc;

public:
/// Used for a named element of a tuple type.
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc)
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc) {
}
/// Used for a named parameter of a function type.
NamedTypeRepr(Identifier Id, TypeRepr *Ty, SourceLoc IdLoc,
SourceLoc underscoreLoc)
: TypeRepr(TypeReprKind::Named), Id(Id), Ty(Ty), IdLoc(IdLoc),
UnderscoreLoc(underscoreLoc) {
}

bool hasName() const { return !Id.empty(); }
Identifier getName() const { return Id; }
TypeRepr *getTypeRepr() const { return Ty; }
SourceLoc getNameLoc() const { return IdLoc; }
SourceLoc getUnderscoreLoc() const { return UnderscoreLoc; }

bool isNamedParameter() const { return UnderscoreLoc.isValid(); }

static bool classof(const TypeRepr *T) {
return T->getKind() == TypeReprKind::Named;
}
static bool classof(const NamedTypeRepr *T) { return true; }

private:
SourceLoc getStartLocImpl() const { return IdLoc; }
SourceLoc getStartLocImpl() const {
return UnderscoreLoc.isValid() ? UnderscoreLoc : IdLoc;
}
SourceLoc getEndLocImpl() const { return Ty->getEndLoc(); }
void printImpl(ASTPrinter &Printer, const PrintOptions &Opts) const;
friend class TypeRepr;
Expand Down
34 changes: 26 additions & 8 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2516,8 +2516,10 @@ void PrintAST::visitVarDecl(VarDecl *decl) {
});
if (decl->hasType()) {
Printer << ": ";
// Use the non-repr external type, but reuse the TypeLoc printing code.
printTypeLoc(TypeLoc::withoutLoc(decl->getType()));
auto tyLoc = decl->getTypeLoc();
if (!tyLoc.getTypeRepr())
tyLoc = TypeLoc::withoutLoc(decl->getType());
printTypeLoc(tyLoc);
}

printAccessors(decl);
Expand Down Expand Up @@ -2777,10 +2779,19 @@ void PrintAST::visitFuncDecl(FuncDecl *decl) {

Type ResultTy = decl->getResultType();
if (ResultTy && !ResultTy->isVoid()) {
TypeLoc ResultTyLoc = decl->getBodyResultTypeLoc();
if (!ResultTyLoc.getTypeRepr())
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
// FIXME: Hacky way to workaround the fact that 'Self' as return
// TypeRepr is not getting 'typechecked'. See
// \c resolveTopLevelIdentTypeComponent function in TypeCheckType.cpp.
if (auto *simId = dyn_cast_or_null<SimpleIdentTypeRepr>(ResultTyLoc.getTypeRepr())) {
if (simId->getIdentifier().str() == "Self")
ResultTyLoc = TypeLoc::withoutLoc(ResultTy);
}
Printer << " -> ";
// Use the non-repr external type, but reuse the TypeLoc printing code.
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
printTypeLoc(TypeLoc::withoutLoc(ResultTy));
printTypeLoc(ResultTyLoc);
Printer.printStructurePost(PrintStructureKind::FunctionReturnType);
}
}
Expand Down Expand Up @@ -3233,6 +3244,9 @@ void Decl::print(raw_ostream &os) const {
options.FunctionDefinitions = true;
options.TypeDefinitions = true;
options.VarInitializers = true;
// FIXME: Move all places where SIL printing is happening to explicit options.
// For example, see \c ProjectionPath::print.
options.PreferTypeRepr = false;

print(os, options);
}
Expand Down Expand Up @@ -3743,10 +3757,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
if (Options.SkipAttributes)
return;

if (info.isAutoClosure())
Printer << "@autoclosure ";
if (inParameterPrinting && !info.isNoEscape())
Printer << "@escaping ";
if (info.isAutoClosure()) {
Printer.printAttrName("@autoclosure");
Printer << " ";
}
if (inParameterPrinting && !info.isNoEscape()) {
Printer.printAttrName("@escaping");
Printer << " ";
}

if (Options.PrintFunctionRepresentationAttrs) {
// TODO: coalesce into a single convention attribute.
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3722,10 +3722,10 @@ ParamDecl::ParamDecl(ParamDecl *PD)
ArgumentName(PD->getArgumentName()),
ArgumentNameLoc(PD->getArgumentNameLoc()),
LetVarInOutLoc(PD->getLetVarInOutLoc()),
typeLoc(PD->getTypeLoc()),
DefaultValueAndIsVariadic(PD->DefaultValueAndIsVariadic),
IsTypeLocImplicit(PD->IsTypeLocImplicit),
defaultArgumentKind(PD->defaultArgumentKind) {
typeLoc = PD->getTypeLoc();
}


Expand Down
39 changes: 31 additions & 8 deletions lib/AST/TypeRepr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ TypeRepr *CloneVisitor::visitTupleTypeRepr(TupleTypeRepr *T) {

TypeRepr *CloneVisitor::visitNamedTypeRepr(NamedTypeRepr *T) {
return new (Ctx) NamedTypeRepr(T->getName(), visit(T->getTypeRepr()),
T->getNameLoc());
T->getNameLoc(), T->getUnderscoreLoc());
}

TypeRepr *CloneVisitor::visitProtocolCompositionTypeRepr(
Expand Down Expand Up @@ -276,13 +276,26 @@ void AttributedTypeRepr::printAttrs(llvm::raw_ostream &OS) const {
void AttributedTypeRepr::printAttrs(ASTPrinter &Printer) const {
const TypeAttributes &Attrs = getAttrs();

if (Attrs.has(TAK_autoclosure)) Printer << "@autoclosure ";
if (Attrs.has(TAK_escaping)) Printer << "@escaping ";
if (Attrs.has(TAK_autoclosure)) {
Printer.printAttrName("@autoclosure");
Printer << " ";
}
if (Attrs.has(TAK_escaping)) {
Printer.printAttrName("@escaping");
Printer << " ";
}

if (Attrs.has(TAK_thin)) Printer << "@thin ";
if (Attrs.has(TAK_thick)) Printer << "@thick ";
if (Attrs.has(TAK_thin)) {
Printer.printAttrName("@thin");
Printer << " ";
}
if (Attrs.has(TAK_thick)) {
Printer.printAttrName("@thick");
Printer << " ";
}
if (Attrs.convention.hasValue()) {
Printer << "@convention(" << Attrs.convention.getValue() << ") ";
Printer.printAttrName("@convention");
Printer << "(" << Attrs.convention.getValue() << ") ";
}
}

Expand Down Expand Up @@ -411,9 +424,19 @@ void TupleTypeRepr::printImpl(ASTPrinter &Printer,

void NamedTypeRepr::printImpl(ASTPrinter &Printer,
const PrintOptions &Opts) const {
if (!Id.empty()) {
Printer.printName(Id, PrintNameContext::TupleElement);
if (isNamedParameter()) {
// Printing empty Identifier is same as printing '_'.
Printer.printName(Identifier(), PrintNameContext::FunctionParameterExternal);
if (!Id.empty()) {
Printer << " ";
Printer.printName(Id, PrintNameContext::FunctionParameterLocal);
}
Printer << ": ";
} else {
if (!Id.empty()) {
Printer.printName(Id, PrintNameContext::TupleElement);
Printer << ": ";
}
}
printTypeRepr(Ty, Printer, Opts);
}
Expand Down
15 changes: 10 additions & 5 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2225,8 +2225,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
Builder.addComma();
if (BodyParams) {
// If we have a local name for the parameter, pass in that as well.
auto name = BodyParams->get(i)->getName();
Builder.addCallParameter(Name, name, ParamType, TupleElt.isVararg(),
auto argName = BodyParams->get(i)->getArgumentName();
auto bodyName = BodyParams->get(i)->getName();
Builder.addCallParameter(argName, bodyName, ParamType, TupleElt.isVararg(),
true);
} else {
Builder.addCallParameter(Name, ParamType, TupleElt.isVararg(), true);
Expand All @@ -2244,8 +2245,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {

modifiedBuilder = true;
if (BodyParams) {
auto name = BodyParams->get(0)->getName();
Builder.addCallParameter(Identifier(), name, T,
auto argName = BodyParams->get(0)->getArgumentName();
auto bodyName = BodyParams->get(0)->getName();
Builder.addCallParameter(argName, bodyName, T,
/*IsVarArg*/false, true);
} else
Builder.addCallParameter(Identifier(), T, /*IsVarArg*/false, true);
Expand Down Expand Up @@ -2319,7 +2321,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {

void addFunctionCallPattern(const AnyFunctionType *AFT,
const AbstractFunctionDecl *AFD = nullptr) {
foundFunction(AFT);
if (AFD)
foundFunction(AFD);
else
foundFunction(AFT);

// Add the pattern, possibly including any default arguments.
auto addPattern = [&](bool includeDefaultArgs = true) {
Expand Down
6 changes: 6 additions & 0 deletions lib/Parse/ParseType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,12 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
else
diag.fixItReplace(SourceRange(firstNameLoc), "_");
}

if (firstNameLoc.isValid() || secondNameLoc.isValid()) {
// Form the named parameter type representation.
ElementsR[i] = new (Context) NamedTypeRepr(secondName, ElementsR[i],
secondNameLoc, firstNameLoc);
}
}
}

Expand Down
29 changes: 29 additions & 0 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,35 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
auto topLocator = cs.getConstraintLocator(semanticExpr);
referencedDecl = solution.resolveLocatorToDecl(topLocator);

if (!referencedDecl.getDecl()) {
// Do another check in case we have a curried call from binding a function
// reference to a variable, for example:
//
// class C {
// func instanceFunc(p1: Int, p2: Int) {}
// }
// func t(c: C) {
// C.instanceFunc(c)#^COMPLETE^#
// }
//
// We need to get the referenced function so we can complete the argument
// labels. (Note that the requirement to have labels in the curried call
// seems inconsistent with the removal of labels from function types.
// If this changes the following code could be removed).
if (auto *CE = dyn_cast<CallExpr>(semanticExpr)) {
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(CE->getFn())) {
if (isa<TypeExpr>(UDE->getBase())) {
auto udeLocator = cs.getConstraintLocator(UDE);
auto udeRefDecl = solution.resolveLocatorToDecl(udeLocator);
if (auto *FD = dyn_cast_or_null<FuncDecl>(udeRefDecl.getDecl())) {
if (FD->isInstanceMember())
referencedDecl = udeRefDecl;
}
}
}
}
}

// Recover the original type if needed.
recoverOriginalType();
return exprType;
Expand Down
14 changes: 11 additions & 3 deletions lib/Sema/TypeCheckPattern.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,8 @@ bool TypeChecker::typeCheckPattern(Pattern *P, DeclContext *dc,
bool hadError = validateTypedPattern(*this, dc, TP, options, resolver);
Pattern *subPattern = TP->getSubPattern();
if (coercePatternToType(subPattern, dc, P->getType(),
options|TR_FromNonInferredPattern, resolver))
options|TR_FromNonInferredPattern, resolver,
TP->getTypeLoc()))
hadError = true;
else {
TP->setSubPattern(subPattern);
Expand Down Expand Up @@ -994,7 +995,12 @@ static bool coercePatternViaConditionalDowncast(TypeChecker &tc,
/// Perform top-down type coercion on the given pattern.
bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
TypeResolutionOptions options,
GenericTypeResolver *resolver) {
GenericTypeResolver *resolver,
TypeLoc tyLoc) {
if (tyLoc.isNull()) {
tyLoc = TypeLoc::withoutLoc(type);
}

TypeResolutionOptions subOptions = options - TR_EnumPatternPayload;
switch (P->getKind()) {
// For parens and vars, just set the type annotation and propagate inwards.
Expand Down Expand Up @@ -1088,7 +1094,9 @@ bool TypeChecker::coercePatternToType(Pattern *&P, DeclContext *dc, Type type,
else if (!var->isInvalid())
type = var->getType();
P->setType(type);

var->getTypeLoc() = tyLoc;
var->getTypeLoc().setType(var->getType());

// If we are inferring a variable to have type AnyObject.Type,
// "()", or optional thereof, emit a diagnostic. In the first 2 cases, the
// coder probably forgot a cast and expected a concrete type. In the later
Expand Down
14 changes: 11 additions & 3 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,11 @@ resolveTopLevelIdentTypeComponent(TypeChecker &TC, DeclContext *DC,
comp->getIdentifier() == TC.Context.Id_Self) {
auto func = cast<FuncDecl>(DC);
assert(func->hasDynamicSelf() && "Not marked as having dynamic Self?");


// FIXME: The passed-in TypeRepr should get 'typechecked' as well.
// The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl
// while the 'Self' type is more than just a reference to a TypeDecl.

return func->getDynamicSelf();
}

Expand Down Expand Up @@ -2427,13 +2431,17 @@ Type TypeResolver::resolveTupleType(TupleTypeRepr *repr,
elementOptions |= TR_FunctionInput;

for (auto tyR : repr->getElements()) {
if (NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR)) {
NamedTypeRepr *namedTyR = dyn_cast<NamedTypeRepr>(tyR);
if (namedTyR && !(options & TR_ImmediateFunctionInput)) {
Type ty = resolveType(namedTyR->getTypeRepr(), elementOptions);
if (!ty || ty->is<ErrorType>()) return ty;

elements.push_back(TupleTypeElt(ty, namedTyR->getName()));
} else {
Type ty = resolveType(tyR, elementOptions);
// FIXME: Preserve and serialize parameter names in function types, maybe
// with a new sugar type.
Type ty = resolveType(namedTyR ? namedTyR->getTypeRepr() : tyR,
elementOptions);
if (!ty || ty->is<ErrorType>()) return ty;

elements.push_back(TupleTypeElt(ty));
Expand Down
Loading