public void restartInstance() { synchronized(this.myLock) { final JSGraphQLNodeLanguageServiceInstance instance = JSGraphQLNodeLanguageServiceClient.getLanguageServiceInstance(myProject); if(instance != null) { if(myToolWindowManager != null) { myToolWindowManager.disconnectFromProcessHandler(); } instance.restart(() -> { final Editor editor = FileEditorManager.getInstance(myProject).getSelectedTextEditor(); if(editor != null) { final VirtualFile file = FileDocumentManager.getInstance().getFile(editor.getDocument()); if(file != null) { final PsiFile psiFile = PsiUtilCore.getPsiFile(myProject, file); if(psiFile != null) { if(psiFile instanceof JSFile || psiFile instanceof JSGraphQLFile) { DaemonCodeAnalyzer.getInstance(myProject).restart(psiFile); } } logErrorsForFile(file, true); // force true to re-show the errors for the same file } } }); } } }
public static String getEnvironment(PsiFile file) { if (file instanceof JSFile) { // for JS Files we have to check the kind of environment being used final Ref<String> envRef = new Ref<>(); file.accept(new PsiRecursiveElementVisitor() { @Override public void visitElement(PsiElement element) { if (!isJSGraphQLLanguageInjectionTarget(element, envRef)) { // no match yet, so keep visiting super.visitElement(element); } } }); final String environment = envRef.get(); if (environment != null) { return environment; } } else if (file instanceof JSGraphQLFile) { final Ref<String> tag = new Ref<>(); if (file.getContext() != null && isJSGraphQLLanguageInjectionTarget(file.getContext(), tag)) { return tag.get(); } } // fallback is traditional GraphQL return GRAPHQL_ENVIRONMENT; }
@NotNull @Override public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { if(element instanceof JSFile || element.getContainingFile() instanceof JSFile) { final JSFile file = (JSFile)(element instanceof JSFile ? element : element.getContainingFile()); file.putUserData(WANT_DEFAULT_FORMATTER_KEY, true); try { final FormattingModelBuilder formattingModelBuilder = LanguageFormatting.INSTANCE.forContext(file.getLanguage(), element); if (formattingModelBuilder != null) { final FormattingModel model = formattingModelBuilder.createModel(element, settings); final Block rootBlock = model.getRootBlock(); return new DelegatingFormattingModel(model, new JSGraphQLBlockWrapper(rootBlock, null, element.getNode(), rootBlock.getWrap(), rootBlock.getAlignment(), createSpaceBuilder(settings, element), settings)); } } finally { file.putUserData(WANT_DEFAULT_FORMATTER_KEY, null); } } throw new IllegalArgumentException("Unsupported element '" + element + "'. It must be an element in a JSFile with its own default formatter to support injected GraphQL formatting"); }
@Override public boolean isEngagedToFormat(PsiElement context) { if(context instanceof JSFile) { if(Boolean.TRUE.equals(context.getUserData(WANT_DEFAULT_FORMATTER_KEY))) { // we're looking up the default formatter at the moment return false; } Collection<JSStringTemplateExpression> templateExpressions = PsiTreeUtil.findChildrenOfType(context, JSStringTemplateExpression.class); for (JSStringTemplateExpression templateExpression : templateExpressions) { if(JSGraphQLLanguageInjectionUtil.isJSGraphQLLanguageInjectionTarget(templateExpression)) { return true; } } } return false; }
public void testSnippetsForBackend() { PsiFile psiFile = myFixture.configureByFile("snippets.js"); Collection<ShopwareSnippet> snippetsInFile = SnippetUtil.getSnippetsInFile((JSFile) psiFile); assertNotNull(ContainerUtil.find(snippetsInFile, snippet -> "backend/foobar/namespace".equals(snippet.getNamespace()) && "start_accept".equals(snippet.getName()) )); assertNotNull(ContainerUtil.find(snippetsInFile, snippet -> "backend/foobar".equals(snippet.getNamespace()) && "start_accept".equals(snippet.getName()) )); assertNotNull(ContainerUtil.find(snippetsInFile, snippet -> "backend/foobar/namespace".equals(snippet.getNamespace()) && "filter_feature".equals(snippet.getName()) )); assertNotNull(ContainerUtil.find(snippetsInFile, snippet -> "foobar".equals(snippet.getNamespace()) && "filter_feature".equals(snippet.getName()) )); }
@RequiredReadAction @NotNull @Override public Collection<? extends DotNetTypeDeclaration> findTypesImpl(@NotNull String key, @NotNull GlobalSearchScope searchScope) { if(DumbService.isDumb(myProject)) { return Collections.emptyList(); } Collection<JSFile> jsFiles = UnityScriptFileByNameIndex.getInstance().get(key, myProject, searchScope); JSFile jsFile = ContainerUtil.getFirstItem(jsFiles); if(jsFile == null) { return Collections.emptyList(); } return Collections.singletonList(new UnityScriptDotNetTypeDeclaration(key, jsFile)); }
@NotNull @Override @RequiredReadAction public Set<PsiElement> compute(@NotNull final Project project, @Nullable final IndexBasedDotNetPsiSearcher searcher, @NotNull final String indexKey, @NotNull final String thisQName, @NotNull final GlobalSearchScope scope) { Set<PsiElement> elements = new LinkedHashSet<>(); Collection<String> keys = UnityScriptFileByNameIndex.getInstance().getAllKeys(project); for(String key : keys) { ProgressManager.checkCanceled(); Collection<JSFile> jsFiles = UnityScriptFileByNameIndex.getInstance().get(key, project, scope); for(JSFile jsFile : jsFiles) { elements.add(new UnityScriptDotNetTypeDeclaration(key, jsFile)); } } return elements; }
@Nullable public static VirtualFile findExecutableFile(ConfigurationContext configurationContext, @Nullable Condition<JSFile> condition) { PsiElement psiLocation = configurationContext.getPsiLocation(); PsiFile psiFile = psiLocation == null ? null : psiLocation.getContainingFile(); if(psiFile instanceof JSFile && psiFile.getFileType() == JavaScriptFileType.INSTANCE) { if(condition != null && !condition.value((JSFile) psiFile)) { return null; } Module module = configurationContext.getModule(); if(module == null) { return null; } NodeJSModuleExtension extension = ModuleUtilCore.getExtension(module, NodeJSModuleExtension.class); if(extension == null) { return null; } return psiFile.getVirtualFile(); } return null; }
@Override public StubBuilder getBuilder() { return new DefaultStubBuilder() { @NotNull @Override protected StubElement createStubForFile(@NotNull PsiFile file) { if(file instanceof JSFile) { return new JSFileStubImpl((JSFile) file, file.getName()); } return super.createStubForFile(file); } }; }
@Override public String getQualifiedName() { final JSFunctionStub jsFunctionStub = getStub(); if(jsFunctionStub != null) { return jsFunctionStub.getQualifiedName(); } final PsiElement parent = JSResolveUtil.findParent(this); if(parent instanceof JSFile || parent instanceof JSPackageStatement) { return JSPsiImplUtils.getQName(this); } else { return getName(); } }
private static <E extends PsiElement> void process(TokenSet filter, final JSFile file, final ArrayList<E> result, final Collection<JSFile> visited) { if(visited.contains(file)) { return; } visited.add(file); for(PsiElement element : JSResolveUtil.getStubbedChildren(file, filter)) { if(element instanceof JSIncludeDirective) { PsiFile includedFile = ((JSIncludeDirective) element).resolveFile(); if(includedFile instanceof JSFile) { process(filter, (JSFile) includedFile, result, visited); } } else { result.add((E) element); } } }
public static JSImportedElementResolveResult resolveTypeNameUsingImplicitImports(@NotNull String referenceName, @NotNull JSFile file) { final PsiElement context = file.getContext(); if(context != null) { JSImportedElementResolveResult expression = tryFindInMap(referenceName, file, implicitImportListMap, null); if(expression != null) { return expression; } expression = tryFindInMap(referenceName, file, mxmlImportListMap, null); if(expression != null) { return expression; } } return null; }
@Override protected CachedValue<JSFile[]> compute(final XmlTag tag, final Object p) { return CachedValuesManager.getManager(tag.getProject()).createCachedValue(new CachedValueProvider<JSFile[]>() { @Override public Result<JSFile[]> compute() { final List<JSFile> injectedFiles = new ArrayList<JSFile>(2); final List<PsiElement> dependencies = new ArrayList<PsiElement>(); dependencies.add(tag); new InjectedScriptsVisitor(tag, doProcessAllTags(tag), false, false, new InjectedFileVisitor() { @Override public void visit(XmlTag rootTag, JSFile file) { injectedFiles.add(file); dependencies.add(file); } }).go(); return new Result<JSFile[]>(injectedFiles.toArray(new JSFile[injectedFiles.size()]), dependencies.toArray()); } }, false); }
protected void evalAnchor(final Editor editor, final PsiFile file) { anchor = null; final PsiElement at = file.findElementAt(editor.getCaretModel().getOffset()); PsiElement parent; if(at != null && ((parent = at.getParent()) == myJsClass || (parent instanceof JSFile && myJsClass.getParent().getContainingFile() == parent .getContext().getContainingFile()))) { final ASTNode atNode = at.getNode(); if(atNode.getElementType() == JSTokenTypes.RBRACE) { return; } for(ASTNode node = atNode; node != null; node = node.getTreeNext()) { if(node.getElementType() == JSTokenTypes.LBRACE) { return; } } anchor = at; } }
@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); } }
@NotNull @Override public Collection<KeyUsagePsiElement> getUsages(PsiFile psiFile) { if(psiFile instanceof JSFile) { JsEnvironmentCallsVisitor visitor = new JsEnvironmentCallsVisitor(); psiFile.acceptChildren(visitor); return visitor.getCollectedItems(); } return Collections.emptyList(); }
@Override public boolean isAcceptable(Object element, @Nullable PsiElement context) { if (element instanceof XmlAttributeValue && context != null && context.getContainingFile() instanceof JSFile) { final XmlAttributeValue value = (XmlAttributeValue) element; final XmlAttribute xmlAttribute = PsiTreeUtil.getParentOfType(value, XmlAttribute.class); if (xmlAttribute != null) { return xmlAttribute.getName().equals("styleName"); } } return false; }
@Override public boolean isAcceptable(Object element, @Nullable PsiElement context) { if (element instanceof JSLiteralExpression && context != null && context.getContainingFile() instanceof JSFile) { final ASTNode value = ((JSLiteralExpression) element).getNode().getFirstChildNode(); return value != null && value.getElementType() == JSTokenTypes.STRING_LITERAL; } return false; }
@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; }
@Override public void processElementsWithName(@NotNull String name, @NotNull final Processor<NavigationItem> processor, @NotNull FindSymbolParameters parameters) { StubIndex.getInstance().processElements(UnityScriptIndexKeys.FILE_BY_NAME_INDEX, name, parameters.getProject(), parameters.getSearchScope(), parameters.getIdFilter(), JSFile.class, new Processor<JSFile>() { @Override public boolean process(final JSFile file) { return processor.process(new FakePsiElement() { @Override public String getName() { return FileUtil.getNameWithoutExtension(file.getName()); } @Nullable @Override public Icon getIcon(boolean open) { IconDescriptor descriptor = new IconDescriptor(AllIcons.Nodes.Class); descriptor.addLayerIcon(Unity3dIcons.Js); descriptor.setRightIcon(AllIcons.Nodes.C_public); return descriptor.toIcon(); } @Override public PsiElement getParent() { return file; } }); } }); }
@Override @RequiredDispatchThread public Collection<AbstractTreeNode> modify(AbstractTreeNode parent, Collection<AbstractTreeNode> children, ViewSettings settings) { if(!myProject.isInitialized()) { return children; } Unity3dRootModuleExtension rootModuleExtension = Unity3dModuleExtensionUtil.getRootModuleExtension(myProject); if(rootModuleExtension == null) { return children; } List<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>(children.size()); for(AbstractTreeNode child : children) { Object value = child.getValue(); if(value instanceof JSFile) { Module moduleForPsiElement = ModuleUtilCore.findModuleForPsiElement((PsiElement) value); if(moduleForPsiElement != null) { nodes.add(new UnityScriptFileNode(myProject, (PsiFile) value, settings)); continue; } } nodes.add(child); } return nodes; }
@RequiredReadAction public UnityScriptDotNetTypeDeclaration(@NotNull String nameWithoutExtension, @NotNull JSFile file) { super(file.getManager(), file.getLanguage()); myNameWithoutExtension = nameWithoutExtension; myFile = file; }
public static boolean containsTestsInFiles(JSFile file) { JSSourceElement[] statements = file.getStatements(); for(JSSourceElement statement : statements) { if(statement instanceof JSExpressionStatement) { JSExpression expression = ((JSExpressionStatement) statement).getExpression(); if(expression instanceof JSCallExpression) { JSExpression methodExpression = ((JSCallExpression) expression).getMethodExpression(); if(methodExpression instanceof JSReferenceExpression) { JSExpression qualifier = ((JSReferenceExpression) methodExpression).getQualifier(); if(qualifier != null) { continue; } String referencedName = ((JSReferenceExpression) methodExpression).getReferencedName(); if("describe".equals(referencedName)) { JSArgumentList argumentList = ((JSCallExpression) expression).getArgumentList(); if(argumentList != null && argumentList.getArguments().length == 2) { return true; } } } } } } return false; }
@Override @RequiredReadAction public boolean value(JSFile file) { Module module = ModuleUtilCore.findModuleForPsiElement(file); return module != null && ModuleUtilCore.getExtension(module, MochaModuleExtension.class) != null && NpmRunUtil.findNpmModule(module, MochaPsiElementUtil.MOCHA) != null && MochaPsiElementUtil.containsTestsInFiles(file); }
@Override @RequiredReadAction public boolean shouldReplace(ConfigurationFromContext self, ConfigurationFromContext other) { RunConfiguration configuration = other.getConfiguration(); if(configuration instanceof NodeJSConfiguration) { PsiFile containingFile = other.getSourceElement().getContainingFile(); if(containingFile instanceof JSFile) { return ourFileCondition.value((JSFile) containingFile); } } return false; }
@Override public void visitJSFile(final JSFile file) { super.visitFile(file); if (isJavaScriptFile(file) && isVisitingPossible(file)) { System.out.println("Visiting: " + file.getVirtualFile().getCanonicalPath()); checkJSFile(file); } }
private void checkJSFile(JSFile file) { String jscsResult = new JscsNativeRunner( file.getName(), file.getProject().getBaseDir().getCanonicalPath() ).runJscs(file.getText()); List<MessageContainer> problemMessages = CheckstyleXMLParser.parse(jscsResult); for (MessageContainer message : problemMessages) { JscsInspection.registerProblem(problemsHolder, file, message); } }
private static PsiElement findPsiElement(int line, int column, JSFile file) { Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); //intellij starts counting here at line 0 and column 0 int elementOffset = document.getLineStartOffset(line - 1) + (column - 1); PsiElement found = file.findElementAt(elementOffset); if (found == null) { return file; } else { return found; } }
@Override public boolean processDeclarations(@NotNull final PsiScopeProcessor processor, @NotNull final ResolveState substitutor, final PsiElement lastParent, @NotNull final PsiElement place) { boolean b = super.processDeclarations(processor, substitutor, lastParent, place); if(b && lastParent != null && lastParent.getParent() == this && getParent() instanceof JSFile) { b = JSImportHandlingUtil.tryResolveImports(processor, this, place); } return b; }
@Override public boolean isEquivalentTo(PsiElement another) { return super.isEquivalentTo(another) || (another instanceof JSFile && ((JSFile) another).getVirtualFile().getNameWithoutExtension().equals(getName()) && another == getParent().getParent()) || JSPsiImplUtils.isTheSameClass(another, this); }
@Override protected boolean processMembers(final PsiScopeProcessor processor, final ResolveState substitutor, final PsiElement lastParent, final PsiElement place) { for(JSFile file : ourCachedScripts.get(CACHED_SCRIPTS_KEY, getParent(), null).getValue()) { if(!file.processDeclarations(processor, ResolveState.initial(), null, place)) { return false; } } return true; }
public JSFile createScriptTag() throws IncorrectOperationException { final XmlTag rootTag = getParent(); if(rootTag != null) { String ns = findScriptNs(rootTag); rootTag.add(rootTag.createChildTag(SCRIPT_TAG_NAME, ns, "<![CDATA[\n]]>", false)); return findFirstScriptTag(); } return null; }
@Nullable public JSFile findFirstScriptTag() { JSFile[] value = ourCachedScripts.get(CACHED_SCRIPTS_KEY, getParent(), null).getValue(); if(value.length > 0) { return value[0]; } return null; }
public JSFile createOrGetFirstScriptTag() throws IncorrectOperationException { JSFile jsFile = findFirstScriptTag(); if(jsFile == null) { jsFile = createScriptTag(); } return jsFile; }
public static Document createDocument(final String text, final Project project, @Nullable VirtualFile contextVirtualFile, int contextOffset) { PsiElement context = null; if(contextVirtualFile != null) { context = getContextElement(contextVirtualFile, contextOffset, project); } JSFile file = JSElementFactory.createExpressionCodeFragment(project, text, context, true); return PsiDocumentManager.getInstance(project).getDocument(file); }
@Override @NotNull public FormattingModel createModel(final PsiElement element, final CodeStyleSettings settings) { final PsiFile psiFile = element.getContainingFile(); return new JSFormattingModel(psiFile, settings, new JSBlock(psiFile instanceof JSFile ? psiFile.getNode() : element.getNode(), null, null, null, settings)); }
private static boolean isClass(final PsiElement element) { if(element instanceof JSClass) { return true; } if(element instanceof JSFile && element.getContext() != null) { return true; } return false; }
@Nullable @RequiredReadAction @SuppressWarnings("unchecked") public <T extends JomElement> JomFileElement<T> getFileElement(@NotNull final PsiFile psiFile) { FileType fileType = psiFile.getFileType(); if(fileType != JsonFileType.INSTANCE) { return null; } CachedValue<JomFileElement<?>> cachedValue = psiFile.getUserData(JOM_FILE_ELEMENT); if(cachedValue == null) { cachedValue = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<JomFileElement<?>>() { @Nullable @Override public Result<JomFileElement<?>> compute() { JomFileElement<?> value = null; JomFileDescriptor fileDescriptor = findFileDescriptor(psiFile); if(fileDescriptor != null) { value = new JomFileElement((JSFile) psiFile, fileDescriptor); } return Result.<JomFileElement<?>>create(value, psiFile, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); } }, false); psiFile.putUserData(JOM_FILE_ELEMENT, cachedValue); } return (JomFileElement<T>) cachedValue.getValue(); }
public static boolean isRTFile(JSFile file) { return file != null && /*isRTFile(file.getVirtualFile()) ||*/ file.getFileType().equals(RTFileType.INSTANCE); }
@Nullable @Override public JSGraphQLAnnotationResult collectInformation(@NotNull PsiFile file, @NotNull Editor editor, boolean hasErrors) { try { boolean isJavaScript = file instanceof JSFile; if(isJavaScript || file instanceof JSGraphQLFile) { CharSequence buffer = editor.getDocument().getCharsSequence(); if (isJavaScript) { // replace the JS with line-preserving whitespace to be ignored by GraphQL buffer = getWhitespacePaddedGraphQL(file, buffer); } if (buffer.length() > 0) { final String environment = JSGraphQLLanguageInjectionUtil.getEnvironment(file); final AnnotationsResponse annotations = JSGraphQLNodeLanguageServiceClient.getAnnotations(buffer.toString(), file.getProject(), environment); if(annotations != null) { for (Annotation annotation : annotations.getAnnotations()) { LogicalPosition from = getLogicalPosition(annotation.getFrom()); int fromOffset = editor.logicalPositionToOffset(from); final PsiElement errorElement = getPsiElementAtErrorOffset(file, fromOffset); if(errorElement instanceof JSGraphQLErrorContextAware) { final String message = StringUtils.substringBefore(annotation.getMessage(), "\n"); final JSGraphQLErrorContextAware errorContextAware = (JSGraphQLErrorContextAware) errorElement; annotation.setErrorInContext(errorContextAware.isErrorInContext(message)); } } } return new JSGraphQLAnnotationResult(annotations, editor); } } else if(file instanceof JSGraphQLSchemaFile) { // no external annotation support yet for schema files return new JSGraphQLAnnotationResult(new AnnotationsResponse(), editor); } } catch (Throwable e) { if(e instanceof ProcessCanceledException) { // annotation was cancelled, e.g. due to an editor being closed return null; } log.error("Error during doAnnotate", e); } return null; }