Use semantic for intellisense in compiler controller (for testing of new feature)

This commit is contained in:
Ivan Bondarev 2021-09-06 20:37:31 +02:00
parent 76f2c12cf9
commit 3a16bafce0
8 changed files with 243 additions and 30 deletions

View file

@ -39,6 +39,8 @@ namespace CodeCompletion
internal bool parse_only_interface = false;
private template_type_reference converted_template_type = null;
private List<var_def_statement> pending_is_pattern_vars = new List<var_def_statement>();
private Compiler compiler;
public static bool use_semantic_for_intellisense;
public SemanticOptions semantic_options = new SemanticOptions();
@ -67,8 +69,148 @@ namespace CodeCompletion
//throw e;
//System.Diagnostics.Debug.WriteLine(e.StackTrace);
}
if (use_semantic_for_intellisense && cu.file_name.IndexOf("PABCSystem.pas") == -1)
try
{
CorrectTreeWithSemantic(cu);
}
catch (Exception e)
{
#if DEBUG
File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine);
#endif
}
}
private named_type_reference BuildSyntaxNodeForTypeReference(type_node tn)
{
if (tn.instance_params != null && tn.instance_params.Count > 0)
{
var ttr = new template_type_reference();
var ntr = new named_type_reference();
ttr.name = ntr;
ttr.params_list = new template_param_list();
var arr = tn.full_name.Split('.');
foreach (string s in arr)
{
if (s.IndexOf("<") == -1)
ntr.names.Add(new ident(s));
else
{
var id = new ident_with_templateparams();
ntr.Add(new ident(s.Substring(0, s.IndexOf("<"))));
foreach (var gen_td in tn.instance_params)
ttr.params_list.Add(BuildSyntaxNodeForTypeReference(gen_td));
}
}
return ttr;
}
else
{
var ntr = new named_type_reference();
var arr = tn.full_name.Split('.');
foreach (string s in arr)
{
ntr.names.Add(new ident(s));
}
return ntr;
}
}
private TypeScope GetIntellisenseTypeByType(Type t)
{
if (t.GetGenericArguments().Length == 0)
return TypeTable.get_compiled_type(t);
else
{
List<TypeScope> gen_args = new List<TypeScope>();
foreach (var gen_tn in t.GetGenericArguments())
{
gen_args.Add(TypeTable.get_compiled_type(gen_tn));
}
return CompiledScope.get_type_instance(t.GetGenericTypeDefinition(), gen_args);
}
}
private TypeScope GetCorrectedType(ElementScope es, type_node tn)
{
if (tn is compiled_type_node)
{
var ctn = tn as compiled_type_node;
if (ctn.compiled_type.IsArray)
return new ArrayScope(GetIntellisenseTypeByType((ctn.element_type as compiled_type_node).compiled_type), null);
if (ctn.compiled_type.GetGenericArguments().Length == 0)
return TypeTable.get_compiled_type(ctn.compiled_type);
else
{
List<TypeScope> gen_args = new List<TypeScope>();
foreach (var gen_tn in ctn.compiled_type.GetGenericArguments())
{
gen_args.Add(GetIntellisenseTypeByType(gen_tn));
}
return CompiledScope.get_type_instance(ctn.compiled_type.GetGenericTypeDefinition(), gen_args);
}
}
else
{
if (tn.full_name.IndexOf("$") != -1 || tn.full_name.IndexOf("#") != -1)
return es.sc as TypeScope;
var ntr = BuildSyntaxNodeForTypeReference(tn);
cur_scope = es.topScope;
ntr.visit(this);
if (returned_scope != null && returned_scope is TypeScope)
return returned_scope as TypeScope;
return es.sc as TypeScope;
}
}
private void CorrectVariableType(var_definition_node vdn)
{
location loc = null;
if (vdn is namespace_variable)
{
loc = (vdn as namespace_variable).loc;
}
else if (vdn is local_variable)
{
loc = (vdn as local_variable).loc;
}
else if (vdn is local_block_variable)
{
loc = (vdn as local_block_variable).loc;
}
if (loc == null)
return;
var es = FindScopeByLocation(loc.begin_line_num,loc.begin_column_num) as ElementScope;
if (es != null)
{
es.sc = GetCorrectedType(es, vdn.type);
es.MakeDescription();
}
}
private void CorrectTreeWithSemantic(compilation_unit cu)
{
var co = new CompilerOptions();
co.SavePCU = false;
co.GenerateCode = false;
co.UnitSyntaxTree = cu;
co.SourceFileName = cu.source_context.FileName;
co.ForIntellisense = true;
compiler = new Compiler();
compiler.CompilerOptions = co;
compiler.ClearAfterCompilation = false;
compiler.Compile();
foreach (var lv in compiler.CompiledVariables)
CorrectVariableType(lv);
compiler.ClearAll();
}
public SymScope FindScopeByLocation(int line, int col)
{
try

View file

@ -5698,7 +5698,7 @@ namespace CodeCompletion
if (this.instances[i].original_type == null && !(this.instances[i].elementType is TemplateParameterScope))
{
if (exact)
sc.instances.Add(gen_args[i]);
sc.instances.Add(gen_args[Math.Min(i, gen_args.Count - 1)]);
else
sc.instances.Add(this.instances[i]);
}

View file

@ -485,6 +485,7 @@ namespace PascalABCCompiler
public bool Debug = false;
public bool ForDebugging = false;
public bool ForIntellisense = false;
public bool Rebuild = false;
public bool Optimise = false;
public bool SavePCUInThreadPull = false;
@ -499,6 +500,8 @@ namespace PascalABCCompiler
public bool IgnoreRtlErrors = true;
public bool Only32Bit = false;
public string Locale = "ru";
public SyntaxTree.compilation_unit UnitSyntaxTree = null;
private string sourceFileName = null;
///имя исходного файла
///при измененнии меняется OutputFileName,OutputDirectory,SourceFileDirectory
@ -815,6 +818,16 @@ namespace PascalABCCompiler
}
}
public program_node semantic_tree
{
get
{
return _semantic_tree;
}
}
public List<var_definition_node> CompiledVariables = new List<var_definition_node>();
private Dictionary<string, List<TreeRealization.compiler_directive>> compilerDirectives = null;
//public Hashtable CompilerDirectives
@ -1878,7 +1891,9 @@ namespace PascalABCCompiler
CurrentUnit.ImplementationUsingNamespaceList,
null,
CompilerOptions.Debug,
CompilerOptions.ForDebugging
CompilerOptions.ForDebugging,
CompilerOptions.ForIntellisense,
CompiledVariables
);
CheckErrors();
}
@ -2073,8 +2088,8 @@ namespace PascalABCCompiler
File.Delete(rc_file);
}
}
if (ErrorsList.Count == 0 && compilerOptions.GenerateCode)
if (ErrorsList.Count == 0)
{
cdo.ForRunningWithEnvironment = CompilerOptions.RunWithEnvironment;
switch (CompilerOptions.OutputFileType)
@ -2144,7 +2159,8 @@ namespace PascalABCCompiler
{
pn.create_main_function_as_in_module();
}
pn = semanticTreeConvertersController.Convert(pn) as TreeRealization.program_node;
if (compilerOptions.GenerateCode)
pn = semanticTreeConvertersController.Convert(pn) as TreeRealization.program_node;
_semantic_tree = pn;
@ -2153,7 +2169,7 @@ namespace PascalABCCompiler
//если мы комилируем PCU
CompilerOptions.OutputFileType = CompilerOptions.OutputType.PascalCompiledUnit;
}
else
else if (compilerOptions.GenerateCode)
{
if( CompilerOptions.OutputFileType!= CompilerOptions.OutputType.SemanticTree)
#if DEBUG
@ -3240,19 +3256,29 @@ namespace PascalABCCompiler
if (FirstCompilationUnit == null)
FirstCompilationUnit = CurrentUnit;
OnChangeCompilerState(this, CompilerState.BeginCompileFile, UnitFileName);
SourceText = GetSourceFileText(UnitFileName);
if (SourceText == null)
if (CurrentUnit == FirstCompilationUnit)
throw new SourceFileNotFound(UnitFileName);
else
throw new UnitNotFound(CurrentCompilationUnit.SyntaxTree.file_name, UnitFileName, SyntaxUsesUnit.source_context);
if (compilerOptions.UnitSyntaxTree == null)
{
SourceText = GetSourceFileText(UnitFileName);
if (SourceText == null)
if (CurrentUnit == FirstCompilationUnit)
throw new SourceFileNotFound(UnitFileName);
else
throw new UnitNotFound(CurrentCompilationUnit.SyntaxTree.file_name, UnitFileName, SyntaxUsesUnit.source_context);
}
List<string> DefinesList = new List<string>();
DefinesList.Add("PASCALABC");
if (!compilerOptions.Debug && !compilerOptions.ForDebugging)
DefinesList.Add("RELEASE");
else
DefinesList.Add("DEBUG");
CurrentUnit.SyntaxTree = InternalParseText(UnitFileName, SourceText, errorsList, warnings, DefinesList);
if (compilerOptions.UnitSyntaxTree != null)
{
CurrentUnit.SyntaxTree = compilerOptions.UnitSyntaxTree;
compilerOptions.UnitSyntaxTree = null;
}
else
CurrentUnit.SyntaxTree = InternalParseText(UnitFileName, SourceText, errorsList, warnings, DefinesList);
if (errorsList.Count == 0) // SSM 2/05/16 - для преобразования синтаксических деревьев извне
{
@ -3293,7 +3319,8 @@ namespace PascalABCCompiler
if (is_dll(CurrentUnit.SyntaxTree))
compilerOptions.OutputFileType = PascalABCCompiler.CompilerOptions.OutputType.ClassLibrary;
CurrentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive;
if (ParsersController.LastParser != null)
CurrentUnit.CaseSensitive = ParsersController.LastParser.CaseSensitive;
CurrentCompilationUnit = CurrentUnit;
CurrentUnit.SyntaxUnitName = SyntaxUsesUnit;
@ -3421,7 +3448,9 @@ namespace PascalABCCompiler
CurrentUnit.InterfaceUsingNamespaceList,
docs,
CompilerOptions.Debug,
CompilerOptions.ForDebugging
CompilerOptions.ForDebugging,
CompilerOptions.ForIntellisense,
CompiledVariables
);
CheckErrors();
}
@ -3506,7 +3535,9 @@ namespace PascalABCCompiler
CurrentUnit.ImplementationUsingNamespaceList,
docs,
CompilerOptions.Debug,
CompilerOptions.ForDebugging
CompilerOptions.ForDebugging,
CompilerOptions.ForIntellisense,
CompiledVariables
);
CheckErrors();
}

