diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index eedd1e611..2c52eae90 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -3194,9 +3194,9 @@ namespace CodeCompletion element_type = element_types[0]; for (int i = 1; i < element_types.Count; i++) { - if (element_type.IsConvertable(element_types[i])) + if (element_type.IsConvertable(element_types[i], true)) element_type = element_types[i]; - else if (!element_types[i].IsConvertable(element_type)) + else if (!element_types[i].IsConvertable(element_type, true)) { element_type = TypeTable.obj_type; break; @@ -4754,7 +4754,7 @@ namespace CodeCompletion return; } - if (type1.IsConvertable(type2)) + if (type1.IsConvertable(type2, true)) { returned_scope = type2; return; diff --git a/CodeCompletion/SymTable.cs b/CodeCompletion/SymTable.cs index 36fc94c4b..dacdeebaa 100644 --- a/CodeCompletion/SymTable.cs +++ b/CodeCompletion/SymTable.cs @@ -1874,12 +1874,12 @@ namespace CodeCompletion return parent.FindNameOnlyInThisType(name); } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts)) return true; if (ts is CompiledScope) - return ts.IsConvertable(this); + return ts.IsConvertable(this, strong); if (ts is TemplateParameterScope || ts.IsGenericParameter) return true; return false; @@ -2423,7 +2423,7 @@ namespace CodeCompletion enum_consts.Add(name); } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts)) return true; @@ -2579,7 +2579,7 @@ namespace CodeCompletion return null; } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts) || ts is TemplateParameterScope || ts.IsGenericParameter) return true; @@ -2703,7 +2703,7 @@ namespace CodeCompletion return new FileScope(gen_args[0], this.topScope); } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (ts is FileScope) { @@ -2929,12 +2929,12 @@ namespace CodeCompletion return actType.FindOverloadNamesOnlyInType(name); } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (ts is TypeSynonim) ts = (ts as TypeSynonim).actType; if (ts is TypeScope) - return this.actType.IsConvertable(ts); + return this.actType.IsConvertable(ts, strong); return false; } @@ -3088,9 +3088,9 @@ namespace CodeCompletion return false; } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { - if (ts is TypeSynonim) return actType.IsConvertable((ts as TypeSynonim).actType); + if (ts is TypeSynonim) return actType.IsConvertable((ts as TypeSynonim).actType, strong); if (ts is ShortStringScope) return true; return false; } @@ -3330,7 +3330,7 @@ namespace CodeCompletion } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (ts is NullTypeScope && is_dynamic_arr) return true; @@ -3553,7 +3553,7 @@ namespace CodeCompletion } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (ts is NullTypeScope) return false; @@ -3638,7 +3638,7 @@ namespace CodeCompletion get { return ref_type; } } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts)) return true; @@ -4194,7 +4194,7 @@ namespace CodeCompletion si.description = CodeCompletionController.CurrentParser.LanguageInformation.GetSynonimDescription(this); } - public virtual bool IsConvertable(TypeScope ts) + public virtual bool IsConvertable(TypeScope ts, bool strong = false) { if (IsEqual(ts)) return true; @@ -5474,7 +5474,7 @@ namespace CodeCompletion instances.Clear(); } - public override bool IsConvertable(TypeScope ts) + public override bool IsConvertable(TypeScope ts, bool strong = false) { CompiledScope cs = ts as CompiledScope; if (ts == null) @@ -5483,7 +5483,7 @@ namespace CodeCompletion return true; if (cs == null) if (ts is TypeSynonim) - return this.IsConvertable((ts as TypeSynonim).actType); + return this.IsConvertable((ts as TypeSynonim).actType, strong); else if (ts is ShortStringScope && ctn == typeof(string)) return true; @@ -5512,7 +5512,7 @@ namespace CodeCompletion for (int i = 0; i < parameters.Length; i++) { CompiledScope param_cs = TypeTable.get_compiled_type(null, parameters[i].ParameterType); - if (!(pt.target.parameters[i].sc is TypeScope) || !param_cs.IsConvertable(pt.target.parameters[i].sc as TypeScope)) + if (!(pt.target.parameters[i].sc is TypeScope) || !param_cs.IsConvertable(pt.target.parameters[i].sc as TypeScope, strong)) return false; } return CompiledScope.get_type_instance(invoke_meth.ReturnType, new List()).IsConvertable(pt.target.return_type); @@ -5587,6 +5587,11 @@ namespace CodeCompletion } if (cs.ctn.IsGenericParameter || this.ctn.IsGenericParameter) return true; + if (!strong && tc == type_compare.greater_type && this.ctn.IsPrimitive && cs.ctn.IsPrimitive) + { + if (code1 != TypeCode.Double && code2 != TypeCode.Single) + return true; + } return tc == type_compare.less_type; } else diff --git a/ParserTools/ParserTools/DefaultLanguageInformation.cs b/ParserTools/ParserTools/DefaultLanguageInformation.cs index e836ab6bc..5c288adca 100644 --- a/ParserTools/ParserTools/DefaultLanguageInformation.cs +++ b/ParserTools/ParserTools/DefaultLanguageInformation.cs @@ -2848,7 +2848,7 @@ namespace PascalABCCompiler.Parsers i--; } } - if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?')) + if (i >= 0 && (char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i+1))) { bound = i + 1; TestForKeyword(Text, i, ref bound, punkt_sym, out keyw); @@ -2942,6 +2942,15 @@ namespace PascalABCCompiler.Parsers return FindExpressionFromAnyPosition(off, Text, line, col, out keyw, out expr_without_brackets); } + private bool IsPunctuation(string Text, int ind) + { + while (ind < Text.Length && char.IsWhiteSpace(Text[ind])) + ind++; + if (ind >= Text.Length) + return true; + return char.IsPunctuation(Text[ind]); + } + public virtual string FindExpressionFromAnyPosition(int off, string Text, int line, int col, out KeywordKind keyw, out string expr_without_brackets) { int i = off - 1; @@ -2951,10 +2960,10 @@ namespace PascalABCCompiler.Parsers return ""; bool is_char = false; System.Text.StringBuilder sb = new System.Text.StringBuilder(); - if (Text[i] != ' ' && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?')) + if (Text[i] != ' ' && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1))) { //sb.Remove(0,sb.Length); - while (i >= 0 && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?')) + while (i >= 0 && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1))) { //sb.Insert(0,Text[i]);//.Append(Text[i]); i--; @@ -2962,7 +2971,7 @@ namespace PascalABCCompiler.Parsers is_char = true; } i = off; - if (i < Text.Length && Text[i] != ' ' && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?')) + if (i < Text.Length && Text[i] != ' ' && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_' || Text[i] == '&' || Text[i] == '?' && IsPunctuation(Text, i + 1))) { while (i < Text.Length && (Char.IsLetterOrDigit(Text[i]) || Text[i] == '_')) { @@ -3112,6 +3121,8 @@ namespace PascalABCCompiler.Parsers if (ind != -1) return ss.Substring(ind + 3); } + if (is_new && ss != null && ss.IndexOf("new") == -1 && ss.IndexOf(":") != -1) + return expr_without_brackets + "(true?"+ss; return ss; } return null; diff --git a/TestSuite/intellisense_tests/question2.pas b/TestSuite/intellisense_tests/question2.pas new file mode 100644 index 000000000..c0b02dd6f --- /dev/null +++ b/TestSuite/intellisense_tests/question2.pas @@ -0,0 +1,8 @@ +type + t1=class + constructor(i: byte) := exit; + end; + +begin + new t1{@constructor t1(i: byte);@}(true?0:1); +end. \ No newline at end of file diff --git a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionActions.cs b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionActions.cs index 8433c6d31..4f0abb06e 100644 --- a/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionActions.cs +++ b/VisualPascalABCNET/IB/CodeCompletion/CodeCompletionActions.cs @@ -131,7 +131,7 @@ namespace VisualPascalABC if (expressionResult != full_expr && full_expr.StartsWith("(")) return new List(); List poses = ccp.GetDefinition(full_expr, textArea.MotherTextEditorControl.FileName, textArea.Caret.Line, textArea.Caret.Column, only_check); - if (poses == null) + if (poses == null || poses.Count == 0) poses = ccp.GetDefinition(expressionResult, textArea.MotherTextEditorControl.FileName, textArea.Caret.Line, textArea.Caret.Column, only_check); return poses; } @@ -145,7 +145,7 @@ namespace VisualPascalABC string full_expr; string expressionResult = FindFullExpression(textContent, textArea, out ccp.keyword, out full_expr); List poses = ccp.GetRealization(full_expr, textArea.MotherTextEditorControl.FileName, textArea.Caret.Line, textArea.Caret.Column); - if (poses == null) + if (poses == null || poses.Count == 0) poses = ccp.GetRealization(expressionResult, textArea.MotherTextEditorControl.FileName, textArea.Caret.Line, textArea.Caret.Column); return poses; } @@ -163,7 +163,7 @@ namespace VisualPascalABC { if (CodeCompletion.CodeCompletionController.CurrentParser == null) return; position = GetRealizationPosition(textArea); - if (position == null) return; + if (position == null || position.Count == 0) return; if (position.Count == 1) { Position pos = position[0];