private static void DefineTypes(FileDef fileDef, String fileName) { ClassDef classDef = new ClassDef(fileDef, $"Class{fileName}"); ClassPropertyDef classPropertyDef = new ClassPropertyDef(classDef, "Test", TypeInt64.Instance, new LiteralInt64(42)); ConstantDef classConstantDef = new ConstantDef(classDef, "ID", TypeText.Instance, new LiteralText("<N/A>")); InterfaceDef interfaceDef = new InterfaceDef(fileDef, $"Interface{fileName}"); InterfacePropertyDef interfacePropertyDef = new InterfacePropertyDef(interfaceDef, "Test", TypeText.Instance, false, true, true); EnumerationDef enumerationDef = new EnumerationDef(fileDef, $"Enumeration{fileName}", IntegralType.Int32); EnumerationMemberDef enumerationMemberDef1 = new EnumerationMemberDef(enumerationDef, "A", new LiteralInt32(1)); EnumerationMemberDef enumerationMemberDef2 = new EnumerationMemberDef(enumerationDef, "A", new LiteralInt32(2)); DecoratorDef decoratorDef = new DecoratorDef(fileDef, $"Decorator{fileName}"); DecoratorPropertyDef decoratorPropertyDef = new DecoratorPropertyDef(decoratorDef, "Value", TypeInt64.Instance, new LiteralInt64(42)); }
private void ParseInterface(string namespace_, InterfaceDeclarationSyntax interfaceSyntax, SemanticModel semanticModel) { var interfaceDef = new InterfaceDef(); interfaceDef.Namespace = namespace_; interfaceDef.Name = interfaceSyntax.Identifier.ValueText; var fullName = interfaceDef.Namespace + "." + interfaceDef.Name; if (TypesNotParsed.Contains(fullName)) { return; } // Summary var declaredSymbol = semanticModel.GetDeclaredSymbol(interfaceSyntax); var xml = declaredSymbol?.GetDocumentationCommentXml(); interfaceDef.Summary = SummaryComment.Parse(xml); ParseTypeDeclaration(interfaceDef, interfaceSyntax, semanticModel); definitions.Interfaces.Add(interfaceDef); }
/// <summary> /// 式中のメンバアクセス、定数等を解析する。 /// </summary> /// <param name="syntax"></param> /// <param name="semanticModel"></param> /// <returns></returns> Expression ParseExpression(ExpressionSyntax syntax, SemanticModel semanticModel) { if (syntax == null) { return(null); } var mae = syntax as MemberAccessExpressionSyntax; var gns = syntax as GenericNameSyntax; var le = syntax as LiteralExpressionSyntax; var ie = syntax as InvocationExpressionSyntax; var oce = syntax as ObjectCreationExpressionSyntax; var ce = syntax as CastExpressionSyntax; var thise = syntax as ThisExpressionSyntax; var ae = syntax as AssignmentExpressionSyntax; var pe = syntax as ParenthesizedExpressionSyntax; var ine = syntax as IdentifierNameSyntax; var eae = syntax as ElementAccessExpressionSyntax; var be = syntax as BinaryExpressionSyntax; var preue = syntax as PrefixUnaryExpressionSyntax; var poue = syntax as PostfixUnaryExpressionSyntax; var basee = syntax as BaseExpressionSyntax; var ace = syntax as ArrayCreationExpressionSyntax; var sace = syntax as StackAllocArrayCreationExpressionSyntax; var iee = syntax as InitializerExpressionSyntax; /* * var coe = syntax as ConditionalExpressionSyntax; * var sle = syntax as SimpleLambdaExpressionSyntax; * var ple = syntax as ParenthesizedLambdaExpressionSyntax; * var oase = syntax as OmittedArraySizeExpressionSyntax; * var iace = syntax as ImplicitArrayCreationExpressionSyntax; * * var qua = syntax as QualifiedNameSyntax; * var predf = syntax as PredefinedTypeSyntax; */ // 自己の型を解析 TypeInfo?selfTypeInfo = null; selfTypeInfo = semanticModel.GetTypeInfo(syntax); var selfType = ParseType(syntax, selfTypeInfo, semanticModel); if (mae != null) { MemberAccessExpression exp = new MemberAccessExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Name = mae.Name.ToString(); if (mae.Name is GenericNameSyntax) { var gns_ = mae.Name as GenericNameSyntax; exp.Types = gns_.TypeArgumentList.Arguments.Select(_ => ParseType(_, semanticModel)).ToArray(); } TypeInfo?parentType = null; if (mae.Expression != null) { parentType = semanticModel.GetTypeInfo(mae.Expression); } // 種類を取得 var symbol = semanticModel.GetSymbolInfo(mae); var methodSymbol = symbol.Symbol as IMethodSymbol; var propertySymbol = symbol.Symbol as IPropertySymbol; // 親の種類を探索 List <ClassDef> classDefPs = new List <ClassDef>(); EnumDef enumDefP = null; InterfaceDef interfaceDefP = null; StructDef structDefP = null; // プロパティである if (propertySymbol != null) { exp.IsProperty = true; } if (parentType.HasValue && parentType.Value.Type != null) { if (parentType.Value.Type.TypeKind == TypeKind.Interface) { var memName = mae.Name.ToString(); var sym = semanticModel.GetSymbolInfo(mae); var name_ = parentType.Value.Type.Name; var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace); interfaceDefP = definitions.Interfaces.Where(_ => _.Namespace == namespace_ && _.Name == name_).FirstOrDefault(); } else if (parentType.Value.Type.TypeKind == TypeKind.Class) { var memName = mae.Name.ToString(); var sym = semanticModel.GetSymbolInfo(mae); var name_ = parentType.Value.Type.Name; var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace); classDefPs = definitions.FindTypeWithBases(namespace_, name_).OfType <ClassDef>().ToList(); } else if (parentType.Value.Type.TypeKind == TypeKind.Enum) { var enumName = selfTypeInfo.Value.Type.Name; var namespace_ = Utils.ToStr(selfTypeInfo.Value.Type.ContainingNamespace); enumDefP = definitions.Enums.Where(_ => _.Namespace == namespace_ && _.Name == enumName).FirstOrDefault(); } else if (parentType.Value.Type.TypeKind == TypeKind.Struct) { var memName = mae.Name.ToString(); var sym = semanticModel.GetSymbolInfo(mae); var name_ = parentType.Value.Type.Name; var namespace_ = Utils.ToStr(parentType.Value.Type.ContainingNamespace); structDefP = definitions.Structs.Where(_ => _.Namespace == namespace_ && _.Name == name_).FirstOrDefault(); } } // 親から子を探索 if (interfaceDefP != null) { if (methodSymbol != null) { var method = interfaceDefP.Methods.Where(_ => { if (_.Name != methodSymbol.Name) { return(false); } if (_.Parameters.Count() != methodSymbol.Parameters.Count()) { return(false); } for (int i = 0; i < _.Parameters.Count(); i++) { if (_.Parameters[i].Name != methodSymbol.Parameters[i].Name) { return(false); } // TODO 正しい変換 //if(_.Parameters[i].Type != methodSymbol.Parameters[i].Type) } return(true); }).FirstOrDefault(); if (method != null) { exp.Name = null; exp.Method = method; } } else if (propertySymbol != null) { var prop = interfaceDefP.Properties.Where(_ => { if (_.Name != propertySymbol.Name) { return(false); } return(true); }).FirstOrDefault(); if (prop != null) { exp.Name = null; exp.Property = prop; } } } else if (classDefPs.Count > 0) { if (methodSymbol != null) { foreach (var classDefP in classDefPs) { var method = classDefP.Methods.Where(_ => { if (_.Name != methodSymbol.Name) { return(false); } if (_.Parameters.Count() != methodSymbol.Parameters.Count()) { return(false); } for (int i = 0; i < _.Parameters.Count(); i++) { if (_.Parameters[i].Name != methodSymbol.Parameters[i].Name) { return(false); } // TODO 正しい変換 //if(_.Parameters[i].Type != methodSymbol.Parameters[i].Type) } return(true); }).FirstOrDefault(); if (method != null) { exp.Name = null; exp.Class = classDefP; exp.Method = method; // staticの場合走査停止 if (method.IsStatic) { return(exp); } break; } } } else if (propertySymbol != null) { foreach (var classDefP in classDefPs) { var prop = classDefP.Properties.Where(_ => { if (_.Name != propertySymbol.Name) { return(false); } return(true); }).FirstOrDefault(); if (prop != null) { exp.Name = null; exp.Class = classDefP; exp.Property = prop; break; } } } } else if (structDefP != null) { if (propertySymbol != null) { var prop = structDefP.Properties.Where(_ => { if (_.Name != propertySymbol.Name) { return(false); } return(true); }).FirstOrDefault(); if (prop != null) { exp.Name = null; exp.Struct = structDefP; exp.Property = prop; } } } else if (enumDefP != null) { var name = mae.Name.ToString(); exp.EnumMember = enumDefP.Members.Where(_ => _.Name == name).FirstOrDefault(); if (exp.EnumMember != null) { exp.Enum = enumDefP; exp.Name = null; } } else { // 代替処理 if (propertySymbol != null) { exp.Property = new PropertyDef(); exp.Property.Name = exp.Name; } } if (exp.EnumMember != null) { // enumのメンバーだった場合、親は必ずenumなのでこれ以上走査しない } else if (mae.Expression != null) { exp.Expression = ParseExpression(mae.Expression, semanticModel); } return(exp); } else if (gns != null) { var symbol = semanticModel.GetSymbolInfo(gns); var methodSymbol = symbol.Symbol as IMethodSymbol; var fieldSymbol = symbol.Symbol as IFieldSymbol; var propertySymbol = symbol.Symbol as IPropertySymbol; var exp = new GenericNameExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Name = gns.Identifier.ValueText; if (methodSymbol != null) { exp.IsMethod = true; } if (propertySymbol != null) { exp.IsProperty = true; } exp.Types = gns.TypeArgumentList.Arguments.Select(_ => ParseType(_, semanticModel)).ToArray(); return(exp); } else if (le != null) { var text = le.GetText().ToString(); var exp = new LiteralExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Text = text; return(exp); } else if (ie != null) { var exp = new InvocationExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Method = ParseExpression(ie.Expression, semanticModel); exp.Args = ie.ArgumentList.Arguments.Select(_ => ParseExpression(_.Expression, semanticModel)).ToArray(); return(exp); } else if (oce != null) { var exp = new ObjectCreationExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Type = ParseType(oce.Type, semanticModel); if (oce.ArgumentList != null) { exp.Args = oce.ArgumentList.Arguments.Select(_ => ParseExpression(_.Expression, semanticModel)).ToArray(); } else { exp.Args = new Expression[0]; } return(exp); } else if (ce != null) { var exp = new CastExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Type = ParseType(ce.Type, semanticModel); exp.Expression = ParseExpression(ce.Expression, semanticModel); return(exp); } else if (thise != null) { var exp = new ThisExpression(); exp.SelfType = selfType; exp.Internal = syntax; return(exp); } else if (ae != null) { var exp = new AssignmentExpression(); exp.SelfType = selfType; exp.Internal = syntax; if (ae.Kind() == SyntaxKind.AddAssignmentExpression) { exp.Type = AssignmentExpression.OperatorType.Add; } if (ae.Kind() == SyntaxKind.SubtractAssignmentExpression) { exp.Type = AssignmentExpression.OperatorType.Substract; } if (ae.Kind() == SyntaxKind.SimpleAssignmentExpression) { exp.Type = AssignmentExpression.OperatorType.Simple; } if (ae.Kind() == SyntaxKind.DivideAssignmentExpression) { exp.Type = AssignmentExpression.OperatorType.Divide; } if (ae.Kind() == SyntaxKind.ModuloAssignmentExpression) { exp.Type = AssignmentExpression.OperatorType.Modulo; } exp.Temp = ae.Kind(); exp.Target = ParseExpression(ae.Left, semanticModel); exp.Expression = ParseExpression(ae.Right, semanticModel); return(exp); } else if (pe != null) { // ()の構文 return(ParseExpression(pe.Expression, semanticModel)); } else if (ine != null) { var symbol = semanticModel.GetSymbolInfo(ine); var methodSymbol = symbol.Symbol as IMethodSymbol; var fieldSymbol = symbol.Symbol as IFieldSymbol; var propertySymbol = symbol.Symbol as IPropertySymbol; var exp = new IdentifierNameExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Name = ine.Identifier.Text; if (selfTypeInfo?.Type != null) { exp.Type = ParseType(selfTypeInfo.Value.Type); } if (methodSymbol != null) { exp.IsMethod = true; } if (propertySymbol != null) { exp.IsProperty = true; } return(exp); } else if (eae != null) { if (eae.ArgumentList.Arguments.Count() != 1) { throw new ParseException("多次元配列は使用禁止です。"); } var value_ = eae.Expression; var arg = eae.ArgumentList.Arguments[0].Expression; var exp = new ElementAccessExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Value = ParseExpression(value_, semanticModel); exp.Arg = ParseExpression(arg, semanticModel); return(exp); } else if (be != null) { var exp = new BinaryExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Left = ParseExpression(be.Left, semanticModel); exp.Right = ParseExpression(be.Right, semanticModel); if (be.Kind() == SyntaxKind.AddExpression) { exp.Operator = BinaryExpression.OperatorType.Add; } if (be.Kind() == SyntaxKind.SubtractExpression) { exp.Operator = BinaryExpression.OperatorType.Subtract; } if (be.Kind() == SyntaxKind.IsExpression) { exp.Operator = BinaryExpression.OperatorType.Is; } if (be.Kind() == SyntaxKind.AsExpression) { exp.Operator = BinaryExpression.OperatorType.As; } if (be.Kind() == SyntaxKind.EqualsExpression) { exp.Operator = BinaryExpression.OperatorType.Equals; } if (be.Kind() == SyntaxKind.NotEqualsExpression) { exp.Operator = BinaryExpression.OperatorType.NotEquals; } if (be.Kind() == SyntaxKind.LogicalAndExpression) { exp.Operator = BinaryExpression.OperatorType.LogicalAnd; } if (be.Kind() == SyntaxKind.LogicalOrExpression) { exp.Operator = BinaryExpression.OperatorType.LogicalOr; } if (be.Kind() == SyntaxKind.GreaterThanExpression) { exp.Operator = BinaryExpression.OperatorType.GreaterThan; } if (be.Kind() == SyntaxKind.GreaterThanOrEqualExpression) { exp.Operator = BinaryExpression.OperatorType.GreaterThanOrEqual; } if (be.Kind() == SyntaxKind.LessThanExpression) { exp.Operator = BinaryExpression.OperatorType.LessThan; } if (be.Kind() == SyntaxKind.LessThanOrEqualExpression) { exp.Operator = BinaryExpression.OperatorType.LessThanOrEqual; } if (be.Kind() == SyntaxKind.MultiplyExpression) { exp.Operator = BinaryExpression.OperatorType.Multiply; } if (be.Kind() == SyntaxKind.DivideExpression) { exp.Operator = BinaryExpression.OperatorType.Divide; } if (be.Kind() == SyntaxKind.ModuloExpression) { exp.Operator = BinaryExpression.OperatorType.Modulo; } if (exp.Operator == BinaryExpression.OperatorType.None) { var span_ = syntax.SyntaxTree.GetLineSpan(syntax.Span); Console.WriteLine(string.Format("{0} : {1} には未対応です。", span_, be.Kind())); } return(exp); } else if (preue != null) { var exp = new PrefixUnaryExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Expression = ParseExpression(preue.Operand, semanticModel); switch (preue.Kind()) { case SyntaxKind.LogicalNotExpression: exp.Type = PrefixUnaryExpression.OperatorType.LogicalNot; break; case SyntaxKind.UnaryPlusExpression: exp.Type = PrefixUnaryExpression.OperatorType.UnaryPlus; break; case SyntaxKind.UnaryMinusExpression: exp.Type = PrefixUnaryExpression.OperatorType.UnaryMinus; break; case SyntaxKind.PreIncrementExpression: exp.Type = PrefixUnaryExpression.OperatorType.PreIncrement; break; default: throw new Exception(); break; } return(exp); } else if (poue != null) { var exp = new PostfixUnaryExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Operand = ParseExpression(poue.Operand, semanticModel); if (poue.Kind() == SyntaxKind.PostIncrementExpression) { exp.Type = PostfixUnaryExpression.OperatorType.PostIncrement; } if (poue.Kind() == SyntaxKind.PostDecrementExpression) { exp.Type = PostfixUnaryExpression.OperatorType.PostDecrement; } return(exp); } else if (basee != null) { var exp = new BaseExpression(); exp.SelfType = selfType; exp.Internal = syntax; return(exp); } else if (iee != null) { var exp = new InitializerExpression(); exp.SelfType = selfType; exp.Internal = syntax; var expressions = iee.Expressions.Select(_ => _).ToArray(); exp.Expressions = expressions.Select(_ => ParseExpression(_, semanticModel)).ToArray(); return(exp); } else if (ace != null || sace != null) { // stackallocも含め、配列の確保として扱う。 ArrayTypeSyntax ats = null; if (ace != null) { ats = ace.Type; } if (sace != null) { ats = sace.Type as ArrayTypeSyntax; } var exp = new ObjectArrayCreationExpression(); exp.SelfType = selfType; exp.Internal = syntax; exp.Type = ParseType(ats.ElementType, semanticModel); exp.Args = ats.RankSpecifiers.Select(_ => ParseExpression(_.Sizes.FirstOrDefault(), semanticModel)).ToArray(); return(exp); } else if (syntax is PredefinedTypeSyntax) { var s = syntax as PredefinedTypeSyntax; var exp = new TypeExpression(); exp.SelfType = selfType; exp.Internal = syntax; return(exp); } else if (syntax is QualifiedNameSyntax) { var s = syntax as QualifiedNameSyntax; var exp = new TypeExpression(); exp.SelfType = selfType; exp.Internal = syntax; return(exp); } var span = syntax.SyntaxTree.GetLineSpan(syntax.Span); Console.WriteLine(string.Format("{0} : {1} には未対応です。", span, syntax.GetType())); return(null); }
public void Add(object item) { if (item is P_Root.AnyTypeDecl) { AnyTypeDecl.Add(item as P_Root.AnyTypeDecl); } else if (item is P_Root.MachineSends) { MachineSends.Add(item as P_Root.MachineSends); } else if (item is P_Root.MachineReceives) { MachineReceives.Add(item as P_Root.MachineReceives); } else if (item is P_Root.EventSetContains) { EventSetContains.Add(item as P_Root.EventSetContains); } else if (item is P_Root.EventSetDecl) { EventSetDecl.Add(item as P_Root.EventSetDecl); } else if (item is P_Root.InterfaceDef) { InterfaceDef.Add(item as P_Root.InterfaceDef); } else if (item is P_Root.ObservesDecl) { Observes.Add(item as P_Root.ObservesDecl); } else if (item is P_Root.Annotation) { Annotations.Add(item as P_Root.Annotation); } else if (item is P_Root.DoDecl) { Dos.Add(item as P_Root.DoDecl); } else if (item is P_Root.AnonFunDecl) { AnonFunctions.Add(item as P_Root.AnonFunDecl); } else if (item is P_Root.FunDecl) { Functions.Add(item as P_Root.FunDecl); } else if (item is P_Root.TransDecl) { Transitions.Add(item as P_Root.TransDecl); } else if (item is P_Root.VarDecl) { Variables.Add(item as P_Root.VarDecl); } else if (item is P_Root.StateDecl) { States.Add(item as P_Root.StateDecl); } else if (item is P_Root.MachineDecl) { Machines.Add(item as P_Root.MachineDecl); } else if (item is P_Root.MachineCard) { MachineCards.Add(item as P_Root.MachineCard); } else if (item is P_Root.MachineKind) { MachineKinds.Add(item as P_Root.MachineKind); } else if (item is P_Root.MachineStart) { MachineStarts.Add(item as P_Root.MachineStart); } else if (item is P_Root.EventDecl) { Events.Add(item as P_Root.EventDecl); } else if (item is P_Root.EnumTypeDef) { EnumTypeDefs.Add(item as P_Root.EnumTypeDef); } else if (item is P_Root.TypeDef) { TypeDefs.Add(item as P_Root.TypeDef); } else if (item is P_Root.DependsOn) { DependsOn.Add(item as P_Root.DependsOn); } else { throw new Exception("Cannot add into the Program : " + item); } }