Skip to content

Commit

Permalink
add some snippest
Browse files Browse the repository at this point in the history
  • Loading branch information
CppCXY committed Apr 14, 2024
1 parent 547de93 commit 034d7e9
Show file tree
Hide file tree
Showing 21 changed files with 455 additions and 71 deletions.
1 change: 0 additions & 1 deletion .idea/.idea.EmmyLuaAnalyzer/.idea/.name

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ private void AnalyzeClosureExpr(LuaClosureExprSyntax closureExprSyntax)

var overloads = docList?
.OfType<LuaDocTagOverloadSyntax>()
.Where(it=>it.TypeFunc is not null)
.Select(it => Context.Infer(it.TypeFunc))
.Cast<LuaMethodType>()
.Select(it => it.MainSignature).ToList();
Expand Down
2 changes: 2 additions & 0 deletions EmmyLua/CodeAnalysis/Compilation/Declaration/Declarations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public class ParameterLuaDeclaration(

public LuaSyntaxNodePtr<LuaDocTypedParamSyntax> TypedParamPtr => Ptr.Cast<LuaDocTypedParamSyntax>();

public bool IsVararg => Name == "...";

public override ParameterLuaDeclaration WithType(LuaType type) =>
new(Name, Ptr, type);
}
Expand Down
90 changes: 70 additions & 20 deletions EmmyLua/CodeAnalysis/Compilation/Infer/GenericInfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@ public static void InferInstantiateByExpr(
InferInstantiateByType(type, exprType, genericParameter, result, context);
}

public static void InferInstantiateByVarargTypeAndExprs(
LuaGenericVarargType genericVarargType,
IEnumerable<LuaExprSyntax> expr,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
SearchContext context
)
{
InferInstantiateByVarargTypeAndTypes(genericVarargType, expr.Select(context.Infer), genericParameter, result,
context);
}

public static void InferInstantiateByVarargTypeAndTypes(
LuaGenericVarargType genericVarargType,
IEnumerable<LuaType> types,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
SearchContext context
)
{
result.TryAdd(genericVarargType.Name, new LuaMultiReturnType(types.ToList()));
}