View file

@ -73,7 +73,7 @@ namespace PascalABCCompiler.TreeConverter
//TODO: Исправить коллекцию модулей.
public PascalABCCompiler.TreeRealization.common_unit_node CompileInterface(SyntaxTree.compilation_unit SyntaxUnit,
PascalABCCompiler.TreeRealization.unit_node_list UsedUnits, List<Errors.Error> ErrorsList, List<Errors.CompilerWarning> WarningsList, PascalABCCompiler.Errors.SyntaxError parser_error,
System.Collections.Hashtable bad_nodes, TreeRealization.using_namespace_list namespaces, Dictionary<SyntaxTree.syntax_tree_node,string> docs, bool debug, bool debugging)
System.Collections.Hashtable bad_nodes, TreeRealization.using_namespace_list namespaces, Dictionary<SyntaxTree.syntax_tree_node,string> docs, bool debug, bool debugging, bool for_intellisense, List<TreeRealization.var_definition_node> CompiledVariables)
{
//convertion_data_and_alghoritms.__i = 0;
stv.parser_error=parser_error;
@ -92,6 +92,7 @@ namespace PascalABCCompiler.TreeConverter
stv.docs = docs;
stv.debug = debug;
stv.debugging = debugging;
stv.for_intellisense = for_intellisense;
SystemLibrary.SystemLibrary.syn_visitor = stv;
SetSemanticRules(SyntaxUnit);
@ -102,7 +103,8 @@ namespace PascalABCCompiler.TreeConverter
stv.DirectivesToNodesLinks = CompilerDirectivesToSyntaxTreeNodesLinker.BuildLinks(SyntaxUnit, ErrorsList); //MikhailoMMX добавил передачу списка ошибок (02.10.10)
SyntaxUnit.visit(stv);
/*SyntaxTree.program_module pmod=SyntaxUnit as SyntaxTree.program_module;
CompiledVariables.AddRange(stv.CompiledVariables);
/*SyntaxTree.program_module pmod=SyntaxUnit as SyntaxTree.program_module;
if (pmod!=null)
{
stv.visit(pmod);
@ -116,15 +118,15 @@ namespace PascalABCCompiler.TreeConverter
}
stv.visit(umod);
}*/
//stv.visit(SyntaxUnit);
//if (ErrorsList.Count>0) throw ErrorsList[0];
return stv.compiled_unit;
//stv.visit(SyntaxUnit);
//if (ErrorsList.Count>0) throw ErrorsList[0];
return stv.compiled_unit;
}
public void CompileImplementation(PascalABCCompiler.TreeRealization.common_unit_node SemanticUnit,
SyntaxTree.compilation_unit SyntaxUnit,PascalABCCompiler.TreeRealization.unit_node_list UsedUnits,List<Errors.Error> ErrorsList,List<Errors.CompilerWarning> WarningsList,
PascalABCCompiler.Errors.SyntaxError parser_error, System.Collections.Hashtable bad_nodes, TreeRealization.using_namespace_list interface_namespaces, TreeRealization.using_namespace_list imlementation_namespaces,
Dictionary<SyntaxTree.syntax_tree_node,string> docs, bool debug, bool debugging)
Dictionary<SyntaxTree.syntax_tree_node,string> docs, bool debug, bool debugging, bool for_intellisense, List<TreeRealization.var_definition_node> CompiledVariables)
{
//if (ErrorsList.Count>0) throw ErrorsList[0];
stv.parser_error=parser_error;
@ -142,7 +144,8 @@ namespace PascalABCCompiler.TreeConverter
stv.docs = docs;
stv.debug = debug;
stv.debugging = debugging;
SystemLibrary.SystemLibrary.syn_visitor = stv;
stv.for_intellisense = for_intellisense;
SystemLibrary.SystemLibrary.syn_visitor = stv;
SetSemanticRules(SyntaxUnit);
SyntaxTree.unit_module umod = SyntaxUnit as SyntaxTree.unit_module;
@ -158,7 +161,7 @@ namespace PascalABCCompiler.TreeConverter
cd.visit(stv);
stv.visit_implementation(umod);
CompiledVariables.AddRange(stv.CompiledVariables);
//stv.visit(SyntaxUnit);
//return stv.compiled_unit;
}

