Browse Source

Fix some parser issues.

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
136fd88f14
  1. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs
  2. 4
      ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs
  3. 6
      ICSharpCode.NRefactory/CSharp/Ast/AstLocation.cs
  4. 32
      ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs
  5. 2
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  6. 25
      README
  7. 33
      doc/TODO

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/DelegateDeclarationTests.cs

@ -7,7 +7,7 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
{ {
[TestFixture, Ignore("Delegate.Name is broken")] [TestFixture]
public class DelegateDeclarationTests public class DelegateDeclarationTests
{ {
[Test] [Test]
@ -26,7 +26,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
}}); }});
} }
[Test] [Test, Ignore("Generics not yet supported")]
public void GenericDelegateDeclarationTest() public void GenericDelegateDeclarationTest()
{ {
ParseUtilCSharp.AssertGlobal( ParseUtilCSharp.AssertGlobal(

4
ICSharpCode.NRefactory.Tests/CSharp/Parser/GeneralScope/TypeDeclarationTests.cs

@ -70,7 +70,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
Assert.AreEqual(Modifiers.Static, td.Modifiers); Assert.AreEqual(Modifiers.Static, td.Modifiers);
} }
[Test, Ignore("Generic classes not yet supported")] [Test, Ignore("Generics not yet supported")]
public void GenericClassTypeDeclarationTest() public void GenericClassTypeDeclarationTest()
{ {
ParseUtilCSharp.AssertGlobal( ParseUtilCSharp.AssertGlobal(
@ -83,7 +83,7 @@ namespace ICSharpCode.NRefactory.CSharp.Parser.GeneralScope
}); });
} }
[Test, Ignore("Generic classes not yet supported")] [Test, Ignore("Constraints not yet supported")]
public void GenericClassWithWhere() public void GenericClassWithWhere()
{ {
ParseUtilCSharp.AssertGlobal( ParseUtilCSharp.AssertGlobal(

6
ICSharpCode.NRefactory/CSharp/Ast/AstLocation.cs

@ -57,11 +57,11 @@ namespace ICSharpCode.NRefactory.CSharp
get { return column; } get { return column; }
} }
public override bool Equals (object other) public override bool Equals (object obj)
{ {
if (!(other is AstLocation)) if (!(obj is AstLocation))
return false; return false;
return (AstLocation)other == this; return (AstLocation)obj == this;
} }
public override int GetHashCode () public override int GetHashCode ()

32
ICSharpCode.NRefactory/CSharp/Parser/CSharpParser.cs

@ -225,7 +225,7 @@ namespace ICSharpCode.NRefactory.CSharp
var typeArgLocation = LocationsBag.GetLocations (c.MemberName); var typeArgLocation = LocationsBag.GetLocations (c.MemberName);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron);
// AddTypeArguments (newType, typeArgLocation, c.MemberName.TypeArguments); AddTypeParameters (newType, typeArgLocation, c.MemberName.TypeArguments);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron);
AddConstraints (newType, c); AddConstraints (newType, c);
@ -254,7 +254,7 @@ namespace ICSharpCode.NRefactory.CSharp
var typeArgLocation = LocationsBag.GetLocations (s.MemberName); var typeArgLocation = LocationsBag.GetLocations (s.MemberName);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron);
// AddTypeArguments (newType, typeArgLocation, s.MemberName.TypeArguments); AddTypeParameters (newType, typeArgLocation, s.MemberName.TypeArguments);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron);
AddConstraints (newType, s); AddConstraints (newType, s);
@ -283,7 +283,7 @@ namespace ICSharpCode.NRefactory.CSharp
var typeArgLocation = LocationsBag.GetLocations (i.MemberName); var typeArgLocation = LocationsBag.GetLocations (i.MemberName);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), MemberReferenceExpression.Roles.LChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), MemberReferenceExpression.Roles.LChevron);
// AddTypeArguments (newType, typeArgLocation, i.MemberName.TypeArguments); AddTypeParameters (newType, typeArgLocation, i.MemberName.TypeArguments);
if (typeArgLocation != null) if (typeArgLocation != null)
newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), MemberReferenceExpression.Roles.RChevron); newType.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), MemberReferenceExpression.Roles.RChevron);
AddConstraints (newType, i); AddConstraints (newType, i);
@ -307,12 +307,12 @@ namespace ICSharpCode.NRefactory.CSharp
if (location != null) if (location != null)
newDelegate.AddChild (new CSharpTokenNode (Convert (location[0]), "delegate".Length), TypeDeclaration.Roles.Keyword); newDelegate.AddChild (new CSharpTokenNode (Convert (location[0]), "delegate".Length), TypeDeclaration.Roles.Keyword);
newDelegate.AddChild (ConvertToType (d.ReturnType), AstNode.Roles.Type); newDelegate.AddChild (ConvertToType (d.ReturnType), AstNode.Roles.Type);
newDelegate.AddChild (new Identifier (d.Name, Convert (d.MemberName.Location)), AstNode.Roles.Identifier); newDelegate.AddChild (new Identifier (d.Basename, Convert (d.MemberName.Location)), AstNode.Roles.Identifier);
if (d.MemberName.TypeArguments != null) { if (d.MemberName.TypeArguments != null) {
var typeArgLocation = LocationsBag.GetLocations (d.MemberName); var typeArgLocation = LocationsBag.GetLocations (d.MemberName);
if (typeArgLocation != null) if (typeArgLocation != null)
newDelegate.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron); newDelegate.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), TypeDeclaration.Roles.LChevron);
// AddTypeArguments (newDelegate, typeArgLocation, d.MemberName.TypeArguments); AddTypeParameters (newDelegate, typeArgLocation, d.MemberName.TypeArguments);
if (typeArgLocation != null) if (typeArgLocation != null)
newDelegate.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron); newDelegate.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), TypeDeclaration.Roles.RChevron);
AddConstraints (newDelegate, d); AddConstraints (newDelegate, d);
@ -632,7 +632,7 @@ namespace ICSharpCode.NRefactory.CSharp
var typeArgLocation = LocationsBag.GetLocations (m.MemberName); var typeArgLocation = LocationsBag.GetLocations (m.MemberName);
if (typeArgLocation != null) if (typeArgLocation != null)
newMethod.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), MemberReferenceExpression.Roles.LChevron); newMethod.AddChild (new CSharpTokenNode (Convert (typeArgLocation[0]), 1), MemberReferenceExpression.Roles.LChevron);
// AddTypeArguments (newMethod, typeArgLocation, m.MemberName.TypeArguments); AddTypeParameters (newMethod, typeArgLocation, m.MemberName.TypeArguments);
if (typeArgLocation != null) if (typeArgLocation != null)
newMethod.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), MemberReferenceExpression.Roles.RChevron); newMethod.AddChild (new CSharpTokenNode (Convert (typeArgLocation[1]), 1), MemberReferenceExpression.Roles.RChevron);
@ -1835,17 +1835,22 @@ namespace ICSharpCode.NRefactory.CSharp
} }
} }
void AddTypeArguments (AstNode parent, LocationsBag.MemberLocations location, Mono.CSharp.TypeArguments typeArguments) void AddTypeParameters (AstNode parent, List<Location> location, Mono.CSharp.TypeArguments typeArguments)
{ {
if (typeArguments == null || typeArguments.IsEmpty) if (typeArguments == null || typeArguments.IsEmpty)
return; return;
for (int i = 0; i < typeArguments.Count; i++) { for (int i = 0; i < typeArguments.Count; i++) {
if (location != null && i > 0 && i - 1 < location.Count) if (location != null && i > 0 && i - 1 < location.Count)
parent.AddChild (new CSharpTokenNode (Convert (location[i - 1]), 1), InvocationExpression.Roles.Comma); parent.AddChild (new CSharpTokenNode (Convert (location[i - 1]), 1), InvocationExpression.Roles.Comma);
var arg = typeArguments.Args[i]; var arg = (TypeParameterName)typeArguments.Args[i];
if (arg == null) if (arg == null)
continue; continue;
parent.AddChild (ConvertToType (arg), InvocationExpression.Roles.TypeArgument); TypeParameterDeclaration tp = new TypeParameterDeclaration();
// TODO: attributes
if (arg.Variance != Variance.None)
throw new NotImplementedException(); // TODO: variance
tp.AddChild (new Identifier (arg.Name, Convert (arg.Location)), InvocationExpression.Roles.Identifier);
parent.AddChild (tp, InvocationExpression.Roles.TypeParameter);
} }
} }
@ -1871,11 +1876,12 @@ namespace ICSharpCode.NRefactory.CSharp
Constraints c = d.Constraints[i]; Constraints c = d.Constraints[i];
var location = LocationsBag.GetLocations (c); var location = LocationsBag.GetLocations (c);
var constraint = new Constraint (); var constraint = new Constraint ();
parent.AddChild (new CSharpTokenNode (Convert (location[0]), "where".Length), InvocationExpression.Roles.Keyword); constraint.AddChild (new CSharpTokenNode (Convert (location[0]), "where".Length), InvocationExpression.Roles.Keyword);
parent.AddChild (new Identifier (c.TypeParameter.Value, Convert (c.TypeParameter.Location)), InvocationExpression.Roles.Identifier); constraint.AddChild (new Identifier (c.TypeParameter.Value, Convert (c.TypeParameter.Location)), InvocationExpression.Roles.Identifier);
parent.AddChild (new CSharpTokenNode (Convert (location[1]), 1), Constraint.ColonRole); constraint.AddChild (new CSharpTokenNode (Convert (location[1]), 1), Constraint.ColonRole);
foreach (var expr in c.ConstraintExpressions) foreach (var expr in c.ConstraintExpressions)
parent.AddChild (ConvertToType (expr), Constraint.BaseTypeRole); constraint.AddChild (ConvertToType (expr), Constraint.BaseTypeRole);
parent.AddChild (constraint, AstNode.Roles.Constraint);
} }
} }

