private static void AssertMainProgram(OraclePlSqlProgram mainProgram, OracleObjectIdentifier expectedObjectIdentifier) { mainProgram.Variables.Count.ShouldBe(3); mainProgram.Variables[0].Name.ShouldBe("\"TEST_VARIABLE1\""); mainProgram.Variables[0].IsConstant.ShouldBe(false); mainProgram.Variables[0].Nullable.ShouldBe(true); mainProgram.Variables[0].DefaultExpressionNode.ShouldBe(null); mainProgram.Variables[0].DataTypeNode.ShouldNotBe(null); mainProgram.Variables[0].DataTypeNode.FirstTerminalNode.Id.ShouldBe(Terminals.Number); mainProgram.Variables[0].DataTypeNode.LastTerminalNode.Id.ShouldBe(Terminals.Number); mainProgram.Variables[1].Name.ShouldBe("\"TEST_VARIABLE2\""); mainProgram.Variables[1].IsConstant.ShouldBe(false); mainProgram.Variables[1].Nullable.ShouldBe(true); mainProgram.Variables[1].DefaultExpressionNode.ShouldBe(null); mainProgram.Variables[1].DataTypeNode.ShouldNotBe(null); mainProgram.Variables[1].DataTypeNode.FirstTerminalNode.Id.ShouldBe(Terminals.Varchar2); mainProgram.Variables[1].DataTypeNode.LastTerminalNode.Id.ShouldBe(Terminals.RightParenthesis); mainProgram.Variables[2].Name.ShouldBe("\"TEST_CONSTANT1\""); mainProgram.Variables[2].IsConstant.ShouldBe(true); mainProgram.Variables[2].Nullable.ShouldBe(false); mainProgram.Variables[2].DefaultExpressionNode.ShouldNotBe(null); mainProgram.Exceptions.Count.ShouldBe(0); mainProgram.PlSqlVariableReferences.Count.ShouldBe(1); mainProgram.PlSqlExceptionReferences.Count.ShouldBe(0); mainProgram.Types.Count.ShouldBe(2); mainProgram.Types[0].Name.ShouldBe("\"TEST_TYPE1\""); mainProgram.Types[1].Name.ShouldBe("\"TEST_TABLE_TYPE1\""); mainProgram.SubPrograms.Count.ShouldBe(2); mainProgram.SqlModels.Count.ShouldBe(2); mainProgram.ProgramReferences.Count.ShouldBe(1); var programReference = mainProgram.ProgramReferences.First(); programReference.Name.ShouldBe("put_line"); programReference.ObjectNode.Token.Value.ShouldBe("dbms_output"); programReference.ParameterListNode.ShouldNotBe(null); programReference.ParameterReferences.Count.ShouldBe(1); programReference.ParameterReferences[0].OptionalIdentifierTerminal.Token.Value.ShouldBe("item"); programReference.ParameterReferences[0].ParameterNode.LastTerminalNode.Token.Value.ShouldBe("test_constant1"); mainProgram.SubPrograms[0].ObjectIdentifier.ShouldBe(expectedObjectIdentifier); mainProgram.SubPrograms[0].Name.ShouldBe("\"TEST_INNER_PROCEDURE\""); mainProgram.SubPrograms[0].Parameters.Count.ShouldBe(1); mainProgram.SubPrograms[0].Parameters[0].Name.ShouldBe("\"P1\""); mainProgram.SubPrograms[0].Parameters[0].Direction.ShouldBe(ParameterDirection.Input); mainProgram.SubPrograms[0].ReturnParameter.ShouldBe(null); mainProgram.SubPrograms[0].Variables.Count.ShouldBe(1); mainProgram.SubPrograms[0].Variables[0].Name.ShouldBe("\"TEST_VARIABLE3\""); mainProgram.SubPrograms[0].Variables[0].IsConstant.ShouldBe(false); mainProgram.SubPrograms[0].Variables[0].Nullable.ShouldBe(false); mainProgram.SubPrograms[0].Variables[0].DefaultExpressionNode.ShouldNotBe(null); mainProgram.SubPrograms[0].Exceptions.Count.ShouldBe(0); mainProgram.SubPrograms[0].PlSqlVariableReferences.Count.ShouldBe(1); mainProgram.SubPrograms[0].PlSqlExceptionReferences.Count.ShouldBe(0); mainProgram.SubPrograms[0].Types.Count.ShouldBe(0); mainProgram.SubPrograms[0].SubPrograms.Count.ShouldBe(0); mainProgram.SubPrograms[0].SqlModels.Count.ShouldBe(0); mainProgram.SubPrograms[1].ObjectIdentifier.ShouldBe(expectedObjectIdentifier); mainProgram.SubPrograms[1].Name.ShouldBe("\"TEST_INNER_FUNCTION\""); mainProgram.SubPrograms[1].Parameters.Count.ShouldBe(1); mainProgram.SubPrograms[1].Parameters[0].Name.ShouldBe("\"P1\""); mainProgram.SubPrograms[1].Parameters[0].Direction.ShouldBe(ParameterDirection.Input); mainProgram.SubPrograms[1].ReturnParameter.ShouldNotBe(null); mainProgram.SubPrograms[1].ReturnParameter.DataTypeNode.ShouldNotBe(null); mainProgram.SubPrograms[1].ReturnParameter.DefaultExpressionNode.ShouldBe(null); mainProgram.SubPrograms[1].ReturnParameter.Nullable.ShouldBe(true); mainProgram.SubPrograms[1].ReturnParameter.Direction.ShouldBe(ParameterDirection.ReturnValue); mainProgram.SubPrograms[1].Variables.Count.ShouldBe(0); mainProgram.SubPrograms[1].Exceptions.Count.ShouldBe(1); mainProgram.SubPrograms[1].Exceptions[0].Name.ShouldBe("\"TEST_EXCEPTION1\""); mainProgram.SubPrograms[1].PlSqlExceptionReferences.Count.ShouldBe(2); mainProgram.SubPrograms[1].PlSqlExceptionReferences.ForEach(r => r.Name.ShouldBe("test_exception1")); mainProgram.SubPrograms[1].PlSqlVariableReferences.Count.ShouldBe(0); mainProgram.SubPrograms[1].Types.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms.Count.ShouldBe(1); mainProgram.SubPrograms[1].SqlModels.Count.ShouldBe(1); mainProgram.SubPrograms[1].SubPrograms[0].ObjectIdentifier.ShouldBe(expectedObjectIdentifier); mainProgram.SubPrograms[1].SubPrograms[0].Name.ShouldBe("\"TEST_NESTED_PROCEDURE\""); mainProgram.SubPrograms[1].SubPrograms[0].Parameters.Count.ShouldBe(1); mainProgram.SubPrograms[1].SubPrograms[0].Parameters[0].Name.ShouldBe("\"P1\""); mainProgram.SubPrograms[1].SubPrograms[0].Parameters[0].Direction.ShouldBe(ParameterDirection.Input); mainProgram.SubPrograms[1].SubPrograms[0].ReturnParameter.ShouldBe(null); mainProgram.SubPrograms[1].SubPrograms[0].Variables.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].Exceptions.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].PlSqlVariableReferences.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].PlSqlExceptionReferences.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].Types.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].SubPrograms.Count.ShouldBe(0); mainProgram.SubPrograms[1].SubPrograms[0].SqlModels.Count.ShouldBe(1); }
private static IEnumerable <string> GetScopeNames(OraclePlSqlProgram program) { return(String.IsNullOrEmpty(program.Name) ? program.Labels.Select(l => l.Name) : Enumerable.Repeat(program.Name, 1)); }
public OraclePlSqlReferenceElementMatchVisitor(OraclePlSqlReference plSqlReference, OraclePlSqlProgram currentProgram) { _plSqlReference = plSqlReference; _currentProgram = currentProgram; }
private static void SetDataTypeAndNullablePropertiesAndAddIfIdentifierFound(OraclePlSqlVariable variable, StatementGrammarNode variableNode, OraclePlSqlProgram program) { var identifierNode = variableNode[Terminals.PlSqlIdentifier]; if (identifierNode == null) { return; } variable.Name = identifierNode.Token.Value.ToQuotedIdentifier(); variable.Nullable = variableNode[NonTerminals.NotNull, Terminals.Not] == null; variable.DataTypeNode = variableNode[NonTerminals.PlSqlDataType]; program.Variables.Add(variable); }
private void ResolveLocalVariableTypeAndLabelDeclarations(OraclePlSqlProgram program) { StatementGrammarNode programSourceNode; switch (program.RootNode.Id) { case NonTerminals.CreateFunction: programSourceNode = program.RootNode[NonTerminals.PlSqlFunctionSource, NonTerminals.FunctionTypeDefinition, NonTerminals.ProgramImplentationDeclaration]; break; case NonTerminals.PlSqlBlock: programSourceNode = program.RootNode[NonTerminals.PlSqlBlockDeclareSection]; break; case NonTerminals.CreatePackageBody: programSourceNode = program.RootNode[NonTerminals.PackageBodyDefinition]; break; default: programSourceNode = program.RootNode[NonTerminals.ProgramImplentationDeclaration]; break; } ResolveProgramDeclarationLabels(program); var firstItemNode = programSourceNode?[NonTerminals.ProgramDeclareSection, NonTerminals.ItemList1, NonTerminals.Item1OrPragmaDefinition]; if (firstItemNode == null) { return; } var itemOrPragmaNodes = StatementGrammarNode.GetAllChainedClausesByPath(firstItemNode, n => n.ParentNode, NonTerminals.ItemList1Chained, NonTerminals.Item1OrPragmaDefinition); foreach (var itemOrPragmaSwitchNode in itemOrPragmaNodes) { var itemOrPragmaNode = itemOrPragmaSwitchNode[0]; if (String.Equals(itemOrPragmaNode.Id, NonTerminals.Item1)) { var declarationRoot = itemOrPragmaNode[0]; switch (declarationRoot?.Id) { case NonTerminals.ItemDeclaration: var specificNode = declarationRoot[0]; if (specificNode != null) { OraclePlSqlVariable variable; switch (specificNode.Id) { case NonTerminals.ConstantDeclaration: variable = new OraclePlSqlVariable { Owner = program, DefinitionNode = specificNode, IsConstant = true, DefaultExpressionNode = specificNode[NonTerminals.PlSqlExpression] }; SetDataTypeAndNullablePropertiesAndAddIfIdentifierFound(variable, specificNode, program); break; case NonTerminals.ExceptionDeclaration: var exceptionName = specificNode[Terminals.ExceptionIdentifier]?.Token.Value.ToQuotedIdentifier(); if (exceptionName != null) { var exception = new OraclePlSqlException { Owner = program, Name = exceptionName, DefinitionNode = specificNode }; program.Exceptions.Add(exception); } break; case NonTerminals.VariableDeclaration: specificNode = specificNode[NonTerminals.FieldDefinition]; if (specificNode != null) { variable = new OraclePlSqlVariable { Owner = program, DefinitionNode = specificNode, DefaultExpressionNode = specificNode[NonTerminals.VariableDeclarationDefaultValue, NonTerminals.PlSqlExpression], }; SetDataTypeAndNullablePropertiesAndAddIfIdentifierFound(variable, specificNode, program); } break; } } break; case NonTerminals.TypeDefinition: var typeIdentifierNode = declarationRoot[Terminals.TypeIdentifier]; var associativeArrayTypeDefinitionNode = declarationRoot[NonTerminals.TypeDefinitionSpecification, NonTerminals.CollectionTypeDefinition, NonTerminals.AssociativeArrayTypeDefinition]; if (typeIdentifierNode != null) { var type = new OraclePlSqlType { Owner = program, DefinitionNode = declarationRoot, Name = typeIdentifierNode.Token.Value.ToQuotedIdentifier(), IsAssociativeArray = associativeArrayTypeDefinitionNode?[Terminals.Index] != null }; program.Types.Add(type); var associativeArrayIndexTypeNode = associativeArrayTypeDefinitionNode?[NonTerminals.AssociativeArrayIndexType]; if (associativeArrayIndexTypeNode != null && OracleReferenceBuilder.TryCreatePlSqlDataTypeReference(program, associativeArrayIndexTypeNode, out OracleDataTypeReference dataTypeReference)) { type.AssociativeArrayIndexDataTypeReference = dataTypeReference; } } break; case NonTerminals.CursorDefinition: var identifierNode = declarationRoot[Terminals.CursorIdentifier]; if (identifierNode != null) { var cursor = new OraclePlSqlCursorVariable { Owner = program, DefinitionNode = declarationRoot, Name = identifierNode.Token.Value.ToQuotedIdentifier() }; SetStatementModelIfFound(cursor, declarationRoot[NonTerminals.SelectStatement]); program.Variables.Add(cursor); } break; } } else { var exceptionInit = itemOrPragmaNode[NonTerminals.PragmaType, Terminals.ExceptionInit]; if (exceptionInit != null) { var exceptionIdentifier = exceptionInit.ParentNode[Terminals.ExceptionIdentifier]; var errorCodeModifier = exceptionInit.ParentNode[Terminals.MathMinus] == null ? 1 : -1; var integerLiteral = exceptionInit.ParentNode[Terminals.IntegerLiteral]; if (exceptionIdentifier != null && integerLiteral != null && Int32.TryParse(integerLiteral.Token.Value, out int errorCode)) { var exceptionName = exceptionIdentifier.Token.Value.ToQuotedIdentifier(); foreach (var exception in program.Exceptions) { if (String.Equals(exception.Name, exceptionName)) { exception.ErrorCode = errorCodeModifier * errorCode; } } CreatePlSqlExceptionReference(program, integerLiteral.ParentNode); } } } } }
private void FindPlSqlReferences(OraclePlSqlProgram program, StatementGrammarNode node) { if (node == null) { return; } var excludedIdentifiers = new HashSet <StatementGrammarNode>(); switch (node.Id) { case NonTerminals.PlSqlRaiseStatement: var prefixedExceptionIdentifierNode = node[NonTerminals.PrefixedExceptionIdentifier]; CreatePlSqlExceptionReference(program, prefixedExceptionIdentifierNode); break; case NonTerminals.PlSqlCursorForLoopStatement: var cursorIdentifier = node[Terminals.PlSqlIdentifier]; var cursorScopeNode = node[NonTerminals.PlSqlBasicLoopStatement]; if (cursorIdentifier != null && cursorScopeNode != null) { excludedIdentifiers.Add(cursorIdentifier); var cursor = new OraclePlSqlCursorVariable { Name = cursorIdentifier.Token.Value.ToQuotedIdentifier(), IsImplicit = true, Owner = program, DefinitionNode = cursorIdentifier, ScopeNode = cursorScopeNode }; SetStatementModelIfFound(cursor, node[NonTerminals.CursorSource, NonTerminals.SelectStatement]); program.Variables.Add(cursor); var cursorReferenceIdentifier = node[NonTerminals.CursorSource, Terminals.CursorIdentifier]; if (cursorReferenceIdentifier != null) { var cursorReference = new OraclePlSqlVariableReference { RootNode = cursorReferenceIdentifier.ParentNode, IdentifierNode = cursorReferenceIdentifier, //ObjectNode = cursorIdentifierNode.ParentNode[NonTerminals.ObjectPrefix, Terminals.ObjectIdentifier], //OwnerNode = cursorIdentifierNode.ParentNode[NonTerminals.SchemaPrefix, Terminals.SchemaIdentifier], Container = program, PlSqlProgram = program }; program.PlSqlVariableReferences.Add(cursorReference); } } goto default; case NonTerminals.PlSqlForLoopStatement: var identifier = node[Terminals.PlSqlIdentifier]; var scopeNode = node[NonTerminals.PlSqlBasicLoopStatement]; if (identifier != null && scopeNode != null) { excludedIdentifiers.Add(identifier); var variable = new OraclePlSqlVariable { Name = identifier.Token.Value.ToQuotedIdentifier(), Owner = program, DefinitionNode = identifier, DataType = OracleDataType.BinaryIntegerType, ScopeNode = scopeNode }; program.Variables.Add(variable); } goto default; default: var identifiers = node.GetPathFilterDescendants(NodeFilters.BreakAtPlSqlSubProgramOrSqlCommand, Terminals.Identifier, Terminals.PlSqlIdentifier, Terminals.RowIdPseudocolumn, Terminals.Level, Terminals.RowNumberPseudocolumn, Terminals.User) .Where(i => !excludedIdentifiers.Contains(i)); ResolveColumnFunctionOrDataTypeReferencesFromIdentifiers(null, program, identifiers, StatementPlacement.None, null, null, GetFunctionCallNodes); var grammarSpecificFunctions = GetGrammarSpecificFunctionNodes(node); CreateGrammarSpecificFunctionReferences(grammarSpecificFunctions, program, null, StatementPlacement.None, null); break; } }