View file

@ -1808,6 +1808,8 @@ namespace PascalABCCompiler.TreeConverter
lv.block.local_variables.Add(lv);
if (tn == null) //Тип еще неизвестен, будем закрывать.
var_defs.Add(lv);
if (syntax_tree_visitor.for_intellisense)
syntax_tree_visitor.CompiledVariables.Add(lv);
return lv;
}
switch (converting_block())
@ -1844,6 +1846,8 @@ namespace PascalABCCompiler.TreeConverter
}
if (tn == null) //Тип еще неизвестен, будем закрывать.
var_defs.Add(vdn);
if (syntax_tree_visitor.for_intellisense)
syntax_tree_visitor.CompiledVariables.Add(vdn);
return vdn;
}

View file

@ -87,6 +87,8 @@ namespace PascalABCCompiler.TreeConverter
private common_unit_node _system_unit;
internal bool debug=true;
internal bool debugging=false;
public bool for_intellisense = false;
public List<var_definition_node> CompiledVariables = new List<var_definition_node>();
internal List<Errors.Error> ErrorsList;
internal List<Errors.CompilerWarning> WarningsList;
internal Dictionary<SyntaxTree.syntax_tree_node,string> docs;
@ -123,7 +125,7 @@ namespace PascalABCCompiler.TreeConverter
internal void AddError(Errors.Error err, bool shouldReturn=false)
{
if (ThrowCompilationError || !shouldReturn /*|| err.MustThrow && !shouldReturn*/)
if (!for_intellisense && (ThrowCompilationError || !shouldReturn) /*|| err.MustThrow && !shouldReturn*/)
{
throw err;
}
@ -136,7 +138,7 @@ namespace PascalABCCompiler.TreeConverter
internal void AddError(location loc, string ErrResourceString, params object[] values)
{
Errors.Error err = new SimpleSemanticError(loc, ErrResourceString, values);
if (ThrowCompilationError)
if (ThrowCompilationError && !for_intellisense)
{
throw err;
}
@ -1720,6 +1722,8 @@ namespace PascalABCCompiler.TreeConverter
lastname.source_context = l?.source_context;
di = context.check_name_node_type(lastname.name, sil?.FirstOrDefault(), get_location(lastname), general_node_type.type_node);
if (di == null)
return new undefined_type(lastname.name, loc);
return (type_node)di;
}
@ -17892,11 +17896,16 @@ namespace PascalABCCompiler.TreeConverter
{
if (ex is CompilationErrorWithLocation && (ex as CompilationErrorWithLocation).loc == null)
(ex as CompilationErrorWithLocation).loc = get_location(syntax_statement);
if (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference)//TODO: add interface
if (!for_intellisense && (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference))//TODO: add interface
throw ex;
else
ErrorsList.Add(ex);
}
catch (Exception ex)
{
if (!for_intellisense)
throw ex;
}
}
convertion_data_and_alghoritms.statement_list_stack.pop();

