Browse Source

Fixed SD2-460: Parse error (inner classes in generic types)

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@532 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
51ee84424e
  1. 7
      src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs
  2. 7
      src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs
  3. 114
      src/Libraries/NRefactory/Project/Src/Parser/AST/General/TypeReference.cs
  4. 2323
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs
  5. 80
      src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG
  6. 2437
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs
  7. 191
      src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG
  8. 6
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/AbstractASTVisitor.cs
  9. 1
      src/Libraries/NRefactory/Project/Src/Parser/Visitors/IASTVisitor.cs
  10. 85
      src/Libraries/NRefactory/Test/Parser/Expressions/FieldReferenceExpressionTests.cs
  11. 32
      src/Libraries/NRefactory/Test/Parser/Expressions/TypeOfExpressionTests.cs
  12. 36
      src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs
  13. 3
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs
  14. 16
      src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs
  15. 12
      src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionLoader.cs

7
src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs

@ -179,6 +179,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -179,6 +179,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null;
}
public object Visit(InnerClassTypeReference typeReference, object data)
{
nodeTracker.TrackedVisit(typeReference.BaseType, data);
outputFormatter.PrintToken(Tokens.Dot);
return Visit((TypeReference)typeReference, data); // call Visit(TypeReference, object)
}
#region Global scope
void VisitAttributes(ICollection attributes, object data)
{

7
src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs

@ -160,6 +160,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -160,6 +160,13 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null;
}
public object Visit(InnerClassTypeReference typeReference, object data)
{
nodeTracker.TrackedVisit(typeReference.BaseType, data);
outputFormatter.PrintToken(Tokens.Dot);
return Visit((TypeReference)typeReference, data); // call Visit(TypeReference, object)
}
#region Global scope
public object Visit(AttributeSection attributeSection, object data)
{

114
src/Libraries/NRefactory/Project/Src/Parser/AST/General/TypeReference.cs

@ -80,18 +80,30 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -80,18 +80,30 @@ namespace ICSharpCode.NRefactory.Parser.AST
return this.Clone();
}
public TypeReference Clone()
public virtual TypeReference Clone()
{
TypeReference c = new TypeReference(type, systemType);
c.pointerNestingLevel = pointerNestingLevel;
if (rankSpecifier != null) {
c.rankSpecifier = (int[])rankSpecifier.Clone();
CopyFields(this, c);
return c;
}
/// <summary>
/// Copies the pointerNestingLevel, RankSpecifier, GenericTypes and IsGlobal flag
/// from <paramref name="from"/> to <paramref name="to"/>.
/// </summary>
/// <remarks>
/// If <paramref name="to"/> already contains generics, the new generics are appended to the list.
/// </remarks>
protected static void CopyFields(TypeReference from, TypeReference to)
{
to.pointerNestingLevel = from.pointerNestingLevel;
if (from.rankSpecifier != null) {
to.rankSpecifier = (int[])from.rankSpecifier.Clone();
}
foreach (TypeReference r in genericTypes) {
c.genericTypes.Add(r.Clone());
foreach (TypeReference r in from.genericTypes) {
to.genericTypes.Add(r.Clone());
}
c.isGlobal = isGlobal;
return c;
to.isGlobal = from.isGlobal;
}
public string Type {
@ -147,6 +159,11 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -147,6 +159,11 @@ namespace ICSharpCode.NRefactory.Parser.AST
}
}
public static TypeReference CheckNull(TypeReference typeReference)
{
return typeReference ?? NullTypeReference.Instance;
}
public static NullTypeReference Null {
get {
return NullTypeReference.Instance;
@ -171,11 +188,6 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -171,11 +188,6 @@ namespace ICSharpCode.NRefactory.Parser.AST
}
}
public static TypeReference CheckNull(TypeReference typeReference)
{
return typeReference == null ? NullTypeReference.Instance : typeReference;
}
string GetSystemType(string type)
{
if (types.ContainsKey(type)) {
@ -236,7 +248,26 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -236,7 +248,26 @@ namespace ICSharpCode.NRefactory.Parser.AST
public override string ToString()
{
return String.Format("[TypeReference: Type={0}, PointerNestingLevel={1}, RankSpecifier={2}]", type, pointerNestingLevel, rankSpecifier);
StringBuilder b = new StringBuilder(type);
if (genericTypes != null && genericTypes.Count > 0) {
b.Append('<');
for (int i = 0; i < genericTypes.Count; i++) {
if (i > 0) b.Append(',');
b.Append(genericTypes[i].ToString());
}
b.Append('>');
}
if (pointerNestingLevel > 0) {
b.Append('*', pointerNestingLevel);
}
if (IsArrayType) {
foreach (int rank in rankSpecifier) {
b.Append('[');
b.Append(',', rank);
b.Append(']');
}
}
return b.ToString();
}
}
@ -263,4 +294,59 @@ namespace ICSharpCode.NRefactory.Parser.AST @@ -263,4 +294,59 @@ namespace ICSharpCode.NRefactory.Parser.AST
return String.Format("[NullTypeReference]");
}
}
/// <summary>
/// We need this special type reference for cases like
/// OuterClass(Of T1).InnerClass(Of T2) (in expression or type context)
/// or Dictionary(Of String, NamespaceStruct).KeyCollection (in type context, otherwise it's a
/// MemberReferenceExpression)
/// </summary>
public class InnerClassTypeReference: TypeReference
{
TypeReference baseType;
public TypeReference BaseType {
get {
return baseType;
}
}
public override TypeReference Clone()
{
InnerClassTypeReference c = new InnerClassTypeReference(baseType.Clone(), Type, GenericTypes);
CopyFields(this, c);
return c;
}
public InnerClassTypeReference(TypeReference outerClass, string innerType, List<TypeReference> innerGenericTypes)
: base(innerType, innerGenericTypes)
{
this.baseType = outerClass;
}
public override object AcceptVisitor(IASTVisitor visitor, object data)
{
return visitor.Visit(this, data);
}
/// <summary>
/// Creates a type reference where all type parameters are specified for the innermost class.
/// Namespace.OuterClass(of string).InnerClass(of integer).InnerInnerClass
/// becomes Namespace.OuterClass.InnerClass.InnerInnerClass(of string, integer)
/// </summary>
public TypeReference CombineToNormalTypeReference()
{
TypeReference tr = (baseType is InnerClassTypeReference)
? ((InnerClassTypeReference)baseType).CombineToNormalTypeReference()
: baseType.Clone();
CopyFields(this, tr);
tr.Type += "." + Type;
return tr;
}
public override string ToString()
{
return "[InnerClassTypeReference: (" + baseType.ToString() + ")." + base.ToString() + "]";
}
}
}