2
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -16,6 +16,8 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors> <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<NoWarn>1591,0618</NoWarn> <NoWarn>1591,0618</NoWarn>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
<RunCodeAnalysis>False</RunCodeAnalysis>
<CodeAnalysisRules>-Microsoft.Design#CA1026;-Microsoft.Security#CA2104</CodeAnalysisRules>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' "> <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>

25
README

@ -6,15 +6,22 @@ ICSharpCode.NRefactory.TypeSystem:
ICSharpCode.NRefactory.TypeSystem.Implementation: ICSharpCode.NRefactory.TypeSystem.Implementation:
Contains base classes that help implementing the type system interfaces. Contains base classes that help implementing the type system interfaces.
ICSharpCode.NRefactory.CSharp.Dom: ICSharpCode.NRefactory.CSharp.Ast:
Abstract Syntax Tree for C# Abstract Syntax Tree for C#
ICSharpCode.NRefactory.CSharp.Resolver: ICSharpCode.NRefactory.CSharp.Resolver:
Semantic analysis for C# Semantic analysis for C#
ICSharpCode.NRefactory.VB.Dom: ICSharpCode.NRefactory.Util:
Various helper classes.
ICSharpCode.NRefactory.VB.Dom: (in the separate ICSharpCode.NRefactory.VB assembly)
Abstract Syntax Tree for VB Abstract Syntax Tree for VB
Dependencies:
.NET 3.5 or .NET 4.0
Mono.Cecil 0.9.4
Null-Object pattern: Null-Object pattern:
The NRefactory library makes extensive use of the null object pattern. The NRefactory library makes extensive use of the null object pattern.
As a result, NullReferenceExceptions should be very rare when working with this library. As a result, NullReferenceExceptions should be very rare when working with this library.
@ -33,6 +40,10 @@ Null-Object pattern:
Also note that many resolver errors still have a meaningful type attached, this allows code Also note that many resolver errors still have a meaningful type attached, this allows code
completion to work in the presence of minor semantic errors. completion to work in the presence of minor semantic errors.
The C# AST makes use of special null nodes when accessing the getter of an AST property and no
child node with that role exists. Check the IsNull property to test whether a node is a null node.
Null nodes are not considered to be part of the AST (e.g. they don't have a parent).
FAQ: FAQ:
Q: What is the difference between types and type definitions? Q: What is the difference between types and type definitions?
@ -193,3 +204,13 @@ A: Because if you're asking whether a type is a struct, it's very likely that yo
If you really need to know, you can do If you really need to know, you can do
"type.GetDefinition() != null && type.GetDefinition().ClassType == WhatIWant" "type.GetDefinition() != null && type.GetDefinition().ClassType == WhatIWant"
yourself, but for the most part you should be fine with IsReferenceType, IsEnum and IsDelegate. yourself, but for the most part you should be fine with IsReferenceType, IsEnum and IsDelegate.
Q: What's the difference between the .NET 3.5 and .NET 4.0 versions?
A: As for visible API difference, not much. The .NET 4.0 build has some additional overloads for a few methods,
taking a System.Threading.CancellationToken to allow aborting a resolve run.
Internally, the .NET 4.0 version might be tiny bit more performant because it uses covariance for IEnumerable,
where the .NET 3.5 version has to allocate wrapper objects instead.
Both versions support loading assemblies of all .NET versions (1.0 to 4.0); and both support C# 4.0.

33
doc/TODO

@ -1,15 +1,24 @@
TypeSystem API: 
Parser:
- "extern alias" declarations
- "fixed int Field[100];" (fixed-size field declarations)
- support generics
- fix bugs (see currently ignored unit tests)
- put newlines into the AST
- add API to report errors
- allow multithreaded parsing
* Decide on the fate of ISupportsInterning (depends on how we're going to implement persistence) Resolver:
- Tons of unit tests for TypeSystemConvertVisitor
- Lambda expressions
- Handle attributes
- Port all #D resolver unit tests to NR
- Port all MD resolver unit tests to NR
* Try to build SharedTypes for void, int, etc. Features:
Take care of equality with the real System.Void, System.Int32 etc. - Code Completion
This seems to be hard/impossible to do, see comment in SharedTypes.cs. - Find References
I'm trying to work without those types now. - Extract Method refactoring
Note that having shared type *references* is possible (typeof(int).ToTypeReference()) For integration into SharpDevelop:
- Review NR and DOM changes done in the timeframe
* Implement the C# parser producing the DOM
* Implement ResolveVisitor
* Implement all the nasty context-dependent stuff (local variables, lambdas) that CSharpResolver doesn't do (yet)
Where should that go? I'd like to keep it out of CSharpResolver, that class is bloated enough with the pure logic.
Loading…
Cancel
Save