Exemplo n.º 1
0
	private static SymbolDeclaration GetNodeDeclaration(ParseTree.Node node, string fileName = null)
	{
		if (node.declaration == null)
		{
			var declarationSemantics = node.semantics & SemanticFlags.SymbolDeclarationsMask;

			var enclosingScopeNode = EnclosingSemanticNode(node.parent, SemanticFlags.ScopesMask);
			var enclosingScope = GetNodeScope(enclosingScopeNode, fileName);
			
			if (enclosingScope == null)
				return null;

			ParseTree.BaseNode modifiersNode = null;
			ParseTree.BaseNode partialNode = null;
			ParseTree.Node typeParamsNode = null;

			switch (declarationSemantics)
			{
				case SemanticFlags.NamespaceDeclaration:
					node.declaration = new NamespaceDeclaration { parseTreeNode = node, kind = SymbolKind.Namespace };
					break;

				case SemanticFlags.UsingNamespace:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.ImportedNamespace };
					break;
					//var namespaceToImport = node.Print();
					//(enclosingScope as NamespaceScope).declaration.importedNamespaces[namespaceToImport] = new SymbolReference(node.ChildAt(0));
					//return null;

				case SemanticFlags.UsingAlias:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.TypeAlias };
					break;
					//var name = node.ChildAt(0).Print();
					//((NamespaceScope) enclosingScope).declaration.typeAliases[name] = new SymbolReference(node.ChildAt(2));
					//return null;

				case SemanticFlags.ExternAlias:
					break;
				case SemanticFlags.ClassDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					partialNode = node.parent.FindChildByName("PARTIAL");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Class };
					typeParamsNode = node.FindChildByName("typeParameterList") as ParseTree.Node;
				//	Debug.Log(node.declaration + " mods: " + node.declaration.modifiers);
					break;
				case SemanticFlags.TypeParameterDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.TypeParameter };
					break;
				case SemanticFlags.BaseListDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.BaseTypesList };
					break;
				case SemanticFlags.ConstantDeclarator:
					modifiersNode = node.parent.parent.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration {
						parseTreeNode = node,
						kind =
							node.parent.parent.RuleName == "constantDeclaration" ?
							SymbolKind.ConstantField :
							SymbolKind.LocalConstant
					};
					break;
				case SemanticFlags.ConstructorDeclarator:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Constructor };
					break;
				case SemanticFlags.DestructorDeclarator:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Destructor };
					break;
				case SemanticFlags.OperatorDeclarator:
				case SemanticFlags.ConversionOperatorDeclarator:
					modifiersNode = node.parent.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Operator };
					break;
				case SemanticFlags.MethodDeclarator:
					modifiersNode = node.parent.FindChildByName("modifiers");
					typeParamsNode = node.NodeAt(0);
					if (typeParamsNode != null)
						typeParamsNode = typeParamsNode.NodeAt(0);
					if (typeParamsNode != null)
						typeParamsNode = typeParamsNode.NodeAt(0);
					if (typeParamsNode != null)
						typeParamsNode = typeParamsNode.NodeAt(-1);
					if (typeParamsNode != null)
						typeParamsNode = typeParamsNode.FindChildByName("typeParameterList") as ParseTree.Node;
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Method };
					break;
				case SemanticFlags.LocalVariableDeclarator:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Variable };
					break;
				case SemanticFlags.ForEachVariableDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.ForEachVariable };
					break;
				case SemanticFlags.FromClauseVariableDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.FromClauseVariable };
					break;
				case SemanticFlags.LabeledStatement:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Label };
					break;
				case SemanticFlags.CatchExceptionParameterDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.CatchParameter };
					break;
				case SemanticFlags.FixedParameterDeclaration:
					modifiersNode = node.FindChildByName("parameterModifier");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Parameter };
				//	Debug.Log("Adding parameter declaration to " + enclosingScope);
					break;
				case SemanticFlags.ParameterArrayDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Parameter, modifiers = Modifiers.Params };
					break;
				case SemanticFlags.ImplicitParameterDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Parameter };
					break;
				case SemanticFlags.ExplicitParameterDeclaration:
					modifiersNode = node.FindChildByName("anonymousFunctionParameterModifier");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Parameter };
					break;
				case SemanticFlags.PropertyDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Property };
					break;
				case SemanticFlags.IndexerDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Indexer };
					break;
				case SemanticFlags.GetAccessorDeclaration:
				case SemanticFlags.SetAccessorDeclaration:
					modifiersNode = node.parent.FindChildByName("accessorModifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Accessor };
					break;
				case SemanticFlags.InterfaceGetAccessorDeclaration:
				case SemanticFlags.InterfaceSetAccessorDeclaration:
				case SemanticFlags.AddAccessorDeclaration:
				case SemanticFlags.RemoveAccessorDeclaration:
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Accessor };
					break;
				case SemanticFlags.EventDeclarator:
					modifiersNode = node.parent.parent.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Event };
					break;
				case SemanticFlags.EventWithAccessorsDeclaration:
					modifiersNode = node.parent.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Event };
					break;
				case SemanticFlags.VariableDeclarator:
					modifiersNode = node.parent.parent.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Field };
					break;
				case SemanticFlags.StructDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					partialNode = node.parent.FindChildByName("PARTIAL");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Struct };
					break;
				case SemanticFlags.InterfaceDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					partialNode = node.parent.FindChildByName("PARTIAL");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Interface };
					break;
				case SemanticFlags.InterfaceIndexerDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Property };
					break;
				case SemanticFlags.InterfacePropertyDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Property };
					break;
				case SemanticFlags.InterfaceMethodDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Method };
					break;
				case SemanticFlags.InterfaceEventDeclaration:
					break;
				case SemanticFlags.EnumDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Enum };
					break;
				case SemanticFlags.EnumMemberDeclaration:
					node.declaration = new SymbolDeclaration {
						parseTreeNode = node, kind = SymbolKind.EnumMember,
						modifiers = Modifiers.ReadOnly | Modifiers.Public | Modifiers.Static
					};
					break;
				case SemanticFlags.DelegateDeclaration:
					modifiersNode = node.parent.FindChildByName("modifiers");
					typeParamsNode = node.FindChildByName("typeParameterList") as ParseTree.Node;
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.Delegate };
					break;
				case SemanticFlags.AnonymousObjectCreation:
					break;
				case SemanticFlags.MemberDeclarator:
					break;
				case SemanticFlags.LambdaExpressionDeclaration:
				case SemanticFlags.AnonymousMethodDeclaration:
					enclosingScopeNode = EnclosingScopeNode(node.parent,
						SemanticFlags.CodeBlockScope,
						SemanticFlags.MethodBodyScope,
						SemanticFlags.TypeDeclarationScope);
					enclosingScope = GetNodeScope(enclosingScopeNode, fileName);
					node.declaration = new SymbolDeclaration { parseTreeNode = node, kind = SymbolKind.LambdaExpression };
					break;
				case SemanticFlags.None:
					Debug.LogWarning("declarationSemantics is None on " + node);
					break;
				default:
					throw new ArgumentOutOfRangeException("Unhandled case " + declarationSemantics + " for node " + node);
			}

			if (node.declaration != null)
			{
				if (modifiersNode != null)
					node.declaration.modifiers = ParseModifiers(modifiersNode);
				if (partialNode != null)
					node.declaration.modifiers |= Modifiers.Partial;
				if (typeParamsNode != null)
					node.declaration.numTypeParameters = CountTypeParameters(typeParamsNode);
				if (enclosingScope == null)
					Debug.LogWarning("Symbol declaration " + declarationSemantics + " outside of declaration space!\nenclosingScopeNode: " + (enclosingScopeNode != null ? enclosingScopeNode.RuleName : "null") + "\nnode: " + node);
				else
				{
					var saved = SymbolReference.dontResolveNow;
					SymbolReference.dontResolveNow = true;
					try
					{
						//var symbol =
						enclosingScope.AddDeclaration(node.declaration);
						//if (symbol != null)
						//	Debug.Log("Added declaration " + symbol.ReflectionName);
						//else
						//	Debug.Log("Adding declaration for " + node.declaration.Name + " failed!");
					}
					catch (Exception e)
					{
						Debug.LogException(e);
					}
					finally
					{
						SymbolReference.dontResolveNow = saved;
					}
					++ParseTree.resolverVersion;
					if (ParseTree.resolverVersion == 0)
						++ParseTree.resolverVersion;
				}
			}
		}
		return node.declaration;
	}