2323
src/Libraries/NRefactory/Project/Src/Parser/CSharp/Parser.cs

File diff suppressed because it is too large Load Diff

80
src/Libraries/NRefactory/Project/Src/Parser/CSharp/cs.ATG

@ -358,9 +358,14 @@ bool IsLocalVarDecl () { @@ -358,9 +358,14 @@ bool IsLocalVarDecl () {
StartPeek();
Token pt = la ;
string ignore;
return IsQualident(ref pt, out ignore) && SkipGeneric(ref pt) && SkipQuestionMark(ref pt) && IsPointerOrDims(ref pt) &&
pt.kind == Tokens.Identifier;
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
while (pt.kind == Tokens.Dot) {
pt = Peek();
if (!IsQualident(ref pt, out ignore)) return false;
if (!SkipGeneric(ref pt)) return false;
}
return SkipQuestionMark(ref pt) && IsPointerOrDims(ref pt) && pt.kind == Tokens.Identifier;
}
/* True if lookahead is type parameters (<...>) followed by the specified token */
@ -431,6 +436,7 @@ bool IsTypeReferenceExpression(Expression expr) @@ -431,6 +436,7 @@ bool IsTypeReferenceExpression(Expression expr)
if (expr is TypeReferenceExpression) return ((TypeReferenceExpression)expr).TypeReference.GenericTypes.Count == 0;
while (expr is FieldReferenceExpression) {
expr = ((FieldReferenceExpression)expr).TargetObject;
if (expr is TypeReferenceExpression) return true;
}
return expr is IdentifierExpression;
}
@ -442,19 +448,43 @@ TypeReferenceExpression GetTypeReferenceExpression(Expression expr, List<TypeRef @@ -442,19 +448,43 @@ TypeReferenceExpression GetTypeReferenceExpression(Expression expr, List<TypeRef
return new TypeReferenceExpression(new TypeReference(tre.TypeReference.Type, tre.TypeReference.PointerNestingLevel, tre.TypeReference.RankSpecifier, genericTypes));
}
StringBuilder b = new StringBuilder();
WriteFullTypeName(b, expr);
if (!WriteFullTypeName(b, expr)) {
// there is some TypeReferenceExpression hidden in the expression
while (expr is FieldReferenceExpression) {
expr = ((FieldReferenceExpression)expr).TargetObject;
}
tre = expr as TypeReferenceExpression;
if (tre != null) {
TypeReference typeRef = tre.TypeReference;
if (typeRef.GenericTypes.Count == 0) {
typeRef = typeRef.Clone();
typeRef.Type += "." + b.ToString();
typeRef.GenericTypes.AddRange(genericTypes);
} else {
typeRef = new InnerClassTypeReference(typeRef, b.ToString(), genericTypes);
}
return new TypeReferenceExpression(typeRef);
}
}
return new TypeReferenceExpression(new TypeReference(b.ToString(), 0, null, genericTypes));
}
void WriteFullTypeName(StringBuilder b, Expression expr)
/* Writes the type name represented through the expression into the string builder. */
/* Returns true when the expression was converted successfully, returns false when */
/* There was an unknown expression (e.g. TypeReferenceExpression) in it */
bool WriteFullTypeName(StringBuilder b, Expression expr)
{
FieldReferenceExpression fre = expr as FieldReferenceExpression;
if (fre != null) {
WriteFullTypeName(b, fre.TargetObject);
b.Append('.');
bool result = WriteFullTypeName(b, fre.TargetObject);
if (b.Length > 0) b.Append('.');
b.Append(fre.FieldName);
return result;
} else if (expr is IdentifierExpression) {
b.Append(((IdentifierExpression)expr).Identifier);
return true;
} else {
return false;
}
}
@ -2048,7 +2078,9 @@ PrimaryExpr<out Expression pexpr> @@ -2048,7 +2078,9 @@ PrimaryExpr<out Expression pexpr>
| "null" (.pexpr = new PrimitiveExpression(null, "null"); .) /* from literal token */
| Literal (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| IF (la.kind == Tokens.Identifier && Peek(1).kind == Tokens.DoubleColon)
TypeName<out type, false> (. pexpr = new TypeReferenceExpression(type); .)
ident (. type = new TypeReference(t.val); .)
"::" (. pexpr = new TypeReferenceExpression(type); .)
ident (. if (type.Type == "global") { type.IsGlobal = true; type.Type = t.val; } else type.Type += "." + t.val; .)
/*--- simple name: */
| ident (. pexpr = new IdentifierExpression(t.val); .)
/*--- parenthesized expression: */
@ -2147,14 +2179,15 @@ PrimaryExpr<out Expression pexpr> @@ -2147,14 +2179,15 @@ PrimaryExpr<out Expression pexpr>
| "." ident (. pexpr = new FieldReferenceExpression(pexpr, t.val);.)
/* member access on generic type */
| ( IF (IsGenericFollowedBy(Tokens.Dot) && IsTypeReferenceExpression(pexpr))
TypeArgumentList<out typeList> )
"." ident (. pexpr = new FieldReferenceExpression(GetTypeReferenceExpression(pexpr, typeList), t.val);.)
TypeArgumentList<out typeList, false> )
"." ident
(. pexpr = new FieldReferenceExpression(GetTypeReferenceExpression(pexpr, typeList), t.val);.)
/*--- invocation expression: */
| "(" (. ArrayList parameters = new ArrayList(); .)
[ Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
{ "," Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
} ] ")" (. pexpr = new InvocationExpression(pexpr, parameters); .)
| ( IF (IsGenericFollowedBy(Tokens.OpenParenthesis)) TypeArgumentList<out typeList> )
| ( IF (IsGenericFollowedBy(Tokens.OpenParenthesis)) TypeArgumentList<out typeList, false> )
"(" (. ArrayList parameters = new ArrayList(); .)
[ Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
{ "," Argument<out expr> (. if (expr != null) {parameters.Add(expr);} .)
@ -2329,14 +2362,7 @@ TypeName<out TypeReference typeRef, bool canBeUnbound> @@ -2329,14 +2362,7 @@ TypeName<out TypeReference typeRef, bool canBeUnbound>
"::"
]
Qualident<out qualident>
( IF (canBeUnbound && la.kind == Tokens.LessThan && (Peek(1).kind == Tokens.GreaterThan || Peek(1).kind == Tokens.Comma))
(. typeArguments = new List<TypeReference>(); .)
"<"
(. typeArguments.Add(NullTypeReference.Instance); .)
{ "," (. typeArguments.Add(NullTypeReference.Instance); .) }
">"
| [TypeArgumentList<out typeArguments>]
)
[TypeArgumentList<out typeArguments, canBeUnbound>]
(.
if (alias == null) {
typeRef = new TypeReference(qualident, typeArguments);
@ -2347,6 +2373,11 @@ TypeName<out TypeReference typeRef, bool canBeUnbound> @@ -2347,6 +2373,11 @@ TypeName<out TypeReference typeRef, bool canBeUnbound>
typeRef = new TypeReference(alias + "." + qualident, typeArguments);
}
.)
{ "." (. typeArguments = null; .)
Qualident<out qualident>
[TypeArgumentList<out typeArguments, canBeUnbound>]
(. typeRef = new InnerClassTypeReference(typeRef, qualident, typeArguments); .)
}
.
@ -2360,14 +2391,19 @@ NullableQuestionMark<ref TypeReference typeRef> @@ -2360,14 +2391,19 @@ NullableQuestionMark<ref TypeReference typeRef>
.)
.
TypeArgumentList<out List<TypeReference> types>
TypeArgumentList<out List<TypeReference> types, bool canBeUnbound>
(.
types = new List<TypeReference>();
TypeReference type = null;
.)
=
"<" Type<out type> (. types.Add(type); .)
{ "," Type<out type> (. types.Add(type); .) }
"<"
( IF (canBeUnbound && (la.kind == Tokens.GreaterThan || la.kind == Tokens.Comma))
(. types.Add(TypeReference.Null); .)
{ "," (. types.Add(TypeReference.Null); .) }
| Type<out type> (. types.Add(type); .)
{ "," Type<out type> (. types.Add(type); .) }
)
">"
.

