/// <param name="wname">Receiving item; must be found and its type known</param> /// <param name="sent">Sending item; must be found and its type known</param> private static void CheckVariable(Node node, QualifiedName wname, object sent) { DataDefinition sendingTypeDefinition = null, receivingTypeDefinition = null; if (sent == null || wname == null) { return; //Both items needed } var wsymbol = GetSymbol(node.SymbolTable, wname); if (wsymbol == null) { return; // receiving symbol name unresolved } receivingTypeDefinition = wsymbol.TypeDefinition; if (receivingTypeDefinition == null) //No TypeDefinition found, try to get DataType { receivingTypeDefinition = GetDataDefinitionType(node.SymbolTable, wsymbol); } var sname = sent as QualifiedName; if (sname != null) { var ssymbol = GetSymbol(node.SymbolTable, sname); if (ssymbol == null) { return; // sending symbol name unresolved } sendingTypeDefinition = ssymbol.TypeDefinition; if (sendingTypeDefinition == null) //No TypeDefinition found try to get DataType { sendingTypeDefinition = GetDataDefinitionType(node.SymbolTable, ssymbol); } } else { //This will resolve the following cases MOVE 1 TO myVar / MOVE true TO myVar / MOVE "test" TO myVar. if (sent is bool?) { sendingTypeDefinition = GeneratedDefinition.BooleanGeneratedDefinition; } if (sent is double?) { sendingTypeDefinition = GeneratedDefinition.NumericGeneratedDefinition; } if (sent is string) { sendingTypeDefinition = GeneratedDefinition.AlphanumericGeneratedDefinition; } } //TypeDefinition Comparison if (receivingTypeDefinition != null && !receivingTypeDefinition.Equals(sendingTypeDefinition)) { var isUnsafe = ((VariableWriter)node).IsUnsafe; if (receivingTypeDefinition.DataType.RestrictionLevel > RestrictionLevel.WEAK) { if (!isUnsafe) { var sendingName = sendingTypeDefinition != null ? sendingTypeDefinition.DataType.Name : null; var receivingName = receivingTypeDefinition.DataType.Name; if (sendingTypeDefinition != null && sendingTypeDefinition.DataType.Name == receivingTypeDefinition.DataType.Name) //In case type names are equals { sendingName = sendingTypeDefinition.VisualQualifiedName.ToString().Replace(".", "::"); receivingName = receivingTypeDefinition.VisualQualifiedName.ToString().Replace(".", "::"); } var message = string.Format("Cannot write {0} to {1} typed variable {2}:{3}.", sendingName, receivingTypeDefinition.DataType.RestrictionLevel == RestrictionLevel.STRONG ? "strongly" : "strictly", wname.Head, receivingName); DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser); } } else { if (isUnsafe) { var message = "Useless UNSAFE with non strongly typed receiver."; DiagnosticUtils.AddError(node, message, MessageCode.SyntaxWarningInParser); } } } }
/// <param name="wname">Receiving item; must be found and its type known</param> /// <param name="sent">Sending item; must be found and its type known</param> private static void CheckVariable(Node node, StorageArea wname, object sent) { DataDefinition sendingTypeDefinition = null, receivingTypeDefinition = null; if (sent == null || wname == null) { return; //Both items needed } //var wsymbol = CrossCompleteChecker.CheckVariable(node, wname,false); Tuple <string, DataDefinition> searchExistingDataDefinition; DataDefinition wsymbol = null; //check if dico not null if (node.StorageAreaWritesDataDefinition != null) { node.StorageAreaWritesDataDefinition.TryGetValue(wname, out searchExistingDataDefinition); wsymbol = searchExistingDataDefinition?.Item2; } if (wsymbol != null) { receivingTypeDefinition = wsymbol.TypeDefinition ?? GetDataDefinitionType(node, wsymbol, false); } var sname = sent as QualifiedName; if (sname != null) { var ssymbol = node.GetDataDefinitionForQualifiedName(sname); if (ssymbol == null) { return; // sending symbol name unresolved } sendingTypeDefinition = ssymbol.TypeDefinition ?? GetDataDefinitionType(node, ssymbol, true); } else if (sent is StorageArea) { DataDefinition rsymbol = null; //var rsymbol = CrossCompleteChecker.CheckVariable(node, (StorageArea) sent,true); if (node.StorageAreaReadsDataDefinition != null) { node.StorageAreaReadsDataDefinition.TryGetValue((StorageArea)sent, out searchExistingDataDefinition); rsymbol = searchExistingDataDefinition?.Item2; } if (rsymbol != null) { sendingTypeDefinition = rsymbol.TypeDefinition ?? GetDataDefinitionType(node, rsymbol, true); } } else { //This will resolve the following cases MOVE 1 TO myVar / MOVE true TO myVar / MOVE "test" TO myVar. if (sent is bool?) { sendingTypeDefinition = GeneratedDefinition.BooleanGeneratedDefinition; } if (sent is double?) { sendingTypeDefinition = GeneratedDefinition.NumericGeneratedDefinition; } if (sent is string) { sendingTypeDefinition = GeneratedDefinition.AlphanumericGeneratedDefinition; } } //TypeDefinition Comparison if (receivingTypeDefinition != null && !(receivingTypeDefinition.Equals(sendingTypeDefinition) || (wname is StorageAreaPropertySpecialRegister && sent is StorageAreaPropertySpecialRegister))) { var isUnsafe = ((VariableWriter)node).IsUnsafe; if (receivingTypeDefinition.DataType.RestrictionLevel > RestrictionLevel.WEAK) { if (!isUnsafe) { var sendingName = sendingTypeDefinition != null ? sendingTypeDefinition.DataType.Name : null; var receivingName = receivingTypeDefinition.DataType.Name; if (sendingTypeDefinition != null && sendingTypeDefinition.DataType.Name == receivingTypeDefinition.DataType.Name) //In case type names are equals { sendingName = sendingTypeDefinition.VisualQualifiedName.ToString().Replace(".", "::"); receivingName = receivingTypeDefinition.VisualQualifiedName.ToString().Replace(".", "::"); } var message = string.Format("Cannot write {0} to {1} typed variable {2}:{3}.", sendingName, receivingTypeDefinition.DataType.RestrictionLevel == RestrictionLevel.STRONG ? "strongly" : "strictly", wname, receivingName); DiagnosticUtils.AddError(node, message, MessageCode.SemanticTCErrorInParser); } } else { if (isUnsafe) { var message = "Useless UNSAFE with non strongly typed receiver."; DiagnosticUtils.AddError(node, message, MessageCode.SyntaxWarningInParser); } } } }