diff --git a/Client/language-configuration.json b/Client/language-configuration.json new file mode 100644 index 0000000..349a925 --- /dev/null +++ b/Client/language-configuration.json @@ -0,0 +1,23 @@ +{ + "comments": { + "lineComment": "--" + }, + "brackets": [["(", ")"], ["[", "]"], ["{", "}"]], + "autoClosingPairs": [ + ["(", ")"], + ["[", "]"], + ["{", "}"], + { "open": "'", "close": "'", "notIn": ["string", "comment"] }, + { "open": "\"", "close": "\"", "notIn": ["string"] }, + { "open": "`", "close": "`", "notIn": ["string", "comment"] }, + { "open": "/**", "close": " */", "notIn": ["string"] } + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["'", "'"], + ["\"", "\""], + ["`", "`"] + ] +} diff --git a/Client/out/extension.js b/Client/out/extension.js index f36ce08..251e2c5 100644 --- a/Client/out/extension.js +++ b/Client/out/extension.js @@ -8,7 +8,7 @@ const path = require("path"); const fs = require("fs"); // Defines the search path of your language server DLL. (.NET Core) const languageServerPaths = [ - "server/DemoLanguageServer.dll", + "./server/UpsilonLanguageServer.dll", "../UpsilonLanguageServer/UpsilonLanguageServer/bin/Debug/netcoreapp2.1/UpsilonLanguageServer.dll" ]; function activateLanguageServer(context) { @@ -55,9 +55,9 @@ function activateLanguageServer(context) { configurationSection: "upsilonLanguageServer", // Notify the server about file changes to '.clientrc files contain in the workspace fileEvents: [ - vscode.workspace.createFileSystemWatcher("**/.clientrc"), - vscode.workspace.createFileSystemWatcher("**/.yup"), - vscode.workspace.createFileSystemWatcher("**/.lua"), + vscode.workspace.createFileSystemWatcher("**/*.clientrc"), + vscode.workspace.createFileSystemWatcher("**/*.yup"), + vscode.workspace.createFileSystemWatcher("**/*.lua"), vscode.workspace.createFileSystemWatcher("**/.upsilon/*.json") ] } diff --git a/Client/out/extension.js.map b/Client/out/extension.js.map index c716d56..e9c6d2e 100644 --- a/Client/out/extension.js.map +++ b/Client/out/extension.js.map @@ -1 +1 @@ -{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,6DAA6D;AAC7D,8EAA8E;AAE9E,iCAAiC;AACjC,wDAAwD;AACxD,6BAA6B;AAC7B,yBAAyB;AAEzB,mEAAmE;AACnE,MAAM,mBAAmB,GAAG;IAC1B,+BAA+B;IAC/B,kGAAkG;CACnG,CAAC;AAEF,SAAS,sBAAsB,CAAC,OAAgC;IAC9D,0DAA0D;IAC1D,IAAI,YAAY,GAAW,IAAI,CAAC;IAChC,KAAK,IAAI,CAAC,IAAI,mBAAmB,EAAE;QACjC,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9B,kBAAkB;QAClB,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;YACpB,YAAY,GAAG,CAAC,CAAC;YACjB,MAAM;SACP;KACF;IACD,IAAI,CAAC,YAAY;QACf,MAAM,IAAI,QAAQ,CAAC,yCAAyC,CAAC,CAAC;IAChE,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,YAAY,oBAAoB,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,GAAG,CAAC,CAAC;IAEvC,oFAAoF;IACpF,qCAAqC;IACrC,IAAI,aAAa,GAAiC;QAChD,GAAG,EAAE;YACH,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,CAAC,YAAY,CAAC;YACpB,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;SAC3B;QACD,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;YAC/B,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;SAC3B;KACF,CAAC;IACF,yCAAyC;IACzC,IAAI,aAAa,GAAyC;QACxD,+CAA+C;QAC/C,gBAAgB,EAAE;YAChB;gBACE,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,MAAM;aACf;SACF;QACD,WAAW,EAAE;YACX,wEAAwE;YACxE,oBAAoB,EAAE,uBAAuB;YAC7C,oFAAoF;YACpF,UAAU,EAAE;gBACV,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,cAAc,CAAC;gBACxD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,SAAS,CAAC;gBACnD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,SAAS,CAAC;gBACnD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,oBAAoB,CAAC;aAC/D;SACF;KACF,CAAC;IAEF,mDAAmD;IACnD,IAAI,MAAM,GAAG,IAAI,cAAc,CAAC,cAAc,CAC5C,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,aAAa,CACd,CAAC;IACF,IAAI,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAEhC,iEAAiE;IACjE,sDAAsD;IACtD,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,yDAAyD;AACzD,0EAA0E;AAC1E,SAAgB,QAAQ,CAAC,OAAgC;IACvD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAHD,4BAGC;AAED,2DAA2D;AAC3D,SAAgB,UAAU,KAAI,CAAC;AAA/B,gCAA+B"} \ No newline at end of file +{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,6DAA6D;AAC7D,8EAA8E;AAE9E,iCAAiC;AACjC,wDAAwD;AACxD,6BAA6B;AAC7B,yBAAyB;AAEzB,mEAAmE;AACnE,MAAM,mBAAmB,GAAG;IAC1B,oCAAoC;IACpC,kGAAkG;CACnG,CAAC;AAEF,SAAS,sBAAsB,CAAC,OAAgC;IAC9D,0DAA0D;IAC1D,IAAI,YAAY,GAAW,IAAI,CAAC;IAChC,KAAK,IAAI,CAAC,IAAI,mBAAmB,EAAE;QACjC,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QAC9B,kBAAkB;QAClB,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;YACpB,YAAY,GAAG,CAAC,CAAC;YACjB,MAAM;SACP;KACF;IACD,IAAI,CAAC,YAAY;QACf,MAAM,IAAI,QAAQ,CAAC,yCAAyC,CAAC,CAAC;IAChE,IAAI,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,YAAY,oBAAoB,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,GAAG,CAAC,CAAC;IAEvC,oFAAoF;IACpF,qCAAqC;IACrC,IAAI,aAAa,GAAiC;QAChD,GAAG,EAAE;YACH,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,CAAC,YAAY,CAAC;YACpB,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;SAC3B;QACD,KAAK,EAAE;YACL,OAAO,EAAE,QAAQ;YACjB,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;YAC/B,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE;SAC3B;KACF,CAAC;IACF,yCAAyC;IACzC,IAAI,aAAa,GAAyC;QACxD,+CAA+C;QAC/C,gBAAgB,EAAE;YAChB;gBACE,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,MAAM;aACf;SACF;QACD,WAAW,EAAE;YACX,wEAAwE;YACxE,oBAAoB,EAAE,uBAAuB;YAC7C,oFAAoF;YACpF,UAAU,EAAE;gBACV,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,eAAe,CAAC;gBACzD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,UAAU,CAAC;gBACpD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,UAAU,CAAC;gBACpD,MAAM,CAAC,SAAS,CAAC,uBAAuB,CAAC,oBAAoB,CAAC;aAC/D;SACF;KACF,CAAC;IAEF,mDAAmD;IACnD,IAAI,MAAM,GAAG,IAAI,cAAc,CAAC,cAAc,CAC5C,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,aAAa,CACd,CAAC;IACF,IAAI,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAEhC,iEAAiE;IACjE,sDAAsD;IACtD,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,yDAAyD;AACzD,0EAA0E;AAC1E,SAAgB,QAAQ,CAAC,OAAgC;IACvD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAHD,4BAGC;AAED,2DAA2D;AAC3D,SAAgB,UAAU,KAAI,CAAC;AAA/B,gCAA+B"} \ No newline at end of file diff --git a/Client/package.json b/Client/package.json index 18dfe02..6de8591 100644 --- a/Client/package.json +++ b/Client/package.json @@ -1,5 +1,6 @@ { "name": "upsilon-language-extension", + "publisher": "Deuk", "version": "1.0.0", "engines": { "vscode": "^1.29.1" @@ -15,6 +16,7 @@ "aliases": [ "Upsilon" ], + "configuration": "./language-configuration.json", "extensions": [ ".yup", ".lua" @@ -30,23 +32,12 @@ ], "configuration": { "type": "object", - "title": "Example configuration", + "title": "Upsilon configuration", "properties": { "upsilonLanguageServer.maxNumberOfProblems": { "type": "number", "default": 100, "description": "Controls the maximum number of problems produced by the server." - }, - "upsilonLanguageServer.trace.server": { - "scope": "window", - "type": "string", - "enum": [ - "off", - "messages", - "verbose" - ], - "default": "off", - "description": "Traces the communication between VSCode and the upsilonLanguageServer service." } } } diff --git a/Client/src/extension.ts b/Client/src/extension.ts index 516d61b..e743ece 100644 --- a/Client/src/extension.ts +++ b/Client/src/extension.ts @@ -9,7 +9,7 @@ import * as fs from "fs"; // Defines the search path of your language server DLL. (.NET Core) const languageServerPaths = [ - "server/DemoLanguageServer.dll", + "./server/UpsilonLanguageServer.dll", "../UpsilonLanguageServer/UpsilonLanguageServer/bin/Debug/netcoreapp2.1/UpsilonLanguageServer.dll" ]; @@ -58,9 +58,9 @@ function activateLanguageServer(context: vscode.ExtensionContext) { configurationSection: "upsilonLanguageServer", // Notify the server about file changes to '.clientrc files contain in the workspace fileEvents: [ - vscode.workspace.createFileSystemWatcher("**/.clientrc"), - vscode.workspace.createFileSystemWatcher("**/.yup"), - vscode.workspace.createFileSystemWatcher("**/.lua"), + vscode.workspace.createFileSystemWatcher("**/*.clientrc"), + vscode.workspace.createFileSystemWatcher("**/*.yup"), + vscode.workspace.createFileSystemWatcher("**/*.lua"), vscode.workspace.createFileSystemWatcher("**/.upsilon/*.json") ] } diff --git a/Client/upsilon-language-extension-1.0.0.vsix b/Client/upsilon-language-extension-1.0.0.vsix new file mode 100644 index 0000000..86dcfb5 Binary files /dev/null and b/Client/upsilon-language-extension-1.0.0.vsix differ diff --git a/UpsilonLanguageServer/Lib/Microsoft.CSharp.dll b/UpsilonLanguageServer/Lib/Microsoft.CSharp.dll new file mode 100644 index 0000000..5079c5f Binary files /dev/null and b/UpsilonLanguageServer/Lib/Microsoft.CSharp.dll differ diff --git a/UpsilonLanguageServer/Lib/Microsoft.CSharp.xml b/UpsilonLanguageServer/Lib/Microsoft.CSharp.xml new file mode 100644 index 0000000..1dab2ff --- /dev/null +++ b/UpsilonLanguageServer/Lib/Microsoft.CSharp.xml @@ -0,0 +1,216 @@ + + + Microsoft.CSharp + + + + Represents an error that occurs when a dynamic bind in the C# runtime binder is processed. + + + Initializes a new instance of the class. + + + Initializes a new instance of the class that has a specified error message. + The message that describes the exception. The caller of this constructor is required to ensure that this string has been localized for the current system culture. + + + Initializes a new instance of the class that has serialized data. + The object that holds the serialized object data about the exception being thrown.. + The contextual information about the source or destination. + + + Initializes a new instance of the class that has a specified error message and a reference to the inner exception that is the cause of this exception. + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference if no inner exception is specified. + + + Represents an error that occurs when a dynamic bind in the C# runtime binder is processed. + + + Initializes a new instance of the class with a system-supplied message that describes the error. + + + Initializes a new instance of the class with a specified message that describes the error. + The message that describes the exception. The caller of this constructor is required to ensure that this string has been localized for the current system culture. + + + Initializes a new instance of the class with serialized data. + The that holds the serialized object data about the exception being thrown. + The that contains contextual information about the source or destination. + + + Initializes a new instance of the class that has a specified error message and a reference to the inner exception that is the cause of this exception. + The error message that explains the reason for the exception. + The exception that is the cause of the current exception, or a null reference if no inner exception is specified. + + + Contains factory methods to create dynamic call site binders for CSharp. + + + Initializes a new CSharp binary operation binder. + The flags with which to initialize the binder. + The binary operation kind. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp binary operation binder. + + + Initializes a new CSharp convert binder. + The flags with which to initialize the binder. + The type to convert to. + The that indicates where this operation is used. + Returns a new CSharp convert binder. + + + Initializes a new CSharp get index binder. + The flags with which to initialize the binder. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp get index binder. + + + Initializes a new CSharp get member binder. + The flags with which to initialize the binder. + The name of the member to get. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp get member binder. + + + Initializes a new CSharp invoke binder. + The flags with which to initialize the binder. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp invoke binder. + + + Initializes a new CSharp invoke constructor binder. + The flags with which to initialize the binder. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp invoke constructor binder. + + + Initializes a new CSharp invoke member binder. + The flags with which to initialize the binder. + The name of the member to invoke. + The list of type arguments specified for this invoke. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp invoke member binder. + + + Initializes a new CSharp is event binder. + The flags with which to initialize the binder. + The name of the event to look for. + The that indicates where this operation is used. + Returns a new CSharp is event binder. + + + Initializes a new CSharp set index binder. + The flags with which to initialize the binder. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp set index binder. + + + Initializes a new CSharp set member binder. + The flags with which to initialize the binder. + The name of the member to set. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp set member binder. + + + Initializes a new CSharp unary operation binder. + The flags with which to initialize the binder. + The unary operation kind. + The that indicates where this operation is used. + The sequence of instances for the arguments to this operation. + Returns a new CSharp unary operation binder. + + + Represents information about C# dynamic operations that are specific to particular arguments at a call site. Instances of this class are generated by the C# compiler. + + + Initializes a new instance of the class. + The flags for the argument. + The name of the argument, if named; otherwise null. + A new instance of the class. + + + Represents information about C# dynamic operations that are specific to particular arguments at a call site. Instances of this class are generated by the C# compiler. + + + The argument is a constant. + + + + The argument is passed to an out parameter. + + + + The argument is passed to a ref parameter. + + + + The argument is a indicating an actual type name used in source. Used only for target objects in static calls. + + + + The argument is a named argument. + + + + No additional information to represent. + + + + The argument's compile-time type should be considered during binding. + + + + Represents information about C# dynamic operations that are not specific to particular arguments at a call site. Instances of this class are generated by the C# compiler. + + + The binder represents a logical AND or logical OR that is part of a conditional logical operator evaluation. + + + + The evaluation of this binder happens in a checked context. + + + + The binder represents an implicit conversion for use in an array creation expression. + + + + The binder represents an explicit conversion. + + + + The binder represents an invoke on a simple name. + + + + The binder represents an invoke on a specialname. + + + + There is no additional information required for this binder. + + + + The binder is used in a position that does not require a result, and can therefore bind to a void returning method. + + + + The result of any bind is going to be indexed get a set index or get index binder. + + + + The value in this set index or set member comes a compound assignment operator. + + + + \ No newline at end of file diff --git a/UpsilonLanguageServer/Lib/Upsilon.deps.json b/UpsilonLanguageServer/Lib/Upsilon.deps.json index 2b86f15..8a52037 100644 --- a/UpsilonLanguageServer/Lib/Upsilon.deps.json +++ b/UpsilonLanguageServer/Lib/Upsilon.deps.json @@ -10,7 +10,8 @@ "Upsilon/1.0.0": { "dependencies": { "NETStandard.Library": "2.0.3", - "System.Collections.Immutable": "1.5.0" + "System.Collections.Immutable": "1.5.0", + "Microsoft.CSharp": "4.0.0.0" }, "runtime": { "Upsilon.dll": {} @@ -29,6 +30,14 @@ "fileVersion": "4.6.26515.6" } } + }, + "Microsoft.CSharp/4.0.0.0": { + "runtime": { + "Microsoft.CSharp.dll": { + "assemblyVersion": "4.0.0.0", + "fileVersion": "4.6.26515.6" + } + } } } }, @@ -58,6 +67,11 @@ "sha512": "sha512-RGxi2aQoXgZ5ge0zxrKqI4PU9LrYYoLC+cnEnWXKsSduCOUhE1GEAAoTexUVT8RZOILQyy1B27HC8Xw/XLGzdQ==", "path": "system.collections.immutable/1.5.0", "hashPath": "system.collections.immutable.1.5.0.nupkg.sha512" + }, + "Microsoft.CSharp/4.0.0.0": { + "type": "reference", + "serviceable": false, + "sha512": "" } } } \ No newline at end of file diff --git a/UpsilonLanguageServer/Lib/Upsilon.dll b/UpsilonLanguageServer/Lib/Upsilon.dll index 2c03dc7..9a7cb8b 100644 Binary files a/UpsilonLanguageServer/Lib/Upsilon.dll and b/UpsilonLanguageServer/Lib/Upsilon.dll differ diff --git a/UpsilonLanguageServer/Lib/Upsilon.pdb b/UpsilonLanguageServer/Lib/Upsilon.pdb index 0ed0e56..8d0f737 100644 Binary files a/UpsilonLanguageServer/Lib/Upsilon.pdb and b/UpsilonLanguageServer/Lib/Upsilon.pdb differ diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/BoundTypeParser.cs b/UpsilonLanguageServer/UpsilonLanguageServer/BoundTypeParser.cs index a2b925d..fc1b739 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/BoundTypeParser.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/BoundTypeParser.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using Upsilon.Binder.VariableSymbols; using Upsilon.BoundTypes; +using Upsilon.StandardLibraries; using Type = Upsilon.BaseTypes.Type; namespace UpsilonLanguageServer @@ -24,18 +25,123 @@ namespace UpsilonLanguageServer var value = (JObject)innerProperty.Value; var type = value.GetValue("type", StringComparison.InvariantCultureIgnoreCase)?.ToString(); var comment = value.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)?.ToString(); - dic.Add(propertyName, new UserDataBoundProperty() + if (string.Equals("function", type, StringComparison.InvariantCultureIgnoreCase)) { - Name = propertyName, - ActualType = type, - Comment = comment, - Type = ParseType(type) - }); + ParseMethod(value, dic, propertyName, type, comment); + } + else + { + dic.Add(propertyName.ToLowerInvariant(), new UserDataBoundProperty() + { + Name = propertyName, + ActualType = type, + Comment = comment, + Type = ParseType(type) + }); + } } BoundTypeHandler.LoadUserDataTypeDefinition(new UserDataBoundTypeDefinition(typeName, dic)); } + } + private static void ParseMethod(JObject value, IDictionary dic, string propertyName, string type, string comment) + { + var returnType = value.GetValue("returns", StringComparison.InvariantCultureIgnoreCase)?.ToString(); + var parameters = new List(); + if (value.GetValue("Parameters", StringComparison.InvariantCultureIgnoreCase) is JObject parameterJson) + { + var properties = parameterJson.Properties(); + foreach (var property in properties) + { + var parameterName = property.Name; + var parameterValue = (JObject) property.Value; + var parType = parameterValue.GetValue("type", StringComparison.InvariantCultureIgnoreCase) + ?.ToString(); + var parComment = parameterValue.GetValue("comment", StringComparison.InvariantCultureIgnoreCase) + ?.ToString(); + var isOptional = parameterValue.GetValue("IsOptional", StringComparison.InvariantCultureIgnoreCase) + ?.ToObject(); + parameters.Add(new UserDataBoundFunctionParameter() + { + Name = parameterName, + Type = ParseType(parType), + Comment = parComment, + IsOptional = isOptional.HasValue && isOptional.Value + }); + } + } + + dic.Add(propertyName.ToLowerInvariant(), new UserDataBoundMethod() + { + Name = propertyName, + ActualType = type, + Comment = comment, + Type = ParseType(type), + ResultType = ParseType(returnType), + Parameters = parameters.ToArray() + }); + } + + public static void LoadStaticVariables(string fileContent) + { + StaticScope.BoundScope = StaticScope.CreateStandardLibrary().Item2; + var json = JObject.Parse(fileContent); + foreach (var property in json.Properties()) + { + var name = property.Name; + var obj = (JObject)property.Value; + var stringType = obj.GetValue("type", StringComparison.InvariantCultureIgnoreCase).ToString().ToLowerInvariant(); + var comments = obj.GetValue("comment", StringComparison.InvariantCultureIgnoreCase)?.ToString() + .Split('\n'); + var type = ParseType(stringType); + if (type == Type.UserData) + { + var boundType = BoundTypeHandler.GetTypeDefinition(stringType); + if (boundType != null) + { + StaticScope.BoundScope.AssignToNearest(new UserDataVariableSymbol(name, boundType){CommentValue = comments}); + } + else + { + StaticScope.BoundScope.AssignToNearest(new UserDataVariableSymbol(name, Type.Unknown){CommentValue = comments}); + } + } + else if (type == Type.Function) + { + var returnType = obj.GetValue("returns", StringComparison.InvariantCultureIgnoreCase).ToString().ToLowerInvariant(); + var parameters = new List(); + if (obj.GetValue("Parameters", StringComparison.InvariantCultureIgnoreCase) is JObject parameterJson) + { + var properties = parameterJson.Properties(); + foreach (var prop in properties) + { + var parameterValue = (JObject) prop.Value; + var parType = parameterValue.GetValue("type", StringComparison.InvariantCultureIgnoreCase) + ?.ToString(); + var parsedType = ParseType(parType); + var isOptional = parameterValue.GetValue("IsOptional", StringComparison.InvariantCultureIgnoreCase) + ?.ToObject(); + parameters.Add(new InternalFunctionVariableSymbol.InternalFunctionParameter(parsedType, + isOptional.HasValue && isOptional.Value)); + } + } + var parsedReturnType = ParseType(returnType); + StaticScope.BoundScope.AssignToNearest(new InternalFunctionVariableSymbol(name, false, + parsedReturnType, parameters.ToArray()) + { + CommentValue = comments + }); + } + else + { + StaticScope.BoundScope.AssignToNearest(new VariableSymbol(property.Name, + type, false) + { + CommentValue = comments + }); + } + } } private static Type ParseType(string input) diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/DiagnosticsProvider.cs b/UpsilonLanguageServer/UpsilonLanguageServer/DiagnosticsProvider.cs index b5a1ac7..5496d60 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/DiagnosticsProvider.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/DiagnosticsProvider.cs @@ -39,7 +39,8 @@ namespace UpsilonLanguageServer private static readonly ScriptOptions Options = new ScriptOptions() { ThrowExceptionOnError = false, - SaveDataComments = true + SaveDataComments = true, + }; private static async Task RealLint(TextDocument document, int maxNumberOfProblems, SessionDocument session, diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/Program.cs b/UpsilonLanguageServer/UpsilonLanguageServer/Program.cs index 07647d0..6dc8a98 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/Program.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/Program.cs @@ -16,9 +16,9 @@ using Microsoft.Extensions.Logging.Debug; namespace UpsilonLanguageServer { - static class Program + internal static class Program { - static void Main(string[] args) + private static void Main(string[] args) { var debugMode = args.Any(a => a.Equals("--debug", StringComparison.OrdinalIgnoreCase)); #if WAIT_FOR_DEBUGGER diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/Services/InitializationService.cs b/UpsilonLanguageServer/UpsilonLanguageServer/Services/InitializationService.cs index 23f57dc..359b683 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/Services/InitializationService.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/Services/InitializationService.cs @@ -25,6 +25,11 @@ namespace UpsilonLanguageServer.Services { BoundTypeParser.LoadBoundTypes(File.ReadAllText(typesConfigFile)); } + var staticConfigFile = configPath + "/static.json"; + if (File.Exists(staticConfigFile)) + { + BoundTypeParser.LoadStaticVariables(File.ReadAllText(staticConfigFile)); + } } return new InitializeResult(new ServerCapabilities { diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/Services/TextDocumentServer.cs b/UpsilonLanguageServer/UpsilonLanguageServer/Services/TextDocumentServer.cs index 0e63a31..060ecca 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/Services/TextDocumentServer.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/Services/TextDocumentServer.cs @@ -8,6 +8,7 @@ using JsonRpc.Standard.Contracts; using LanguageServer.VsCode; using LanguageServer.VsCode.Contracts; using Upsilon.Binder; +using Upsilon.Binder.VariableSymbols; using Upsilon.BoundTypes; using Upsilon.Utilities; using Type = Upsilon.BaseTypes.Type; @@ -148,7 +149,7 @@ namespace UpsilonLanguageServer.Services if (node is BoundFullStopIndexExpression indexExpression) { var expression = indexExpression.Expression; - var variableSymbol = ResolveVariable(expression); + var variableSymbol = Binder.ResolveVariable(expression, null); var result = await GetListFromVariableSymbol(variableSymbol); if (result != null) { @@ -166,7 +167,7 @@ namespace UpsilonLanguageServer.Services variables.Select(x => { var (key, value) = x; - return new CompletionItem(key, + return new CompletionItem(value.Name, CompletionItemKind.Variable, value.Type.ToString(), x.Value.CommentValue == null ? "" @@ -179,7 +180,7 @@ namespace UpsilonLanguageServer.Services private static async Task GetListFromVariableSymbol(VariableSymbol variableSymbol) { - if (variableSymbol is FunctionParameterSymbol parameterSymbol && + if (variableSymbol is UserDataVariableSymbol parameterSymbol && parameterSymbol.BoundTypeDefinition is UserDataBoundTypeDefinition udBoundDef) { return new CompletionList( @@ -206,34 +207,5 @@ namespace UpsilonLanguageServer.Services return null; } - - private VariableSymbol ResolveVariable(BoundExpression expression) - { - if (expression.Kind == BoundKind.VariableExpression) - { - var variableExpression = (BoundVariableExpression) expression; - return variableExpression.Variable.VariableSymbol; - } - if (expression.Kind == BoundKind.BoundFullstopIndexExpression) - { - var fullStopIndexExpression = (BoundFullStopIndexExpression) expression; - var indexerExpression = fullStopIndexExpression.Expression; - var indexerVariable = ResolveVariable(indexerExpression); - if (indexerVariable.Type == Type.Table) - { - return ((TableVariableSymbol)indexerVariable).Variables[fullStopIndexExpression.Index]; - } - if (indexerVariable.Type == Type.UserData) - { - var bDefProperty = ((UserDataBoundTypeDefinition) ((FunctionParameterSymbol) indexerVariable) - .BoundTypeDefinition).Properties[fullStopIndexExpression.Index]; - var boundDef = BoundTypeHandler.GetTypeDefinition(bDefProperty.ActualType); - return new FunctionParameterSymbol(fullStopIndexExpression.Index, boundDef); - } - } - return null; - } - - } } diff --git a/UpsilonLanguageServer/UpsilonLanguageServer/Services/WorkspaceService.cs b/UpsilonLanguageServer/UpsilonLanguageServer/Services/WorkspaceService.cs index 3ceed29..f65e235 100644 --- a/UpsilonLanguageServer/UpsilonLanguageServer/Services/WorkspaceService.cs +++ b/UpsilonLanguageServer/UpsilonLanguageServer/Services/WorkspaceService.cs @@ -51,7 +51,7 @@ namespace UpsilonLanguageServer.Services StringComparison.InvariantCultureIgnoreCase)) { var name = Path.GetFileName(localPath); - if (string.Equals(Path.GetFileName(localPath), "types.json", + if (string.Equals(name, "types.json", StringComparison.InvariantCultureIgnoreCase)) { if (change.Type == FileChangeType.Created || change.Type == FileChangeType.Changed) @@ -64,6 +64,19 @@ namespace UpsilonLanguageServer.Services } } } + else if (string.Equals(name, "static.json", + StringComparison.InvariantCultureIgnoreCase)) + { + if (change.Type == FileChangeType.Created || change.Type == FileChangeType.Changed) + { + BoundTypeParser.LoadStaticVariables(File.ReadAllText(localPath)); + foreach (var doc in Session.Documents.Values) + { + var diag = await DiagnosticProvider.LintDocument(doc.Document, doc, Session.Settings.MaxNumberOfProblems); + await Client.Document.PublishDiagnostics(doc.Document.Uri, diag); + } + } + } } } }