2437
src/Libraries/NRefactory/Project/Src/Parser/VBNet/Parser.cs

File diff suppressed because it is too large Load Diff

191
src/Libraries/NRefactory/Project/Src/Parser/VBNet/VBNET.ATG

@ -200,6 +200,53 @@ bool IsMustOverride(Modifiers m) @@ -200,6 +200,53 @@ bool IsMustOverride(Modifiers m)
return m.Contains(Modifier.Abstract);
}
TypeReferenceExpression GetTypeReferenceExpression(Expression expr, List<TypeReference> genericTypes)
{
TypeReferenceExpression tre = expr as TypeReferenceExpression;
if (tre != null) {
return new TypeReferenceExpression(new TypeReference(tre.TypeReference.Type, tre.TypeReference.PointerNestingLevel, tre.TypeReference.RankSpecifier, genericTypes));
}
StringBuilder b = new StringBuilder();
if (!WriteFullTypeName(b, expr)) {
// there is some TypeReferenceExpression hidden in the expression
while (expr is FieldReferenceExpression) {
expr = ((FieldReferenceExpression)expr).TargetObject;
}
tre = expr as TypeReferenceExpression;
if (tre != null) {
TypeReference typeRef = tre.TypeReference;
if (typeRef.GenericTypes.Count == 0) {
typeRef = typeRef.Clone();
typeRef.Type += "." + b.ToString();
typeRef.GenericTypes.AddRange(genericTypes);
} else {
typeRef = new InnerClassTypeReference(typeRef, b.ToString(), genericTypes);
}
return new TypeReferenceExpression(typeRef);
}
}
return new TypeReferenceExpression(new TypeReference(b.ToString(), 0, null, genericTypes));
}
/* Writes the type name represented through the expression into the string builder. */
/* Returns true when the expression was converted successfully, returns false when */
/* There was an unknown expression (e.g. TypeReferenceExpression) in it */
bool WriteFullTypeName(StringBuilder b, Expression expr)
{
FieldReferenceExpression fre = expr as FieldReferenceExpression;
if (fre != null) {
bool result = WriteFullTypeName(b, fre.TargetObject);
if (b.Length > 0) b.Append('.');
b.Append(fre.FieldName);
return result;
} else if (expr is IdentifierExpression) {
b.Append(((IdentifierExpression)expr).Identifier);
return true;
} else {
return false;
}
}
/*
True, if lookahead is a local attribute target specifier,
i.e. one of "event", "return", "field", "method",
@ -1678,72 +1725,86 @@ AssignmentOperator<out AssignmentOperatorType op> @@ -1678,72 +1725,86 @@ AssignmentOperator<out AssignmentOperatorType op>
/* 11.4 */
SimpleExpr<out Expression pexpr>
(.
Expression expr;
TypeReference type = null;
string name = String.Empty;
pexpr = null;
.) =
(.
Expression expr;
TypeReference type = null;
string name = String.Empty;
pexpr = null;
.) =
(
(
/* 11.4.1 */
LiteralString (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralCharacter (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralSingle (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDouble (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralInteger (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDate (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDecimal (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralCharacter (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralSingle (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDouble (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralInteger (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDate (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
| LiteralDecimal (.pexpr = new PrimitiveExpression(t.literalValue, t.val); .)
/* True, False and Nothing are handled as literals in the spec */
| "True" (.pexpr = new PrimitiveExpression(true, "true"); .)
| "False" (.pexpr = new PrimitiveExpression(false, "false"); .)
| "Nothing" (.pexpr = new PrimitiveExpression(null, "null"); .)
| /* 11.4.2 */ "(" Expr<out expr> ")" (. pexpr = new ParenthesizedExpression(expr); .)
| /* 11.4.4 */ Identifier (. pexpr = new IdentifierExpression(t.val); .)
| (. string val = String.Empty; .) PrimitiveTypeName<out val>
| "True" (.pexpr = new PrimitiveExpression(true, "true"); .)
| "False" (.pexpr = new PrimitiveExpression(false, "false"); .)
| "Nothing" (.pexpr = new PrimitiveExpression(null, "null"); .)
| /* 11.4.2 */ "(" Expr<out expr> ")" (. pexpr = new ParenthesizedExpression(expr); .)
| /* 11.4.4 */ Identifier (. pexpr = new IdentifierExpression(t.val); .)
| (. string val = String.Empty; .)
PrimitiveTypeName<out val>
"." (. t.val = ""; .) Identifier (. pexpr = new FieldReferenceExpression(new TypeReferenceExpression(val), t.val); .)
| "Me" (. pexpr = new ThisReferenceExpression(); .)
| (. Expression retExpr = null; .)
( "MyBase" (. retExpr = new BaseReferenceExpression(); .)
| "MyClass" (. retExpr = new ClassReferenceExpression(); .)
)
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(retExpr, name); .)
| IF (la.kind == Tokens.Global) TypeName<out type> (. pexpr = new TypeReferenceExpression(type); .)
| ObjectCreateExpression<out expr> (. pexpr = expr; .)
| /* 11.11 */ ( "DirectCast" | "CType" ) "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new CastExpression(type, expr); .)
| /* 11.11 */ "TryCast" "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new BinaryOperatorExpression(expr, BinaryOperatorType.AsCast, new TypeReferenceExpression(type)); .)
| /* 11.11 */ CastTarget<out type> "(" Expr<out expr> ")" (. pexpr = new CastExpression(type, expr, true); .)
| /* 11.4.5 */ "AddressOf" Expr<out expr> (. pexpr = new AddressOfExpression(expr); .)
| /* 11.5.1 */ "GetType" "(" GetTypeTypeName<out type> ")" (. pexpr = new TypeOfExpression(type); .)
| /* 11.5.2 */ "TypeOf" SimpleExpr<out expr> "Is" TypeName<out type> (. pexpr = new TypeOfIsExpression(expr, type); .)
| "Me" (. pexpr = new ThisReferenceExpression(); .)
| (. Expression retExpr = null; .)
( "MyBase" (. retExpr = new BaseReferenceExpression(); .)
| "MyClass" (. retExpr = new ClassReferenceExpression(); .)
)
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(retExpr, name); .)
| "Global" "."
Identifier (. type = new TypeReference(t.val ?? ""); .)
/* fallback to "" is required if the token wasn't an identifier (->parser error but no exception) */
(. type.IsGlobal = true; .)
(. pexpr = new TypeReferenceExpression(type); .)
| ObjectCreateExpression<out expr> (. pexpr = expr; .)
| /* 11.11 */ ( "DirectCast" | "CType" ) "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new CastExpression(type, expr); .)
| /* 11.11 */ "TryCast" "(" Expr<out expr> "," TypeName<out type> ")" (. pexpr = new BinaryOperatorExpression(expr, BinaryOperatorType.AsCast, new TypeReferenceExpression(type)); .)
| /* 11.11 */ CastTarget<out type> "(" Expr<out expr> ")" (. pexpr = new CastExpression(type, expr, true); .)
| /* 11.4.5 */ "AddressOf" Expr<out expr> (. pexpr = new AddressOfExpression(expr); .)
| /* 11.5.1 */ "GetType" "(" GetTypeTypeName<out type> ")" (. pexpr = new TypeOfExpression(type); .)
| /* 11.5.2 */ "TypeOf" SimpleExpr<out expr> "Is" TypeName<out type> (. pexpr = new TypeOfIsExpression(expr, type); .)
)
{
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(pexpr, name); .)
| InvocationExpression<ref pexpr>
}
{ InvocationOrMemberReferenceExpression<ref pexpr> }
|
/* this form only occurs in with statements*/
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(pexpr, name);.)
{
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(pexpr, name); .)
| InvocationExpression<ref pexpr>
}
/* this form only occurs in WithStatements*/
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(pexpr, name);.)
{ InvocationOrMemberReferenceExpression<ref pexpr> }
)
.
InvocationOrMemberReferenceExpression<ref Expression pexpr>
(. string name; .)
=
"." IdentifierOrKeyword<out name> (. pexpr = new FieldReferenceExpression(pexpr, name); .)
| InvocationExpression<ref pexpr>
.
InvocationExpression<ref Expression pexpr>
(. List<TypeReference> typeParameters = new List<TypeReference>();
ArrayList parameters = null;
TypeReference type; .)
=
"(" (. Point start = t.Location; .)
[ "Of"
TypeName<out type> (. if (type != null) typeParameters.Add(type); .)
")" "("
]
ArgumentList<out parameters>
")"
(. pexpr = new InvocationExpression(pexpr, parameters, typeParameters); .)
( "Of"
TypeName<out type> (. if (type != null) typeParameters.Add(type); .)
")"
(
"." Identifier
(. pexpr = new FieldReferenceExpression(GetTypeReferenceExpression(pexpr, typeParameters), t.val); .)
| "("
ArgumentList<out parameters>
")"
(. pexpr = new InvocationExpression(pexpr, parameters, typeParameters); .)
)
| ArgumentList<out parameters>
")"
(. pexpr = new InvocationExpression(pexpr, parameters, typeParameters); .)
)
(. pexpr.StartLocation = start; pexpr.EndLocation = t.Location; .)
.
@ -1975,22 +2036,32 @@ NonArrayTypeName<out TypeReference typeref, bool canBeUnbound> @@ -1975,22 +2036,32 @@ NonArrayTypeName<out TypeReference typeref, bool canBeUnbound>
.) =
(
[ "Global" "." (. isGlobal = true; .) ]
Qualident<out name>
(. typeref = new TypeReference(name); typeref.IsGlobal = isGlobal; .)
[IF (la.kind == Tokens.OpenParenthesis && Peek(1).kind == Tokens.Of)
"(" "Of"
( IF (canBeUnbound && (la.kind == Tokens.CloseParenthesis || la.kind == Tokens.Comma))
(. typeref.GenericTypes.Add(NullTypeReference.Instance); .)
{ "," (. typeref.GenericTypes.Add(NullTypeReference.Instance); .) }
| TypeArgumentList<typeref.GenericTypes>
)
")"
]
QualIdentAndTypeArguments<out typeref, canBeUnbound>
(. typeref.IsGlobal = isGlobal; .)
{ "." (. TypeReference nestedTypeRef; .)
QualIdentAndTypeArguments<out nestedTypeRef, canBeUnbound>
(. typeref = new InnerClassTypeReference(typeref, nestedTypeRef.Type, nestedTypeRef.GenericTypes); .)
}
)
| "Object" (. typeref = new TypeReference("System.Object"); .)
| PrimitiveTypeName<out name> (. typeref = new TypeReference(name); .)
.
QualIdentAndTypeArguments<out TypeReference typeref, bool canBeUnbound>
(. string name; typeref = null; .)
=
Qualident<out name>
(. typeref = new TypeReference(name); .)
[IF (la.kind == Tokens.OpenParenthesis && Peek(1).kind == Tokens.Of)
"(" "Of"
( IF (canBeUnbound && (la.kind == Tokens.CloseParenthesis || la.kind == Tokens.Comma))
(. typeref.GenericTypes.Add(NullTypeReference.Instance); .)
{ "," (. typeref.GenericTypes.Add(NullTypeReference.Instance); .) }
| TypeArgumentList<typeref.GenericTypes>
)
")"
]
.
/* 7.9 */
ArrayNameModifier<out ArrayList arrayModifiers>

6
src/Libraries/NRefactory/Project/Src/Parser/Visitors/AbstractASTVisitor.cs

@ -47,6 +47,12 @@ namespace ICSharpCode.NRefactory.Parser @@ -47,6 +47,12 @@ namespace ICSharpCode.NRefactory.Parser
return data;
}
public virtual object Visit(InnerClassTypeReference innerClassTypeReference, object data)
{
Debug.Assert(innerClassTypeReference != null);
return data;
}
public virtual object Visit(AttributeSection attributeSection, object data)
{
Debug.Assert(attributeSection != null);

1
src/Libraries/NRefactory/Project/Src/Parser/Visitors/IASTVisitor.cs

@ -17,6 +17,7 @@ namespace ICSharpCode.NRefactory.Parser @@ -17,6 +17,7 @@ namespace ICSharpCode.NRefactory.Parser
object Visit(CompilationUnit compilationUnit, object data);
object Visit(TypeReference typeReference, object data);
object Visit(InnerClassTypeReference innerClassTypeReference, object data);
object Visit(AttributeSection attributeSection, object data);
object Visit(ICSharpCode.NRefactory.Parser.AST.Attribute attribute, object data);
object Visit(NamedArgumentExpression namedArgumentExpression, object data);

85
src/Libraries/NRefactory/Test/Parser/Expressions/FieldReferenceExpressionTests.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -49,6 +49,35 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -49,6 +49,35 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].SystemType);
}
[Test]
public void CSharpGlobalFullNamespaceGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilCSharp.ParseExpression("global::Namespace.Subnamespace.SomeClass<string>.myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.IsFalse(tr is InnerClassTypeReference);
Assert.AreEqual("Namespace.Subnamespace.SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].SystemType);
Assert.IsTrue(tr.IsGlobal);
}
[Test]
public void CSharpNestedGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilCSharp.ParseExpression("MyType<string>.InnerClass<int>.myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
InnerClassTypeReference ic = (InnerClassTypeReference)((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
#endregion
#region VB.NET
@ -60,6 +89,60 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -60,6 +89,60 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.IsTrue(fre.TargetObject is IdentifierExpression);
Assert.AreEqual("myTargetObject", ((IdentifierExpression)fre.TargetObject).Identifier);
}
[Test]
public void VBNetGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilVBNet.ParseExpression("SomeClass(of string).myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].SystemType);
}
[Test]
public void VBNetFullNamespaceGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilVBNet.ParseExpression("System.Subnamespace.SomeClass(of string).myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("System.Subnamespace.SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].SystemType);
}
[Test]
public void VBNetGlobalFullNamespaceGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilVBNet.ParseExpression("Global.System.Subnamespace.SomeClass(of string).myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
TypeReference tr = ((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.IsFalse(tr is InnerClassTypeReference);
Assert.AreEqual("System.Subnamespace.SomeClass", tr.Type);
Assert.AreEqual(1, tr.GenericTypes.Count);
Assert.AreEqual("System.String", tr.GenericTypes[0].SystemType);
Assert.IsTrue(tr.IsGlobal);
}
[Test]
public void VBNetNestedGenericFieldReferenceExpressionTest()
{
FieldReferenceExpression fre = (FieldReferenceExpression)ParseUtilVBNet.ParseExpression("MyType(of string).InnerClass(of integer).myField", typeof(FieldReferenceExpression));
Assert.AreEqual("myField", fre.FieldName);
Assert.IsTrue(fre.TargetObject is TypeReferenceExpression);
InnerClassTypeReference ic = (InnerClassTypeReference)((TypeReferenceExpression)fre.TargetObject).TypeReference;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
#endregion
}
}

32
src/Libraries/NRefactory/Test/Parser/Expressions/TypeOfExpressionTests.cs

@ -61,6 +61,22 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -61,6 +61,22 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual("System.String", toe.TypeReference.GenericTypes[0].SystemType);
}
[Test]
public void CSharpNestedGenericTypeOfExpressionTest()
{
TypeOfExpression toe = (TypeOfExpression)ParseUtilCSharp.ParseExpression("typeof(MyType<string>.InnerClass<int>.InnerInnerClass)", typeof(TypeOfExpression));
InnerClassTypeReference ic = (InnerClassTypeReference)toe.TypeReference;
Assert.AreEqual("InnerInnerClass", ic.Type);
Assert.AreEqual(0, ic.GenericTypes.Count);
ic = (InnerClassTypeReference)ic.BaseType;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
[Test]
public void CSharpNullableTypeOfExpressionTest()
{
@ -133,6 +149,22 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -133,6 +149,22 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.IsTrue(toe.TypeReference.GenericTypes[0].IsNull);
Assert.IsTrue(toe.TypeReference.GenericTypes[1].IsNull);
}
[Test]
public void VBNestedGenericTypeOfExpressionTest()
{
TypeOfExpression toe = (TypeOfExpression)ParseUtilVBNet.ParseExpression("GetType(MyType(Of string).InnerClass(of integer).InnerInnerClass)", typeof(TypeOfExpression));
InnerClassTypeReference ic = (InnerClassTypeReference)toe.TypeReference;
Assert.AreEqual("InnerInnerClass", ic.Type);
Assert.AreEqual(0, ic.GenericTypes.Count);
ic = (InnerClassTypeReference)ic.BaseType;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
#endregion
}
}

36
src/Libraries/NRefactory/Test/Parser/Statements/LocalVariableDeclarationTests.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -47,6 +47,23 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -47,6 +47,23 @@ namespace ICSharpCode.NRefactory.Tests.AST
// TODO: Check initializer
}
[Test]
public void CSharpNestedGenericLocalVariableDeclarationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilCSharp.ParseStatment("MyType<string>.InnerClass<int>.InnerInnerClass a;", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
InnerClassTypeReference ic = (InnerClassTypeReference)lvd.GetTypeForVariable(0);
Assert.AreEqual("InnerInnerClass", ic.Type);
Assert.AreEqual(0, ic.GenericTypes.Count);
ic = (InnerClassTypeReference)ic.BaseType;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
[Test]
public void CSharpGenericWithArrayLocalVariableDeclarationTest1()
{
@ -291,6 +308,23 @@ namespace ICSharpCode.NRefactory.Tests.AST @@ -291,6 +308,23 @@ namespace ICSharpCode.NRefactory.Tests.AST
Assert.AreEqual("Integer", type.GenericTypes[0].Type);
// TODO: Check initializer
}
[Test]
public void VBNetNestedGenericLocalVariableDeclarationTest()
{
LocalVariableDeclaration lvd = (LocalVariableDeclaration)ParseUtilVBNet.ParseStatment("Dim a as MyType(of string).InnerClass(of integer).InnerInnerClass", typeof(LocalVariableDeclaration));
Assert.AreEqual(1, lvd.Variables.Count);
InnerClassTypeReference ic = (InnerClassTypeReference)lvd.GetTypeForVariable(0);
Assert.AreEqual("InnerInnerClass", ic.Type);
Assert.AreEqual(0, ic.GenericTypes.Count);
ic = (InnerClassTypeReference)ic.BaseType;
Assert.AreEqual("InnerClass", ic.Type);
Assert.AreEqual(1, ic.GenericTypes.Count);
Assert.AreEqual("System.Int32", ic.GenericTypes[0].SystemType);
Assert.AreEqual("MyType", ic.BaseType.Type);
Assert.AreEqual(1, ic.BaseType.GenericTypes.Count);
Assert.AreEqual("System.String", ic.BaseType.GenericTypes[0].SystemType);
}
#endregion
}
}

3
src/Main/Base/Project/Src/Dom/NRefactoryResolver/TypeVisitor.cs

@ -484,6 +484,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -484,6 +484,9 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
if (reference == null) return null;
if (reference.IsNull) return null;
if (reference is InnerClassTypeReference) {
reference = ((InnerClassTypeReference)reference).CombineToNormalTypeReference();
}
LanguageProperties languageProperties = projectContent.Language;
IReturnType t = null;
if (callingClass != null && !reference.IsGlobal) {

16
src/Main/Base/Project/Src/Dom/ReflectionLayer/DomPersistence.cs

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 28.09.2005
* Time: 19:52
*/
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
@ -76,7 +76,9 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -76,7 +76,9 @@ namespace ICSharpCode.SharpDevelop.Dom
pc = new ReadWriteHelper(reader).ReadProjectContent();
}
}
pc.InitializeSpecialClasses();
if (pc != null) {
pc.InitializeSpecialClasses();
}
return pc;
}
#endregion

12
src/Main/Base/Project/Src/Dom/ReflectionLayer/ReflectionLoader.cs

@ -1,9 +1,9 @@ @@ -1,9 +1,9 @@
/*
* Created by SharpDevelop.
* User: Daniel Grunwald
* Date: 28.09.2005
* Time: 18:48
*/
// <file>
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
// <license see="prj:///doc/license.txt">GNU General Public License</license>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.IO;

Loading…
Cancel
Save