Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Issue 5481 - Support deprecated("message") #463

Merged
merged 1 commit into from

8 participants

Daniel Murphy Andrei Alexandrescu Andrej Mitrović Damian Ziemba David Nadlinger Walter Bright Brad Roberts Hara Kenji
Daniel Murphy
Collaborator

Add an optional message to deprecated.

Andrei Alexandrescu
Owner

This is a highly useful feature. I think we should merge it in and document it properly.

Andrej Mitrović
Collaborator

If the code to handle @disable is similar to @deprecated we could consider implementing messages for the former too in another pull request. http://d.puremagic.com/issues/show_bug.cgi?id=8728

Damian Ziemba

LGTM :+1:
Indeed it is very useful.

@yebblies what do you think about adding unittest for failure (without -d) and asserting about correct deprecated message being displayed?

@9rnsr @dawgfoto what you think?

Daniel Murphy
Collaborator

@nazriel Does the autotester support that? I don't remember any other tests that check the output from dmd.

David Nadlinger
Collaborator

@yebblies: Kenji recently added support for that, see e.g. 21f32ed.

Damian Ziemba

@yebblies won't https://github.com/D-Programming-Language/dmd/blob/master/test/d_do_test.d#L178 work?
I think I saw it somewhere in action for Error message enhancement PR

Edit: Ups, @klickverbot was faster. And yea, that's exactly the PR I was looking for.

Daniel Murphy
Collaborator

Awesome, done. The duplicated error messages are caused by a different bug.

Damian Ziemba

