public override TypeNode VisitTypeReference(TypeNode type, bool addNonNullWrapperIfNeeded) { if (type == null) { return(null); } // begin change by drunje (allow pointers to managed structures) if (this.AllowPointersToManagedStructures && (type.NodeType == NodeType.PointerTypeExpression)) { PointerTypeExpression ptrExpr = (PointerTypeExpression)type; TypeNode et = this.VisitTypeReference(ptrExpr.ElementType); if ((et != null) && (et.Name != Looker.NotFound) && (!et.IsUnmanaged) && (et.IsValueType)) { return(et.GetPointerType()); } } // end of change by drunje ClassParameter cp = this.typeParamToClassParamMap[type.UniqueKey] as ClassParameter; if (cp != null) { return(cp); } return(base.VisitTypeReference(type, addNonNullWrapperIfNeeded)); }
public override TypeNode VisitTypeReference(TypeNode type) { //TODO: break up this method if (type == null) { return(null); } TypeNodeList pars = this.pars; TypeNodeList args = this.args; switch (type.NodeType) { case NodeType.ArrayType: ArrayType arrType = (ArrayType)type; TypeNode elemType = this.VisitTypeReference(arrType.ElementType); if (elemType == arrType.ElementType || elemType == null) { return(arrType); } if (arrType.IsSzArray()) { return(elemType.GetArrayType(1)); } return(elemType.GetArrayType(arrType.Rank, arrType.Sizes, arrType.LowerBounds)); case NodeType.DelegateNode: { FunctionType ftype = type as FunctionType; if (ftype == null) { goto default; } TypeNode referringType = ftype.DeclaringType == null ? this.CurrentType : this.VisitTypeReference(ftype.DeclaringType); return(FunctionType.For(this.VisitTypeReference(ftype.ReturnType), this.VisitParameterList(ftype.Parameters), referringType)); } case NodeType.Pointer: Pointer pType = (Pointer)type; elemType = this.VisitTypeReference(pType.ElementType); if (elemType == pType.ElementType || elemType == null) { return(pType); } return(elemType.GetPointerType()); case NodeType.Reference: Reference rType = (Reference)type; elemType = this.VisitTypeReference(rType.ElementType); if (elemType == rType.ElementType || elemType == null) { return(rType); } return(elemType.GetReferenceType()); case NodeType.ArrayTypeExpression: ArrayTypeExpression aExpr = (ArrayTypeExpression)type; aExpr.ElementType = this.VisitTypeReference(aExpr.ElementType); return(aExpr); case NodeType.BoxedTypeExpression: BoxedTypeExpression bExpr = (BoxedTypeExpression)type; bExpr.ElementType = this.VisitTypeReference(bExpr.ElementType); return(bExpr); case NodeType.ClassExpression: { ClassExpression cExpr = (ClassExpression)type; cExpr.Expression = this.VisitTypeExpression(cExpr.Expression); //Could happen if the expression is a template parameter if (cExpr.Expression is Literal lit) { return(lit.Value as TypeNode); } cExpr.TemplateArguments = this.VisitTypeReferenceList(cExpr.TemplateArguments); return(cExpr); } case NodeType.ClassParameter: case NodeType.TypeParameter: int key = type.UniqueKey; for (int i = 0, n = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; i < n && i < m; i++) { //^ assert pars != null && args != null; TypeNode tp = pars[i]; if (tp == null) { continue; } if (tp.UniqueKey == key) { return(args[i]); } if (tp.Name.UniqueIdKey == type.Name.UniqueIdKey && (tp is ClassParameter && type is TypeParameter)) { //This shouldn't really happen, but in practice it does. Hack past it. return(args[i]); } } return(type); case NodeType.FlexArrayTypeExpression: FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type; flExpr.ElementType = this.VisitTypeReference(flExpr.ElementType); return(flExpr); case NodeType.FunctionTypeExpression: FunctionTypeExpression ftExpr = (FunctionTypeExpression)type; ftExpr.Parameters = this.VisitParameterList(ftExpr.Parameters); ftExpr.ReturnType = this.VisitTypeReference(ftExpr.ReturnType); return(ftExpr); case NodeType.InvariantTypeExpression: InvariantTypeExpression invExpr = (InvariantTypeExpression)type; invExpr.ElementType = this.VisitTypeReference(invExpr.ElementType); return(invExpr); case NodeType.InterfaceExpression: InterfaceExpression iExpr = (InterfaceExpression)type; if (iExpr.Expression == null) { goto default; } iExpr.Expression = this.VisitTypeExpression(iExpr.Expression); iExpr.TemplateArguments = this.VisitTypeReferenceList(iExpr.TemplateArguments); return(iExpr); case NodeType.NonEmptyStreamTypeExpression: NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type; neExpr.ElementType = this.VisitTypeReference(neExpr.ElementType); return(neExpr); case NodeType.NonNullTypeExpression: NonNullTypeExpression nnExpr = (NonNullTypeExpression)type; nnExpr.ElementType = this.VisitTypeReference(nnExpr.ElementType); return(nnExpr); case NodeType.NonNullableTypeExpression: NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type; nbExpr.ElementType = this.VisitTypeReference(nbExpr.ElementType); return(nbExpr); case NodeType.NullableTypeExpression: NullableTypeExpression nuExpr = (NullableTypeExpression)type; nuExpr.ElementType = this.VisitTypeReference(nuExpr.ElementType); return(nuExpr); case NodeType.OptionalModifier: { TypeModifier modType = (TypeModifier)type; TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType); TypeNode modifierType = this.VisitTypeReference(modType.Modifier); if (modifiedType == null || modifierType == null) { return(type); } return(OptionalModifier.For(modifierType, modifiedType)); } case NodeType.RequiredModifier: { TypeModifier modType = (TypeModifier)type; TypeNode modifiedType = this.VisitTypeReference(modType.ModifiedType); TypeNode modifierType = this.VisitTypeReference(modType.Modifier); if (modifiedType == null || modifierType == null) { Debug.Fail(""); return(type); } return(RequiredModifier.For(modifierType, modifiedType)); } case NodeType.OptionalModifierTypeExpression: OptionalModifierTypeExpression optmodType = (OptionalModifierTypeExpression)type; optmodType.ModifiedType = this.VisitTypeReference(optmodType.ModifiedType); optmodType.Modifier = this.VisitTypeReference(optmodType.Modifier); return(optmodType); case NodeType.RequiredModifierTypeExpression: RequiredModifierTypeExpression reqmodType = (RequiredModifierTypeExpression)type; reqmodType.ModifiedType = this.VisitTypeReference(reqmodType.ModifiedType); reqmodType.Modifier = this.VisitTypeReference(reqmodType.Modifier); return(reqmodType); case NodeType.PointerTypeExpression: PointerTypeExpression pExpr = (PointerTypeExpression)type; pExpr.ElementType = this.VisitTypeReference(pExpr.ElementType); return(pExpr); case NodeType.ReferenceTypeExpression: ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type; rExpr.ElementType = this.VisitTypeReference(rExpr.ElementType); return(rExpr); case NodeType.StreamTypeExpression: StreamTypeExpression sExpr = (StreamTypeExpression)type; sExpr.ElementType = this.VisitTypeReference(sExpr.ElementType); return(sExpr); case NodeType.TupleTypeExpression: TupleTypeExpression tuExpr = (TupleTypeExpression)type; tuExpr.Domains = this.VisitFieldList(tuExpr.Domains); return(tuExpr); case NodeType.TypeExpression: { TypeExpression tExpr = (TypeExpression)type; tExpr.Expression = this.VisitTypeExpression(tExpr.Expression); if (tExpr.Expression is Literal) { return(type); } tExpr.TemplateArguments = this.VisitTypeReferenceList(tExpr.TemplateArguments); return(tExpr); } case NodeType.TypeIntersectionExpression: TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type; tiExpr.Types = this.VisitTypeReferenceList(tiExpr.Types); return(tiExpr); case NodeType.TypeUnionExpression: TypeUnionExpression tyuExpr = (TypeUnionExpression)type; tyuExpr.Types = this.VisitTypeReferenceList(tyuExpr.Types); return(tyuExpr); default: TypeNode declaringType = this.VisitTypeReference(type.DeclaringType); if (declaringType != null) { Identifier tname = type.Name; if (type.Template != null && type.IsGeneric) { tname = type.Template.Name; } TypeNode nt = declaringType.GetNestedType(tname); if (nt != null) { TypeNodeList arguments = type.TemplateArguments; type = nt; if (TargetPlatform.UseGenerics) { if (arguments != null && arguments.Count > 0 && nt.ConsolidatedTemplateParameters != null && nt.ConsolidatedTemplateParameters.Count > 0) { type = nt.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, arguments); } } } } if (type.Template != null && (type.ConsolidatedTemplateParameters == null || type.ConsolidatedTemplateParameters.Count == 0)) { if (!type.IsNotFullySpecialized && (!type.IsNormalized || (this.CurrentType != null && type.DeclaringModule == this.CurrentType.DeclaringModule))) { return(type); } // Type is a template instance, but some of its arguments were themselves parameters. // See if any of these parameters are to be specialized by this specializer. bool mustSpecializeFurther = false; TypeNodeList targs = type.TemplateArguments; int numArgs = targs == null ? 0 : targs.Count; if (targs != null) { targs = new TypeNodeList(targs); for (int i = 0; i < numArgs; i++) { TypeNode targ = targs[i]; if (targ is ITypeParameter tparg) { for (int j = 0, np = pars == null ? 0 : pars.Count, m = args == null ? 0 : args.Count; j < np && j < m; j++) { //^ assert pars != null && args != null; if (TargetPlatform.UseGenerics) { if (!(pars[j] is ITypeParameter par)) { continue; } if (tparg == par || (tparg.ParameterListIndex == par.ParameterListIndex && tparg.DeclaringMember == par.DeclaringMember)) { targ = this.args[j]; break; } } else { if (targ == pars[j]) { targ = this.args[j]; break; } } } } else { if (targ != type) { targ = this.VisitTypeReference(targ); } if (targ == type) { continue; } } mustSpecializeFurther |= targs[i] != targ; targs[i] = targ; } } if (targs == null || !mustSpecializeFurther) { return(type); } return(type.Template.GetTemplateInstance(this.TargetModule, this.CurrentType, declaringType, targs)); } TypeNodeList tPars = type.TemplateParameters; if (tPars == null || tPars.Count == 0) { return(type); //Not a parameterized type. No need to get an instance. } TypeNodeList tArgs = new TypeNodeList(); for (int i = 0, n = tPars.Count; i < n; i++) { TypeNode tPar = tPars[i]; tArgs.Add(tPar); //Leave parameter in place if there is no match if (tPar == null || tPar.Name == null) { continue; } int idKey = tPar.Name.UniqueIdKey; for (int j = 0, m = pars == null ? 0 : pars.Count, k = args == null ? 0 : args.Count; j < m && j < k; j++) { //^ assert pars != null && args != null; TypeNode par = pars[j]; if (par == null || par.Name == null) { continue; } if (par.Name.UniqueIdKey == idKey) { tArgs[i] = args[j]; break; } } } return(type.GetTemplateInstance(this.TargetModule, this.CurrentType, this.VisitTypeReference(type.DeclaringType), tArgs)); } }
public override TypeNode VisitTypeReference(TypeNode type) { if (type == null) { return(null); } Class cl = type as Class; if (cl != null) { this.VisitTypeReference(cl.BaseClass); } if (this.MembersToFind[type.UniqueKey] != null) { this.FoundMembers[type.UniqueKey] = type; if (!this.insideMethodBody) { this.AllReferencesAreConfinedToMethodBodies = false; } return(type); } switch (type.NodeType) { case NodeType.ArrayType: ArrayType arrType = (ArrayType)type; this.VisitTypeReference(arrType.ElementType); return(type); case NodeType.DelegateNode: { FunctionType ftype = type as FunctionType; if (ftype == null) { goto default; } this.VisitTypeReference(ftype.ReturnType); this.VisitParameterList(ftype.Parameters); return(type); } case NodeType.Pointer: Pointer pType = (Pointer)type; this.VisitTypeReference(pType.ElementType); return(type); case NodeType.Reference: Reference rType = (Reference)type; this.VisitTypeReference(rType.ElementType); return(type); case NodeType.TupleType: { TupleType tType = (TupleType)type; MemberList members = tType.Members; int n = members == null ? 0 : members.Count; for (int i = 0; i < n; i++) { Field f = members[i] as Field; if (f == null) { continue; } this.VisitTypeReference(f.Type); } return(type); } case NodeType.TypeIntersection: TypeIntersection tIntersect = (TypeIntersection)type; this.VisitTypeReferenceList(tIntersect.Types); return(type); case NodeType.TypeUnion: TypeUnion tUnion = (TypeUnion)type; this.VisitTypeReferenceList(tUnion.Types); return(type); case NodeType.ArrayTypeExpression: ArrayTypeExpression aExpr = (ArrayTypeExpression)type; this.VisitTypeReference(aExpr.ElementType); return(type); case NodeType.BoxedTypeExpression: BoxedTypeExpression bExpr = (BoxedTypeExpression)type; this.VisitTypeReference(bExpr.ElementType); return(type); case NodeType.ClassExpression: ClassExpression cExpr = (ClassExpression)type; this.VisitExpression(cExpr.Expression); this.VisitTypeReferenceList(cExpr.TemplateArguments); return(type); case NodeType.ClassParameter: case NodeType.TypeParameter: return(type); case NodeType.ConstrainedType: ConstrainedType conType = (ConstrainedType)type; this.VisitTypeReference(conType.UnderlyingType); this.VisitExpression(conType.Constraint); return(type); case NodeType.FlexArrayTypeExpression: FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type; this.VisitTypeReference(flExpr.ElementType); return(type); case NodeType.FunctionTypeExpression: FunctionTypeExpression ftExpr = (FunctionTypeExpression)type; this.VisitParameterList(ftExpr.Parameters); this.VisitTypeReference(ftExpr.ReturnType); return(type); case NodeType.InvariantTypeExpression: InvariantTypeExpression invExpr = (InvariantTypeExpression)type; this.VisitTypeReference(invExpr.ElementType); return(type); case NodeType.InterfaceExpression: InterfaceExpression iExpr = (InterfaceExpression)type; this.VisitExpression(iExpr.Expression); this.VisitTypeReferenceList(iExpr.TemplateArguments); return(type); case NodeType.NonEmptyStreamTypeExpression: NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type; this.VisitTypeReference(neExpr.ElementType); return(type); case NodeType.NonNullTypeExpression: NonNullTypeExpression nnExpr = (NonNullTypeExpression)type; this.VisitTypeReference(nnExpr.ElementType); return(type); case NodeType.NonNullableTypeExpression: NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type; this.VisitTypeReference(nbExpr.ElementType); return(type); case NodeType.NullableTypeExpression: NullableTypeExpression nuExpr = (NullableTypeExpression)type; this.VisitTypeReference(nuExpr.ElementType); return(type); case NodeType.OptionalModifier: case NodeType.RequiredModifier: TypeModifier modType = (TypeModifier)type; this.VisitTypeReference(modType.ModifiedType); this.VisitTypeReference(modType.Modifier); return(type); case NodeType.PointerTypeExpression: PointerTypeExpression pExpr = (PointerTypeExpression)type; this.VisitTypeReference(pExpr.ElementType); return(type); case NodeType.ReferenceTypeExpression: ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type; this.VisitTypeReference(rExpr.ElementType); return(type); case NodeType.StreamTypeExpression: StreamTypeExpression sExpr = (StreamTypeExpression)type; this.VisitTypeReference(sExpr.ElementType); return(type); case NodeType.TupleTypeExpression: TupleTypeExpression tuExpr = (TupleTypeExpression)type; this.VisitFieldList(tuExpr.Domains); return(type); case NodeType.TypeExpression: TypeExpression tExpr = (TypeExpression)type; this.VisitExpression(tExpr.Expression); this.VisitTypeReferenceList(tExpr.TemplateArguments); return(type); case NodeType.TypeIntersectionExpression: TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type; this.VisitTypeReferenceList(tiExpr.Types); return(type); case NodeType.TypeUnionExpression: TypeUnionExpression tyuExpr = (TypeUnionExpression)type; this.VisitTypeReferenceList(tyuExpr.Types); return(type); default: if (type.Template != null && type.TemplateArguments != null) { this.VisitTypeReference(type.Template); this.VisitTypeReferenceList(type.TemplateArguments); } return(type); } }
private Expression ParseNew(TokenSet followers) //^ requires this.currentToken == Token.New; //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { SourceLocationBuilder ctx = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken); this.GetNextToken(); if (this.currentToken == Token.LeftBracket) return this.ParseNewImplicitlyTypedArray(ctx, followers); if (this.currentToken == Token.LeftBrace) return this.ParseNewAnonymousTypeInstance(ctx, followers); TypeExpression t = this.ParseBaseTypeExpression(false, followers|Parser.InfixOperators|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis); if (this.currentToken == Token.Conditional) { SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation); slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); //^ assume this.currentToken == Token.Conditional; //no side effects from the methods can touch this.currentToken this.GetNextToken(); t = new NullableTypeExpression(t, slb); //} else if (this.currentToken == Token.LogicalNot) { // TypeExpression type = t; // t = new NonNullableTypeExpression(type); // t.SourceContext = type.SourceContext; // t.SourceContext.EndPos = this.scanner.endPos; // this.GetNextToken(); } else if (this.currentToken == Token.Multiply) { SourceLocationBuilder slb = new SourceLocationBuilder(t.SourceLocation); slb.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); //^ assume this.currentToken == Token.Multiply; //no side effects from the methods can touch this.currentToken this.GetNextToken(); t = new PointerTypeExpression(t, slb); } ctx.UpdateToSpan(t.SourceLocation); TypeExpression et = t; uint rank = 0; while (this.currentToken == Token.LeftBracket) { Token nextTok = this.PeekNextToken(); if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier rank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis); et = t; t = new ArrayTypeExpression(et, rank, ctx); } if (rank > 0) { //new T[] {...} or new T[,] {{..} {...}...}, etc where T can also be an array type List<Expression> initializers; if (this.currentToken == Token.LeftBrace) initializers = this.ParseArrayInitializers(rank, et, followers, false, ctx); else { initializers = new List<Expression>(0); if (Parser.UnaryStart[this.currentToken]) this.HandleError(Error.ExpectedLeftBrace); else this.HandleError(Error.MissingArraySize); while (Parser.UnaryStart[this.currentToken]) { this.ParseExpression(followers|Token.Comma|Token.RightBrace); if (this.currentToken != Token.Comma) break; this.GetNextToken(); } ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); this.SkipOverTo(Token.RightBrace, followers); } return new CreateArray(et, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, new List<Expression>(0).AsReadOnly(), ctx); } if (this.currentToken == Token.LeftBracket) { //new T[x] or new T[x,y] etc. possibly followed by an initializer or element type rank specifier this.GetNextToken(); List<Expression> sizes = this.ParseExpressionList(ctx, followers|Token.LeftBrace|Token.LeftBracket); rank = (uint)sizes.Count; List<Expression> initializers; if (this.currentToken == Token.LeftBrace) initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx); else { uint elementRank = 0; tryAgain: while (this.currentToken == Token.LeftBracket) { Token nextTok = this.PeekNextToken(); if (nextTok != Token.Comma && nextTok != Token.RightBracket) break; //not a rank specifier, but a size specifier elementRank = this.ParseRankSpecifier(ctx, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis); t = new ArrayTypeExpression(t, elementRank, ctx); } if (this.currentToken == Token.LeftBrace) initializers = this.ParseArrayInitializers(rank, t, followers, false, ctx); else { if (this.currentToken == Token.LeftBracket) { //new T[x][y] or something like that this.GetNextToken(); this.HandleError(Error.InvalidArray); elementRank = (uint)this.ParseExpressionList(ctx, followers).Count; goto tryAgain; } else { initializers = new List<Expression>(0); ctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); this.SkipTo(followers); } } } return new CreateArray(t, initializers.AsReadOnly(), new List<Expression>(0).AsReadOnly(), rank, sizes.AsReadOnly(), ctx); } //new T(...) IEnumerable<Expression> arguments = Expression.EmptyCollection; IEnumerable<Expression> elementValues = Expression.EmptyCollection; IEnumerable<NamedArgument> namedArguments = NamedArgument.EmptyCollection; if (this.currentToken == Token.LeftParenthesis) { //if (t is NonNullableTypeExpression) { // this.SkipTo(followers, Error.BadNewExpr); // return null; //} arguments = this.ParseArgumentList(ctx, followers|Token.LeftBrace).AsReadOnly(); } else if (this.currentToken != Token.LeftBrace) { this.SkipTo(followers, Error.BadNewExpr); } Expression result = new CreateObjectInstance(t, arguments, ctx.GetSourceLocation()); if (this.currentToken == Token.LeftBrace) { this.ParseElementValuesOrNamedArguments(ref elementValues, ref namedArguments, ctx, followers); if (elementValues != Expression.EmptyCollection) return new PopulateCollection(result, elementValues, ctx); else if (namedArguments != NamedArgument.EmptyCollection) return new InitializeObject(result, namedArguments, ctx); else { this.HandleError(Error.SyntaxError); //TODO: better error } } return result; }
private TypeExpression ParseTypeExpression(bool formsPartOfBooleanExpression, bool allowEmptyArguments, TokenSet followers) //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { if (this.currentToken == Token.EndOfFile) { this.HandleError(Error.TypeExpected); return this.GetTypeExpressionFor(Token.Object, SourceDummy.SourceLocation); } TokenSet followersOrTypeOperator = followers|Parser.TypeOperator; TypeExpression type = this.ParseBaseTypeExpression(allowEmptyArguments, followersOrTypeOperator); SourceLocationBuilder sctx = new SourceLocationBuilder(type.SourceLocation); for (; ; ) { sctx.UpdateToSpan(this.scanner.SourceLocationOfLastScannedToken); switch (this.currentToken) { case Token.BitwiseAnd: this.HandleError(Error.ExpectedIdentifier); //TODO: this matches C#, but a better error would be nice this.GetNextToken(); break; case Token.LeftBracket: uint rank = this.ParseRankSpecifier(sctx, followersOrTypeOperator); type = this.ParseArrayType(rank, type, sctx, followersOrTypeOperator); break; case Token.Multiply: { this.GetNextToken(); type = new PointerTypeExpression(type, sctx.GetSourceLocation()); break; } case Token.LogicalNot: { this.GetNextToken(); type = new NonNullTypeExpression(type, sctx.GetSourceLocation()); break; } case Token.Conditional: { if (formsPartOfBooleanExpression && Parser.NullableTypeNonFollower[this.PeekNextToken()]) goto done; this.GetNextToken(); type = new NullableTypeExpression(type, sctx.GetSourceLocation()); break; } default: goto done; } } done: this.SkipTo(followers); return type; }