View file

@ -51,6 +51,7 @@
this.cbRunMono = new System.Windows.Forms.CheckBox();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.cbUseSemanticForIntellisense = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.PluginImage)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.RunILDASMImage)).BeginInit();
@ -303,11 +304,24 @@
this.button4.UseVisualStyleBackColor = true;
this.button4.Click += new System.EventHandler(this.Button4_Click);
//
// cbUseSemanticForIntellisense
//
this.cbUseSemanticForIntellisense.AutoSize = true;
this.cbUseSemanticForIntellisense.Location = new System.Drawing.Point(158, 272);
this.cbUseSemanticForIntellisense.Name = "cbUseSemanticForIntellisense";
this.cbUseSemanticForIntellisense.Size = new System.Drawing.Size(159, 17);
this.cbUseSemanticForIntellisense.TabIndex = 22;
this.cbUseSemanticForIntellisense.Text = "Use semantic for intellisense";
this.cbUseSemanticForIntellisense.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.cbUseSemanticForIntellisense.UseVisualStyleBackColor = true;
this.cbUseSemanticForIntellisense.CheckedChanged += new System.EventHandler(this.cbUseSemanticForIntellisense_CheckedChanged);
//
// CompilerInformation
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(379, 633);
this.Controls.Add(this.cbUseSemanticForIntellisense);
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.cbRunMono);
@ -375,5 +389,6 @@
public System.Windows.Forms.CheckBox cbRunMono;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.CheckBox cbUseSemanticForIntellisense;
}
}