public static void InferInstantiateByType(
LuaType type,
LuaType exprType,
Expand Down Expand Up @@ -63,7 +86,8 @@ private static bool IsGenericParameter(string name, HashSet<string> genericParam
return genericParameter.Contains(name);
}

private static void GenericInstantiateByType(LuaGenericType genericType,
private static void GenericInstantiateByType(
LuaGenericType genericType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand Down Expand Up @@ -97,7 +121,8 @@ private static void GenericInstantiateByType(LuaGenericType genericType,
}
}

private static void GenericTableExprInstantiate(LuaGenericType genericType,
private static void GenericTableExprInstantiate(
LuaGenericType genericType,
LuaTableExprSyntax tableExpr,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand Down Expand Up @@ -131,7 +156,8 @@ private static void GenericTableExprInstantiate(LuaGenericType genericType,
InferInstantiateByType(genericArgs[1], valueType, genericParameter, result, context);
}

private static void NamedTypeInstantiateByType(LuaNamedType namedType,
private static void NamedTypeInstantiateByType(
LuaNamedType namedType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand All @@ -143,7 +169,8 @@ private static void NamedTypeInstantiateByType(LuaNamedType namedType,
}
}

private static void ArrayTypeInstantiateByType(LuaArrayType arrayType,
private static void ArrayTypeInstantiateByType(
LuaArrayType arrayType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand Down Expand Up @@ -174,7 +201,8 @@ private static void ArrayTypeInstantiateByType(LuaArrayType arrayType,
}
}

private static void MethodTypeInstantiateByType(LuaMethodType methodType,
private static void MethodTypeInstantiateByType(
LuaMethodType methodType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand Down Expand Up @@ -202,7 +230,8 @@ private static void MethodTypeInstantiateByType(LuaMethodType methodType,
}
}

private static void UnionTypeInstantiateByType(LuaUnionType unionType,
private static void UnionTypeInstantiateByType(
LuaUnionType unionType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand All @@ -224,7 +253,8 @@ private static void UnionTypeInstantiateByType(LuaUnionType unionType,
}
}

private static void TupleTypeInstantiateByType(LuaTupleType tupleType,
private static void TupleTypeInstantiateByType(
LuaTupleType tupleType,
LuaType exprType,
HashSet<string> genericParameter,
Dictionary<string, LuaType> result,
Expand All @@ -234,31 +264,51 @@ private static void TupleTypeInstantiateByType(LuaTupleType tupleType,
{
for (var i = 0; i < tupleType.TupleDeclaration.Count && i < tupleType2.TupleDeclaration.Count; i++)
{
InferInstantiateByType(tupleType.TupleDeclaration[i].DeclarationType!, tupleType2.TupleDeclaration[i].DeclarationType!, genericParameter, result, context);
var leftElementType = tupleType.TupleDeclaration[i].DeclarationType!;
if (leftElementType is LuaGenericVarargType genericVarargType)
{
var rightExprs = tupleType2.TupleDeclaration[i..]
.Where(it => it.DeclarationType is not null)
.Select(it => it.DeclarationType!);
InferInstantiateByVarargTypeAndTypes(genericVarargType, rightExprs, genericParameter, result,
context);
}
else
{
var rightElementType = tupleType2.TupleDeclaration[i].DeclarationType!;
InferInstantiateByType(leftElementType, rightElementType, genericParameter, result, context);
}
}
}
else if (exprType is LuaTableLiteralType tableLiteralType)
{
var tableExpr = tableLiteralType.TableExprPtr.ToNode(context);
if (tableExpr is not null)
{
var arrayCount = 0;
foreach (var field in tableExpr.FieldList)
var fileList = tableExpr.FieldList.ToList();
for (var i = 0; i < fileList.Count && i < tupleType.TupleDeclaration.Count; i++)
{
if (field.IsValue)
var tupleElementType = tupleType.TupleDeclaration[i].DeclarationType!;
if (tupleElementType is LuaGenericVarargType genericVarargType)
{
if (arrayCount >= tupleType.TupleDeclaration.Count)
{
break;
}

if (field.Value is not null)
var fileExprs = fileList[i..]
.Where(it => it is { IsValue: true, Value: not null })
.Select(it => it.Value!);
InferInstantiateByVarargTypeAndExprs(genericVarargType, fileExprs, genericParameter, result,
context);
break;
}
else
{
var field = fileList[i];
if (field is { IsValue: true, Value: { } valueExpr })
{
InferInstantiateByExpr(tupleType.TupleDeclaration[arrayCount].DeclarationType!, field.Value, genericParameter,
InferInstantiateByExpr(
tupleElementType,
valueExpr,
genericParameter,
result, context);
}

arrayCount++;
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions EmmyLua/CodeAnalysis/Compilation/Infer/TypeInfer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public static LuaType InferType(LuaDocTypeSyntax type, SearchContext context)
return InferTupleType(tupleType, context);
case LuaDocGenericTypeSyntax genericType:
return InferGenericType(genericType, context);
case LuaDocGenericVarargTypeSyntax genericVarargType:
return InferGenericVarargType(genericVarargType, context);
default:
throw new UnreachableException();
}
Expand Down Expand Up @@ -143,4 +145,14 @@ private static LuaType InferGenericType(LuaDocGenericTypeSyntax genericType, Sea

return Builtin.Unknown;
}

private static LuaType InferGenericVarargType(LuaDocGenericVarargTypeSyntax genericVarargType, SearchContext context)
{
if (genericVarargType is { Name: { } name })
{
return new LuaGenericVarargType(name.RepresentText);
}

return Builtin.Unknown;
}
}
17 changes: 13 additions & 4 deletions EmmyLua/CodeAnalysis/Compilation/Type/LuaMethodType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,16 +280,25 @@ private LuaSignature InnerInstantiate(
var genericParameterMap = new Dictionary<string, LuaType>();
var paramStart = skipParam;
var argStart = matchedParam;

for (var i = 0;
i + paramStart < Parameters.Count
&& i + argStart < args.Count
&& i +argStart < args.Count
&& genericParameterMap.Count < genericParameters.Count;
i++)
{
var parameter = Parameters[i + paramStart];
var arg = args[i + argStart];
var parameterType = parameter.DeclarationType ?? Builtin.Any;
GenericInfer.InferInstantiateByExpr(parameterType, arg, genericParameters, genericParameterMap, context);
if (parameter is { IsVararg: true, DeclarationType: LuaGenericVarargType varargType })
{
var varargs = args[(i + argStart)..];
GenericInfer.InferInstantiateByVarargTypeAndExprs(varargType, varargs, genericParameters, genericParameterMap, context);
}
else
{
var arg = args[i + argStart];
var parameterType = parameter.DeclarationType ?? Builtin.Any;
GenericInfer.InferInstantiateByExpr(parameterType, arg, genericParameters, genericParameterMap, context);
}
}

var newReturnType = ReturnType.Instantiate(genericParameterMap);
Expand Down
24 changes: 24 additions & 0 deletions EmmyLua/CodeAnalysis/Compilation/Type/LuaTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,3 +404,27 @@ public override int GetHashCode()
return base.GetHashCode();
}
}

public class LuaGenericVarargType(string baseName) : LuaNamedType(baseName), IEquatable<LuaGenericVarargType>
{
public override bool Equals(object? obj)
{
return Equals(obj as LuaGenericVarargType);
}

public override bool Equals(LuaType? other)
{
return Equals(other as LuaGenericVarargType);
}

public bool Equals(LuaGenericVarargType? other)
{
if (ReferenceEquals(this, other)) return true;
return base.Equals(other);
}

public override int GetHashCode()
{
return base.GetHashCode();
}
}
4 changes: 4 additions & 0 deletions EmmyLua/CodeAnalysis/Compile/Grammar/Doc/Tags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ private static CompleteMarker GenericParam(LuaDocParser p)
p.Bump();
TypesParser.Type(p);
}
else if (p.Current is LuaTokenKind.TkDots)
{
p.Bump();
}

return m.Complete(p, LuaSyntaxKind.GenericParameter);
}
Expand Down
19 changes: 18 additions & 1 deletion EmmyLua/CodeAnalysis/Compile/Grammar/Doc/Types.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ private static CompleteMarker PrimaryType(LuaDocParser p)
LuaTokenKind.TkLeftBracket => TupleType(p),
LuaTokenKind.TkString or LuaTokenKind.TkInt => LiteralType(p),
LuaTokenKind.TkName => OtherType(p),
LuaTokenKind.TkDots => VarargType(p),
_ => CompleteMarker.Empty
};
}
Expand Down Expand Up @@ -200,6 +201,21 @@ private static CompleteMarker OtherType(LuaDocParser p)
return m.Complete(p, LuaSyntaxKind.TypeName);
}

private static CompleteMarker VarargType(LuaDocParser p)
{
var m = p.Marker();
try
{
p.Bump();
p.Expect(LuaTokenKind.TkName);
return m.Complete(p, LuaSyntaxKind.TypeGenericVararg);
}
catch (UnexpectedTokenException e)
{
return m.Fail(p, LuaSyntaxKind.TypeGenericVararg, e.Message);
}
}

public static CompleteMarker FunType(LuaDocParser p)
{
var m = p.Marker();
Expand Down Expand Up @@ -243,14 +259,15 @@ public static CompleteMarker FunType(LuaDocParser p)
}
}

public static CompleteMarker TypedParameter(LuaDocParser p)
private static CompleteMarker TypedParameter(LuaDocParser p)
{
var m = p.Marker();
try
{
if (p.Current is LuaTokenKind.TkName)
{
p.Bump();
p.Accept(LuaTokenKind.TkNullable);
}
else if (p.Current is LuaTokenKind.TkDots)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ public abstract class DiagnosticHandlerBase(LuaCompilation compilation)
{
public LuaCompilation Compilation { get; } = compilation;

public virtual List<DiagnosticCode> GetDiagnosticCodes() => new List<DiagnosticCode>();

public virtual void Check(DiagnosticContext context)
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ namespace EmmyLua.CodeAnalysis.Diagnostics.Handlers;

public class UndefinedGlobalHandler(LuaCompilation compilation) : DiagnosticHandlerBase(compilation)
{
public override List<DiagnosticCode> GetDiagnosticCodes() =>
[DiagnosticCode.UndefinedGlobal, DiagnosticCode.NeedImport];

public override void Check(DiagnosticContext context)
{
var semanticModel = Compilation.GetSemanticModel(context.Document.Id);
Expand Down
2 changes: 0 additions & 2 deletions EmmyLua/CodeAnalysis/Diagnostics/Handlers/UnusedHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public class UnusedHandler(LuaCompilation compilation) : DiagnosticHandlerBase(c
{
private DiagnosticCode Code { get; } = DiagnosticCode.Unused;

public override List<DiagnosticCode> GetDiagnosticCodes() => [Code];

public override void Check(DiagnosticContext context)
{
var semanticModel = Compilation.GetSemanticModel(context.Document.Id);
Expand Down
30 changes: 7 additions & 23 deletions EmmyLua/CodeAnalysis/Diagnostics/LuaDiagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,20 @@

namespace EmmyLua.CodeAnalysis.Diagnostics;

public class LuaDiagnostics
public class LuaDiagnostics(LuaCompilation compilation)
{
private List<DiagnosticHandlerBase> Handlers { get; }

private Dictionary<DiagnosticCode, DiagnosticHandlerBase> HandlerMap { get; }
private List<DiagnosticHandlerBase> Handlers { get; } = new()
{
new UnusedHandler(compilation),
new UndefinedGlobalHandler(compilation)
};

public LuaCompilation Compilation { get; }
public LuaCompilation Compilation { get; } = compilation;

private HashSet<LuaDocumentId> IsMetaDocument { get; } = new();

public DiagnosticConfig Config { get; set; } = new();

public LuaDiagnostics(LuaCompilation compilation)
{
Compilation = compilation;
Handlers = new List<DiagnosticHandlerBase>
{
new UnusedHandler(compilation),
new UndefinedGlobalHandler(compilation)
};
HandlerMap = new Dictionary<DiagnosticCode, DiagnosticHandlerBase>();
foreach (var handler in Handlers)
{
foreach (var code in handler.GetDiagnosticCodes())
{
HandlerMap.TryAdd(code, handler);
}
}
}

public void Check(LuaDocument document)
{
if (IsMetaDocument.Contains(document.Id))
Expand Down
Loading

0 comments on commit 034d7e9

Please sign in to comment.