private TypeExpression VisitTypeExpression(TypeExpression tExpr) { this.Visit(tExpr.Expression); return tExpr; }
private TypeNode ParseBaseTypeExpression(Identifier className, TokenSet followers, bool returnNullIfError, bool Typeof){ TypeNode result = null; switch(this.currentToken){ case Token.Bool: case Token.Decimal: case Token.Sbyte: case Token.Byte: case Token.Short: case Token.Ushort: case Token.Int: case Token.Uint: case Token.Long: case Token.Ulong: case Token.Char: case Token.Float: case Token.Double: case Token.Object: case Token.String: result = this.TypeExpressionFor(this.currentToken); if (this.sink != null) this.StartTypeName(this.currentToken); //TODO: if sink != null start a name (Looker also has to co-operate) this.GetNextToken(); if (returnNullIfError && !followers[this.currentToken]) return null; this.SkipTo(followers); return result; case Token.Void: result = this.TypeExpressionFor(this.currentToken); SourceContext sctx = this.scanner.CurrentSourceContext; this.GetNextToken(); if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken] && !(this.currentToken == Token.Multiply && this.inUnsafeCode)){ if (this.currentToken == Token.Operator || this.currentToken == Token.Implicit || this.currentToken == Token.Explicit) this.HandleError(sctx, Error.OperatorCantReturnVoid); else this.HandleError(sctx, Error.NoVoidHere); result = this.TypeExpressionFor(Token.Object); result.SourceContext = sctx; } this.SkipTo(followers); return result; default: if (this.currentToken == Token.EndOfFile) { this.returnedEmptyIdentForEOF = true; } Identifier id = this.scanner.GetIdentifier(); TypeExpression te = null; if (className != null && Parser.IdentifierOrNonReservedKeyword[this.currentToken] && className.UniqueIdKey == id.UniqueIdKey){ this.GetNextToken(); if (this.currentToken == Token.LeftParenthesis) return this.TypeExpressionFor(Token.Void); }else if (returnNullIfError && !Parser.IdentifierOrNonReservedKeyword[this.currentToken]) return null; else if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]){ this.GetNextToken(); if (this.currentToken == Token.DoubleColon){ this.GetNextToken(); Identifier id2 = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); id2.Prefix = id; id2.SourceContext.StartPos = id.SourceContext.StartPos; te = new TypeExpression(id2); id = id2; } if (this.sink != null) this.sink.StartName(id); }else{ this.SkipIdentifierOrNonReservedKeyword(Error.TypeExpected); } if (this.currentToken == Token.Dot){ te = new TypeExpression(this.ParseQualifiedIdentifier(id, followers|Token.LessThan, returnNullIfError)); if (returnNullIfError && te.Expression == null) return null; }else if (te == null) te = new TypeExpression(id); te.SourceContext = te.Expression.SourceContext; result = te; break; } while (this.currentToken == Token.LessThan){ int endCol, arity; TypeExpression te = result as TypeExpression; result.TemplateArgumentExpressions = this.ParseTypeArguments(returnNullIfError, Typeof && te != null, followers|Token.Dot, out endCol, out arity); if (Typeof && te != null && arity > 0) te.Arity = arity; else{ result.TemplateArguments = result.TemplateArgumentExpressions == null ? null : result.TemplateArgumentExpressions.Clone(); if (returnNullIfError && result.TemplateArguments == null && this.sink == null) return null; if (result.TemplateArguments == null){ result.TemplateArguments = new TypeNodeList(1); result.TemplateArguments.Add(null); } } if (this.currentToken == Token.Dot) { MemberBinding mb = new MemberBinding(null, result, result.SourceContext); te = new TypeExpression(this.ParseQualifiedIdentifier(mb, followers|Token.LessThan, returnNullIfError)); if (returnNullIfError && te.Expression == null) return null; te.SourceContext = te.Expression.SourceContext; result = te; } } if (returnNullIfError && !followers[this.currentToken]) return null; if (className != null){ if (followers[this.currentToken]) return result; this.SkipTo(followers, Error.InvalidMemberDecl, this.scanner.GetTokenSource()); }else this.SkipTo(followers); return result; }
private bool TypeExpressionIsUnambiguous(TypeExpression texpr){ if (texpr == null) return false; if (texpr.Expression is Literal && ((Literal)texpr.Expression).Value is TypeCode) return true; Expression e = texpr.Expression; for (QualifiedIdentifier qual = e as QualifiedIdentifier; qual != null; qual = qual.Qualifier as QualifiedIdentifier); Identifier id = e as Identifier; if (id != null && id.Prefix != null) return true; return false; }
private void ParseEvent(TypeNode parentType, AttributeList attributes, TokenList modifierTokens, SourceContextList modifierContexts, object sctx, TokenSet followers){ Debug.Assert(this.currentToken == Token.Event); this.GetNextToken(); Event e = new Event(parentType, attributes, EventFlags.None, null, null, null, null, null); e.DeclaringType = parentType; e.Documentation = this.LastDocComment; TypeNode t = this.ParseTypeExpression(Identifier.Empty, followers|Parser.IdentifierOrNonReservedKeyword); //REVIEW: allow events with anonymous delegate type? e.HandlerType = e.HandlerTypeExpression = t; TypeExpression interfaceType = null; Identifier id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); TypeNodeList templateArguments = null; int endPos = 0, arity = 0; while (this.currentToken == Token.Dot || this.currentToken == Token.LessThan) { if (interfaceType == null && this.ExplicitInterfaceImplementationIsAllowable(parentType, id)) { for (int i = 0, n = modifierContexts == null ? 0 : modifierContexts.Length; i < n; i++){ this.HandleError(modifierContexts[i], Error.InvalidModifier, modifierContexts[i].SourceText); modifierTokens = new TokenList(0); } } TypeExpression intfExpr = interfaceType; if (intfExpr == null) { intfExpr = new TypeExpression(id, id.SourceContext); } else if( templateArguments == null) { SourceContext ctx = intfExpr.Expression.SourceContext; ctx.EndPos = id.SourceContext.EndPos; intfExpr.Expression = new QualifiedIdentifier(intfExpr.Expression, id, ctx); } if (templateArguments != null) { intfExpr.TemplateArguments = templateArguments; intfExpr.SourceContext.EndPos = endPos; } if (this.currentToken == Token.LessThan) { templateArguments = this.ParseTypeArguments(true, false, followers | Token.Dot | Token.LeftParenthesis | Token.LeftBrace, out endPos, out arity); } else { // Dot templateArguments = null; this.GetNextToken(); id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); if (intfExpr == null) id.SourceContext.Document = null; } interfaceType = intfExpr; } e.Name = id; MethodFlags mflags = this.GetMethodFlags(modifierTokens, modifierContexts, parentType, e); if ((mflags & MethodFlags.Static) != 0 && parentType is Interface){ this.HandleError(id.SourceContext, Error.InvalidModifier, "static"); mflags &= ~MethodFlags.Static; mflags |= MethodFlags.Abstract; } e.HandlerFlags = mflags|MethodFlags.SpecialName; bool hasAccessors = this.currentToken == Token.LeftBrace || interfaceType != null; if (hasAccessors){ if (interfaceType != null){ e.ImplementedTypeExpressions = e.ImplementedTypes = new TypeNodeList(interfaceType); if (this.currentToken != Token.LeftBrace){ this.HandleError(Error.ExplicitEventFieldImpl); hasAccessors = false; goto nextDeclarator; } } this.Skip(Token.LeftBrace); TokenSet followersOrRightBrace = followers|Token.RightBrace; bool alreadyGivenAddOrRemoveExpectedError = false; bool alreadyComplainedAboutAccessors = false; for(;;){ SourceContext sc = this.scanner.CurrentSourceContext; AttributeList accessorAttrs = this.ParseAttributes(null, followers|Parser.AddOrRemoveOrModifier|Token.LeftBrace); switch (this.currentToken){ case Token.Add: if (parentType is Interface && !alreadyComplainedAboutAccessors){ this.HandleError(Error.EventPropertyInInterface, parentType.FullName+"."+id); alreadyComplainedAboutAccessors = true; }else if (e.HandlerAdder != null) this.HandleError(Error.DuplicateAccessor); SourceContext scntx = this.scanner.CurrentSourceContext; this.GetNextToken(); ParameterList parList = new ParameterList(); parList.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, t, null, null)); Method m = new Method(parentType, accessorAttrs, new Identifier("add_"+id.ToString()), parList, this.TypeExpressionFor(Token.Void), null); m.HidesBaseClassMember = e.HidesBaseClassMember; m.OverridesBaseClassMember = e.OverridesBaseClassMember; m.Name.SourceContext = scntx; if ((mflags & MethodFlags.Static) == 0) m.CallingConvention = CallingConventionFlags.HasThis; m.Flags = mflags|MethodFlags.HideBySig|MethodFlags.SpecialName; if (interfaceType != null){ m.Flags = MethodFlags.Private|MethodFlags.HideBySig|MethodFlags.NewSlot|MethodFlags.Final|MethodFlags.Virtual|MethodFlags.SpecialName; m.ImplementedTypeExpressions = m.ImplementedTypes = new TypeNodeList(interfaceType); } if (this.currentToken != Token.LeftBrace){ this.SkipTo(followersOrRightBrace|Token.Remove, Error.AddRemoveMustHaveBody); alreadyGivenAddOrRemoveExpectedError = true; }else m.Body = this.ParseBody(m, sc, followersOrRightBrace|Token.Remove); if (!(parentType is Interface)){ e.HandlerAdder = m; m.DeclaringMember = e; parentType.Members.Add(m); } continue; case Token.Remove: if (parentType is Interface && !alreadyComplainedAboutAccessors){ this.HandleError(Error.EventPropertyInInterface, parentType.FullName+"."+id); alreadyComplainedAboutAccessors = true; }else if (e.HandlerRemover != null) this.HandleError(Error.DuplicateAccessor); scntx = this.scanner.CurrentSourceContext; this.GetNextToken(); parList = new ParameterList(); parList.Add(new Parameter(null, ParameterFlags.None, StandardIds.Value, t, null, null)); m = new Method(parentType, accessorAttrs, new Identifier("remove_"+id.ToString()), parList, this.TypeExpressionFor(Token.Void), null); m.HidesBaseClassMember = e.HidesBaseClassMember; m.OverridesBaseClassMember = e.OverridesBaseClassMember; m.Name.SourceContext = scntx; if ((mflags & MethodFlags.Static) == 0) m.CallingConvention = CallingConventionFlags.HasThis; m.Flags = mflags|MethodFlags.HideBySig|MethodFlags.SpecialName; if (interfaceType != null){ m.Flags = MethodFlags.Private|MethodFlags.HideBySig|MethodFlags.NewSlot|MethodFlags.Final|MethodFlags.Virtual|MethodFlags.SpecialName; m.ImplementedTypeExpressions = m.ImplementedTypes = new TypeNodeList(interfaceType); } if (this.currentToken != Token.LeftBrace){ this.SkipTo(followersOrRightBrace|Token.Add, Error.AddRemoveMustHaveBody); alreadyGivenAddOrRemoveExpectedError = true; }else m.Body = this.ParseBody(m, sc, followersOrRightBrace|Token.Add); if (!(parentType is Interface)){ e.HandlerRemover = m; m.DeclaringMember = e; parentType.Members.Add(m); } continue; case Token.New: case Token.Public: case Token.Protected: case Token.Internal: case Token.Private: case Token.Abstract: case Token.Sealed: case Token.Static: case Token.Readonly: case Token.Volatile: case Token.Virtual: case Token.Override: case Token.Extern: case Token.Unsafe: this.HandleError(Error.NoModifiersOnAccessor); this.GetNextToken(); break; default: if ((e.HandlerAdder == null || e.HandlerRemover == null) && this.sink != null && this.currentToken == Token.Identifier && this.scanner.endPos == this.scanner.maxPos){ e.SourceContext.EndPos = this.scanner.startPos; KeywordCompletionList keywords; if (e.HandlerAdder != null) keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("remove")); else if (e.HandlerRemover != null) keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("add")); else keywords = new KeywordCompletionList(this.scanner.GetIdentifier(), new KeywordCompletion("add"), new KeywordCompletion("remove")); parentType.Members.Add(keywords); this.GetNextToken(); } if (!alreadyGivenAddOrRemoveExpectedError && !alreadyComplainedAboutAccessors && (e.HandlerAdder == null || e.HandlerRemover == null)) { if (this.currentToken == Token.RightBrace) this.HandleError(id.SourceContext, Error.EventNeedsBothAccessors, parentType.FullName+"."+id.Name); else this.HandleError(Error.AddOrRemoveExpected); alreadyGivenAddOrRemoveExpectedError = true; if (!(Parser.EndOfFile|Token.LeftBrace|Token.RightBrace)[this.currentToken]) this.GetNextToken(); this.SkipTo(followersOrRightBrace|Token.LeftBrace, Error.None); if (this.currentToken == Token.LeftBrace){ this.ParseBlock(followersOrRightBrace|Token.Add|Token.Remove); continue; } } break; } break; } this.Skip(Token.RightBrace); //TODO: brace matching } nextDeclarator: e.Name = id; e.SourceContext = (SourceContext)sctx; e.SourceContext.EndPos = this.scanner.endPos; parentType.Members.Add(e); if (!hasAccessors){ switch(this.currentToken){ case Token.Assign: this.GetNextToken(); e.InitialHandler = this.ParseExpression(followers|Token.Semicolon); if (parentType is Interface && e.InitialHandler != null){ this.HandleError(e.InitialHandler.SourceContext, Error.InterfaceEventInitializer, parentType.FullName+"."+id); e.InitialHandler = null; } if (this.currentToken == Token.Comma) goto case Token.Comma; else goto default; case Token.Comma: this.GetNextToken(); id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); //REVIEW: allow interface name? e = new Event(parentType, attributes, (EventFlags)0, null, null, null, null, null); e.HandlerFlags = mflags; e.HandlerType = e.HandlerTypeExpression = t; goto nextDeclarator; default: this.Skip(Token.Semicolon); break; } } }
private void ParseFieldOrMethodOrPropertyOrStaticInitializer(TypeNode t, TypeNode parentType, AttributeList attributes, TokenList modifierTokens, SourceContextList modifierContexts, object sctx, SourceContext idCtx, TokenSet followers){ if (Parser.IsVoidType(t) && this.currentToken == Token.LeftParenthesis){ this.ParseConstructor(parentType, attributes, modifierTokens, modifierContexts, sctx, idCtx, followers|Token.Semicolon); if (this.currentToken == Token.Semicolon) this.GetNextToken(); this.SkipTo(followers); return; } bool badModifier = false; tryAgain: switch (this.currentToken){ case Token.This: Identifier itemId = new Identifier("Item"); itemId.SourceContext = this.scanner.CurrentSourceContext; this.ParseProperty(parentType, attributes, modifierTokens, modifierContexts, sctx, t, null, itemId, followers); return; case Token.Explicit: case Token.Implicit: case Token.Operator: this.ParseOperator(parentType, attributes, modifierTokens, modifierContexts, t, sctx, followers); return; case Token.New: case Token.Public: case Token.Protected: case Token.Internal: case Token.Private: case Token.Abstract: case Token.Sealed: case Token.Static: case Token.Readonly: case Token.Volatile: case Token.Virtual: case Token.Override: case Token.Extern: case Token.Unsafe: if (this.scanner.TokenIsFirstAfterLineBreak) break; if (!badModifier){ this.HandleError(Error.BadModifierLocation, this.scanner.GetTokenSource()); badModifier = true; } this.GetNextToken(); goto tryAgain; case Token.LeftParenthesis: case Token.LessThan: if (t is TypeExpression && ((TypeExpression)t).Expression is Identifier){ this.HandleError(t.SourceContext, Error.MemberNeedsType); this.ParseMethod(parentType, attributes, modifierTokens, modifierContexts, sctx, this.TypeExpressionFor(Token.Void), null, (Identifier)((TypeExpression)t).Expression, followers); return; } break; default: if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]){ if (followers[this.currentToken]) this.HandleError(Error.ExpectedIdentifier); else this.SkipTo(followers); this.ParseField(parentType, attributes, modifierTokens, modifierContexts, sctx, t, Identifier.Empty, followers); return; } break; } TypeExpression interfaceType = null; Identifier id = this.scanner.GetIdentifier(); if (badModifier) id.SourceContext.Document = null; //suppress any further errors involving this member this.SkipIdentifierOrNonReservedKeyword(); if (this.currentToken == Token.DoubleColon){ Identifier prefix = id; this.GetNextToken(); id = this.scanner.GetIdentifier(); id.Prefix = prefix; id.SourceContext.StartPos = prefix.SourceContext.StartPos; this.SkipIdentifierOrNonReservedKeyword(); } if (this.currentToken == Token.Dot){ this.GetNextToken(); if (this.ExplicitInterfaceImplementationIsAllowable(parentType, id)) interfaceType = new TypeExpression(id, id.SourceContext); if (this.currentToken == Token.This){ id = new Identifier("Item"); id.SourceContext = this.scanner.CurrentSourceContext; }else{ id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); } if (interfaceType == null) id.SourceContext.Document = null; } onceMore: switch(this.currentToken){ case Token.This: if (interfaceType == null) goto default; goto case Token.LeftBrace; case Token.LeftBrace: this.ParseProperty(parentType, attributes, modifierTokens, modifierContexts, sctx, t, interfaceType, id, followers); return; case Token.LeftParenthesis: this.ParseMethod(parentType, attributes, modifierTokens, modifierContexts, sctx, t, interfaceType, id, followers); return; case Token.LessThan: if (modifierTokens == null || modifierTokens.Length == 0) { TypeExpression intfExpr = interfaceType; if (intfExpr == null) { if (parentType is Class || parentType is Struct) intfExpr = new TypeExpression(id, id.SourceContext); else goto case Token.LeftParenthesis; } int savedStartPos = this.scanner.startPos; ScannerState ss = this.scanner.state; int endPos, arity; TypeNodeList templateArguments = this.ParseTypeArguments(true, false, followers | Token.Dot | Token.LeftParenthesis | Token.LeftBrace, out endPos, out arity); if (templateArguments != null && this.currentToken == Token.Dot) { if (intfExpr != null && intfExpr.Expression != id) { SourceContext ctx = intfExpr.Expression.SourceContext; ctx.EndPos = id.SourceContext.EndPos; intfExpr.Expression = new QualifiedIdentifier(intfExpr.Expression, id, ctx); } intfExpr.TemplateArguments = templateArguments; intfExpr.SourceContext.EndPos = endPos; interfaceType = intfExpr; this.GetNextToken(); if (this.currentToken == Token.This) { id = new Identifier("Item"); id.SourceContext = this.scanner.CurrentSourceContext; } else { id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); } goto onceMore; } this.scanner.state = ss; this.scanner.endPos = savedStartPos; this.currentToken = Token.None; this.GetNextToken(); Debug.Assert(this.currentToken == Token.LessThan); } goto case Token.LeftParenthesis; case Token.Dot: if (interfaceType != null){ this.GetNextToken(); SourceContext ctx = interfaceType.Expression.SourceContext; ctx.EndPos = id.SourceContext.EndPos; interfaceType.SourceContext.EndPos = id.SourceContext.EndPos; interfaceType.Expression = new QualifiedIdentifier(interfaceType.Expression, id, ctx); if (this.currentToken == Token.This) { id = new Identifier("Item"); id.SourceContext = this.scanner.CurrentSourceContext; } else { id = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); } goto onceMore; } goto default; default: if (interfaceType != null) this.ParseMethod(parentType, attributes, modifierTokens, modifierContexts, sctx, t, interfaceType, id, followers); else this.ParseField(parentType, attributes, modifierTokens, modifierContexts, sctx, t, id, followers); return; } }
public TypeExpression VisitTypeExpression(TypeExpression typeExpression) { typeExpression.Expression = this.VisitExpression(typeExpression.Expression); return typeExpression; }
// Create a secondary constructor that provides for initialization of // the "this" pointer as well as the input parameters private void ExtendMethodConstructor(Class newClass, ZMethod zMethod) { int numAddedParams = 0; // Duplicate our basic constructor so we can make an extended version System.Compiler.Duplicator dup = new System.Compiler.Duplicator(null, null); InstanceInitializer ctor = dup.VisitInstanceInitializer((InstanceInitializer)newClass.Members[0]); if (!zMethod.IsStatic) { // For instance methods, add a "This" parameter to the constructor ctor.Parameters.Add(new Parameter(Identifier.For("This"), new TypeExpression(Identifier.For("Pointer")))); // this.This = This; ctor.Body.Statements.Add( new ExpressionStatement( new AssignmentExpression( new AssignmentStatement( new QualifiedIdentifier(new This(), Identifier.For("This")), Identifier.For("This")))) ); numAddedParams++; } for (int i = 0, n = zMethod.Parameters.Count; i < n; i++) { TypeNode paramType; Parameter param = zMethod.Parameters[i]; if (param == null || param.Type == null) continue; if (param.IsOut) continue; if (GetTypeClassification(param.Type) == TypeClassification.Heap) paramType = this.ZingPtrType; else if (!IsPredefinedType(param.Type)) paramType = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), param.Type.Name)); else paramType = param.Type; ctor.Parameters.Add(new Parameter(param.Name, paramType)); // inputs.foo = foo; ctor.Body.Statements.Add( new ExpressionStatement( new AssignmentExpression( new AssignmentStatement( new QualifiedIdentifier(Identifier.For("inputs"), param.Name), param.Name))) ); numAddedParams++; } // If we didn't actually add any parameters, then the basic constructor is // all that we need. Only add the new constructor if it's different. if (numAddedParams > 0) { newClass.Members.Add(ctor); ctor.DeclaringType = newClass; } }
private void collectStructAccessors(bool isGlobalVar, Struct s, Expression expPrefix, string strPrefix, Class theClass) { if (s == null) return; for (int i = 0, n = s.Members.Count; i < n; i++) { Field f = s.Members[i] as Field; if (f == null) continue; string name = strPrefix + "_" + f.Name.Name; QualifiedIdentifier qf = new QualifiedIdentifier(expPrefix, f.Name); TypeNode generatedType = f.Type; if (GetTypeClassification(f.Type) == TypeClassification.Heap) generatedType = this.ZingPtrType; else if (!IsPredefinedType(f.Type)) generatedType = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), f.Type.Name), f.Type.SourceContext); QualifiedIdentifier localsInputsOrOutputs = isGlobalVar ? new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Global")) : new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Local")); Property accessor = GetStructAccessorProperty(isGlobalVar ? "globalAccessor" : "localAccessor", generatedType, new Identifier("__strprops_" + name), qf, localsInputsOrOutputs); theClass.Members.Add(accessor); accessor.DeclaringType = theClass; if (accessor.Getter != null) { theClass.Members.Add(accessor.Getter); accessor.Getter.DeclaringType = theClass; } if (accessor.Setter != null) { theClass.Members.Add(accessor.Setter); accessor.Setter.DeclaringType = theClass; } if (f.Type is Struct && !f.Type.IsPrimitive && f.Type != SystemTypes.Decimal) collectStructAccessors(isGlobalVar, (Struct)f.Type, qf, name, theClass); } }