private int OSA(string s1, string s2) { var d1 = StringMetrics.OptimalStringAlignmentDistance(s1, s2); var d2 = StringMetrics.OptimalStringAlignmentDistance(s2, s1); Assert.AreEqual(d1, d2); return(d1); }
protected override object?Visit(Expression.DotPath dot) { base.Visit(dot); var leftType = System.TypeOf(dot.Left); if (leftType.Equals(Type.Type_)) { // Static member access, we need the type value itself var leftValue = System.EvaluateType(dot.Left); var token = ((Syntax.ParseTree.Expression.DotPath?)dot.ParseTreeNode)?.Right; var _ = token == null ? leftValue.DefinedScope.Reference(dot.Right, System) : leftValue.DefinedScope.Reference(token, System); } else if (leftType is Type.Struct structType) { // Field access if (!(structType.Fields.ContainsKey(dot.Right))) { var rightIdent = (dot.ParseTreeNode as Syntax.ParseTree.Expression.DotPath)?.Right; var err = rightIdent == null ? new UndefinedSymbolError(dot.Right) : new UndefinedSymbolError(rightIdent); err.Context = "field access"; err.SimilarExistingNames = structType.Fields.Keys .Where(f => StringMetrics.OptimalStringAlignmentDistance(f, dot.Right) <= 2); System.Report(err); } } else { // TODO throw new NotImplementedException(); } return(null); }
protected override object?Visit(Expression.StructValue sval) { base.Visit(sval); // Check if it's even a struct type var instanceType = System.EvaluateType(sval.StructType); if (!(instanceType is Type.Struct structType)) { // TODO throw new NotImplementedException("Can't instantiate non-struct!"); } // Check if all fields are instantiated exactly once and with their proper type var remainingFields = structType.Fields.ToDictionary(f => f.Key, f => f.Value); var alreadyInitialized = new Dictionary <string, IParseTreeElement?>(); foreach (var field in sval.Fields) { if (!remainingFields.Remove(field.Name, out var declaredField)) { // Either already initialized, or unknown field if (structType.Fields.ContainsKey(field.Name)) { System.Report(new DoubleInitializationError(structType, field.Name) { TypeInitializer = sval.StructType?.ParseTreeNode, FirstInitialized = alreadyInitialized[field.Name], SecondInitialized = field.ParseTreeNode, }); } else { System.Report(new UnknownInitializedFieldError(structType, field.Name) { TypeInitializer = sval.StructType?.ParseTreeNode, UnknownInitialized = field.ParseTreeNode, SimilarExistingNames = remainingFields.Keys .Where(n => StringMetrics.OptimalStringAlignmentDistance(n, field.Name) <= 2), }); } } else { // Types need to match var assignedType = System.TypeOf(field.Value); if (!assignedType.Equals(declaredField.Type.Value)) { System.Report(new TypeMismatchError(declaredField.Type.Value, assignedType) { Context = "struct value initialization", Defined = declaredField.Definition?.ParseTreeNode, Wrong = field.ParseTreeNode, }); } alreadyInitialized.Add(field.Name, field.ParseTreeNode); } } if (remainingFields.Count > 0) { System.Report(new MissingInitializationError(structType, remainingFields.Keys) { TypeInitializer = sval.StructType?.ParseTreeNode, }); } return(null); }