internal static IEnumerable <KeyValuePair <string, DType> > GetSuggestionsFromType(DType typeToSuggestFrom, DType suggestionType) { Contracts.AssertValid(typeToSuggestFrom); Contracts.AssertValid(suggestionType); // If no suggestion type provided, accept all suggestions. if (suggestionType == DType.Invalid) { suggestionType = DType.Error; } List <KeyValuePair <string, DType> > suggestions = new List <KeyValuePair <string, DType> >(); foreach (TypedName tName in typeToSuggestFrom.GetNames(DPath.Root)) { if (suggestionType.Accepts(tName.Type)) { var usedName = tName.Name.Value; string maybeDisplayName; if (DType.TryGetDisplayNameForColumn(typeToSuggestFrom, usedName, out maybeDisplayName)) { usedName = maybeDisplayName; } suggestions.Add(new KeyValuePair <string, DType>(usedName, tName.Type)); } } return(suggestions); }
private bool CheckOtherType(DType otherType, TexlNode otherArg, DType expectedType, IErrorContainer errors, ref Dictionary <TexlNode, DType> nodeToCoercedTypeMap) { Contracts.Assert(otherType.IsValid); Contracts.AssertValue(otherArg); Contracts.Assert(expectedType == DType.Color || expectedType == DType.Number); Contracts.AssertValue(errors); if (otherType.IsTable) { // Ensure we have a one-column table of numerics/color values based on expected type. return(expectedType == DType.Number ? CheckNumericColumnType(otherType, otherArg, errors, ref nodeToCoercedTypeMap) : CheckColorColumnType(otherType, otherArg, errors, ref nodeToCoercedTypeMap)); } if (expectedType.Accepts(otherType)) { return(true); } if (otherType.CoercesTo(expectedType)) { CollectionUtils.Add(ref nodeToCoercedTypeMap, otherArg, expectedType); return(true); } errors.EnsureError(DocumentErrorSeverity.Severe, otherArg, TexlStrings.ErrTypeError_Ex1_Ex2_Found, TableKindString, expectedType.GetKindString(), otherType.GetKindString()); return(false); }
internal override bool TryAddSuggestionsForNodeKind(IntellisenseData.IntellisenseData intellisenseData) { Contracts.AssertValue(intellisenseData); TexlNode curNode = intellisenseData.CurNode; int cursorPos = intellisenseData.CursorPos; // Cursor position is after the dot (If it was before the dot FindNode would have returned the left node). Contracts.Assert(curNode.Token.IsDottedNamePunctuator); Contracts.Assert(curNode.Token.Span.Lim <= cursorPos); DottedNameNode dottedNameNode = curNode.CastDottedName(); Identifier ident = dottedNameNode.Right; string identName = ident.Name; var leftNode = dottedNameNode.Left; DType leftType = intellisenseData.Binding.GetType(leftNode); intellisenseData.BeforeAddSuggestionsForDottedNameNode(leftNode); bool isOneColumnTable = leftType.IsColumn && leftNode.Kind == NodeKind.DottedName && leftType.Accepts(intellisenseData.Binding.GetType(((DottedNameNode)leftNode).Left)); if (cursorPos < ident.Token.Span.Min) { // Cursor position is before the identifier starts. // i.e. "this. | Awards" AddSuggestionsForLeftNodeScope(intellisenseData, leftNode, isOneColumnTable, leftType); } else if (cursorPos <= ident.Token.Span.Lim) { // Cursor position is in the identifier. // Suggest fields that don't need to be qualified. // Identifiers can include open and close brackets and the Token.Span covers them. // Get the matching string as a substring from the script so that the whitespace is preserved. intellisenseData.SetMatchArea(ident.Token.Span.Min, cursorPos, ident.Token.Span.Lim - ident.Token.Span.Min); if (!intellisenseData.Binding.ErrorContainer.HasErrors(dottedNameNode)) { intellisenseData.BoundTo = identName; } AddSuggestionsForLeftNodeScope(intellisenseData, leftNode, isOneColumnTable, leftType); } else if (IntellisenseHelper.CanSuggestAfterValue(cursorPos, intellisenseData.Script)) { // Verify that cursor is after a space after the identifier. // i.e. "this.Awards |" // Suggest binary operators. IntellisenseHelper.AddSuggestionsForAfterValue(intellisenseData, intellisenseData.Binding.GetType(dottedNameNode)); } return(true); }
protected static void TypeMatchPriority(DType type, IList <IntellisenseSuggestion> suggestions) { Contracts.Assert(type.IsValid); Contracts.AssertValue(suggestions); // The string type is too nebulous to push all matching string values to the top of the suggestion list if (type == DType.Unknown || type == DType.Error || type == DType.String) { return; } foreach (var suggestion in suggestions) { if (!suggestion.Type.IsUnknown && type.Accepts(suggestion.Type)) { suggestion.SortPriority++; } } }
public override bool CheckInvocation(TexlBinding binding, TexlNode[] args, DType[] argTypes, IErrorContainer errors, out DType returnType, out Dictionary <TexlNode, DType> nodeToCoercedTypeMap) { Contracts.AssertValue(args); Contracts.AssertAllValues(args); Contracts.AssertValue(argTypes); Contracts.Assert(args.Length == argTypes.Length); Contracts.AssertValue(errors); Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity); bool fValid = base.CheckInvocation(args, argTypes, errors, out returnType, out nodeToCoercedTypeMap); Contracts.Assert(returnType.IsTable); returnType = argTypes[0]; DType sourceType = argTypes[0]; TexlNode nameArg = args[1]; DType nameArgType = argTypes[1]; StrLitNode nameNode = null; DType columnType = DType.Invalid; if (nameArgType.Kind != DKind.String) { errors.EnsureError(DocumentErrorSeverity.Severe, nameArg, TexlStrings.ErrStringExpected); fValid = false; } else if ((nameNode = nameArg.AsStrLit()) != null) { // Verify that the name is valid. if (DName.IsValidDName(nameNode.Value)) { DName columnName = new DName(nameNode.Value); // Verify that the name exists. if (!sourceType.TryGetType(columnName, out columnType)) { sourceType.ReportNonExistingName(FieldNameKind.Logical, errors, columnName, nameNode); fValid = false; } else if (!columnType.IsPrimitive) { fValid = false; errors.EnsureError(nameArg, TexlStrings.ErrSortWrongType); } } else { errors.EnsureError(DocumentErrorSeverity.Severe, nameNode, TexlStrings.ErrArgNotAValidIdentifier_Name, nameNode.Value); fValid = false; } } TexlNode valuesArg = args[2]; IEnumerable <TypedName> columns; if ((columns = argTypes[2].GetNames(DPath.Root)).Count() != 1) { errors.EnsureError(DocumentErrorSeverity.Severe, valuesArg, TexlStrings.ErrInvalidSchemaNeedCol); return(false); } TypedName column = columns.Single(); if (nameNode != null && columnType.IsValid && !columnType.Accepts(column.Type)) { errors.EnsureError(DocumentErrorSeverity.Severe, valuesArg, TexlStrings.ErrTypeError_Arg_Expected_Found, nameNode.Value, columnType.GetKindString(), column.Type.GetKindString()); fValid = false; } return(fValid); }