public NullableTypeExpression(TypeExpression underlyingType, SourceSpan span) : this() { _underlyingType = underlyingType; Span = span; }
private Expression DoResolve(ParseContext ec, Expression rightSide) { if (_resolved != null) { return(_resolved); } var type = Type; if (type != null) { throw new Exception(); } // // Resolve the expression with flow analysis turned off, we'll do the definite // assignment checks later. This is because we don't know yet what the expression // will resolve to - it may resolve to a FieldExpr and in this case we must do the // definite assignment check on the actual field and not on the whole struct. // var original = Left as NameExpression; var leftResolved = Left.Resolve(ec, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis); if (leftResolved == null) { return(null); } var typeArguments = TypeArguments; var lookupIdentifier = MemberName.MakeName(Name, typeArguments); var ns = leftResolved as NamespaceExpression; if (ns != null) { FullNamedExpression resolved = null; MemberTracker namespaceChild; bool found; var trackerGroup = ns.Tracker as NamespaceGroupTracker; if (trackerGroup != null) { found = trackerGroup.TryGetValue((SymbolId)lookupIdentifier, out namespaceChild); } else { found = ns.Tracker.TryGetValue((SymbolId)lookupIdentifier, out namespaceChild); } if (!found) { // TODO: ns.Error_NamespaceDoesNotExist(loc, lookupIdentifier, ec.Report); } else if (HasTypeArguments) { if (!typeArguments.Resolve(ec)) { return(null); } var typeTracker = namespaceChild as TypeGroup; if (typeTracker != null) { var matchingType = typeTracker.GetTypeForArity(typeArguments.Count); if (matchingType != null) { resolved = new GenericTypeExpression( matchingType.Type, typeArguments, Span).ResolveAsTypeStep(ec, false); } else { // TODO: Error? } } } else { var typeGroup = namespaceChild as TypeGroup; if (typeGroup != null) { Type nonGenericType; if (typeGroup.TryGetNonGenericType(out nonGenericType)) { resolved = new TypeExpression(nonGenericType) { Span = Span }; } else { // TODO: Error? } } else { var nestedType = namespaceChild as NestedTypeTracker; if (nestedType != null) { resolved = new TypeExpression(nestedType.Type) { Span = Span }; } else { // TODO: Error? } } } //FullNamedExpression retval = ns.Lookup(ec, lookupIdentifier, loc); if (resolved == null) { } else if (HasTypeArguments) { resolved = new GenericTypeExpression( resolved.Type, typeArguments, Span).ResolveAsTypeStep(ec, false); } _resolved = resolved; if (resolved != null) { ExpressionClass = resolved.ExpressionClass; } return(resolved); } var expressionType = leftResolved.Type; if (expressionType.IsPointer || expressionType == TypeManager.CoreTypes.Void) { // TODO: Unary.Error_OperatorCannotBeApplied(ec, loc, ".", expressionType); return(null); } var c = leftResolved as ConstantExpression; if (c != null && c.Value == null) { ec.ReportError( 1720, "Expression will always cause a 'System.NullReferenceException'.", Severity.Warning, Span); } if (typeArguments != null && !typeArguments.Resolve(ec)) { return(null); } var memberLookup = MemberLookup( ec, null, expressionType, expressionType, Name, Span); if (memberLookup == null && typeArguments != null) { memberLookup = MemberLookup( ec, null, expressionType, expressionType, lookupIdentifier, Span); } if (memberLookup == null) { var expressionClass = leftResolved.ExpressionClass; // // Extension methods are not allowed on all expression types // if (expressionClass == ExpressionClass.Value || expressionClass == ExpressionClass.Variable || expressionClass == ExpressionClass.IndexerAccess || expressionClass == ExpressionClass.PropertyAccess || expressionClass == ExpressionClass.EventAccess) { var exMethodLookup = ec.LookupExtensionMethod(expressionType, Name, Span); if (exMethodLookup != null) { exMethodLookup.ExtensionExpression = leftResolved; if ((typeArguments != null) && typeArguments.Any()) { exMethodLookup.SetTypeArguments(ec, typeArguments); } _resolved = exMethodLookup.DoResolve(ec); if (_resolved != null) { ExpressionClass = _resolved.ExpressionClass; } return(_resolved); } } Left = leftResolved; memberLookup = OnErrorMemberLookupFailed( ec, null, expressionType, expressionType, Name, null, AllMemberTypes, AllBindingFlags); if (memberLookup == null) { return(null); } } var texpr = memberLookup as TypeExpression; if (texpr != null) { if (!(leftResolved is TypeExpression) && (original == null || !original.IdenticalNameAndTypeName(ec, leftResolved, Span))) { ec.ReportError( 572, string.Format( "'{0}': cannot reference a type through an expression; try '{1}' instead.", Name, memberLookup.GetSignatureForError()), Severity.Error, Span); return(null); } if (!texpr.CheckAccessLevel(ec)) { ec.ReportError( CompilerErrors.MemberIsInaccessible, Span, TypeManager.GetCSharpName(memberLookup.Type)); return(null); } var ct = leftResolved as GenericTypeExpression; if (ct != null) { // // When looking up a nested type in a generic instance // via reflection, we always get a generic type definition // and not a generic instance - so we have to do this here. // // See gtest-172-lib.cs and gtest-172.cs for an example. // TypeArguments nestedTargs; if (HasTypeArguments) { nestedTargs = ct.TypeArguments.Clone(); nestedTargs.Add(typeArguments); } else { nestedTargs = ct.TypeArguments; } ct = new GenericTypeExpression(memberLookup.Type, nestedTargs, Span); _resolved = ct.ResolveAsTypeStep(ec, false); if (_resolved != null) { ExpressionClass = _resolved.ExpressionClass; } return(_resolved); } _resolved = memberLookup; ExpressionClass = _resolved.ExpressionClass; return(memberLookup); } var me = (MemberExpression)memberLookup; me = me.ResolveMemberAccess(ec, leftResolved, Span, original); if (me == null) { return(null); } if ((typeArguments != null) && typeArguments.Any()) { me.SetTypeArguments(ec, typeArguments); } if (original != null && !TypeManager.IsValueType(expressionType)) { if (me.IsInstance) { } } // The following DoResolve/DoResolveLValue will do the definite assignment // check. Left = leftResolved; if (rightSide != null) { return(_resolved = me.DoResolveLValue(ec, rightSide)); } return(_resolved = me.DoResolve(ec)); }
public override void Dump(SourceWriter sw, int indentChange) { sw.Write("default("); TypeExpression.Dump(sw, indentChange); sw.Write(")"); }