View file

@ -166,7 +166,8 @@ namespace VisualPascalABCPlugins
string oiUseStandarParserForInellisense = "UseStandarParserForInellisense";
string oiNotUseRemoteCompiler = "NotUseRemoteCompiler";
string oiRunMono = "RunOnMono";
string oiUseSemanticForIntellisense = "UseSemanticForIntellisense";
public string OptionsFileName = Path.ChangeExtension(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName, ".ini");
public void SaveOptions(string FileName)
{
@ -174,7 +175,8 @@ namespace VisualPascalABCPlugins
Options.Add(oiNoCodeGeneration, NoCodeGeneration.Checked);
Options.Add(oiUseStandarParserForInellisense, cbUseStandarParserForInellisense.Checked);
Options.Add(oiNotUseRemoteCompiler, cbNotUseRemoteCompiler.Checked);
Options.Add(oiRunMono,cbRunMono.Checked);
Options.Add(oiRunMono, cbRunMono.Checked);
Options.Add(oiUseSemanticForIntellisense, cbUseSemanticForIntellisense.Checked);
try
{
PascalABCCompiler.StringResources.WriteStringsToStream(new StreamWriter(FileName, false, System.Text.Encoding.GetEncoding(1251)), Options);
@ -201,6 +203,8 @@ namespace VisualPascalABCPlugins
cbNotUseRemoteCompiler.Checked = Convert.ToBoolean(value);
if ((value = (string)Options[oiRunMono]) != null)
cbRunMono.Checked = Convert.ToBoolean(value);
if ((value = (string)Options[oiUseSemanticForIntellisense]) != null)
cbUseSemanticForIntellisense.Checked = Convert.ToBoolean(value);
}
catch (Exception)
{
@ -254,5 +258,10 @@ namespace VisualPascalABCPlugins
{
CodeCompletion.CodeCompletionTester.TestRename(@"c:\Work\Miks\_PABCNETGitHub\TestSuite\refactoring_tests\rename_tests");
}
private void cbUseSemanticForIntellisense_CheckedChanged(object sender, EventArgs e)
{
CodeCompletion.DomSyntaxTreeVisitor.use_semantic_for_intellisense = cbUseSemanticForIntellisense.Checked;
}
}
}