Skip to content

Commit

Permalink
AST CHANGE: NamespaceDeclarations now contain the namespace name as
Browse files Browse the repository at this point in the history
AstType - it's now more like the using declaration and makes renames
much easier.
  • Loading branch information
Mike Krüger committed Jun 14, 2013
1 parent bbcde1e commit dd43d89
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ namespace ICSharpCode.NRefactory.CSharp
public class NamespaceDeclaration : AstNode
{
public static readonly Role<AstNode> MemberRole = SyntaxTree.MemberRole;

public static readonly Role<AstType> NamespaceNameRole = new Role<AstType> ("NamespaceName");

public override NodeType NodeType {
get {
return NodeType.Unknown;
Expand All @@ -46,26 +47,21 @@ public override NodeType NodeType {
public CSharpTokenNode NamespaceToken {
get { return GetChildByRole (Roles.NamespaceKeyword); }
}


public AstType NamespaceName {
get { return GetChildByRole (NamespaceNameRole) ?? AstType.Null; }
set { SetChildByRole(NamespaceNameRole, value); }
}

public string Name {
get {
StringBuilder builder = new StringBuilder ();
foreach (Identifier identifier in GetChildrenByRole (Roles.Identifier)) {
if (builder.Length > 0)
builder.Append ('.');
builder.Append (identifier.Name);
}
return builder.ToString ();
return NamespaceName.ToString ();
}
set {
GetChildrenByRole(Roles.Identifier).ReplaceWith(value.Split('.').Select(ident => Identifier.Create (ident)));

}
}

public AstNodeCollection<Identifier> Identifiers {
get { return GetChildrenByRole (Roles.Identifier); }
}


/// <summary>
/// Gets the full namespace name (including any parent namespaces)
/// </summary>
Expand All @@ -77,6 +73,21 @@ public string FullName {
return Name;
}
}

public IEnumerable<string> Identifiers {
get {
var result = new Stack<string>();
AstType type = NamespaceName;
while (type is MemberType) {
var mt = (MemberType)type;
result.Push(mt.MemberName);
type = mt.Target;
}
if (type is SimpleType)
result.Push(((SimpleType)type).Identifier);
return result;
}
}

public CSharpTokenNode LBraceToken {
get { return GetChildByRole (Roles.LBrace); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,13 @@ IEnumerable<ICompletionData> HandleMemberReferenceCompletion(ExpressionResult ex
return null;
}
if (expr.Node is AstType) {

// check for namespace names
if (expr.Node.AncestorsAndSelf
.TakeWhile (n => n is AstType)
.Any (m => m.Role == NamespaceDeclaration.NamespaceNameRole))
return null;

// need to look at paren.parent because of "catch (<Type>.A" expression
if (expr.Node.Parent != null && expr.Node.Parent.Parent is CatchClause)
return HandleCatchClauseType(expr);
Expand Down Expand Up @@ -1229,7 +1236,7 @@ IEnumerable<ICompletionData> DefaultControlSpaceItems(ExpressionResult xp = null
// namespace name case
var ns = node as NamespaceDeclaration;
if (ns != null) {
var last = ns.Identifiers.LastOrDefault ();
var last = ns.NamespaceName;
if (last != null && location < last.EndLocation)
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ public void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{
StartNode(namespaceDeclaration);
WriteKeyword(Roles.NamespaceKeyword);
WriteQualifiedIdentifier(namespaceDeclaration.Identifiers);
namespaceDeclaration.NamespaceName.AcceptVisitor (this);
OpenBrace(policy.NamespaceBraceStyle);
foreach (var member in namespaceDeclaration.Members) {
member.AcceptVisitor(this);
Expand Down
29 changes: 9 additions & 20 deletions ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public override void Visit(ModuleContainer mc)
if (loc != null) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword);
}
ConvertNamespaceName(nspace.RealMemberName, nDecl);
nDecl.AddChild (ConvertNamespaceName(nspace.RealMemberName), NamespaceDeclaration.NamespaceNameRole);
if (loc != null && loc.Count > 1) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [1]), Roles.LBrace), Roles.LBrace);
}
Expand Down Expand Up @@ -380,10 +380,11 @@ public override void Visit(NamespaceContainer nspace)
if (loc != null) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword);
}
ConvertNamespaceName(nspace.RealMemberName, nDecl);
nDecl.AddChild (ConvertNamespaceName(nspace.RealMemberName), NamespaceDeclaration.NamespaceNameRole);
if (loc != null && loc.Count > 1) {
nDecl.AddChild(new CSharpTokenNode (Convert(loc [1]), Roles.LBrace), Roles.LBrace);
}

AddToNamespace(nDecl);
namespaceStack.Push(nDecl);
}
Expand Down Expand Up @@ -419,24 +420,12 @@ public override void Visit(NamespaceContainer nspace)
//
// }
//
void ConvertNamespaceName (MemberName memberName, NamespaceDeclaration namespaceDecl)
{
AstNode insertPos = null;
while (memberName != null) {
Identifier newIdent = Identifier.Create (memberName.Name, Convert (memberName.Location));
// HACK for a parser 'bug' - sometimes it generates "<invalid>" identifiers in namespace names (on certain bugs in the input file)
if (newIdent.Name != "<invalid>") {
namespaceDecl.InsertChildBefore (insertPos, newIdent, Roles.Identifier);
insertPos = newIdent;
var loc = LocationsBag.GetLocations (memberName);
if (loc != null) {
var dotToken = new CSharpTokenNode (Convert (loc[0]), Roles.Dot);
namespaceDecl.InsertChildBefore (insertPos, dotToken, Roles.Dot);
insertPos = dotToken;
}
}
memberName = memberName.Left;
}
AstType ConvertNamespaceName (MemberName memberName)
{
// HACK for a parser 'bug' - sometimes it generates "<invalid>" identifiers in namespace names (on certain bugs in the input file)
if (memberName.Name == "<invalid>")
return AstType.Null;
return ConvertToType(memberName);
}

public override void Visit (UsingNamespace un)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,14 @@ bool CheckNamedResolveResult(ResolveResult resolveResult, AstNode node, Affected
public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
{
base.VisitNamespaceDeclaration(namespaceDeclaration);
foreach (var id in namespaceDeclaration.Identifiers) {
CheckNamedResolveResult(null, namespaceDeclaration, AffectedEntity.Namespace, id, Modifiers.None);
var type = namespaceDeclaration.NamespaceName;
while (type is MemberType) {
var mt = (MemberType)type;
CheckNamedResolveResult(null, namespaceDeclaration, AffectedEntity.Namespace, mt.MemberNameToken, Modifiers.None);
type = mt.Target;
}
if (type is SimpleType)
CheckNamedResolveResult(null, namespaceDeclaration, AffectedEntity.Namespace, ((SimpleType)type).IdentifierToken, Modifiers.None);
}

Modifiers GetAccessibiltiy(EntityDeclaration decl, Modifiers defaultModifier)
Expand Down
6 changes: 3 additions & 3 deletions ICSharpCode.NRefactory.CSharp/Resolver/FindReferences.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1487,12 +1487,12 @@ internal override bool CanMatch(AstNode node)
return true;

var st = node as SimpleType;
if (st != null && st.Identifier == ns.Name)
return true;
if (st != null && st.Identifier == ns.Name)
return !st.AncestorsAndSelf.TakeWhile (n => n is AstType).Any (m => m.Role == NamespaceDeclaration.NamespaceNameRole);

var mt = node as MemberType;
if (mt != null && mt.MemberName == ns.Name)
return true;
return !mt.AncestorsAndSelf.TakeWhile (n => n is AstType).Any (m => m.Role == NamespaceDeclaration.NamespaceNameRole);

var identifer = node as IdentifierExpression;
if (identifer != null && identifer.Identifier == ns.Name)
Expand Down
4 changes: 2 additions & 2 deletions ICSharpCode.NRefactory.CSharp/Resolver/ResolveVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,12 +582,12 @@ ResolveResult IAstVisitor<ResolveResult>.VisitNamespaceDeclaration(NamespaceDecl
// For all but the last identifier:
UsingScope usingScope;
for (int i = 0; i < identifiers.Count - 1; i++) {
usingScope = new UsingScope(resolver.CurrentUsingScope.UnresolvedUsingScope, identifiers[i].Name);
usingScope = new UsingScope(resolver.CurrentUsingScope.UnresolvedUsingScope, identifiers[i]);
usingScope.Region = region;
PushUsingScope(usingScope);
}
// Last using scope:
usingScope = new UsingScope(resolver.CurrentUsingScope.UnresolvedUsingScope, identifiers.Last().Name);
usingScope = new UsingScope(resolver.CurrentUsingScope.UnresolvedUsingScope, identifiers.Last());
usingScope.Region = region;
var cv = new TypeSystemConvertVisitor(new CSharpUnresolvedFile(), usingScope);
ApplyVisitorToUsings(cv, namespaceDeclaration.Children);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ public override IUnresolvedEntity VisitNamespaceDeclaration(NamespaceDeclaration
{
DomRegion region = MakeRegion(namespaceDeclaration);
UsingScope previousUsingScope = usingScope;
foreach (Identifier ident in namespaceDeclaration.Identifiers) {
usingScope = new UsingScope(usingScope, ident.Name);
foreach (var ident in namespaceDeclaration.Identifiers) {
usingScope = new UsingScope(usingScope, ident);
usingScope.Region = region;
}
base.VisitNamespaceDeclaration(namespaceDeclaration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class A {}

Assert.AreEqual(new Role[] {
Roles.NamespaceKeyword,
Roles.Identifier,
NamespaceDeclaration.NamespaceNameRole,
Roles.LBrace,
Roles.PreProcessorDirective,
Roles.Comment,
Expand Down Expand Up @@ -83,7 +83,7 @@ void M() {}

Assert.AreEqual(new Role[] {
Roles.NamespaceKeyword,
Roles.Identifier,
NamespaceDeclaration.NamespaceNameRole,
Roles.LBrace,
Roles.PreProcessorDirective,
Roles.Comment,
Expand Down

0 comments on commit dd43d89

Please sign in to comment.