private FullNamedExpression ResolveNested(Type t) { if (!TypeManager.IsGenericTypeDefinition(t) && !TypeManager.IsGenericType(t)) { return(null); } var declaringType = t; while (declaringType != null && !IsNestedChild(t, declaringType)) { declaringType = declaringType.DeclaringType; } if (declaringType == null) { return(null); } var genericParameters = t.GetGenericArguments(); var genericArity = HasTypeArguments ? TypeArguments.Count : 0; for (; (declaringType != null) && TypeManager.IsGenericType(declaringType); declaringType = declaringType.DeclaringType) { var genericArguments = declaringType.GetGenericArguments(); if ((genericArity + genericArguments.Length) != genericParameters.Length) { continue; } var newTypeArguments = new TypeArguments(); foreach (var typeArgument in genericArguments) { newTypeArguments.Add(new TypeExpression(typeArgument, Span)); } if (HasTypeArguments) { newTypeArguments.Add(TypeArguments); } return(new GenericTypeExpression(t, newTypeArguments, Span)); } return(null); }
public FullNamedExpression ResolveNamespaceOrType(ParseContext rc, bool silent) { var resolved = Left.ResolveAsTypeStep(rc, silent); if (resolved == null) { return(null); } var languageContext = (ScriptLanguageContext)rc.Compiler.SourceUnit.LanguageContext; var hasTypeArguments = HasTypeArguments; var typeArguments = TypeArguments; var lookupIdentifier = ReflectionUtils.GetNormalizedTypeName(MemberName.MakeName(Name, typeArguments)); var ns = resolved as NamespaceExpression; if (ns != null) { MemberTracker tracker; bool found; var trackerGroup = ns.Tracker as NamespaceGroupTracker; if (trackerGroup != null) { found = trackerGroup.TryGetValue((SymbolId)lookupIdentifier, out tracker); } else { found = ns.Tracker.TryGetValue((SymbolId)lookupIdentifier, out tracker); } if (found) { var typeGroup = tracker as TypeGroup; if (typeGroup != null) { if (hasTypeArguments) { typeArguments.Resolve(rc); var genericType = typeGroup.GetTypeForArity(typeArguments.Count); if (genericType != null) { return(new TypeExpression( genericType.Type.MakeGenericType(typeArguments.ResolvedTypes))); } // ERROR! } Type nonGenericType; if (typeGroup.TryGetNonGenericType(out nonGenericType)) { return(new TypeExpression(nonGenericType)); } // ERROR! } var singleTypeTracker = tracker as TypeTracker; if (singleTypeTracker != null) { if (hasTypeArguments) { typeArguments.Resolve(rc); return(new TypeExpression( singleTypeTracker.Type.MakeGenericType(typeArguments.ResolvedTypes))); } return(new TypeExpression(singleTypeTracker.Type)); } var childNamespaceTracker = tracker as NamespaceTracker; if (childNamespaceTracker != null) { return(new NamespaceExpression(childNamespaceTracker, Span)); } // ERROR! } //FullNamedExpression retval = ns.Lookup(rc.Compiler, lookupIdentifier, loc); //if (retval == null && !silent) // ns.Error_NamespaceDoesNotExist(loc, lookupIdentifier, rc.Compiler.Report); //else if (targs != null) // retval = new GenericTypeExpr(retval.Type, targs, loc).ResolveAsTypeStep(rc, silent); return(null); } var resolvedAsType = resolved.ResolveAsTypeTerminal(rc, false); if (resolvedAsType == null) { return(null); } var expressionType = resolvedAsType.Type; if (expressionType.IsGenericParameter) { rc.Compiler.Errors.Add( rc.Compiler.SourceUnit, string.Format( "A nested type cannot be specified through a type parameter '{0}'.", expressionType.Name), resolvedAsType.Span, 704, Severity.Error); return(null); } var memberGroup = languageContext.DefaultBinderState.Binder.GetMember( MemberRequestKind.Get, expressionType, Name); if (memberGroup != null) { foreach (var nestedType in memberGroup.OfType <TypeTracker>()) { if (nestedType.IsGenericType != hasTypeArguments) { continue; } if (!hasTypeArguments) { if (nestedType.Type.GetGenericArguments().Length == typeArguments.Count) { return(new TypeExpression(nestedType.Type)); } // ERROR! } var typeGroup = nestedType as TypeGroup; if (typeGroup != null) { var matchingType = typeGroup.GetTypeForArity(typeArguments.Count); if (matchingType != null) { return(new TypeExpression(matchingType.Type)); } // ERROR! } } } //return null; var memberLookup = MemberLookup( rc, null, expressionType, expressionType, lookupIdentifier, MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, Span); if (memberLookup == null) { if (silent) { return(null); } System.Diagnostics.Debugger.Break(); //Error_IdentifierNotFound(rc, resolved, lookupIdentifier); return(null); } var typeExpression = memberLookup.ResolveAsTypeTerminal(rc, false); if (typeExpression == null) { return(null); } var theArgs = typeArguments; var declaringType = typeExpression.Type.DeclaringType; if (TypeManager.HasGenericArguments(declaringType) && !TypeManager.IsGenericTypeDefinition(expressionType)) { while (!TypeManager.IsEqual(TypeManager.DropGenericTypeArguments(expressionType), declaringType)) { expressionType = expressionType.BaseType; } var newArgs = new TypeArguments(); foreach (var decl in expressionType.GetGenericArguments()) { newArgs.Add(new TypeExpression(decl) { Span = Span }); } if (typeArguments != null) { newArgs.Add(typeArguments); } theArgs = newArgs; } if (theArgs != null) { var genericType = new GenericTypeExpression(typeExpression.Type, theArgs, Span); return(genericType.ResolveAsTypeStep(rc, false)); } return(typeExpression); }
public MemberAccessExpression(Expression left, string name, TypeArguments typeArguments, SourceSpan span) : this(left, name, span) { TypeArguments.Add(typeArguments); }
protected bool CheckConstraint( ParseContext ec, Type ptype, Expression expr, Type ctype) { // // All this is needed because we don't have // real inflated type hierarchy // if (TypeManager.HasGenericArguments(ctype)) { var types = ctype.GetGenericArguments(); var newArgs = new TypeArguments(); for (var i = 0; i < types.Length; i++) { var t = types[i]; if (t.IsGenericParameter) { var pos = t.GenericParameterPosition; if (t.DeclaringMethod == null && this is MethodConstraintChecker) { var parent = ((MethodConstraintChecker)this).DeclaringType; t = parent.GetGenericArguments()[pos]; } else { t = ArgumentTypes[pos]; } } newArgs.Add(new TypeExpression(t) { Span = Span }); } var ct = new GenericTypeExpression(ctype, newArgs, Span); if (ct.ResolveAsTypeStep(ec, false) == null) { return(false); } ctype = (ct).Type; } else if (ctype.IsGenericParameter) { var pos = ctype.GenericParameterPosition; if (ctype.DeclaringMethod == null) { // FIXME: Implement return(true); } ctype = ArgumentTypes[pos]; } var expressionType = expr.Type; if (TypeUtils.IsImplicitlyConvertible(expressionType, ctype)) { return(true); } if (Silent) { return(false); } if (TypeUtils.IsNullableType(expressionType) && ctype.IsInterface) { ec.ReportError( 313, string.Format( "The type '{0}' cannot be used as type parameter '{1}' in the generic type or method '{2}'. " + "The nullable type '{0}' never satisfies interface constraint of type '{3}'.", TypeManager.GetCSharpName(expressionType), TypeManager.GetCSharpName(ptype), GetSignatureForError(), TypeManager.GetCSharpName(ctype)), Severity.Error, Span); } else { ec.ReportError( 309, string.Format( "The type '{0}' must be convertible to '{1}' in order to " + "use it as parameter '{2}' in the generic type or method '{3}'.", TypeManager.GetInterfaces(expressionType), TypeManager.GetInterfaces(ctype), TypeManager.GetInterfaces(ptype), GetSignatureForError()), Severity.Error, Span); } return(false); }