public override Expression VisitQualifiedIdentifierCore(QualifiedIdentifier qualId) { Identifier id = qualId.Identifier; Expression target = base.VisitQualifiedIdentifierCore(qualId); if (target == null && !this.inCompatibilityMode && this.insideAssertion) target = Looker.BindPseudoMember(qualId.Qualifier, qualId.Identifier); return target; }
private Expression ParsePrimaryExpression(TokenSet followers){ Expression expression = null; SourceContext sctx = this.scanner.CurrentSourceContext; switch(this.currentToken){ case Token.ArgList: this.GetNextToken(); expression = new ArglistExpression(sctx); break; case Token.Delegate:{ this.GetNextToken(); ParameterList parameters = null; if (this.currentToken == Token.LeftParenthesis) parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace); Block block = null; if (this.currentToken == Token.LeftBrace) block = this.ParseBlock(this.scanner.CurrentSourceContext, followers); else this.SkipTo(followers, Error.ExpectedLeftBrace); sctx.EndPos = this.scanner.endPos; return new AnonymousNestedDelegate(parameters, block, sctx);} case Token.New: expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow); break; case Token.Identifier: expression = this.scanner.GetIdentifier(); if (this.sink != null) { this.sink.StartName((Identifier)expression); } this.GetNextToken(); if (this.currentToken == Token.DoubleColon){ this.GetNextToken(); Identifier id = this.scanner.GetIdentifier(); id.Prefix = (Identifier)expression; id.SourceContext.StartPos = expression.SourceContext.StartPos; expression = id; if (this.currentToken != Token.EndOfFile) this.GetNextToken(); }else if (this.currentToken == Token.Lambda){ Parameter par = new Parameter((Identifier)expression, null); par.SourceContext = expression.SourceContext; return this.ParseLambdaExpression(par.SourceContext, new ParameterList(par), followers); } break; case Token.Null: expression = new Literal(null, null, sctx); this.GetNextToken(); break; case Token.True: expression = new Literal(true, null, sctx); this.GetNextToken(); break; case Token.False: expression = new Literal(false, null, sctx); this.GetNextToken(); break; case Token.CharLiteral: expression = new Literal(this.scanner.charLiteralValue, null, sctx); this.GetNextToken(); break; case Token.HexLiteral: expression = this.ParseHexLiteral(); break; case Token.IntegerLiteral: expression = this.ParseIntegerLiteral(); break; case Token.RealLiteral: expression = this.ParseRealLiteral(); break; case Token.StringLiteral: expression = this.scanner.GetStringLiteral(); this.GetNextToken(); break; case Token.This: expression = new This(sctx, false); if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyThisSeen)){ QualifiedIdentifier thisCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall thisConstructorCall = new MethodCall(thisCons, null, NodeType.Call); thisConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); thisConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out thisConstructorCall.SourceContext.EndPos); expression = thisConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyThisSeen; goto done; } break; case Token.Base: Base ba = new Base(sctx, false); expression = ba; if (this.sink != null) { this.sink.StartName(expression); } this.GetNextToken(); if (this.currentToken == Token.Semicolon && (this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen || this.inInstanceConstructor == BaseOrThisCallKind.None)) { // When there are non-null fields, then the base ctor call can happen only after they are // initialized. // In Spec#, we allow a base ctor call in the body of the ctor. But if someone is using // the C# comment convention, then they cannot do that. // So allow "base;" as a marker to indicate where the base ctor call should happen. // There may be an explicit "colon base call" or it may be implicit. // // Just leave expression as a bare "Base" node; later pipeline stages will all have // to ignore it. Mark the current ctor as having (at least) one of these bad boys // in it. ba.UsedAsMarker = true; this.currentCtor.ContainsBaseMarkerBecauseOfNonNullFields = true; goto done; } if (this.currentToken == Token.LeftParenthesis && (this.inInstanceConstructor==BaseOrThisCallKind.None || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyBaseSeen)){ QualifiedIdentifier supCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call); superConstructorCall.SourceContext = sctx; SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out superConstructorCall.SourceContext.EndPos); expression = superConstructorCall; this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyBaseSeen; goto done; } break; case Token.Typeof: case Token.Sizeof: case Token.Default:{ //if (this.currentToken == Token.Sizeof && !this.inUnsafeCode) //this.HandleError(Error.SizeofUnsafe); UnaryExpression uex = new UnaryExpression(null, this.currentToken == Token.Typeof ? NodeType.Typeof : this.currentToken == Token.Sizeof ? NodeType.Sizeof : NodeType.DefaultValue); uex.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); TypeNode t = null; if (this.currentToken == Token.Void && uex.NodeType == NodeType.Typeof){ t = this.TypeExpressionFor(Token.Void); this.GetNextToken(); }else t = this.ParseTypeExpression(null, followers|Token.RightParenthesis, false, false, uex.NodeType == NodeType.Typeof); if (t == null){this.SkipTo(followers); return null;} uex.Operand = new MemberBinding(null, t, t.SourceContext, null); uex.Operand.SourceContext = t.SourceContext; uex.SourceContext.EndPos = this.scanner.endPos; this.Skip(Token.RightParenthesis); expression = uex; break;} case Token.Stackalloc:{ this.GetNextToken(); TypeNode elementType = this.ParseBaseTypeExpression(null, followers|Token.LeftBracket, false, false); if (elementType == null){this.SkipTo(followers); return null;} Token openingDelimiter = this.currentToken; if (this.currentToken != Token.LeftBracket){ this.HandleError(Error.BadStackAllocExpr); if (this.currentToken == Token.LeftParenthesis) this.GetNextToken(); }else this.GetNextToken(); Expression numElements = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis); sctx.EndPos = this.scanner.endPos; if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis) this.GetNextToken(); else this.Skip(Token.RightBracket); this.SkipTo(followers); return new StackAlloc(elementType, numElements, sctx);} case Token.Checked: case Token.Unchecked: //TODO: use NodeType.SkipCheck and NodeType.EnforceCheck Block b = new Block(new StatementList(1), this.currentToken == Token.Checked, this.currentToken == Token.Unchecked, this.inUnsafeCode); b.SourceContext = sctx; this.GetNextToken(); this.Skip(Token.LeftParenthesis); b.Statements.Add(new ExpressionStatement(this.ParseExpression(followers|Token.RightParenthesis))); this.Skip(Token.RightParenthesis); expression = new BlockExpression(b); expression.SourceContext = b.SourceContext; break; case Token.RefType:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.RightParenthesis); this.Skip(Token.RightParenthesis); expression = new RefTypeExpression(e, sctx); break; } case Token.RefValue:{ this.GetNextToken(); this.Skip(Token.LeftParenthesis); Expression e = this.ParseExpression(followers|Token.Comma); this.Skip(Token.Comma); TypeNode te = this.ParseTypeOrFunctionTypeExpression(followers|Token.RightParenthesis, false, true); Expression operand2 = new MemberBinding(null, te); if (te is TypeExpression) operand2.SourceContext = te.SourceContext; else operand2.SourceContext = sctx; this.Skip(Token.RightParenthesis); expression = new RefValueExpression(e, operand2, sctx); break; } 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: MemberBinding mb = new MemberBinding(null, this.TypeExpressionFor(this.currentToken), sctx); this.GetNextToken(); expression = this.ParseIndexerCallOrSelector(mb, followers); goto done; case Token.LeftParenthesis: expression = this.ParseParenthesizedExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow, true); break; default: if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier; if (Parser.InfixOperators[this.currentToken]){ this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource()); this.GetNextToken(); }else this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource()); if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers); goto done; } if (expression is Base && this.currentToken != Token.Dot && this.currentToken != Token.LeftBracket){ this.HandleError(expression.SourceContext, Error.BaseIllegal); expression = null; } expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); for(;;){ switch(this.currentToken){ case Token.AddOne: case Token.SubtractOne: SourceContext ctx = expression.SourceContext; ctx.EndPos = this.scanner.endPos; PostfixExpression pex = new PostfixExpression(expression, Parser.ConvertToBinaryNodeType(this.currentToken), ctx); this.GetNextToken(); expression = pex; break; case Token.Dot: expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne); break; default: goto done; } } done: this.SkipTo(followers); return expression; }
private Expression ParseNamespaceOrTypeName(Expression root, bool allowDoubleColon, TokenSet followers){ if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]){ if (this.currentToken == Token.EndOfFile){ root = new QualifiedIdentifier(root, this.scanner.GetIdentifier(), root.SourceContext); root.SourceContext.EndPos = this.scanner.endPos; } this.SkipTo(followers, Error.ExpectedIdentifier); return root; } Identifier id = this.scanner.GetIdentifier(); if (root == Identifier.Empty){ root = id; }else{ root = new QualifiedIdentifier(root, id, root.SourceContext); root.SourceContext.EndPos = id.SourceContext.EndPos; } this.GetNextToken(); tryAgain: if (this.currentToken != Token.Dot){ if (this.currentToken == Token.DoubleColon && allowDoubleColon){ Debug.Assert(root == id); this.GetNextToken(); Identifier ident = this.scanner.GetIdentifier(); this.SkipIdentifierOrNonReservedKeyword(); ident.Prefix = id; ident.SourceContext.StartPos = id.SourceContext.StartPos; root = ident; allowDoubleColon = false; goto tryAgain; } TemplateInstance result = null; while (this.currentToken == Token.LessThan) { int endCol, arity; if (result == null) { result = new TemplateInstance(); result.Expression = root; result.SourceContext = root.SourceContext; } result.TypeArgumentExpressions = this.ParseTypeArguments(false, false, followers|Token.Dot, out endCol, out arity); result.TypeArguments = result.TypeArgumentExpressions == null ? null : result.TypeArgumentExpressions.Clone(); result.SourceContext.EndPos = endCol; if (result.TypeArguments == null) { result.TypeArguments = new TypeNodeList(1); result.TypeArguments.Add(null); } if (this.currentToken == Token.Dot) { root = this.ParseQualifiedIdentifier(result, followers|Token.LessThan, false); result = null; } } if (result != null) root = result; this.SkipTo(followers); return root; } this.GetNextToken(); return this.ParseNamespaceOrTypeName(root, false, followers); }
private void ParseConstructor(TypeNode parentType, AttributeList attributes, TokenList modifierTokens, SourceContextList modifierContexts, object sctx, SourceContext idCtx, TokenSet followers){ InstanceInitializer c = new InstanceInitializer(parentType, attributes, null, null, this.TypeExpressionFor(Token.Void)); this.currentCtor = c; c.Name = new Identifier(".ctor", idCtx); MethodFlags flags = this.GetMethodFlags(modifierTokens, modifierContexts, parentType, c); if ((flags & MethodFlags.Static) != 0){ this.currentCtor = null; // Can you call "base" in a static ctor? this.ParseStaticConstructor(parentType, attributes, modifierTokens, modifierContexts, flags, sctx, idCtx, followers); return; } parentType.Members.Add(c); c.Flags |= flags|MethodFlags.HideBySig; c.Parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace|Token.Semicolon|Token.Colon|Parser.ContractStart|Token.Where); c.HasCompilerGeneratedSignature = false; c.Documentation = this.LastDocComment; QualifiedIdentifier supCons = new QualifiedIdentifier(new Base(), StandardIds.Ctor, this.scanner.CurrentSourceContext); MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call); superConstructorCall.SourceContext = this.scanner.CurrentSourceContext; StatementList slist = new StatementList(); Block body = new Block(slist, this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode); body.SourceContext = this.scanner.CurrentSourceContext; Block iblock = new Block(new StatementList(), this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode); if (this.currentToken == Token.Colon){ this.GetNextToken(); bool savedParsingStatement = this.parsingStatement; this.parsingStatement = true; superConstructorCall.SourceContext = this.scanner.CurrentSourceContext; supCons.SourceContext = this.scanner.CurrentSourceContext; bool init = false; this.inInstanceConstructor = BaseOrThisCallKind.ColonThisOrBaseSeen; if (this.currentToken == Token.This){ if (this.sink != null) this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext)); supCons.Qualifier = new This(this.scanner.CurrentSourceContext, true); this.GetNextToken(); }else if (this.currentToken == Token.Base){ if (parentType.IsValueType) this.HandleError(Error.StructWithBaseConstructorCall, new ErrorHandler(this.errors).GetMemberSignature(c)); else if (this.sink != null) this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext)); supCons.Qualifier = new Base(this.scanner.CurrentSourceContext, true); this.GetNextToken(); }else{ if (!init) this.SkipTo(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, Error.ThisOrBaseExpected); if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement; goto parseBody; } SourceContext lpCtx = this.scanner.CurrentSourceContext; this.Skip(Token.LeftParenthesis); superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, lpCtx, out superConstructorCall.SourceContext.EndPos); if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement; } else { // no colon ==> no "base" or "this" before body of ctor if (! parentType.IsValueType) this.inInstanceConstructor = BaseOrThisCallKind.None; } parseBody: superConstructorCall.SourceContext.EndPos = this.scanner.endPos; supCons.SourceContext.EndPos = this.scanner.endPos; bool swallowedSemicolonAlready = false; this.ParseMethodContract(c, followers|Token.LeftBrace|Token.Semicolon, ref swallowedSemicolonAlready); Block b; if (this.parsingContractAssembly) b = this.ParseBody(c, sctx, followers, swallowedSemicolonAlready); // only allow semicolon body in contract assemblies else b = this.ParseBody(c, sctx, followers); slist.Add(iblock); c.IsDeferringConstructor = supCons.Qualifier is This || this.inInstanceConstructor == BaseOrThisCallKind.InCtorBodyThisSeen; if (!c.IsDeferringConstructor){ slist.Add(new FieldInitializerBlock(parentType,false)); } Block baseOrDeferringCallBlock = new Block(new StatementList(1)); c.BaseOrDefferingCallBlock = baseOrDeferringCallBlock; slist.Add(baseOrDeferringCallBlock); if (this.inInstanceConstructor == BaseOrThisCallKind.None || this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen){ if (!(parentType.IsValueType || this.TypeIsSystemObject(parentType)) || supCons.Qualifier is This) baseOrDeferringCallBlock.Statements.Add(new ExpressionStatement(superConstructorCall, superConstructorCall.SourceContext)); } if (b != null){ slist.Add(b); body.SourceContext.EndPos = b.SourceContext.EndPos; if ((c.Flags & MethodFlags.PInvokeImpl) != 0 && b.Statements != null && b.Statements.Count > 0) body = null; else if (this.omitBodies) b.Statements = null; }else if ((c.Flags & MethodFlags.PInvokeImpl) != 0) body = null; c.Body = body; this.inInstanceConstructor = BaseOrThisCallKind.Disallowed; this.currentCtor = null; }
private void GenerateLocals(ZMethod zMethod, Class localsClass) { List<Field> locals = new List<Field>(10); Method localsGetValue = (Method)Templates.GetMemberByName(localsClass.Members, "GetValue"); Method localsSetValue = (Method)Templates.GetMemberByName(localsClass.Members, "SetValue"); System.Compiler.Switch switchLocalsGetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch"); localsGetValue.Body.Statements.Add(switchLocalsGetValue); System.Compiler.Switch switchLocalsSetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch"); localsSetValue.Body.Statements.Add(switchLocalsSetValue); Method copier = (Method)Templates.GetMemberByName(localsClass.Members, "CopyContents"); for (int i = 0, n = zMethod.LocalVars.Count; i < n; i++) { Field localVar = zMethod.LocalVars[i]; TypeNode zingType = localVar.Type; if (localVar.Type == null) continue; Field f = new Field(localsClass, null, FieldFlags.Public, new Identifier("priv_" + localVar.Name.Name), localVar.Type, null); if (GetTypeClassification(f.Type) == TypeClassification.Heap) f.Type = this.ZingPtrType; else if (!IsPredefinedType(f.Type)) f.Type = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), zingType.Name), zingType.SourceContext); Identifier idFieldName = new Identifier("id_" + localVar.Name.Name); Field idf = new Field(localsClass, null, FieldFlags.Public | FieldFlags.Static, idFieldName, SystemTypes.Int32, null); idf.Initializer = new Literal(i, SystemTypes.Int32); SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0]; Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(getCase, "_fieldName", new Identifier(f.Name.Name)); switchLocalsGetValue.Cases.Add(getCase); SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0]; Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(setCase, "_fieldName", new Identifier(f.Name.Name)); TypeExpression tn = f.Type as TypeExpression; Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name)); switchLocalsSetValue.Cases.Add(setCase); QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Local")); Property accessor = GetAccessorProperty("localAccessor", f.Type, localVar.Name, f.Name, idf.Name, localInputOrOutput); Identifier qualifier = new Identifier("locals"); localsClass.Members.Add(f); localsClass.Members.Add(idf); localsClass.Members.Add(accessor); f.DeclaringType = localsClass; idf.DeclaringType = localsClass; accessor.DeclaringType = localsClass; if (accessor.Getter != null) { localsClass.Members.Add(accessor.Getter); accessor.Getter.DeclaringType = localsClass; } if (accessor.Setter != null) { localsClass.Members.Add(accessor.Setter); accessor.Setter.DeclaringType = localsClass; } if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal) collectStructAccessors(false, (Struct)zingType, f.Name, localVar.Name.Name, localsClass); copier.Body.Statements.Add(GetCopyStatement(f.Name)); locals.Add(f); } Method writer = (Method)Templates.GetMemberByName(localsClass.Members, "WriteString"); Method traverser = (Method)Templates.GetMemberByName(localsClass.Members, "TraverseFields"); for (int i = 0, n = locals.Count; i < n; i++) { Field f = (Field)locals[i]; writer.Body.Statements.Add(GetWriterStatement("this", f.Type, f.Name)); traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, f.Name)); } }
public override Expression VisitQualifiedIdentifierCore(QualifiedIdentifier qualifiedIdentifier) { Expression result = base.VisitQualifiedIdentifierCore(qualifiedIdentifier); return result; }
// The method added by Jiri Adamek // It generates NAtiveZOM calls private void GenerateNativeZOMCall(Block block, MethodCall call, bool callIsAsync, AssignmentStatement assignmentStatement) { ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember; // Eventually, this will be checked by an earlier phase. Debug.Assert(method.Parameters.Count == call.Operands.Count); // Asynchronous calls Debug.Assert(!callIsAsync, "async not supporrted for NativeZOM calls"); // Debugging - parameters for (int i = 0, n = call.Operands.Count; i < n; i++) { Parameter param = method.Parameters[i]; Debug.Assert(param != null); // In fact, call.operands[i] MAY BE null due to the error recovery (if the type of the // expression does not match the type in the method definition) // // Debug.Assert(call.Operands[i] != null); Debug.Assert((param.Flags & ParameterFlags.Out) == 0, "out parameters not supported for NativeZOM calls"); } Expression typename = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), method.DeclaringType.Name); Expression callee; if (!method.IsStatic) { callee = Templates.GetExpressionTemplate("NativeZOMCallee"); Replacer.Replace(callee, "_TypeName", typename); Expression pointer = this.VisitExpression(((MemberBinding)call.Callee).TargetObject); Replacer.Replace(callee, "_Pointer", pointer); Replacer.Replace(callee, "_MethodName", method.Name); } else { callee = Templates.GetExpressionTemplate("NativeZOMStaticCall"); Replacer.Replace(callee, "_ClassName", typename); Replacer.Replace(callee, "_MethodName", method.Name); } ExpressionList argumentList = new ExpressionList(); argumentList.Add(Templates.GetExpressionTemplate("NativeZOMCallFirstArgument")); foreach (Expression operand in call.Operands) argumentList.Add(this.VisitExpression(operand)); MethodCall nativeCall = new MethodCall(callee, argumentList); Statement newStatement; if (assignmentStatement != null) { newStatement = Templates.GetStatementTemplate("NativeZOMCallWithAssignment"); Replacer.Replace(newStatement, "_Dest", this.VisitExpression(assignmentStatement.Target)); Replacer.Replace(newStatement, "_Source", nativeCall); } else { newStatement = new ExpressionStatement(nativeCall); } block.Statements.Add(newStatement); }
public virtual Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { if (qualifiedIdentifier == null) return null; qualifiedIdentifier.Qualifier = this.VisitExpression(qualifiedIdentifier.Qualifier); return qualifiedIdentifier; }
protected override MemberList GetMembers(int line, int col, QualifiedIdentifier qualId, Scope scope){ this.suppressAttributeSuffix = scope is AttributeScope; return base.GetMembers(line, col, qualId, scope); }
private void GenerateClass(Class c) { // The following code added by Jiri Adamek // Do not generate any code for native ZOM classes (they were manually written // and their code is placed in another assmbly) if (c is NativeZOM) return; // END of added code TypeNode newClass = Templates.GetTypeTemplateByName("Class"); if (c.Interfaces != null) { for (int i = 0, n = c.Interfaces.Count; i < n; i++) { string iname = c.Interfaces[i].Name.Name; QualifiedIdentifier id = new QualifiedIdentifier(new Identifier(iname), new Identifier("CreateMethods")); newClass.Interfaces.Add(new InterfaceExpression(id)); } } Method writer = (Method)Templates.GetMemberByName(newClass.Members, "WriteString"); Method traverser = (Method)Templates.GetMemberByName(newClass.Members, "TraverseFields"); // Replace all references to the class name Replacer.Replace(newClass, newClass.Name, c.Name); SetTypeId(newClass); Block cloneFields = new Block(); cloneFields.Statements = new StatementList(); Method getValue = (Method)Templates.GetMemberByName(newClass.Members, "GetValue"); Method setValue = (Method)Templates.GetMemberByName(newClass.Members, "SetValue"); System.Compiler.Switch switchGetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch"); getValue.Body.Statements.Add(switchGetValue); System.Compiler.Switch switchSetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch"); setValue.Body.Statements.Add(switchSetValue); // Transfer non-static fields to the emitted class for (int i = 0, n = c.Members.Count; i < n; i++) { Field f = c.Members[i] as Field; if (f != null && f.Type != null && !f.IsStatic) { // Clone the field since we might tinker with it Field newField = (Field)f.Clone(); // change name of the field, so that the accessor can be named appropriately newField.Name = new Identifier("priv_" + f.Name.Name); if (GetTypeClassification(f.Type) == TypeClassification.Heap) newField.Type = this.ZingPtrType; else if (!IsPredefinedType(f.Type)) newField.Type = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), f.Type.Name), f.Type.SourceContext); if (newField.Initializer != null) { // Move the initialization to our constructor. Expression initializer = newField.Initializer; newField.Initializer = null; Statement initStmt = Templates.GetStatementTemplate("InitComplexInstanceField"); Replacer.Replace(initStmt, "_FieldName", newField.Name); Normalizer normalizer = new Normalizer(false); Replacer.Replace(initStmt, "_expr", normalizer.VisitFieldInitializer(initializer)); Method ctor = (Method)newClass.Members[0]; Debug.Assert(ctor.Parameters.Count == 1); ctor.Body.Statements.Add(initStmt); } Identifier idFieldName = new Identifier("id_" + f.Name.Name); Field idf = new Field(newClass, null, FieldFlags.Public | FieldFlags.Static, idFieldName, SystemTypes.Int32, null); idf.Initializer = new Literal(i, SystemTypes.Int32); SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0]; Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(getCase, "_fieldName", new Identifier(newField.Name.Name)); switchGetValue.Cases.Add(getCase); SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0]; Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(setCase, "_fieldName", new Identifier(newField.Name.Name)); TypeExpression tn = newField.Type as TypeExpression; Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(newField.Type.Name.Name)); switchSetValue.Cases.Add(setCase); newClass.Members.Add(newField); newField.DeclaringType = newClass; newClass.Members.Add(idf); idf.DeclaringType = newClass; // add property for the field Property accessor = GetFieldAccessorProperty(f.Type, newField.Type, f.Name, newField.Name, idFieldName); newClass.Members.Add(accessor); accessor.DeclaringType = newClass; if (accessor.Getter != null) { newClass.Members.Add(accessor.Getter); accessor.Getter.DeclaringType = newClass; } if (accessor.Setter != null) { newClass.Members.Add(accessor.Setter); accessor.Setter.DeclaringType = newClass; } writer.Body.Statements.Add(GetWriterStatement("this", f.Type, newField.Name)); traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, newField.Name)); /*if(GetTypeClassification(f.Type) == TypeClassification.Heap) { refTraverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, newField.Name)); } */ Statement cloneStmt = GetCloneStatement(newField.Name); cloneFields.Statements.Add(cloneStmt); } ZMethod zMethod = c.Members[i] as ZMethod; if (zMethod != null) { InterfaceList xs = FindMatchingInterfaces(c, zMethod); Interface x = null; if (xs.Count != 0) { // TODO: Handle the case when one method implements methods declared in multiple interfaces Debug.Assert(xs.Count == 1); x = xs[0]; } Class methodClass = GenerateClassMethod(zMethod, x); newClass.Members.Add(methodClass); methodClass.DeclaringType = newClass; methodClass.Flags = (methodClass.Flags & ~TypeFlags.VisibilityMask) | TypeFlags.NestedFamORAssem; if (x != null) { TypeNode tn = Templates.GetTypeTemplateByName("ClassExtras"); Method member = (Method)Templates.GetMemberByName(tn.Members, "__CreateInterfaceMethod"); member.Name = new Identifier("Create" + methodClass.Name.Name); member.DeclaringType = newClass; Replacer.Replace(member, new Identifier("__InterfaceMethod"), new QualifiedIdentifier(x.Name, methodClass.Name)); Replacer.Replace(member, new Identifier("__ClassMethod"), new QualifiedIdentifier(c.Name, methodClass.Name)); newClass.Members.Add(member); } } } // Splice the cloning assignment statements into the class's Clone method // at the appropriate place. Method cloner = (Method)Templates.GetMemberByName(newClass.Members, "Clone"); Replacer.Replace(cloner.Body, "cloneFields", cloneFields); // Add the emitted class to our Zing application class InstallType(newClass); }
private void GenerateChan(Chan chanNode) { Expression ns = null; string chanStyle = null; switch (GetTypeClassification(chanNode.ChannelType)) { case TypeClassification.Simple: ns = chanNode.ChannelType.Namespace; chanStyle = "SimpleChan"; break; case TypeClassification.Enum: chanStyle = "EnumChan"; break; case TypeClassification.Struct: chanStyle = "StructChan"; break; case TypeClassification.Heap: if (chanNode.ChannelType == SystemTypes.Object) ns = chanNode.ChannelType.Namespace; chanStyle = "ComplexChan"; break; } Class chanClass = (Class)Templates.GetTypeTemplateByName(chanStyle); if (ns == null) ns = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), new Identifier("Application")); Replacer.Replace(chanClass, chanStyle, chanNode.Name); Replacer.Replace(chanClass, "_ElementType", new QualifiedIdentifier(ns, chanNode.ChannelType.Name)); SetTypeId(chanClass); InstallType(chanClass); }
private void GenerateArray(ZArray arrayNode) { Expression ns = null; string arrayStyle = null; if (arrayNode == null || arrayNode.domainType == null || arrayNode.ElementType == null) return; switch (GetTypeClassification(arrayNode.ElementType)) { case TypeClassification.Simple: ns = arrayNode.ElementType.Namespace; arrayStyle = "SimpleArray"; break; case TypeClassification.Enum: arrayStyle = "EnumArray"; break; case TypeClassification.Struct: arrayStyle = "StructArray"; break; case TypeClassification.Heap: if (arrayNode.ElementType == SystemTypes.Object) ns = arrayNode.ElementType.Namespace; arrayStyle = "ComplexArray"; break; } Class arrayClass = (Class)Templates.GetTypeTemplateByName(arrayStyle); if (ns == null) ns = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), new Identifier("Application")); Replacer.Replace(arrayClass, arrayStyle, arrayNode.Name); Replacer.Replace(arrayClass, "_ElementType", new QualifiedIdentifier(ns, arrayNode.ElementType.Name)); // Replacer.Replace(arrayClass, "_size", new Literal(arrayNode.Sizes[0], SystemTypes.Int32)); SetTypeId(arrayClass); InstallType(arrayClass); }
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); } }
private void GenerateSet(Set setNode) { Expression ns = null; string setStyle = null; if (setNode == null || setNode.SetType == null) return; switch (GetTypeClassification(setNode.SetType)) { case TypeClassification.Simple: setStyle = "SimpleSet"; ns = setNode.SetType.Namespace; break; case TypeClassification.Enum: setStyle = "EnumSet"; break; case TypeClassification.Struct: setStyle = "StructSet"; break; case TypeClassification.Heap: setStyle = "ComplexSet"; if (setNode.SetType == SystemTypes.Object) ns = setNode.SetType.Namespace; break; } Class setClass = (Class)Templates.GetTypeTemplateByName(setStyle); Replacer.Replace(setClass, setStyle, setNode.Name); if (ns == null) ns = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), new Identifier("Application")); Replacer.Replace(setClass, "_ElementType", new QualifiedIdentifier(ns, setNode.SetType.Name)); SetTypeId(setClass); InstallType(setClass); }
private void GenerateOutputs(ZMethod zMethod, Class outputsClass) { List<Field> outputs = new List<Field>(10); Method outputsGetValue = (Method)Templates.GetMemberByName(outputsClass.Members, "GetValue"); Method outputsSetValue = (Method)Templates.GetMemberByName(outputsClass.Members, "SetValue"); System.Compiler.Switch switchOutputsGetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoSwitch"); outputsGetValue.Body.Statements.Add(switchOutputsGetValue); System.Compiler.Switch switchOutputsSetValue = (System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoSwitch"); outputsSetValue.Body.Statements.Add(switchOutputsSetValue); Method copier = (Method)Templates.GetMemberByName(outputsClass.Members, "CopyContents"); // Create fields in Inputs or Outputs for the parameters for (int i = 0, n = zMethod.Parameters.Count; i < n; i++) { Parameter param = zMethod.Parameters[i]; if (param == null || param.Type == null || (param.Flags & ParameterFlags.Out) == 0) continue; TypeNode zingType = param.Type; zingType = ((Reference)zingType).ElementType; Field f = new Field(outputsClass, null, FieldFlags.Public, new Identifier("priv_" + param.Name.Name), param.Type, null); if (f.Type is Reference) f.Type = ((Reference)f.Type).ElementType; if (GetTypeClassification(f.Type) == TypeClassification.Heap) { f.Type = this.ZingPtrType; } else if (!IsPredefinedType(f.Type)) f.Type = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), zingType.Name), zingType.SourceContext); Identifier idFieldName = new Identifier("id_" + param.Name.Name); Field idf = new Field(outputsClass, null, FieldFlags.Public | FieldFlags.Static, idFieldName, SystemTypes.Int32, null); idf.Initializer = new Literal(i, SystemTypes.Int32); SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0]; Replacer.Replace(getCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(getCase, "_fieldName", new Identifier(f.Name.Name)); switchOutputsGetValue.Cases.Add(getCase); SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0]; Replacer.Replace(setCase, "_fieldId", new Literal(i, SystemTypes.Int32)); Replacer.Replace(setCase, "_fieldName", new Identifier(f.Name.Name)); TypeExpression tn = f.Type as TypeExpression; Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name)); switchOutputsSetValue.Cases.Add(setCase); QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Output")); Property accessor = GetAccessorProperty("outputAccessor", f.Type, param.Name, f.Name, idf.Name, localInputOrOutput); outputsClass.Members.Add(f); outputsClass.Members.Add(idf); outputsClass.Members.Add(accessor); f.DeclaringType = outputsClass; idf.DeclaringType = outputsClass; accessor.DeclaringType = outputsClass; if (accessor.Getter != null) { outputsClass.Members.Add(accessor.Getter); accessor.Getter.DeclaringType = outputsClass; } if (accessor.Setter != null) { outputsClass.Members.Add(accessor.Setter); accessor.Setter.DeclaringType = outputsClass; } //for outputs create an additional lastfunction accessor QualifiedIdentifier lfcOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("LastFunctionOutput")); Identifier lfcid = new Identifier("_Lfc_" + param.Name.Name); Property lfcAccessor = GetAccessorProperty("lastFunctionOutputAccessor", f.Type, lfcid, f.Name, idf.Name, lfcOutput); outputsClass.Members.Add(lfcAccessor); lfcAccessor.DeclaringType = outputsClass; if (lfcAccessor.Getter != null) { outputsClass.Members.Add(lfcAccessor.Getter); lfcAccessor.Getter.DeclaringType = outputsClass; } if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal) collectStructAccessors(false, (Struct)zingType, f.Name, param.Name.Name, outputsClass); copier.Body.Statements.Add(GetCopyStatement(f.Name)); outputs.Add(f); } if (zMethod.ReturnType.TypeCode != TypeCode.Empty) { Field f = new Field(outputsClass, null, FieldFlags.Public, new Identifier("priv_ReturnValue"), zMethod.ReturnType, null); QualifiedIdentifier localInputOrOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("Output")); TypeNode zingType = zMethod.ReturnType; if (GetTypeClassification(f.Type) == TypeClassification.Heap) { f.Type = this.ZingPtrType; } else if (!IsPredefinedType(f.Type)) { f.Type = new TypeExpression(new QualifiedIdentifier( new Identifier("Application"), zingType.Name), zingType.SourceContext); } Identifier idFieldName = new Identifier("id_ReturnValue"); Field idf = new Field(outputsClass, null, FieldFlags.Public | FieldFlags.Static, idFieldName, SystemTypes.Int32, null); idf.Initializer = new Literal(zMethod.Parameters.Count, SystemTypes.Int32); SwitchCase getCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("GetFieldInfoCase")).Cases[0]; Replacer.Replace(getCase, "_fieldId", new Literal(zMethod.Parameters.Count, SystemTypes.Int32)); Replacer.Replace(getCase, "_fieldName", new Identifier("priv_ReturnValue")); switchOutputsGetValue.Cases.Add(getCase); SwitchCase setCase = ((System.Compiler.Switch)Templates.GetStatementTemplate("SetFieldInfoCase")).Cases[0]; Replacer.Replace(setCase, "_fieldId", new Literal(zMethod.Parameters.Count, SystemTypes.Int32)); Replacer.Replace(setCase, "_fieldName", new Identifier("priv_ReturnValue")); TypeExpression tn = f.Type as TypeExpression; Replacer.Replace(setCase, "_fieldType", tn != null ? tn.Expression : new Identifier(f.Type.Name.Name)); switchOutputsSetValue.Cases.Add(setCase); Property accessor = GetAccessorProperty("outputAccessor", f.Type, new Identifier("_ReturnValue"), f.Name, idf.Name, localInputOrOutput); QualifiedIdentifier lfcOutput = new QualifiedIdentifier(new Identifier("LocType"), new Identifier("LastFunctionOutput")); Property lfcAccessor = GetAccessorProperty("lastFunctionOutputAccessor", f.Type, new Identifier("_Lfc_ReturnValue"), f.Name, idf.Name, lfcOutput); Identifier qualifier = new Identifier("outputs"); outputsClass.Members.Add(f); outputsClass.Members.Add(idf); outputsClass.Members.Add(accessor); outputsClass.Members.Add(lfcAccessor); f.DeclaringType = outputsClass; idf.DeclaringType = outputsClass; accessor.DeclaringType = outputsClass; lfcAccessor.DeclaringType = outputsClass; if (accessor.Getter != null) { outputsClass.Members.Add(accessor.Getter); accessor.Getter.DeclaringType = outputsClass; } if (accessor.Setter != null) { outputsClass.Members.Add(accessor.Setter); accessor.Setter.DeclaringType = outputsClass; } if (lfcAccessor.Getter != null) { outputsClass.Members.Add(lfcAccessor.Getter); lfcAccessor.Getter.DeclaringType = outputsClass; } if (zingType is Struct && !zingType.IsPrimitive && f.Type != SystemTypes.Decimal) { collectStructAccessors(false, (Struct)zingType, f.Name, "_ReturnValue", outputsClass); collectStructAccessors(false, (Struct)zingType, f.Name, "_Lfc_ReturnValue", outputsClass); } copier.Body.Statements.Add(GetCopyStatement(f.Name)); outputs.Add(f); } Method writer = (Method)Templates.GetMemberByName(outputsClass.Members, "WriteString"); Method traverser = (Method)Templates.GetMemberByName(outputsClass.Members, "TraverseFields"); for (int i = 0, n = outputs.Count; i < n; i++) { Field f = (Field)outputs[i]; writer.Body.Statements.Add (GetWriterStatement("this", f.Type, f.Name)); traverser.Body.Statements.Add(GetTraverserStatement("this", f.Type, f.Name)); } }
public override Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { if (qualifiedIdentifier == null) return null; return base.VisitQualifiedIdentifier((QualifiedIdentifier)qualifiedIdentifier.Clone()); }
public static Expression QualifiedIdentifierFor(params string[] memberNameParts) { if (memberNameParts == null || memberNameParts.Length < 1) return null; Identifier id = Identifier.For(memberNameParts[0]); id.Prefix = Identifier.For("global"); Expression qualId = id; for (int i = 1, n = memberNameParts.Length; i < n; i++) qualId = new QualifiedIdentifier(qualId, Identifier.For(memberNameParts[i])); return qualId; }
// Methods that fix traversal issues in StandardVisitor... public override Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { if (qualifiedIdentifier == null) return null; qualifiedIdentifier.Identifier = (Identifier)this.VisitIdentifier(qualifiedIdentifier.Identifier); qualifiedIdentifier.Qualifier = this.VisitExpression(qualifiedIdentifier.Qualifier); return qualifiedIdentifier; }
public override Expression VisitMethodCall(MethodCall call) { // We only reach this point for calls to predicate methods within "wait" // join conditions. ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember; ExpressionList ctorArgs; QualifiedIdentifier methodClass = new QualifiedIdentifier( new QualifiedIdentifier( new QualifiedIdentifier(Identifier.For("Z"), Identifier.For("Application")), method.DeclaringType.Name), method.Name); MethodCall predCall = new MethodCall( new QualifiedIdentifier(Identifier.For("p"), Identifier.For("CallPredicateMethod")), new ExpressionList( new Construct( new MemberBinding(null, new TypeExpression(methodClass)), ctorArgs = new ExpressionList()))); ctorArgs.Add(Identifier.For("application")); if (!method.IsStatic) ctorArgs.Add(this.VisitExpression(((MemberBinding)call.Callee).TargetObject)); for (int i = 0, n = call.Operands.Count; i < n; i++) ctorArgs.Add(this.VisitExpression(call.Operands[i])); return predCall; }
public override Expression VisitQualifiedIdentifier (QualifiedIdentifier qualifiedIdentifier) { return qualifiedIdentifier; }
private Expression VisitMemberBindingExpression(MemberBinding binding) { if (binding.BoundMember.NodeType != NodeType.Field) { Debug.Assert(false, "MemberBinding scenario not yet supported"); return null; } if (binding.BoundMember is ParameterField) { Parameter param = ((ParameterField)binding.BoundMember).Parameter; if ((param.Flags & ParameterFlags.Out) != 0) return new QualifiedIdentifier(refOutputs, param.Name); else return new QualifiedIdentifier(refInputs, param.Name); } Field field = (Field)binding.BoundMember; Expression targetObject = binding.TargetObject; // for output parameters while (targetObject is AddressDereference) targetObject = ((AddressDereference)targetObject).Address; if (field.IsStatic) { // This is a reference to a global variable. Expression globalAccess = Templates.GetExpressionTemplate("GlobalFieldAccess"); Replacer.Replace(globalAccess, "_fieldName", new Identifier(string.Format(CultureInfo.InvariantCulture, "{0}_{1}", field.DeclaringType.Name.Name, field.Name.Name))); return globalAccess; } else if (field.DeclaringType is BlockScope) { return new QualifiedIdentifier(refLocals, field.Name); } else if (targetObject is ImplicitThis || targetObject is This) { Expression thisExpr = Templates.GetExpressionTemplate("ThisFieldAccess"); Replacer.Replace(thisExpr, "_objectType", targetObject.Type.Name); Replacer.Replace(thisExpr, "_fieldName", field.Name); return thisExpr; } else if (targetObject is MemberBinding || targetObject is Indexer) { // Need to distinguish between class field and struct field access. // Structs are not on the heap, so the pointer deref isn't appropriate. if (!field.DeclaringType.IsPrimitive && field.DeclaringType is Struct) { // we're gradually transforming struct // fields into properties so far, we've // done it for globals only, locals will // be added next, then heap objects... string propName = field.Name.Name; bool pFlatten = true; Expression prefix = null; // search for pattern var.struct1...structn.member while (true) { Field vField = null; MemberBinding vBinding = targetObject as MemberBinding; if (vBinding != null) { ParameterField pf = vBinding.BoundMember as ParameterField; if (pf != null) { // param.struct1...structn.member Parameter param = pf.Parameter; propName = param.Name.Name + "_" + propName; if ((param.Flags & ParameterFlags.Out) != 0) prefix = refOutputs; else prefix = refInputs; break; } } else { pFlatten = false; break; } vField = vBinding.BoundMember as Field; if (vField == null) { pFlatten = false; break; } propName = vField.Name.Name + "_" + propName; if (vField.IsStatic) { // global.struct1...structn.member propName = vField.DeclaringType.Name.Name + "_" + propName; prefix = new QualifiedIdentifier(Identifier.For("application"), Identifier.For("globals")); break; } else if (vField.DeclaringType is BlockScope) { // local.struct1...structn.member prefix = refLocals; break; } if (vField.DeclaringType.IsPrimitive || !(vField.DeclaringType is Struct)) { // can't match the pattern. let's bail prefix = null; pFlatten = false; break; } binding = vBinding; targetObject = binding.TargetObject; // for output parameters while (targetObject is AddressDereference) targetObject = ((AddressDereference)targetObject).Address; } if (pFlatten) { Debug.Assert(prefix != null); propName = "__strprops_" + propName; return new QualifiedIdentifier(prefix, Identifier.For(propName)); } else { Expression structRefExpr = Templates.GetExpressionTemplate("StructFieldAccess"); Replacer.Replace(structRefExpr, "_structExpr", this.VisitExpression(targetObject)); Replacer.Replace(structRefExpr, "_fieldName", field.Name); return structRefExpr; } } else { Expression derefExpr = Templates.GetExpressionTemplate("ClassFieldAccess"); Replacer.Replace(derefExpr, "_objectType", field.DeclaringType.Name); Replacer.Replace(derefExpr, "_ptrExpr", this.VisitExpression(targetObject)); Replacer.Replace(derefExpr, "_fieldName", field.Name); return derefExpr; } } else return base.VisitExpression(binding); }
private Expression ParseQualifiedIdentifier(Expression qualifier, TokenSet followers, bool returnNullIfError){ Debug.Assert(this.currentToken == Token.Dot); SourceContext dotContext = this.scanner.CurrentSourceContext; this.GetNextToken(); Expression result = null; Identifier id = null; if (this.insideModifiesClause && this.currentToken == Token.Multiply) { SourceContext sctx = qualifier.SourceContext; sctx.EndPos = this.scanner.CurrentSourceContext.EndPos; this.GetNextToken(); if (this.currentToken == Token.Multiply) { // Handle code such as // // modifies myObject.**; // // which means that the method may modify all fields of all peers of myObject. sctx.EndPos = this.scanner.CurrentSourceContext.EndPos; result = new ModifiesPeersClause(qualifier, sctx); this.GetNextToken(); // eat the second asterisk } else { // Handle code such as // // modifies myObject.*; // // which means that the method may modify all fields of myObject. result = new ModifiesObjectClause(qualifier, sctx); } return result; } if (this.sink != null && Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.sink.QualifyName(dotContext, this.scanner.GetIdentifier()); TypeNode tn = this.TypeExpressionFor(this.currentToken); if (tn != null){ id = this.scanner.GetIdentifier(); this.GetNextToken(); }else{ id = this.scanner.GetIdentifier(); if (this.currentToken == Token.Dot){ this.HandleError(Error.ExpectedIdentifier); while( this.currentToken == Token.Dot) this.GetNextToken(); return qualifier; }else this.SkipIdentifierOrNonReservedKeyword(); } result = new QualifiedIdentifier(qualifier, id, id.SourceContext); if (qualifier != null) result.SourceContext.StartPos = qualifier.SourceContext.StartPos; if (this.currentToken == Token.Dot) return this.ParseQualifiedIdentifier(result, followers, returnNullIfError); if (returnNullIfError && !followers[this.currentToken]) return null; this.SkipTo(followers); return result; }
public override Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { this.VisitExpression(qualifiedIdentifier.Qualifier); Write("."); this.VisitIdentifier(qualifiedIdentifier.Identifier); return qualifiedIdentifier; }
public EventingVisitor(Action<QualifiedIdentifier> visitQualifiedIdentifier) { VisitedQualifiedIdentifier += visitQualifiedIdentifier; } public event Action<QualifiedIdentifier> VisitedQualifiedIdentifier; public override Expression VisitQualifiedIdentifier(QualifiedIdentifier qualifiedIdentifier) { if (VisitedQualifiedIdentifier != null) VisitedQualifiedIdentifier(qualifiedIdentifier); return base.VisitQualifiedIdentifier(qualifiedIdentifier); }