@Override public IBoundNode bindTarget(ISyntaxNode node, IBindingContext bindingContext, IBoundNode target) throws Exception { int childrenCount = node.getNumberOfChildren(); if (childrenCount < 1) { BindHelper.processError("New node should have at least one subnode", node, bindingContext); return new ErrorBoundNode(node); } ISyntaxNode lastNode = node.getChild(childrenCount - 1); String methodName = ((IdentifierNode) lastNode).getIdentifier(); IBoundNode[] children = bindChildren(node, bindingContext, 0, childrenCount - 1); IOpenClass[] types = getTypes(children); IMethodCaller methodCaller = MethodSearch.getMethodCaller(methodName, types, bindingContext, target.getType()); if (methodCaller == null) { StringBuilder buf = new StringBuilder("Method "); MethodUtil.printMethod(methodName, types, buf); buf.append(" not found in '").append(target.getType().getName()).append("'"); BindHelper.processError(buf.toString(), node, bindingContext, false); return new ErrorBoundNode(node); } if (target.isStaticTarget() != methodCaller.getMethod().isStatic()) { if (methodCaller.getMethod().isStatic()) { BindHelper.processWarn( "Access of a static method from non-static object", node, bindingContext); } else { BindHelper.processError( "Access of a non-static method from a static object", node, bindingContext); return new ErrorBoundNode(node); } } MethodBoundNode result = new MethodBoundNode(node, children, methodCaller, target); result.setTargetNode(target); return result; }
/** * Common binding cycle. * * @param moduleNode * @param openl * @param moduleContext * @param moduleOpenClass * @param bindingContext * @return */ private IBoundNode processBinding( XlsModuleSyntaxNode moduleNode, OpenL openl, RulesModuleBindingContext moduleContext, XlsModuleOpenClass moduleOpenClass, IBindingContext bindingContext) { IVocabulary vocabulary = makeVocabulary(moduleNode); if (vocabulary != null) { processVocabulary(vocabulary, moduleContext); } // // Selectors // ASelector<ISyntaxNode> propertiesSelector = getSelector(XlsNodeTypes.XLS_PROPERTIES); ASelector<ISyntaxNode> dataTypeSelector = getSelector(XlsNodeTypes.XLS_DATATYPE); ISelector<ISyntaxNode> notPropertiesAndNotDatatypeSelector = propertiesSelector.not().and(dataTypeSelector.not()); ISelector<ISyntaxNode> spreadsheetSelector = getSelector(XlsNodeTypes.XLS_SPREADSHEET); ISelector<ISyntaxNode> testMethodSelector = getSelector(XlsNodeTypes.XLS_TEST_METHOD); ISelector<ISyntaxNode> runMethodSelector = getSelector(XlsNodeTypes.XLS_RUN_METHOD); ISelector<ISyntaxNode> commonTablesSelector = notPropertiesAndNotDatatypeSelector.and( spreadsheetSelector.not().and(testMethodSelector.not().and(runMethodSelector.not()))); // Bind property node at first. // TableSyntaxNode[] propertiesNodes = selectNodes(moduleNode, propertiesSelector); bindInternal(moduleNode, moduleOpenClass, propertiesNodes, openl, moduleContext); bindPropertiesForAllTables(moduleNode, moduleOpenClass, openl, moduleContext); IBoundNode topNode = null; // Bind datatype nodes. TableSyntaxNode[] datatypeNodes = selectNodes(moduleNode, dataTypeSelector); /* * Processes datatype table nodes before the bind operation. Checks type * declarations and finds invalid using of inheritance feature at this * step. */ TableSyntaxNode[] processedDatatypeNodes = new DatatypesSorter() .sort( datatypeNodes, moduleContext); // Rewrite this sorter with TableSyntaxNodeRelationsUtils bindInternal(moduleNode, moduleOpenClass, processedDatatypeNodes, openl, moduleContext); // Select nodes excluding Properties, Datatype, Spreadsheet, Test, // RunMethod tables TableSyntaxNode[] commonTables = selectNodes(moduleNode, commonTablesSelector); // Select and sort Spreadsheet tables TableSyntaxNode[] spreadsheets = selectSpreadsheetNodes(moduleNode, spreadsheetSelector); if (OpenLSystemProperties.isCustomSpreadsheetType(bindingContext.getExternalParams())) { try { spreadsheets = TableSyntaxNodeRelationsUtils.sort( spreadsheets, new SpreadsheetTableSyntaxNodeRelationsDeterminer()); } catch (TableSyntaxNodeCircularDependencyException e) { for (TableSyntaxNode tsn : e.getTableSyntaxNodes()) { SyntaxNodeException error = SyntaxNodeExceptionUtils.createError(e, tsn); processError(error, tsn, moduleContext); } } } TableSyntaxNode[] commonAndSpreadsheetTables = ArrayUtils.addAll(commonTables, spreadsheets); bindInternal(moduleNode, moduleOpenClass, commonAndSpreadsheetTables, openl, moduleContext); // Select Test and RunMethod tables TableSyntaxNode[] runTables = selectNodes(moduleNode, runMethodSelector); bindInternal(moduleNode, moduleOpenClass, runTables, openl, moduleContext); TableSyntaxNode[] testTables = selectNodes(moduleNode, testMethodSelector); topNode = bindInternal(moduleNode, moduleOpenClass, testTables, openl, moduleContext); if (moduleOpenClass.isUseDescisionTableDispatcher()) { DispatcherTablesBuilder dispTableBuilder = new DispatcherTablesBuilder((XlsModuleOpenClass) topNode.getType(), moduleContext); dispTableBuilder.build(); } ((XlsModuleOpenClass) topNode.getType()).setRulesModuleBindingContext(moduleContext); ((XlsModuleOpenClass) topNode.getType()).completeOpenClassBuilding(); processErrors(moduleOpenClass.getErrors(), bindingContext); return topNode; }