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); } }
public static void report(Node node, int shift) { if (node == null) { indent(shift); Console.WriteLine("NULL ENTITY"); return; } switch (node.NodeType) { case NodeType.AliasDefinition: { AliasDefinition alias = node as AliasDefinition; indent(shift); Console.WriteLine("using {0} = {1};", alias.Alias.Name, alias.AliasedUri.Name); break; } case NodeType.CompilationUnit: case NodeType.CompilationUnitSnippet: { CompilationUnit cu = node as CompilationUnit; for (int i = 0, n = cu.Nodes.Length; i < n; i++) { report(cu.Nodes[i], 0); } break; } case NodeType.Namespace: { Namespace ns = node as Namespace; if (ns.UsedNamespaces != null && ns.UsedNamespaces.Length != 0) { indent(shift); Console.WriteLine("using "); for (int i = 0, n = ns.UsedNamespaces.Length; i < n; i++) { Console.Write("{0}", ns.UsedNamespaces[i].Namespace.Name); if (i < n - 1) { Console.Write(", "); } } Console.WriteLine(); } indent(shift); Console.WriteLine("namespace {0}", ns.FullNameId.Name); indent(shift); Console.WriteLine("{"); if (ns.AliasDefinitions != null && ns.AliasDefinitions.Length != 0) { for (int i = 0, n = ns.AliasDefinitions.Length; i < n; i++) { report(ns.AliasDefinitions[i], shift + ind); } } if (ns.NestedNamespaces != null && ns.NestedNamespaces.Length != 0) { for (int i = 0, n = ns.NestedNamespaces.Length; i < n; i++) { report(ns.NestedNamespaces[i], shift + ind); } } if (ns.Types != null && ns.Types.Length != 0) { for (int i = 0, n = ns.Types.Length; i < n; i++) { report(ns.Types[i], shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Class: { Class cls = node as Class; if (cls == SystemTypes.Object) { Console.Write(cls.Name); break; } indent(shift); if (cls.IsAbstract) { Console.Write("abstract "); } if (cls.IsPrivate) { Console.Write("private "); } else if (cls.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ?????????????? } if (cls.IsSealed) { Console.Write("sealed "); } Console.Write("class "); if (cls.DeclaringType != null) { Console.Write("{0}::", cls.DeclaringType.Name.Name); } Console.Write("{0}", cls.Name != null?cls.Name.Name:"<NONAME>"); if (cls.BaseClass != null) { Console.Write(" : {0}", cls.BaseClass.Name.Name); } if (cls.Interfaces != null && cls.Interfaces.Length != 0) { if (cls.BaseClass != null) { Console.Write(","); } else { Console.Write(" :"); } for (int i = 0, n = cls.Interfaces.Length; i < n; i++) { Interface interfac = cls.Interfaces[i]; if (interfac != null) { Console.Write(" {0}", interfac.Name.Name); } if (i < n - 1) { Console.Write(","); } } } Console.WriteLine(); indent(shift); Console.WriteLine("{"); if (cls.Members != null && cls.Members.Length != 0) { for (int i = 0, n = cls.Members.Length; i < n; i++) { Member member = cls.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Struct: { Struct struc = node as Struct; indent(shift); if (struc.IsAbstract) { Console.Write("abstract "); } if (struc.IsPrivate) { Console.Write("private "); } else if (struc.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ?????????????? } if (struc.IsSealed) { Console.Write("sealed "); } Console.Write("struct "); if (struc.DeclaringType != null) { Console.Write("{0}::", struc.DeclaringType.Name.Name); } Console.Write("{0}", struc.Name != null?struc.Name.Name:"<NONAME>"); if (struc.Interfaces != null && struc.Interfaces.Length != 0) { Console.Write(" :"); for (int i = 0, n = struc.Interfaces.Length; i < n; i++) { Interface interfac = struc.Interfaces[i]; if (interfac != null) { Console.Write(" {0}", interfac.Name.Name); } if (i < n - 1) { Console.Write(","); } } } Console.WriteLine(); indent(shift); Console.WriteLine("{"); if (struc.Members != null && struc.Members.Length != 0) { for (int i = 0, n = struc.Members.Length; i < n; i++) { Member member = struc.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.EnumNode: { EnumNode enume = node as EnumNode; indent(shift); if (enume.Name != null && enume.Name.Name != null) { Console.Write("enum {0} = ", enume.Name.Name); } else { Console.Write("enum <NONAME> = "); } Console.Write("{"); for (int i = 0, n = enume.Members.Length; i < n; i++) { Field enumerator = (Field)enume.Members[i]; Console.Write("{0}", enumerator.Name.Name); if (enumerator.DefaultValue != null) { Console.Write(" = {0}", enumerator.DefaultValue.ToString()); } if (i < n - 1) { Console.Write(", "); } } Console.WriteLine("};"); break; } case NodeType.Interface: { Interface interfac = node as Interface; indent(shift); if (interfac.IsAbstract) { Console.Write("abstract "); } if (interfac.IsPrivate) { Console.Write("private "); } else if (interfac.IsPublic) { Console.Write("public "); } else { Console.Write("internal "); // ??????????? } Console.WriteLine("interface {0}", interfac.Name.Name); indent(shift); Console.WriteLine("{"); if (interfac.Members != null && interfac.Members.Length != 0) { for (int i = 0, n = interfac.Members.Length; i < n; i++) { Member member = interfac.Members[i]; if (member == null) { indent(shift + ind); Console.WriteLine("<UNRESOLVED MEMBER>"); continue; } report(member, shift + ind); } } indent(shift); Console.WriteLine("}"); break; } case NodeType.Method: case NodeType.InstanceInitializer: { Method method = node as Method; indent(shift); if (method.IsAbstract) { Console.Write("abstract "); } if (method.IsPublic) { Console.Write("public "); } if (method.IsStatic) { Console.Write("static "); } if (method.IsVirtual) { Console.Write("virtual "); } if (method.IsPrivate) { Console.Write("private "); } if (method.OverriddenMethod != null) { Console.Write("override "); } if (method.ReturnType != null && method.ReturnType.Name != null) { Console.Write("{0} ", method.ReturnType.Name.Name); } if (method.Name != null) { if (method.ImplementedInterfaceMethods != null && method.ImplementedInterfaceMethods.Length != 0) { Method interf = method.ImplementedInterfaceMethods[0]; if (interf != null) { string name = interf.DeclaringType.Name.Name; Console.Write("{0}.", name); } } Console.Write("{0}", method.Name.Name); } Console.Write(" ("); if (method.Parameters != null && method.Parameters.Length != 0) { for (int i = 0, n = method.Parameters.Length; i < n; i++) { Parameter par = method.Parameters[i]; if (par == null) { continue; } if ((par.Flags & ParameterFlags.In) != 0) { Console.Write("in "); } if ((par.Flags & ParameterFlags.Out) != 0) { Console.Write("out "); } if (par.Type != null && par.Type.Name != null) { Console.Write("{0}", par.Type.Name.Name); } else { report(par.Type, 0); } Console.Write(" {0}", par.Name.Name); if (i < n - 1) { Console.Write(", "); } } } Console.Write(" )"); // method body if (method.Body != null) { Console.WriteLine(); report(method.Body, shift); } else { Console.WriteLine(";"); } break; } case NodeType.DelegateNode: { DelegateNode dn = node as DelegateNode; indent(shift); Console.Write("delegate "); if (dn.ReturnType != null && dn.ReturnType.Name != null) { Console.Write("{0} ", dn.ReturnType.Name.Name); } if (dn.Name != null) { Console.Write("{0}", dn.Name.Name); } Console.Write(" ("); if (dn.Parameters != null && dn.Parameters.Length != 0) { for (int i = 0, n = dn.Parameters.Length; i < n; i++) { Parameter par = dn.Parameters[i]; if (par == null) { continue; } if ((par.Flags & ParameterFlags.In) != 0) { Console.Write("in "); } if ((par.Flags & ParameterFlags.Out) != 0) { Console.Write("out "); } if (par.Type != null && par.Type.Name != null) { Console.Write("{0}", par.Type.Name.Name); } else { report(par.Type, 0); } Console.Write(" {0}", par.Name.Name); if (i < n - 1) { Console.Write(", "); } } } Console.WriteLine(" );"); break; } case NodeType.StaticInitializer: { StaticInitializer si = node as StaticInitializer; indent(shift); Console.WriteLine("static {0} ( )", si.Name.Name); // body if (si.Body != null) { report(si.Body, shift); } else { Console.WriteLine("NO BODY"); } break; } case NodeType.FieldInitializerBlock: { FieldInitializerBlock initializers = node as FieldInitializerBlock; indent(shift); if (initializers.IsStatic) { Console.Write("static "); } Console.WriteLine("init {"); for (int i = 0, n = initializers.Statements.Length; i < n; i++) { report(initializers.Statements[i], shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Base: { Console.Write("base"); break; } case NodeType.Field: { Field field = node as Field; indent(shift); if (field.IsPrivate) { Console.Write("private "); } else if (field.IsPublic) { Console.Write("public "); } if (field.IsStatic) { Console.Write("static "); } if (field.IsInitOnly) { Console.Write("readonly "); } if (field.Type != null) { if (field.Type.Name != null) { Console.Write("{0}", field.Type.Name.Name); } else { report(field.Type, 0); } } Console.Write(" {0}", field.Name.Name); if (field.Initializer != null) { Console.Write(" = "); report(field.Initializer, 0); } Console.WriteLine(";"); break; } case NodeType.VariableDeclaration: { VariableDeclaration variable = node as VariableDeclaration; indent(shift); if (variable.Type != null && variable.Type.Name != null) { Console.Write("{0}", variable.Type.Name.Name); } else { report(variable.Type, 0); } Console.Write(" {0}", variable.Name.Name); if (variable.Initializer != null) { Console.Write(" = "); report(variable.Initializer, 0); } Console.WriteLine(";"); break; } case NodeType.LocalDeclarationsStatement: { LocalDeclarationsStatement stmt = node as LocalDeclarationsStatement; indent(shift); TypeNode type = stmt.Type; if (type != null && type.Name != null) { Console.Write("{0}", type.Name.Name); } else { report(type, 0); } Console.Write(" "); LocalDeclarationList list = stmt.Declarations; for (int i = 0, n = list.Length; i < n; i++) { LocalDeclaration local = list[i]; Console.Write("{0}", local.Name.Name); if (local.InitialValue != null) { Console.Write(" = "); report(local.InitialValue, 0); } if (i < n - 1) { Console.Write(", "); } } Console.WriteLine(";"); break; } case NodeType.Property: { Property property = node as Property; indent(shift); if (property.IsPrivate) { Console.Write("private "); } else if (property.IsPublic) { Console.Write("public "); } if (property.IsStatic) { Console.Write("static "); } if (property != null) { if (property.Type != null && property.Type.Name != null) { Console.Write("{0} ", property.Type.Name.Name); } if (property.ImplementedTypes != null) { TypeNode typ = property.ImplementedTypes[0]; Console.Write("{0}.", typ.Name.Name); } if (property.Name != null) { Console.WriteLine("{0}", property.Name.Name); } } indent(shift); Console.WriteLine("{"); if (property.Getter != null) { report(property.Getter, shift + ind); } if (property.Setter != null) { report(property.Setter, shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Lock: { Lock _lock = node as Lock; indent(shift); Console.Write("lock("); report(_lock.Guard, shift); Console.WriteLine(")"); report(_lock.Body, shift + ind); indent(shift); Console.WriteLine("}"); break; } case NodeType.Block: { Block block = node as Block; if (block == null || block.Statements == null) { break; } indent(shift); Console.WriteLine("{"); for (int i = 0, n = block.Statements.Length; i < n; i++) { report(block.Statements[i], shift + ind); Console.WriteLine(); } indent(shift); Console.WriteLine("}"); break; } case NodeType.MemberBinding: { MemberBinding mb = node as MemberBinding; if (mb.TargetObject != null) { report(mb.TargetObject, 0); } else if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null) { Console.Write(mb.BoundMember.DeclaringType.Name); } Console.Write("."); if (mb.BoundMember.Name != null) { Console.Write(mb.BoundMember.Name.Name); } else { report(mb.BoundMember, 0); } break; } case NodeType.AssignmentStatement: { AssignmentStatement assignment = node as AssignmentStatement; indent(shift); report(assignment.Target, 0); switch (assignment.Operator) { case NodeType.Nop: Console.Write(" = "); break; case NodeType.Add: Console.Write(" += "); break; case NodeType.Add_Ovf: Console.Write(" += "); break; case NodeType.Add_Ovf_Un: Console.Write(" += "); break; case NodeType.Sub: Console.Write(" -= "); break; case NodeType.Sub_Ovf: Console.Write(" -= "); break; case NodeType.Sub_Ovf_Un: Console.Write(" -= "); break; case NodeType.Mul: Console.Write(" *= "); break; case NodeType.Mul_Ovf: Console.Write(" *= "); break; case NodeType.Mul_Ovf_Un: Console.Write(" *= "); break; } report(assignment.Source, 0); Console.Write(";"); break; } case NodeType.ExpressionStatement: { ExpressionStatement exprStatement = node as ExpressionStatement; indent(shift); report(exprStatement.Expression, 0); Console.Write(";"); break; } case NodeType.Return: { Return return_stmt = node as Return; indent(shift); Console.Write("return"); if (return_stmt.Expression != null) { Console.Write(" "); report(return_stmt.Expression, 0); } Console.Write(";"); break; } case NodeType.Branch: { Branch branch = node as Branch; indent(shift); Console.WriteLine("break; (???)"); break; } case NodeType.For: { For for_stmt = node as For; indent(shift); Console.Write("for ( "); for (int i = 0, n = for_stmt.Initializer.Length; i < n; i++) { report(for_stmt.Initializer[i], 0); } report(for_stmt.Condition, 0); Console.Write("; "); for (int i = 0, n = for_stmt.Incrementer.Length; i < n; i++) { report(for_stmt.Incrementer[i], 0); } Console.WriteLine(")"); indent(shift); Console.WriteLine("{"); report(for_stmt.Body, shift + ind); indent(shift); Console.WriteLine("}"); break; } case NodeType.While: { While while_loop = node as While; indent(shift); Console.Write("while ( "); report(while_loop.Condition, 0); Console.WriteLine(" )"); report(while_loop.Body, shift); break; } case NodeType.DoWhile: { DoWhile repeat = node as DoWhile; indent(shift); Console.WriteLine("do"); report(repeat.Body, shift); indent(shift); Console.Write("while ("); report(repeat.Condition, 0); Console.WriteLine(" );"); break; } case NodeType.If: { If if_stmt = node as If; indent(shift); Console.Write("if ( "); report(if_stmt.Condition, 0); Console.WriteLine(" )"); report(if_stmt.TrueBlock, shift); if (if_stmt.FalseBlock == null || if_stmt.FalseBlock.Statements == null || if_stmt.FalseBlock.Statements.Length == 0) { break; } indent(shift); Console.WriteLine("else"); report(if_stmt.FalseBlock, shift); break; } case NodeType.Switch: { Switch swtch = node as Switch; indent(shift); Console.Write("switch ( "); report(swtch.Expression, 0); Console.WriteLine(" )"); indent(shift); Console.WriteLine("{"); for (int i = 0, n = swtch.Cases.Length; i < n; i++) { indent(shift + ind); if (swtch.Cases[i].Label != null) { Console.Write("case "); report(swtch.Cases[i].Label, 0); Console.WriteLine(":"); } else { Console.WriteLine("default:"); } report(swtch.Cases[i].Body, shift + ind); } indent(shift); Console.WriteLine("}"); break; } case NodeType.Throw: { Throw thro = node as Throw; indent(shift); Console.Write("throw ("); report(thro.Expression, 0); Console.Write(");"); break; } case NodeType.Exit: { indent(shift); Console.WriteLine("exit;"); break; } case NodeType.Continue: { indent(shift); Console.WriteLine("continue;"); break; } case NodeType.Try: { Try trys = node as Try; indent(shift); Console.WriteLine("try {"); report(trys.TryBlock, shift + ind); indent(shift); Console.WriteLine("}"); if (trys.Catchers != null) { for (int i = 0, n = trys.Catchers.Length; i < n; i++) { indent(shift); if (trys.Catchers[i].Type != null) { Console.Write("catch ( {0} ", trys.Catchers[i].Type.FullName); } else { Console.Write("catch ( "); } if (trys.Catchers[i].Variable != null) { report(trys.Catchers[i].Variable, 0); } Console.WriteLine(" ) {"); report(trys.Catchers[i].Block, shift + ind); indent(shift); Console.WriteLine("}"); } } if (trys.Finally != null && trys.Finally.Block != null) { indent(shift); Console.WriteLine("finally"); report(trys.Finally.Block, shift); } break; } case NodeType.BlockExpression: { BlockExpression be = node as BlockExpression; Console.WriteLine("("); StatementList sl = be.Block.Statements; for (int i = 0, n = sl.Length; i < n; i++) { report(sl[i], shift + ind); } indent(shift); Console.Write(")"); break; } case NodeType.ArrayTypeExpression: { ArrayTypeExpression array = node as ArrayTypeExpression; indent(shift); if (array.ElementType != null && array.ElementType.Name != null && array.ElementType.Name.Name != null) { Console.Write(array.ElementType.Name.Name); } else { report(array.ElementType, 0); } Console.Write("["); for (int i = 0, n = array.Rank; i < n; i++) { if (array.Sizes != null) { Console.Write(array.Sizes[i]); } if (i < n - 1) { Console.Write(","); } } Console.Write("]"); break; } case NodeType.Construct: { Construct construct = node as Construct; indent(shift); Console.Write("new "); report(construct.Constructor, 0); Console.Write("("); if (construct.Operands != null) { for (int i = 0, n = construct.Operands.Length; i < n; i++) { report(construct.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } } Console.Write(")"); break; } case NodeType.ConstructArray: { ConstructArray initializer = node as ConstructArray; Console.Write("new "); if (initializer.ElementType != null && initializer.ElementType.Name != null && initializer.ElementType.Name.Name != null) { Console.Write(initializer.ElementType.Name.Name); } else { report(initializer.ElementType, 0); } Console.Write("["); for (int i = 0, n = initializer.Operands.Length; i < n; i++) { report(initializer.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } Console.Write("]"); break; } case NodeType.ConstructDelegate: { ConstructDelegate cd = node as ConstructDelegate; // Console.Write("new {0}({1})",cd.DelegateType.Name.Name,cd.MethodName.Name); Console.Write("new {0}(", cd.DelegateType.Name.Name); report(cd.TargetObject, 0); Console.Write(".{0})", cd.MethodName.Name); // cd.Type; break; } default: { if (node is ZonnonCompilation) { ZonnonCompilation zc = node as ZonnonCompilation; report(zc.CompilationUnits[0], shift); } // Expression? else if (node is MethodCall) { MethodCall call = node as MethodCall; report(call.Callee, 0); Console.Write("("); if (call.Operands != null && call.Operands.Length != 0) { for (int i = 0, n = call.Operands.Length; i < n; i++) { report(call.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } } Console.Write(")"); } else if (node is Variable) { Variable variable = node as Variable; Console.Write("{0}", variable.Name.Name); } else if (node is Identifier) { Identifier identifier = node as Identifier; Console.Write("{0}", identifier.Name); } else if (node is QualifiedIdentifier) { QualifiedIdentifier qualid = node as QualifiedIdentifier; report(qualid.Qualifier, 0); Console.Write(".{0}", qualid.Identifier == null?"<UNRESOLVED>":qualid.Identifier.Name); } else if (node is Literal) { Literal literal = node as Literal; if (literal.Value == null) { Console.Write("null"); } else { if (literal.Value is string) { Console.Write("\""); } else if (literal.Value is char) { Console.Write("'"); } Console.Write("{0}", literal.Value.ToString()); if (literal.Value is string) { Console.Write("\""); } else if (literal.Value is char) { Console.Write("'"); } } } else if (node is Indexer) { Indexer indexer = node as Indexer; report(indexer.Object, 0); Console.Write("["); for (int i = 0, n = indexer.Operands.Length; i < n; i++) { report(indexer.Operands[i], 0); if (i < n - 1) { Console.Write(","); } } Console.Write("]"); } else if (node is UnaryExpression) { UnaryExpression unexpr = node as UnaryExpression; bool add_pars = unexpr.Operand is BinaryExpression || unexpr.Operand is UnaryExpression; switch (unexpr.NodeType) { case NodeType.Add: Console.Write("+"); break; case NodeType.Sub: Console.Write("-"); break; case NodeType.Neg: Console.Write("-"); break; case NodeType.Not: Console.Write("~"); break; case NodeType.UnaryPlus: Console.Write("+"); break; case NodeType.LogicalNot: Console.Write("!"); break; case NodeType.Conv_U2: Console.Write("(UInt16)"); break; case NodeType.RefAddress: Console.Write("ref "); break; case NodeType.Ckfinite: Console.Write("(Ckfinite)"); break; default: Console.Write("???"); break; } if (add_pars) { Console.Write("("); } report(unexpr.Operand, 0); if (add_pars) { Console.Write(")"); } } else if (node is BinaryExpression) { BinaryExpression binexpr = node as BinaryExpression; bool add_pars = binexpr.Operand1 is BinaryExpression || binexpr.Operand1 is UnaryExpression; if (binexpr.NodeType == NodeType.Castclass) { Console.Write("("); report(binexpr.Operand2, 0); Console.Write(")"); if (add_pars) { Console.Write("("); } report(binexpr.Operand1, 0); if (add_pars) { Console.Write(")"); } break; } if (add_pars) { Console.Write("("); } report(binexpr.Operand1, 0); if (add_pars) { Console.Write(")"); } switch (binexpr.NodeType) { case NodeType.Add: Console.Write(" + "); break; case NodeType.Add_Ovf: Console.Write(" + "); break; case NodeType.Add_Ovf_Un: Console.Write(" + "); break; case NodeType.Sub: Console.Write(" - "); break; case NodeType.Sub_Ovf: Console.Write(" - "); break; case NodeType.Sub_Ovf_Un: Console.Write(" - "); break; case NodeType.Mul: Console.Write(" * "); break; case NodeType.Mul_Ovf: Console.Write(" * "); break; case NodeType.Mul_Ovf_Un: Console.Write(" * "); break; case NodeType.Div: Console.Write(" / "); break; // case NodeType.Div : Console.Write(" DIV "); break; // "DIV" ????? case NodeType.Rem: Console.Write(" % "); break; // "MOD" ????? case NodeType.Or: Console.Write(" | "); break; case NodeType.And: Console.Write(" & "); break; case NodeType.Eq: Console.Write(" == "); break; case NodeType.Ne: Console.Write(" != "); break; case NodeType.Lt: Console.Write(" < "); break; case NodeType.Le: Console.Write(" <= "); break; case NodeType.Gt: Console.Write(" > "); break; case NodeType.Ge: Console.Write(" >= "); break; case NodeType.LogicalOr: Console.Write(" || "); break; case NodeType.LogicalAnd: Console.Write(" && "); break; case NodeType.Is: Console.Write(" is "); break; case NodeType.Comma: Console.Write(","); break; // case OPERATORS.In : expression.NodeType = NodeType // "IN" break; // case OPERATORS.Implements : expression.NodeType = NodeType // "IMPLEMENTS" break; default: Console.Write(" !! "); break; } add_pars = binexpr.Operand2 is BinaryExpression || binexpr.Operand2 is UnaryExpression; if (add_pars) { Console.Write("("); } report(binexpr.Operand2, 0); if (add_pars) { Console.Write(")"); } } else if (node is TernaryExpression) { TernaryExpression ter = node as TernaryExpression; if (ter.NodeType == NodeType.Conditional) { report(ter.Operand1, 0); Console.Write(" ? "); report(ter.Operand2, 0); Console.Write(" : "); report(ter.Operand3, 0); } } else if (node is PostfixExpression) { PostfixExpression postfixExpr = node as PostfixExpression; report(postfixExpr.Expression, 0); switch (postfixExpr.Operator) { case NodeType.Increment: Console.Write("++"); break; case NodeType.Decrement: Console.Write("--"); break; default: Console.Write("???"); break; } } else if (node is LabeledStatement) { LabeledStatement lbst = node as LabeledStatement; indent(shift); report(lbst.Label, 0); Console.Write(" : "); report(lbst.Statement, 0); } else if (node is Goto) { Goto gt = node as Goto; indent(shift); Console.Write("goto "); report(gt.TargetLabel, 0); } else { indent(shift); Console.WriteLine("No code for reporting {0}:{1}", node.UniqueKey, node.ToString()); } break; } } }
public static Block createElementInitializerInternal(TYPE type, Expression indexer, int level, List <Expression> nonConstantDimensions, bool skipFirstLevel, SourceContext sourceContext) { // Generates internal part of array initializer: // either object constructor or, again, array initializer. // Check if the type is ARRAY. if (!(type is ARRAY_TYPE) && !(type is OBJECT_TYPE)) { return(null); } if (type is ARRAY_TYPE) { EXPRESSION_LIST declaredDimensions = ((ARRAY_TYPE)type).dimensions; int Rank = declaredDimensions.Length; List <Expression> dimensions = new List <Expression>(); // Check if all dimensions are constants or there is an expression available. for (int i = 0, n = Rank; i < n; i++) { if (declaredDimensions[i] == null || declaredDimensions[i].calculate() == null) { if (nonConstantDimensions == null) { return(null); } if (nonConstantDimensions.Count > 0) { dimensions.Add(nonConstantDimensions[0]); nonConstantDimensions.RemoveAt(0); } else { ERROR.MissingParameters(Rank, type.sourceContext); return(null); } } else { long d = (long)declaredDimensions[i].calculate(); Literal dim = new Literal((int)d, SystemTypes.Int32); dimensions.Add(dim); } } Block block = new Block(new StatementList()); // Generate array initializer: // x = new object[n]; if (skipFirstLevel && level == 0) { goto Bypass; } AssignmentStatement array_initializer = new AssignmentStatement(); array_initializer.NodeType = NodeType.AssignmentStatement; array_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. // Generate 'new object[n]' ConstructArray array_construct = new ConstructArray(); Node elem_type = ((ARRAY_TYPE)type).base_type.convert(); if (elem_type is ArrayTypeExpression) { ArrayTypeExpression arr_type = (elem_type.Clone()) as ArrayTypeExpression; // for ( int i=0, n=arr_type.Rank; i<n; i++ ) // arr_type.Sizes[i] = -1; elem_type = arr_type; } array_construct.ElementType = (TypeNode)elem_type; array_construct.Rank = Rank; array_construct.SourceContext = sourceContext; array_construct.Type = (TypeNode)type.convert(); array_construct.Operands = new ExpressionList(); for (int i = 0; i < Rank; i++) { array_construct.Operands.Add(dimensions[i]); } array_initializer.Source = array_construct; array_initializer.Target = indexer; array_initializer.SourceContext = sourceContext; block.Statements.Add(array_initializer); Bypass: // Generate x[i0,i1,...] for passing to the recursive call. Indexer new_indexer = new Indexer(); new_indexer.Object = indexer; new_indexer.Type = type.convert() as TypeNode; new_indexer.ElementType = ((ARRAY_TYPE)type).base_type.convert() as TypeNode; new_indexer.Operands = new ExpressionList(); for (int i = 0; i < Rank; i++) { Identifier index = Identifier.For("_i" + (level + i).ToString()); new_indexer.Operands.Add(index); } // Generate the last part (see comment, part 4, below). Block elem_initializers = createElementInitializerInternal(((ARRAY_TYPE)type).base_type, new_indexer, level + Rank, nonConstantDimensions, true, sourceContext); if (elem_initializers == null) { return(block); } // We do not need loops to initialize elements... // Return just array initializer. // Otherwise go generate initializers. // Generate // 1) int i0, i1, ...; // 2) for (int i1=0; i1<n; i1++) // for (int i2=0; i2<m; i2++) // ... // // Generate recursively: // 3) Initializers for array elements: x[i1,i2,...] = new object[n]; // 4) Initializers for every element (the similar loop(s)). // Generate int i0, i1, ...; for (int i = 0; i < Rank; i++) { VariableDeclaration locali = new VariableDeclaration(Identifier.For("_i" + (level + i).ToString()), SystemTypes.Int32, null); block.Statements.Add(locali); } // Generate loop headers: // for (int i1=0; i1<n; i1++) // for (int i2=0; i2<m; i2++) // ... Block owner = block; // where to put generated for-node for (int i = 0; i < Rank; i++) { For forStatement = new For(); // forStatement.NodeType; forStatement.SourceContext = sourceContext; // Making for-statement's body forStatement.Body = new Block(); forStatement.Body.Checked = true; forStatement.Body.HasLocals = false; // forStatement.Body.NodeType; // forStatement.Body.Scope; forStatement.Body.SourceContext = sourceContext; forStatement.Body.SuppressCheck = false; forStatement.Body.Statements = new StatementList(); // Now leave the body empty... // Making condition: i<n BinaryExpression condition = new BinaryExpression(); condition.NodeType = NodeType.Lt; condition.Operand1 = Identifier.For("_i" + (level + i).ToString()); condition.Operand2 = dimensions[i]; condition.SourceContext = sourceContext; forStatement.Condition = condition; // Making incrementer: i+=1 forStatement.Incrementer = new StatementList(); AssignmentStatement assignment = new AssignmentStatement(); assignment.NodeType = NodeType.AssignmentStatement; assignment.Operator = NodeType.Add; // Hope this means += // assignment.OperatorOverload assignment.Source = new Literal((int)1, SystemTypes.Int32); assignment.SourceContext = sourceContext; assignment.Target = Identifier.For("_i" + (level + i).ToString()); forStatement.Incrementer.Add(assignment); // Making initializer: i=0 forStatement.Initializer = new StatementList(); AssignmentStatement initializer = new AssignmentStatement(); initializer.NodeType = NodeType.AssignmentStatement; initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. initializer.Source = new Literal(0, SystemTypes.Int32); initializer.Target = Identifier.For("_i" + (level + i).ToString()); initializer.SourceContext = sourceContext; forStatement.Initializer.Add(initializer); owner.Statements.Add(forStatement); owner = forStatement.Body; // for next iteration } // Adding element initializers generated in advance. owner.Statements.Add(elem_initializers); return(block); } else if (type is OBJECT_TYPE) { // Check if the type is VAL-object. if (!((OBJECT_TYPE)type).ObjectUnit.modifiers.Value) { return(null); } Block block = new Block(new StatementList()); // Generate 'new obj' DECLARATION objct = ((OBJECT_TYPE)type).ObjectUnit; // We do it for only own value types. They have // extra constcutor that takes ont fictive intgere. Might have // Chtck and call it Construct construct = new Construct(); // Strange thing: CCI expects _class_ in Construst.Constructor, // but not a constructor itself!.. // construct.Constructor = new MemberBinding(null,((TypeNode)objct.convert()).GetConstructors()[0]); // NODE.convertTypeName(objct); construct.Constructor = new MemberBinding(null, (TypeNode)objct.convert()); construct.Constructor.Type = SystemTypes.Type; construct.Operands = new ExpressionList(); construct.SourceContext = sourceContext; construct.Type = (TypeNode)objct.convert(); construct.Operands.Add(new Literal(1, SystemTypes.Int32)); // Generate x[i0,i1,...] = new obj; AssignmentStatement main_initializer = new AssignmentStatement(); main_initializer.NodeType = NodeType.AssignmentStatement; main_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. main_initializer.Source = construct; main_initializer.Target = indexer; main_initializer.SourceContext = sourceContext; block.Statements.Add(main_initializer); return(block); } else if (type is EXTERNAL_TYPE) { // Only value types might need extra calls Struct str = ((EXTERNAL_TYPE)type).entity as Struct; InstanceInitializer ctr = str.GetConstructor(new TypeNode[] { SystemTypes.Int32 }); bool possibly_was_our_structure = (ctr != null); if (ctr == null) { ctr = str.GetConstructor(new TypeNode[0] { }); } // TO_DO: When metadata is available replace this with // more consistent check Block block = new Block(new StatementList()); // Generate 'new obj' Construct construct = new Construct(); construct.Constructor = new MemberBinding(null, ctr); construct.Operands = new ExpressionList(); construct.Type = str; // We do it for only own value types. They have // extra constcutor that takes ont fictive intgere. Might have // Chtck and call it if (possibly_was_our_structure) { construct.Operands.Add(Literal.Int32MinusOne); } // Generate x[i0,i1,...] = new obj; AssignmentStatement main_initializer = new AssignmentStatement(); main_initializer.NodeType = NodeType.AssignmentStatement; main_initializer.Operator = NodeType.Nop; // this means "normal" assignment, but not += etc. main_initializer.Source = construct; main_initializer.Target = indexer; main_initializer.SourceContext = sourceContext; indexer.Type = construct.Type; block.Statements.Add(main_initializer); return(block); } else { return(null); } }
private Expression ParseArrayInitializer(ArrayTypeExpression arrayTypeExpression, TokenSet followers) //^ requires this.currentToken == Token.LeftBrace; //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { uint rank = arrayTypeExpression.Rank; SourceLocationBuilder slb = new SourceLocationBuilder(this.scanner.SourceLocationOfLastScannedToken); List<Expression> initializers = this.ParseArrayInitializers(rank, arrayTypeExpression.ElementType, followers, false, slb); //^ assert followers[this.currentToken] || this.currentToken == Token.EndOfFile; List<Expression> lowerBounds = new List<Expression>(0); List<Expression> sizes = new List<Expression>(0); Expression result = new CreateArray(arrayTypeExpression.ElementType, initializers, lowerBounds, rank, sizes, slb); //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile; return result; }
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 ParseArrayType(uint rank, TypeExpression elementType, SourceLocationBuilder sctx, TokenSet followers) //^ requires rank > 0; //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { List<uint> rankList = new List<uint>(); for (;;) // ^ invariant forall{int i in (0:rankList.Count); rankList[i] > 0}; //TODO: find out why this does not parse { rankList.Add(rank); //TODO: find away to tell Boogie that this does not modify this.currentToken if (this.currentToken != Token.LeftBracket) break; rank = this.ParseRankSpecifier(sctx, followers|Token.LeftBracket); } for (int i = rankList.Count; i > 0; i--) // ^ invariant forall{int i in (0:rankList.Count); rankList[i] > 0}; { rank = rankList[i-1]; //^ assume rank > 0; elementType = new ArrayTypeExpression(elementType, rank, sctx.GetSourceLocation()); //TODO: find away to tell Boogie that this does not modify this.currentToken } //^ assume followers[this.currentToken] || this.currentToken == Token.EndOfFile; return elementType; }
public virtual TypeNode VisitArrayTypeExpression(ArrayTypeExpression atExpr){ if (atExpr == null) return null; this.AbstractSealedUsedAsType = Error.AbstractSealedArrayElementType; TypeNode et = this.VisitTypeReference(atExpr.ElementType, true); this.AbstractSealedUsedAsType = Error.NotAType; if (et == null) return null; if (et == SystemTypes.DynamicallyTypedReference || et == SystemTypes.ArgIterator){ this.HandleError(atExpr.ElementType, Error.ArrayElementCannotBeTypedReference, this.GetTypeName(et)); return null; } if (atExpr.Rank == 1 && (atExpr.Sizes == null || atExpr.Sizes.Length == 0) && (atExpr.LowerBounds == null || atExpr.LowerBounds.Length == 0)) return et.GetArrayType(atExpr.Rank); else return et.GetArrayType(atExpr.Rank, atExpr.Sizes, atExpr.LowerBounds); }