Umm, auto tester bug or I am blind? Because I see no difference between expected and actual output (for example here http://d.puremagic.com/test-results/pull.ghtml?runid=316239)

DOWN: so the latter. NOT good *grins

Daniel Murphy
Collaborator

Path separators

Walter Bright
Owner

LGTM

Brad Roberts
Owner

This pull needs a quick rebase due to a conflict introduced by pulling in the other deprecation refactoring pull.

Daniel Murphy
Collaborator

Done.

Damian Ziemba

@9rnsr @dawgfoto any final words? Can we merge it please?

Hara Kenji 9rnsr merged commit 2c4f26e into from
Hara Kenji
Collaborator

Merged!

Daniel Murphy
Collaborator

Thanks all!

Andrei Alexandrescu
Owner

Great work everyone. This solves a known, long-standing issue to which we had no good solution. A solution has been proposed, implemented, and reviewed by the community and got approved by the BDFL. Congratulations to all involved!

Brad Roberts braddr referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Daniel Murphy yebblies deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 7, 2012
  1. Daniel Murphy

    Fix Issue 5481 - Support deprecated("message")

    yebblies authored
    Add an optional message to deprecated.
This page is out of date. Refresh to see the latest.
38 src/attrib.c
View
@@ -542,6 +542,44 @@ void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
AttribDeclaration::toCBuffer(buf, hgs);
}
+/********************************* DeprecatedDeclaration ****************************/
+
+DeprecatedDeclaration::DeprecatedDeclaration(Expression *msg, Dsymbols *decl)
+ : StorageClassDeclaration(STCdeprecated, decl)
+{
+ this->msg = msg;
+}
+
+Dsymbol *DeprecatedDeclaration::syntaxCopy(Dsymbol *s)
+{
+ assert(!s);
+ return new DeprecatedDeclaration(msg->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
+}
+
+void DeprecatedDeclaration::setScope(Scope *sc)
+{
+ assert(msg);
+ char *depmsg = NULL;
+ StringExp *se = msg->toString();
+ if (se)
+ depmsg = (char *)se->string;
+ else
+ msg->error("string expected, not '%s'", msg->toChars());
+
+ Scope *scx = sc->push();
+ scx->depmsg = depmsg;
+ StorageClassDeclaration::setScope(scx);
+ scx->pop();
+}
+
+void DeprecatedDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+{
+ buf->writestring("deprecated(");
+ msg->toCBuffer(buf, hgs);
+ buf->writestring(") ");
+ AttribDeclaration::toCBuffer(buf, hgs);
+}
+
/********************************* LinkDeclaration ****************************/
LinkDeclaration::LinkDeclaration(enum LINK p, Dsymbols *decl)
12 src/attrib.h
View
@@ -61,7 +61,7 @@ struct AttribDeclaration : Dsymbol
void toObjFile(int multiobj); // compile to .obj file
};
-struct StorageClassDeclaration: AttribDeclaration
+struct StorageClassDeclaration : AttribDeclaration
{
StorageClass stc;
@@ -75,6 +75,16 @@ struct StorageClassDeclaration: AttribDeclaration
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
};
+struct DeprecatedDeclaration : StorageClassDeclaration
+{
+ Expression *msg;
+
+ DeprecatedDeclaration(Expression *msg, Dsymbols *decl);
+ Dsymbol *syntaxCopy(Dsymbol *s);
+ void setScope(Scope *sc);
+ void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+};
+
struct LinkDeclaration : AttribDeclaration
{
enum LINK linkage;
16 src/dsymbol.c
View
@@ -61,6 +61,7 @@ Dsymbol::Dsymbol(Identifier *ident)
this->comment = NULL;
this->scope = NULL;
this->errors = false;
+ this->depmsg = NULL;
}
int Dsymbol::equals(Object *o)
@@ -320,6 +321,8 @@ void Dsymbol::setScope(Scope *sc)
if (!sc->nofree)
sc->setNoFree(); // may need it even after semantic() finishes
scope = sc;
+ if (sc->depmsg)
+ depmsg = sc->depmsg;
}
void Dsymbol::importAll(Scope *sc)
@@ -651,7 +654,18 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
goto L1;
}
- deprecation(loc, "is deprecated");
+ char *message = NULL;
+ for (Dsymbol *p = this; p; p = p->parent)
+ {
+ message = p->depmsg;
+ if (message)
+ break;
+ }
+
+ if (message)
+ deprecation(loc, "is deprecated - %s", message);
+ else
+ deprecation(loc, "is deprecated");
}
L1:
1  src/dsymbol.h
View
@@ -122,6 +122,7 @@ struct Dsymbol : Object
Loc loc; // where defined
Scope *scope; // !=NULL means context to use for semantic()
bool errors; // this symbol failed to pass semantic()
+ char *depmsg; // customized deprecation message
Dsymbol();
Dsymbol(Identifier *);
23 src/parse.c
View
@@ -364,7 +364,6 @@ Dsymbols *Parser::parseDeclDefs(int once)
case TOKoverride: stc = STCoverride; goto Lstc;
case TOKabstract: stc = STCabstract; goto Lstc;
case TOKsynchronized: stc = STCsynchronized; goto Lstc;
- case TOKdeprecated: stc = STCdeprecated; goto Lstc;
#if DMDV2
case TOKnothrow: stc = STCnothrow; goto Lstc;
case TOKpure: stc = STCpure; goto Lstc;
@@ -411,13 +410,17 @@ Dsymbols *Parser::parseDeclDefs(int once)
stc = STCimmutable;
}
goto Lstc;
+ case TOKdeprecated:
+ if (peek(&token)->value == TOKlparen)
+ break;
+ stc = STCdeprecated;
+ goto Lstc;
case TOKfinal: stc = STCfinal; goto Lstc;
case TOKauto: stc = STCauto; goto Lstc;
case TOKscope: stc = STCscope; goto Lstc;
case TOKoverride: stc = STCoverride; goto Lstc;
case TOKabstract: stc = STCabstract; goto Lstc;
case TOKsynchronized: stc = STCsynchronized; goto Lstc;
- case TOKdeprecated: stc = STCdeprecated; goto Lstc;
case TOKnothrow: stc = STCnothrow; goto Lstc;
case TOKpure: stc = STCpure; goto Lstc;
case TOKref: stc = STCref; goto Lstc;
@@ -463,6 +466,22 @@ Dsymbols *Parser::parseDeclDefs(int once)
s = new StorageClassDeclaration(storageClass, a);
break;
+ case TOKdeprecated:
+ if (peek(&token)->value != TOKlparen)
+ {
+ stc = STCdeprecated;
+ goto Lstc;
+ }
+ {
+ nextToken();
+ check(TOKlparen);
+ Expression *e = parseAssignExp();
+ check(TOKrparen);
+ a = parseBlock();
+ s = new DeprecatedDeclaration(e, a);
+ break;
+ }
+
case TOKextern:
if (peek(&token)->value != TOKlparen)
{ stc = STCextern;
2  src/scope.c
View
@@ -67,6 +67,7 @@ Scope::Scope()
this->protection = PROTpublic;
this->explicitProtection = 0;
this->stc = 0;
+ this->depmsg = NULL;
this->offset = 0;
this->inunion = 0;
this->incontract = 0;
@@ -114,6 +115,7 @@ Scope::Scope(Scope *enclosing)
this->linkage = enclosing->linkage;
this->protection = enclosing->protection;
this->explicitProtection = enclosing->explicitProtection;
+ this->depmsg = enclosing->depmsg;
this->stc = enclosing->stc;
this->offset = 0;
this->inunion = enclosing->inunion;
1  src/scope.h
View
@@ -87,6 +87,7 @@ struct Scope
int explicitProtection; // set if in an explicit protection attribute
StorageClass stc; // storage class
+ char *depmsg; // customized deprecation message
unsigned flags;
#define SCOPEctor 1 // constructor type
32 test/compilable/depmsg.d
View
@@ -0,0 +1,32 @@
+// REQUIRED_ARGS: -d
+
+void main()
+{
+ class Inner
+ {
+ deprecated("With message!")
+ {
+ struct A { }
+ class B { }
+ interface C { }
+ union D { }
+ enum E { e };
+ //typedef int F;
+ alias int G;
+ static int H;
+ template I() { class I {} }
+ }
+ }
+ with(Inner)
+ {
+ A a;
+ B b;
+ C c;
+ D d;
+ E e;
+ //F f;
+ G g;
+ auto h = H;
+ I!() i;
+ }
+}
50 test/fail_compilation/depmsg.d
View
@@ -0,0 +1,50 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/depmsg.d(20): Deprecation: struct depmsg.main.Inner.A is deprecated - With message!
+fail_compilation/depmsg.d(20): Deprecation: struct depmsg.main.Inner.A is deprecated - With message!
+fail_compilation/depmsg.d(21): Deprecation: class depmsg.main.Inner.B is deprecated - With message!
+fail_compilation/depmsg.d(21): Deprecation: class depmsg.main.Inner.B is deprecated - With message!
+fail_compilation/depmsg.d(22): Deprecation: interface depmsg.main.Inner.C is deprecated - With message!
+fail_compilation/depmsg.d(22): Deprecation: interface depmsg.main.Inner.C is deprecated - With message!
+fail_compilation/depmsg.d(23): Deprecation: union depmsg.main.Inner.D is deprecated - With message!
+fail_compilation/depmsg.d(23): Deprecation: union depmsg.main.Inner.D is deprecated - With message!
+fail_compilation/depmsg.d(24): Deprecation: enum depmsg.main.Inner.E is deprecated - With message!
+fail_compilation/depmsg.d(24): Deprecation: enum depmsg.main.Inner.E is deprecated - With message!
+fail_compilation/depmsg.d(26): Deprecation: alias depmsg.main.Inner.G is deprecated - With message!
+fail_compilation/depmsg.d(27): Deprecation: variable depmsg.main.Inner.H is deprecated - With message!
+fail_compilation/depmsg.d(28): Deprecation: class depmsg.main.Inner.I!().I is deprecated - With message!
+---
+*/
+
+#line 1
+void main()
+{
+ class Inner
+ {
+ deprecated("With message!")
+ {
+ struct A { }
+ class B { }
+ interface C { }
+ union D { }
+ enum E { e };
+ //typedef int F;
+ alias int G;
+ static int H;
+ template I() { class I {} }
+ }
+ }
+ with(Inner)
+ {
+ A a;
+ B b;
+ C c;
+ D d;
+ E e;
+ //F f;
+ G g;
+ auto h = H;
+ I!() i;
+ }
+}
Something went wrong with that request. Please try again.