private static boolean isEqualParameters(Map<String, String> funcParameters, JSFunction function) { JSParameter[] parameters = function.getParameterList().getParameters(); if(parameters.length == 0) { return true; } if(parameters.length != funcParameters.size()) { return false; } /*int i = 0; for(DotNetTypeRef expectedTypeRef : funcParameters.values()) { JSParameter parameter = parameters[i++]; if(!CSharpTypeUtil.isTypeEqual(parameter.toTypeRef(true), expectedTypeRef, parameter)) { return false; } } */ return true; }
@Override public PsiElement getNavigationElement() { PsiElement parent = getParent(); if(parent instanceof JSClass) { PsiElement parentOriginalElement = parent.getNavigationElement(); if(parentOriginalElement != parent) { JSFunction functionByNameAndKind = ((JSClass) parentOriginalElement).findFunctionByNameAndKind(getName(), getKind()); return functionByNameAndKind != null ? functionByNameAndKind : this; } } return JSPsiImplUtils.findTopLevelNavigatableElement(this); }
@Override public JSFunction findFunctionByName(String functionName) { if(functionName == null) { return null; } final Map<String, Object> name2FunctionMap = initFunctions(); final Object o = name2FunctionMap.get(functionName); if(o instanceof JSFunction) { return (JSFunction) o; } else if(o instanceof JSFunction[]) { return ((JSFunction[]) o)[0]; } return null; }
private void processElements(PsiElementProcessor<JSLabeledStatement> processor) { PsiElement run = getParent(); while(run != null) { if(run instanceof JSLabeledStatement) { if(!processor.execute((JSLabeledStatement) run)) { return; } } if(run instanceof JSFunction) { break; } run = run.getParent(); } }
private static void doAddSignature(final List<JSFunction> lookupItems, final Set<String> availableSignatures, final PsiElement el) { if(el instanceof JSFunction) { final JSFunction function = (JSFunction) el; final JSParameterList parameterList = function.getParameterList(); if(parameterList != null) { final String typedSignature = buildSignature(parameterList.getParameters(), false, -1).text; final String untypedSignature = buildSignature(parameterList.getParameters(), true, -1).text; if(!availableSignatures.contains(typedSignature) && !availableSignatures.contains(untypedSignature)) { lookupItems.add(function); availableSignatures.add(typedSignature); availableSignatures.add(untypedSignature); } } } }
@Override public void updateUI(final JSFunction p, final ParameterInfoUIContext context) { final JSParameterList parameterList = p.getParameterList(); final JSParameter[] params = parameterList != null ? parameterList.getParameters() : new JSParameter[0]; final int currentParameterIndex = context.getCurrentParameterIndex() >= 0 ? context.getCurrentParameterIndex() : params.length; final JSParameter parameter = currentParameterIndex < params.length ? params[currentParameterIndex] : null; final SignatureInfo signatureInfo = buildSignature(params, false, currentParameterIndex); final String name = signatureInfo.text; final String currentParameterSignature = parameter != null ? getSignatureForParameter(parameter, false) : null; int highlightStart = parameter != null ? signatureInfo.selectedParameterStart : 0; int highlightEnd = parameter != null ? highlightStart + currentParameterSignature.length() : 0; context.setupUIComponentPresentation(name, highlightStart, highlightEnd, false, false, false, context.getDefaultParameterColor()); }
@Override public Result calculateResult(@NotNull Expression[] params, ExpressionContext context) { final PsiElement elementAtCaret = JSClassNameMacro.findElementAtCaret(context); if(elementAtCaret != null) { JSFunction function = PsiTreeUtil.getParentOfType(elementAtCaret, JSFunction.class); if(function instanceof JSFunctionExpression) { function = ((JSFunctionExpression) function).getFunction(); } if(function != null) { final String name = function.getName(); if(name != null) { return new TextResult(name); } } } return null; }
@Override public Result calculateResult(@NotNull final Expression[] params, final ExpressionContext context) { final PsiElement elementAtCaret = findElementAtCaret(context); final JSResolveUtil.ContextResolver resolver = new JSResolveUtil.ContextResolver(elementAtCaret); String text = resolver.getQualifierAsString(); if(text == null) { final JSFunction previousFunction = PsiTreeUtil.getPrevSiblingOfType(elementAtCaret, JSFunction.class); if(previousFunction != null) { text = previousFunction.getName(); } } if(text != null) { return new TextResult(text); } return null; }
protected String importType(final String s, T fun) { if(s == null) { return null; } if(fun instanceof JSFunction) { final String resolvedTypeName = JSImportHandlingUtil.resolveTypeName(s, fun); if(!resolvedTypeName.equals(s)) { ImportUtils.doImport(myJsClass, resolvedTypeName); } } return s; }
protected @NonNls String buildFunctionKind(final T fun) { if(fun instanceof JSFunction) { final JSFunction function = (JSFunction) fun; if(function.isGetProperty()) { return "get "; } else if(function.isSetProperty()) { return "set "; } } return ""; }
private static boolean forStatementDefinitelyRecurses( JSForStatement forStatement, JSFunction method) { final JSStatement declaration = forStatement.getVarDeclaration(); final JSExpression initialization = forStatement.getInitialization(); if (declaration != null && RecursionUtil.statementDefinitelyRecurses(declaration, method)) { return true; } else if (initialization != null && RecursionUtil.expressionDefinitelyRecurses(initialization, method)) { return true; } final JSExpression condition = forStatement.getCondition(); if (RecursionUtil.expressionDefinitelyRecurses(condition, method)) { return true; } if (BoolUtils.isTrue(condition)) { final JSStatement body = forStatement.getBody(); return RecursionUtil.statementDefinitelyRecurses(body, method); } return false; }
public static JSFunction findFunctionWithTheSameKind(final Map<String, Object> functions, final JSFunction function, final String name) { Object o = functions.get(name); if(o instanceof JSFunction && ((JSFunction) o).getKind() != function.getKind()) { o = null; } else if(o instanceof JSFunction[]) { final JSFunction[] jsFunctions = (JSFunction[]) o; o = null; for(JSFunction fun : jsFunctions) { if(fun.getKind() == function.getKind()) { o = fun; break; } } } return (JSFunction) o; }
public static Query<JSFunction> doFindOverridenFunctionStatic(final JSFunction elt) { PsiElement parent = JSResolveUtil.findParent(elt); if(parent instanceof JSClass) { return JSFunctionsSearch.searchOverridingFunctions(elt, true); } final String qName = JSResolveUtil.getQNameToStartHierarchySearch(elt); if(qName != null) { final ArrayList<JSFunction> result = new ArrayList<JSFunction>(); return new CollectionQuery<JSFunction>(result); } return new CollectionQuery<JSFunction>(Collections.<JSFunction>emptyList()); }
@Nullable private static JSFunction findImplementedFunction(JSFunction implementingFunction) { PsiElement clazz = implementingFunction.getParent(); if(!(clazz instanceof JSClass)) { clazz = JSResolveUtil.getClassReferenceForXmlFromContext(clazz); } if(!(clazz instanceof JSClass)) { return null; } final Ref<JSFunction> result = new Ref<JSFunction>(); JSResolveUtil.processInterfaceMethods((JSClass) clazz, new JSResolveUtil.CollectMethodsToImplementProcessor(implementingFunction.getName(), implementingFunction) { @Override protected boolean process(final ResolveProcessor processor) { result.set((JSFunction) processor.getResult()); return false; } }); return result.get(); }
@Override protected String buildFunctionAttrText(String attrText, final JSAttributeList attributeList, final JSFunction function) { attrText = super.buildFunctionAttrText(attrText, attributeList, function); final PsiElement element = JSResolveUtil.findParent(function); if(attributeList == null || !attributeList.hasModifier(JSAttributeList.ModifierType.OVERRIDE)) { if(element instanceof JSClass && !"Object".equals(((JSClass) element).getQualifiedName())) { final PsiElement typeElement = attributeList != null ? attributeList.findAccessTypeElement() : null; if(typeElement == null) { attrText += " override"; } else { final int index = attrText.indexOf(typeElement.getText()); attrText = attrText.substring(0, index) + ((index > 0) ? " " : "") + "override " + attrText.substring(index); } } } return attrText; }
@Override public boolean execute(final SearchParameters queryParameters, final Processor<JSFunction> consumer) { final JSFunction baseFunction = queryParameters.getBaseFunction(); PsiElement clazz = JSResolveUtil.findParent(baseFunction); if(!(clazz instanceof JSClass)) { return true; } return makeQuery(queryParameters, clazz).forEach(new Processor<JSClass>() { @Override public boolean process(final JSClass jsClass) { JSFunction function = jsClass.findFunctionByNameAndKind(baseFunction.getName(), baseFunction.getKind()); if(function != null) { return consumer.process(function); } return true; } }); }
private static void process(final JSNamedElement node, final ProblemsHolder holder) { if(node.getContainingFile().getLanguage() != JavaScriptSupportLoader.ECMA_SCRIPT_L4) { return; } PsiElement nameIdentifier = node.getNameIdentifier(); if(nameIdentifier != null && JSPsiImplUtils.getTypeFromDeclaration(node) == null && (!(node instanceof JSParameter) || !((JSParameter) node).isRest())) { holder.registerProblem(nameIdentifier, JavaScriptBundle.message(node instanceof JSFunction ? "js.untyped.function.problem" : "js.untyped" + ".variable.problem", nameIdentifier.getText()), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddTypeToDclFix()); } }
@RequiredReadAction private void insertCommitReformat(final Project project, final Editor editor, final PsiFile psiFile, final int offset, final String str, final int shiftOffset, boolean adjustLineIndent) { editor.getDocument().insertString(offset, str); editor.getCaretModel().moveToOffset(offset + shiftOffset); commit(editor); PsiElement at = psiFile.findElementAt(offset + shiftOffset - 1); final PsiElement parentOfType = PsiTreeUtil.getParentOfType(at, JSStatement.class, JSFunction.class, JSClass.class, JSFile.class); try { reformat(parentOfType); if(adjustLineIndent) { CodeStyleManager.getInstance(project).adjustLineIndent(psiFile, editor.getCaretModel().getOffset()); } } catch(IncorrectOperationException ex) { LoggerFactory.getInstance().getLoggerInstance(getClass().getName()).error(ex); } }
public static boolean functionDefinitelyRecurses( @NotNull JSFunction method) { final JSSourceElement[] body = method.getBody(); if (body != null) { for (final JSSourceElement element : body) { if (element instanceof JSStatement && RecursionUtil.statementDefinitelyRecurses((JSStatement) element, method)) { return true; } else if (element instanceof JSExpression && RecursionUtil.expressionDefinitelyRecurses((JSExpression) element, method)) { return true; } } } return false; }
@Override public void visitJSFunctionDeclaration(JSFunction function) { super.visitJSFunctionDeclaration(function); final JSParameterList parameterList = function.getParameterList(); if (parameterList == null) { return; } final JSParameter[] parameters = parameterList.getParameters(); for (JSVariable variable : parameters) { final String name = variable.getName(); if (name == null) { continue; } if (isValid(name)) { continue; } registerVariableError(variable); } }
@Override public void visitJSThisExpression(JSThisExpression jsThisExpression) { super.visitJSThisExpression(jsThisExpression); final JSObjectLiteralExpression containingObject = PsiTreeUtil.getParentOfType(jsThisExpression, JSObjectLiteralExpression.class); if (containingObject != null) { return; } final JSFunction containingFunction = PsiTreeUtil.getParentOfType(jsThisExpression, JSFunction.class); if (containingFunction != null) { return; } final XmlAttributeValue containingAttribute = PsiTreeUtil.getParentOfType(jsThisExpression, XmlAttributeValue.class); if (containingAttribute != null) { return; } final PsiFile containingFile = jsThisExpression.getContainingFile(); if (containingFile instanceof JSExpressionCodeFragment || containingFile.getContext() instanceof XmlAttributeValue) { return; } registerError(jsThisExpression); }
@Override public void visitJSFunctionDeclaration(@NotNull JSFunction function) { final PsiElement lastChild = function.getLastChild(); if(!(lastChild instanceof JSBlockStatement)) { return; } final StatementCountVisitor visitor = new StatementCountVisitor(); lastChild.accept(visitor); final int statementCount = visitor.getStatementCount(); if (statementCount <= getLimit()) { return; } registerFunctionError(function); }
private static Iterable<PsiElement> getReferences(@NotNull final JSVariable variable, @Nullable final PsiElement scope, final int minTextOffset, final int maxTextOffset) { final PsiElement iteratedScope; if (scope == null) { JSElement function = PsiTreeUtil.getParentOfType(variable, JSFunction.class); iteratedScope = ((function == null) ? FindReferenceUtil.getFarthestAncestor(variable, XmlFile.class) : function); } else { iteratedScope = scope; } return new Iterable<PsiElement>() { @Override public Iterator<PsiElement> iterator() { return new JSReferenceIterator(variable, minTextOffset, maxTextOffset, iteratedScope); } }; }
private static boolean blockStatementMayReturnBeforeRecursing( JSBlockStatement block, JSFunction method, boolean endsInImplicitReturn) { if (block == null) { return true; } final JSStatement[] statements = block.getStatements(); for (final JSStatement statement : statements) { if (RecursionUtil.statementMayReturnBeforeRecursing(statement, method)) { return true; } if (RecursionUtil.statementDefinitelyRecurses(statement, method)) { return false; } } return endsInImplicitReturn; }
private static boolean binaryExpressionDefinitelyRecurses( JSBinaryExpression expression, JSFunction method) { final JSExpression lhs = expression.getLOperand(); if (RecursionUtil.expressionDefinitelyRecurses(lhs, method)) { return true; } final IElementType tokenType = expression.getOperationSign(); if (tokenType.equals(JSTokenTypes.ANDAND) || tokenType.equals(JSTokenTypes.OROR)) { return false; } return RecursionUtil.expressionDefinitelyRecurses(expression.getROperand(), method); }
public static PsiElement getRealFirstChild (ES6Class es6Class){ PsiElement[] children = es6Class.getChildren(); if(children.length>2){ if((children[2] instanceof JSFunction)|| children[2] instanceof JSVarStatementBase){ return children[2]; } } if(children.length>3){ if((children[3] instanceof JSFunction)|| children[3] instanceof JSVarStatementBase){ return children[3]; } } return null; }
@RequiredReadAction @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { if(element.getNode().getElementType() == JSTokenTypes.IDENTIFIER && element.getParent() instanceof JSReferenceExpression && element.getParent().getParent() instanceof JSFunction) { UnityFunctionManager functionManager = UnityFunctionManager.getInstance(); Map<String, UnityFunctionManager.FunctionInfo> map = functionManager.getFunctionsByType().get(Unity3dTypes.UnityEngine.MonoBehaviour); if(map == null) { return null; } UnityFunctionManager.FunctionInfo functionInfo = map.get(element.getText()); if(functionInfo == null) { return null; } Unity3dModuleExtension extension = ModuleUtilCore.getExtension(element, Unity3dModuleExtension.class); if(extension == null) { return null; } JSFunction jsFunction = (JSFunction) element.getParent().getParent(); if(jsFunction.getParent() instanceof JSFile) { if(!isEqualParameters(functionInfo.getParameters(), jsFunction)) { return null; } return new LineMarkerInfo<>(element, element.getTextRange(), Unity3dIcons.EventMethod, Pass.LINE_MARKERS, new ConstantFunction<>(functionInfo.getDescription()), null, GutterIconRenderer.Alignment.LEFT); } } return null; }
@RequiredReadAction @Override public JSFunctionStub createStub(@NotNull JSFunction psi, StubElement parentStub) { String name = psi.getName(); String qualifiedName = psi.getQualifiedName(); String returnTypeString = psi.getReturnTypeString(); int flags = JSFunctionStubImpl.buildFlags(psi); return new JSFunctionStubImpl(name, flags, qualifiedName, returnTypeString, parentStub, this); }
@Override public JSFunction[] getFunctions() { final JSClassStub classStub = getStub(); if(classStub != null) { return getStubChildrenByType(classStub, JSElementTypes.FUNCTION_DECLARATION, JSFunction.ARRAY_FACTORY); } else { final List<JSFunction> functions = new ArrayList<JSFunction>(); processDeclarations(new PsiScopeProcessor() { @Override public boolean execute(final PsiElement element, final ResolveState state) { if(element instanceof JSFunction) { functions.add((JSFunction) element); } return true; } @Override public <T> T getHint(final Key<T> hintClass) { return null; } @Override public void handleEvent(final Event event, final Object associated) { } }, ResolveState.initial(), this, this); return functions.toArray(JSFunction.EMPTY_ARRAY); } }
@Override public JSFunction findFunctionByNameAndKind(final String name, JSFunction.FunctionKind kind) { if(name == null) { return null; } Map<String, Object> name2FunctionMap = initFunctions(); final Object o = name2FunctionMap.get(name); if(o instanceof JSFunction) { final JSFunction function = (JSFunction) o; return function.getKind() == kind ? function : null; } else if(o instanceof JSFunction[]) { for(JSFunction fun : (JSFunction[]) o) { if(fun.getKind() == kind) { return fun; } } } return null; }
private static boolean newExpressionDefinitelyRecurses(JSNewExpression exp, JSFunction method) { final JSArgumentList argumentList = exp.getArgumentList(); if (argumentList != null) { final JSExpression[] args = argumentList.getArguments(); for (final JSExpression arg : args) { if (RecursionUtil.expressionDefinitelyRecurses(arg, method)) { return true; } } } return false; }
@Override public Object[] getParametersForLookup(final LookupElement item, final ParameterInfoContext context) { if(!(item instanceof MutableLookupElement)) { return null; } PsiElement element = item.getPsiElement(); if(element instanceof JSFunction) { final JSFunction originalFunction = (JSFunction) element; final List<JSFunction> lookupItems = new ArrayList<JSFunction>(); Set<String> availableSignatures = new HashSet<String>(); for(PsiElement el : DefinitionsScopedSearch.search(originalFunction)) { doAddSignature(lookupItems, availableSignatures, el); } if(lookupItems.size() == 0) { lookupItems.add(originalFunction); } return lookupItems.toArray(new Object[lookupItems.size()]); } return ArrayUtil.EMPTY_OBJECT_ARRAY; }
@Override public Object[] getParametersForDocumentation(final JSFunction p, final ParameterInfoContext context) { final JSParameterList list = p.getParameterList(); if(list != null) { return list.getParameters(); } return ArrayUtil.EMPTY_OBJECT_ARRAY; }
private static void processFunction(JSStructureViewElement parentElement, Map<String, Group> groups, TreeElement _child, PsiElement value) { final PsiElement element = JSStructureViewElement.getPsiElementResolveProxy(parentElement); if(element instanceof JSClass) { JSClass parentClass = (JSClass) element; JSClass declaringClass = JSResolveUtil.findDeclaringClass((JSFunction) value); if(parentClass != declaringClass) { addGroup(groups, _child, declaringClass.getQualifiedName()); } } }
@Override protected @NonNls String buildFunctionAttrText(@NonNls String attrText, final JSAttributeList attributeList, final JSFunction function) { attrText = super.buildFunctionAttrText(attrText, attributeList, function); if(attributeList == null || attributeList.getAccessType() != JSAttributeList.AccessType.PUBLIC) { attrText = "public"; } return attrText; }
private static boolean whileStatementDefinitelyRecurses( JSWhileStatement whileStatement, JSFunction method) { final JSExpression condition = whileStatement.getCondition(); if (RecursionUtil.expressionDefinitelyRecurses(condition, method)) { return true; } if (BoolUtils.isTrue(condition)) { final JSStatement body = whileStatement.getBody(); return RecursionUtil.statementDefinitelyRecurses(body, method); } return false; }
@Override protected TextRange getSurroundSelectionRange(final ASTNode statementNode) { JSFunction stmt = (JSFunction) statementNode.getPsi(); ASTNode conditionNode = stmt.getNameIdentifier().getNode(); int offset = conditionNode.getStartOffset(); stmt.getNode().removeChild(conditionNode); return new TextRange(offset, offset); }
private static boolean tryStatementDefinitelyRecurses( JSTryStatement tryStatement, JSFunction method) { final JSStatement statement = tryStatement.getStatement(); if (RecursionUtil.statementDefinitelyRecurses(statement, method)) { return true; } final JSStatement finallyStatement = tryStatement.getFinallyStatement(); return RecursionUtil.statementDefinitelyRecurses(finallyStatement, method); }
@Override protected void collectCandidates(final JSClass clazz, final Collection<JSNamedElementNode> candidates) { ImplementedMethodProcessor processor = new ImplementedMethodProcessor(clazz) { @Override protected void addNonimplementedFunction(final JSFunction function) { candidates.add(new JSNamedElementNode(function)); } }; JSResolveUtil.processInterfaceMethods(clazz, processor); }
private static Icon buildIcon(final JSNamedElement node) { Icon icon = IconDescriptorUpdaters.getIcon(node, 0); if(node instanceof JSFunction) { final JSFunction function = (JSFunction) node; final Icon accessIcon; if(function.isGetProperty()) { accessIcon = AllIcons.Nodes.Read_access; } else if(function.isSetProperty()) { accessIcon = AllIcons.Nodes.Write_access; } else { accessIcon = null; } if(accessIcon != null) { final LayeredIcon layeredIcon = new LayeredIcon(1); layeredIcon.setIcon(accessIcon, 0, 1, 3); RowIcon rowIcon = new RowIcon(2); rowIcon.setIcon(layeredIcon, 1); rowIcon.setIcon(icon, 0); icon = rowIcon; } } return icon; }