private void AssignInferredType(AstExpressionOperand operand, AstTypeDefinition typeDef) { var typeRef = AstTypeReferenceType.From(typeDef); typeRef.IsInferred = true; SymbolTable !.Add(typeRef); operand.SetTypeReference(typeRef); }
public override void VisitAssignment(AstAssignment assign) { Ast.Guard(assign.HasVariable, "AstVariable not set on assign."); assign.VisitChildren(this); if (assign.Variable is AstVariableReference varRef && varRef.VariableDefinition is null) { var symbol = varRef.Symbol; AstTypeReference?typeRef = null; // Variable.TypeReference is usually null. if (varRef.HasTypeReference) { typeRef = varRef.TypeReference.MakeCopy(); } // It is set only when type is explicitly in source code, or has been inferred. var varDef = new AstVariableDefinition(typeRef); varDef.SetIdentifier(varRef.Identifier); varDef.SetSymbol(symbol); symbol.RemoveReference(varRef); AstSymbolReferenceRemover.RemoveReference(varRef); symbol.AddNode(varDef); assign.SetVariableDefinition(varDef); // do the children again for types assign.VisitChildren(this); } if (!assign.Variable !.HasTypeReference) { // typeless assign of var (x = 42) var expr = assign.Expression; var typeRef = expr.TypeReference; Ast.Guard(typeRef.HasIdentifier, "AstIdentifier not set on AstTypeReference."); var symbol = assign.Variable.Symbol; var def = symbol.DefinitionAs <AstTypeDefinition>(); if (def is not null) { typeRef = AstTypeReferenceType.From(def); assign.Variable.SetTypeReference(typeRef); } else { assign.Variable.SetTypeReference(typeRef.MakeCopy()); } Visit(assign.Variable.TypeReference); } }