diff --git a/.idea/externalDependencies.xml b/.idea/externalDependencies.xml index 5fc34a223d8d..4c698556438e 100644 --- a/.idea/externalDependencies.xml +++ b/.idea/externalDependencies.xml @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 064010d8399b..44693dcf252d 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -238,7 +238,6 @@ - diff --git a/build/scripts/download_kotlin.gant b/build/scripts/download_kotlin.gant index 372dc3de7002..622ff8d0c852 100644 --- a/build/scripts/download_kotlin.gant +++ b/build/scripts/download_kotlin.gant @@ -18,7 +18,7 @@ import com.intellij.util.text.VersionComparatorUtil import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant") -String kotlinBuildConfigurationOnPublicTeamCity = "Kotlin_Beta3_Idea142branch150versionNoTests" +String kotlinBuildConfigurationOnPublicTeamCity = "Kotlin_Beta4_Idea142branch150versionNoTests" target('default': 'Ensures that build/kotlinc directory contains JARs from Kotlin plugin compatible with current IDEA sources. These JARs are used by build scripts.') { def communityHome = guessHome(this) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java index 9d4c1b738ed6..c77b8529f482 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java @@ -31,7 +31,7 @@ class JCiPUtil { private static final String GUARDED_BY = "net.jcip.annotations.GuardedBy"; static boolean isJCiPAnnotation(String ref) { - return "Immutable".equals(ref) || "GuardedBy".equals(ref) || "ThreadSafe".equals("ref"); + return "Immutable".equals(ref) || "GuardedBy".equals(ref) || "ThreadSafe".equals(ref) || "NotThreadSafe".equals(ref); } private JCiPUtil() { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java index 619a604dc8fc..ce827c34353c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/actions/AddImportAction.java @@ -22,7 +22,6 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.actions.OptimizeImportsProcessor; -import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.daemon.QuickFixBundle; import com.intellij.codeInsight.hint.QuestionAction; import com.intellij.ide.util.DefaultPsiElementCellRenderer; @@ -267,17 +266,6 @@ public class AddImportAction implements QuestionAction { myEditor.getCaretModel().moveToLogicalPosition(new LogicalPosition(pos2.line, newCol)); myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); } - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - if (!myProject.isDisposed() && myProject.isOpen()) { - DaemonCodeAnalyzer daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(myProject); - if (daemonCodeAnalyzer != null) { - daemonCodeAnalyzer.updateVisibleHighlighters(myEditor); - } - } - } - }); } protected void bindReference(PsiReference ref, PsiClass targetClass) { diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java index 2f0c016d0f75..4db2bbc90154 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodFix.java @@ -19,42 +19,32 @@ import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.JavaProjectCodeInsightSettings; import com.intellij.codeInsight.completion.JavaCompletionUtil; import com.intellij.codeInsight.daemon.QuickFixBundle; -import com.intellij.codeInsight.daemon.impl.actions.AddImportAction; +import com.intellij.codeInsight.daemon.impl.ShowAutoImportPass; +import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.codeInsight.intention.impl.AddSingleMemberStaticImportAction; -import com.intellij.ide.util.MethodCellRenderer; +import com.intellij.codeInspection.HintAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.popup.PopupStep; -import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.psi.util.*; import com.intellij.psi.util.proximity.PsiProximityComparator; -import com.intellij.ui.popup.list.ListPopupImpl; -import com.intellij.ui.popup.list.PopupListElementRenderer; import com.intellij.util.ArrayUtilRt; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.ObjectUtils; import com.intellij.util.Processor; import com.intellij.util.containers.LinkedMultiMap; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import javax.swing.*; -import java.awt.*; import java.util.*; -import java.util.List; -public class StaticImportMethodFix implements IntentionAction { +public class StaticImportMethodFix implements IntentionAction, HintAction { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix"); private final SmartPsiElementPointer myMethodCall; private List candidates; @@ -68,9 +58,7 @@ public class StaticImportMethodFix implements IntentionAction { public String getText() { String text = QuickFixBundle.message("static.import.method.text"); if (candidates != null && candidates.size() == 1) { - text += " '" + PsiFormatUtil.formatMethod(candidates.get(0), PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | - PsiFormatUtilBase.SHOW_CONTAINING_CLASS | - PsiFormatUtilBase.SHOW_FQ_NAME, 0)+"'"; + text += " '" + getMethodPresentableText() + "'"; } else { text += "..."; @@ -78,6 +66,13 @@ public class StaticImportMethodFix implements IntentionAction { return text; } + @NotNull + private String getMethodPresentableText() { + return PsiFormatUtil.formatMethod(candidates.get(0), PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | + PsiFormatUtilBase.SHOW_CONTAINING_CLASS | + PsiFormatUtilBase.SHOW_FQ_NAME, 0); + } + @Override @NotNull public String getFamilyName() { @@ -91,6 +86,7 @@ public class StaticImportMethodFix implements IntentionAction { && myMethodCall.getElement() != null && myMethodCall.getElement().isValid() && myMethodCall.getElement().getMethodExpression().getQualifierExpression() == null + && myMethodCall.getElement().resolveMethod() == null && file.getManager().isInProject(file) && !(candidates == null ? candidates = getMethodsToImport() : candidates).isEmpty() ; @@ -263,146 +259,61 @@ public class StaticImportMethodFix implements IntentionAction { @Override public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) { if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; - if (candidates.size() == 1) { - final PsiMethod toImport = candidates.get(0); - doImport(toImport); - } - else { - chooseAndImport(editor, project); - } - } - - private void doImport(final PsiMethod toImport) { - CommandProcessor.getInstance().executeCommand(toImport.getProject(), new Runnable(){ + ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - try { - PsiMethodCallExpression element = myMethodCall.getElement(); - if (element != null) { - AddSingleMemberStaticImportAction.bindAllClassRefs(element.getContainingFile(), toImport, toImport.getName(), toImport.getContainingClass()); - } - } - catch (IncorrectOperationException e) { - LOG.error(e); - } - } - }); - + final List methodsToImport = getMethodsToImport(); + if (methodsToImport.isEmpty()) return; + createQuestionAction(methodsToImport, project, editor).execute(); } - }, getText(), this); - + }); } - private void chooseAndImport(Editor editor, final Project project) { - if (ApplicationManager.getApplication().isUnitTestMode()) { - doImport(candidates.get(0)); - return; + @NotNull + private StaticImportMethodQuestionAction createQuestionAction(List methodsToImport, @NotNull Project project, Editor editor) { + return new StaticImportMethodQuestionAction(project, editor, methodsToImport, myMethodCall); + } + + private ImportClassFixBase.Result doFix(Editor editor) { + if (candidates.isEmpty()) { + return ImportClassFixBase.Result.POPUP_NOT_SHOWN; } - final BaseListPopupStep step = - new BaseListPopupStep(QuickFixBundle.message("class.to.import.chooser.title"), candidates) { - + + final StaticImportMethodQuestionAction action = createQuestionAction(candidates, myMethodCall.getProject(), editor); + + if (candidates.size() == 1) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { @Override - public PopupStep onChosen(PsiMethod selectedValue, boolean finalChoice) { - if (selectedValue == null) { - return FINAL_CHOICE; - } - - if (finalChoice) { - PsiDocumentManager.getInstance(project).commitAllDocuments(); - LOG.assertTrue(selectedValue.isValid()); - doImport(selectedValue); - return FINAL_CHOICE; - } - - String qname = PsiUtil.getMemberQualifiedName(selectedValue); - if (qname == null) return FINAL_CHOICE; - List excludableStrings = AddImportAction.getAllExcludableStrings(qname); - return new BaseListPopupStep(null, excludableStrings) { - @NotNull - @Override - public String getTextFor(String value) { - return "Exclude '" + value + "' from auto-import"; - } - - @Override - public PopupStep onChosen(String selectedValue, boolean finalChoice) { - if (finalChoice) { - AddImportAction.excludeFromImport(project, selectedValue); - } - - return super.onChosen(selectedValue, finalChoice); - } - }; + public void run() { + action.execute(); } + }); + return ImportClassFixBase.Result.CLASS_AUTO_IMPORTED; + } - @Override - public boolean hasSubstep(PsiMethod selectedValue) { - return true; - } - - @NotNull - @Override - public String getTextFor(PsiMethod value) { - return ObjectUtils.assertNotNull(value.getName()); - } - - @Override - public Icon getIconFor(PsiMethod aValue) { - return aValue.getIcon(0); - } - }; - - final ListPopupImpl popup = new ListPopupImpl(step) { - final PopupListElementRenderer rightArrow = new PopupListElementRenderer(this); - @Override - protected ListCellRenderer getListElementRenderer() { - return new MethodCellRenderer(true, PsiFormatUtilBase.SHOW_NAME){ - - @Nullable - @Override - protected TextAttributes getNavigationItemAttributes(Object value) { - TextAttributes attrs = super.getNavigationItemAttributes(value); - if (value instanceof PsiMethod && !((PsiMethod)value).isDeprecated()) { - PsiClass psiClass = ((PsiMethod)value).getContainingClass(); - if (psiClass != null && psiClass.isDeprecated()) { - return TextAttributes.merge(attrs, super.getNavigationItemAttributes(psiClass)); - } - } - return attrs; - } - - @Override - protected DefaultListCellRenderer getRightCellRenderer(final Object value) { - final DefaultListCellRenderer moduleRenderer = super.getRightCellRenderer(value); - return new DefaultListCellRenderer(){ - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - JPanel panel = new JPanel(new BorderLayout()); - if (moduleRenderer != null) { - Component moduleComponent = moduleRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (!isSelected) { - moduleComponent.setBackground(getBackgroundColor(value)); - } - panel.add(moduleComponent, BorderLayout.CENTER); - } - rightArrow.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - Component rightArrowComponent = rightArrow.getNextStepLabel(); - panel.add(rightArrowComponent, BorderLayout.EAST); - return panel; - } - }; - } - }; - } - }; - popup.showInBestPositionFor(editor); + String hintText = ShowAutoImportPass.getMessage(candidates.size() > 1, getMethodPresentableText()); + if (!ApplicationManager.getApplication().isUnitTestMode() && !HintManager.getInstance().hasShownHintsThatWillHideByOtherHint(true)) { + final PsiMethodCallExpression element = myMethodCall.getElement(); + final TextRange textRange = element.getTextRange(); + HintManager.getInstance().showQuestionHint(editor, hintText, + textRange.getStartOffset(), + textRange.getEndOffset(), action); + } + return ImportClassFixBase.Result.POPUP_SHOWN; } @Override public boolean startInWriteAction() { - return true; + return false; + } + + @Override + public boolean showHint(@NotNull Editor editor) { + final PsiMethodCallExpression callExpression = myMethodCall.getElement(); + if (callExpression == null || callExpression.getMethodExpression().getQualifierExpression() != null) { + return false; + } + ImportClassFixBase.Result result = doFix(editor); + return result == ImportClassFixBase.Result.POPUP_SHOWN || result == ImportClassFixBase.Result.CLASS_AUTO_IMPORTED; } } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodQuestionAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodQuestionAction.java new file mode 100644 index 000000000000..4f83e31e79ed --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMethodQuestionAction.java @@ -0,0 +1,217 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.daemon.impl.quickfix; + +import com.intellij.codeInsight.daemon.QuickFixBundle; +import com.intellij.codeInsight.daemon.impl.actions.AddImportAction; +import com.intellij.codeInsight.hint.QuestionAction; +import com.intellij.codeInsight.intention.impl.AddSingleMemberStaticImportAction; +import com.intellij.ide.util.MethodCellRenderer; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiFormatUtilBase; +import com.intellij.psi.util.PsiUtil; +import com.intellij.ui.popup.list.ListPopupImpl; +import com.intellij.ui.popup.list.PopupListElementRenderer; +import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ObjectUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.util.List; + +public class StaticImportMethodQuestionAction implements QuestionAction { + private static final Logger LOG = Logger.getInstance("#" + StaticImportMethodQuestionAction.class.getName()); + private final Project myProject; + private final Editor myEditor; + private List myCandidates; + private final SmartPsiElementPointer myMethodCall; + + public StaticImportMethodQuestionAction(Project project, + Editor editor, + List candidates, + SmartPsiElementPointer methodCall) { + myProject = project; + myEditor = editor; + myCandidates = candidates; + myMethodCall = methodCall; + } + + @Override + public boolean execute() { + PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + + final PsiMethodCallExpression element = myMethodCall.getElement(); + if (element == null || !element.isValid()){ + return false; + } + + for (PsiMethod targetMethod : myCandidates) { + if (!targetMethod.isValid()) { + return false; + } + } + + if (myCandidates.size() == 1){ + doImport(myCandidates.get(0)); + } + else{ + chooseAndImport(myEditor, myProject); + } + return true; + } + + private void doImport(final PsiMethod toImport) { + final Project project = toImport.getProject(); + CommandProcessor.getInstance().executeCommand(project, new Runnable(){ + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + try { + PsiMethodCallExpression element = myMethodCall.getElement(); + if (element != null) { + AddSingleMemberStaticImportAction.bindAllClassRefs(element.getContainingFile(), toImport, toImport.getName(), toImport.getContainingClass()); + } + } + catch (IncorrectOperationException e) { + LOG.error(e); + } + } + }); + + } + }, QuickFixBundle.message("add.import"), this); + + } + + private void chooseAndImport(final Editor editor, final Project project) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + doImport(myCandidates.get(0)); + return; + } + final BaseListPopupStep step = + new BaseListPopupStep(QuickFixBundle.message("method.to.import.chooser.title"), myCandidates) { + + @Override + public PopupStep onChosen(PsiMethod selectedValue, boolean finalChoice) { + if (selectedValue == null) { + return FINAL_CHOICE; + } + + if (finalChoice) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + LOG.assertTrue(selectedValue.isValid()); + doImport(selectedValue); + return FINAL_CHOICE; + } + + String qname = PsiUtil.getMemberQualifiedName(selectedValue); + if (qname == null) return FINAL_CHOICE; + List excludableStrings = AddImportAction.getAllExcludableStrings(qname); + return new BaseListPopupStep(null, excludableStrings) { + @NotNull + @Override + public String getTextFor(String value) { + return "Exclude '" + value + "' from auto-import"; + } + + @Override + public PopupStep onChosen(String selectedValue, boolean finalChoice) { + if (finalChoice) { + AddImportAction.excludeFromImport(project, selectedValue); + } + + return super.onChosen(selectedValue, finalChoice); + } + }; + } + + @Override + public boolean hasSubstep(PsiMethod selectedValue) { + return true; + } + + @NotNull + @Override + public String getTextFor(PsiMethod value) { + return ObjectUtils.assertNotNull(value.getName()); + } + + @Override + public Icon getIconFor(PsiMethod aValue) { + return aValue.getIcon(0); + } + }; + + final ListPopupImpl popup = new ListPopupImpl(step) { + final PopupListElementRenderer rightArrow = new PopupListElementRenderer(this); + @Override + protected ListCellRenderer getListElementRenderer() { + return new MethodCellRenderer(true, PsiFormatUtilBase.SHOW_NAME){ + + @Nullable + @Override + protected TextAttributes getNavigationItemAttributes(Object value) { + TextAttributes attrs = super.getNavigationItemAttributes(value); + if (value instanceof PsiMethod && !((PsiMethod)value).isDeprecated()) { + PsiClass psiClass = ((PsiMethod)value).getContainingClass(); + if (psiClass != null && psiClass.isDeprecated()) { + return TextAttributes.merge(attrs, super.getNavigationItemAttributes(psiClass)); + } + } + return attrs; + } + + @Override + protected DefaultListCellRenderer getRightCellRenderer(final Object value) { + final DefaultListCellRenderer moduleRenderer = super.getRightCellRenderer(value); + return new DefaultListCellRenderer(){ + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JPanel panel = new JPanel(new BorderLayout()); + if (moduleRenderer != null) { + Component moduleComponent = moduleRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (!isSelected) { + moduleComponent.setBackground(getBackgroundColor(value)); + } + panel.add(moduleComponent, BorderLayout.CENTER); + } + rightArrow.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + Component rightArrowComponent = rightArrow.getNextStepLabel(); + panel.add(rightArrowComponent, BorderLayout.EAST); + return panel; + } + }; + } + }; + } + }; + popup.showInBestPositionFor(editor); + } +} + + diff --git a/platform/built-in-server/built-in-server-tests.iml b/platform/built-in-server/built-in-server-tests.iml index af9d31a88f4a..1ee2004f04e2 100644 --- a/platform/built-in-server/built-in-server-tests.iml +++ b/platform/built-in-server/built-in-server-tests.iml @@ -22,6 +22,5 @@ - \ No newline at end of file diff --git a/platform/built-in-server/built-in-server.iml b/platform/built-in-server/built-in-server.iml index 383652bc7ca0..a49a37419e3b 100644 --- a/platform/built-in-server/built-in-server.iml +++ b/platform/built-in-server/built-in-server.iml @@ -5,6 +5,7 @@ + diff --git a/platform/built-in-server/client/.gitignore b/platform/built-in-server/client/.gitignore index 40b878db5b1c..fee741232909 100644 --- a/platform/built-in-server/client/.gitignore +++ b/platform/built-in-server/client/.gitignore @@ -1 +1,3 @@ -node_modules/ \ No newline at end of file +node_modules/ +npm-debug.log +out/ \ No newline at end of file diff --git a/platform/built-in-server/client/node-rpc-client/gulpfile.js b/platform/built-in-server/client/node-rpc-client/gulpfile.js deleted file mode 100644 index ea4c5ed0e837..000000000000 --- a/platform/built-in-server/client/node-rpc-client/gulpfile.js +++ /dev/null @@ -1,42 +0,0 @@ -var gulp = require('gulp') -var ts = require('gulp-typescript') -var concat = require('gulp-concat') -var uglify = require('gulp-uglify') -var newer = require('gulp-newer') -var sourcemaps = require('gulp-sourcemaps') -var path = require('path') - -var outDir = 'out' -var outFile = 'ij-rpc-client.js' -var sources = "src/*.ts"; - -var tsProject = ts.createProject({ - target: "ES5", - noImplicitAny: true, - removeComments: true, - sortOutput: true, - module: "commonjs" -}); - -gulp.task("compile", function () { - var tsResult = gulp.src(sources) - .pipe(sourcemaps.init()) - //.pipe(newer(outDir + '/' + outFile)) - .pipe(ts(tsProject)); - - tsResult.js.pipe(concat(outFile)) - //.pipe(uglify({ - // output: { - // beautify: true, - // indent_level: 2 - // } - // })) - .pipe(sourcemaps.write('.', {includeContent: false, sourceRoot: path.resolve('testData')})) - .pipe(gulp.dest(outDir)) -}); - -gulp.task('watch', function () { - gulp.watch(sources, ['compile']); -}); - -gulp.task('default', ['compile']); \ No newline at end of file diff --git a/platform/built-in-server/client/node-rpc-client/node-rpc-client.iml b/platform/built-in-server/client/node-rpc-client/node-rpc-client.iml new file mode 100644 index 000000000000..80cc7391bd40 --- /dev/null +++ b/platform/built-in-server/client/node-rpc-client/node-rpc-client.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/platform/built-in-server/client/node-rpc-client/package.json b/platform/built-in-server/client/node-rpc-client/package.json index 862a64057dac..2f5c4fbc836d 100644 --- a/platform/built-in-server/client/node-rpc-client/package.json +++ b/platform/built-in-server/client/node-rpc-client/package.json @@ -2,16 +2,21 @@ "name": "ij-rpc-client", "version": "0.0.1", "description": "IntelliJ Platform RPC client", + "scripts": { + "compile": "rimraf app/out && tsconfig -i 2 && tsc", + "test": "mocha --harmony_default_parameters --harmony_rest_parameters" + }, "repository": { "type": "git", "url": "https://github.com/JetBrains/intellij-community.git" }, "devDependencies": { - "gulp": "^3.8.11", - "gulp-concat": "^2.4.3", - "gulp-newer": "^0.5.0", - "gulp-sourcemaps": "^1.3.0", - "gulp-typescript": "^2.4.2", - "gulp-uglify": "^1.1.0" + "rimraf": "^2.5.0", + "should": "^8.0.2", + "tsconfig-glob": "^0.3.3", + "typescript": "^1.8.0-dev.20151231" + }, + "dependencies": { + "bluebird": "^3.1.1" } } diff --git a/platform/built-in-server/client/node-rpc-client/src/rpc-client.ts b/platform/built-in-server/client/node-rpc-client/src/rpc-client.ts index b8425f3ee9d6..45343ddd758c 100644 --- a/platform/built-in-server/client/node-rpc-client/src/rpc-client.ts +++ b/platform/built-in-server/client/node-rpc-client/src/rpc-client.ts @@ -1,82 +1,98 @@ -"use strict" - -import net = require("net") -import rpc = require("./rpc") +import * as net from "net" +import { JsonRpc, Transport } from "./rpc" export class RpcClient { - connect(port:Number = 63342) { - var socket = net.connect({port: port}, function () { - console.log('Connected to IJ RPC server localhost:' + port) - }); + connect(port: number = 63342) { + const socket = net.connect({port: port}, () => { + console.log("Connected to IJ RPC server localhost: " + port) + }) - var jsonRpc = new rpc.JsonRpc(new SocketTransport(socket)) - var decoder:MessageDecoder = new MessageDecoder(jsonRpc.messageReceived) - socket.on('data', decoder.messageReceived) + const transport = new SocketTransport(socket) + const jsonRpc = new JsonRpc(transport) + const decoder = new MessageDecoder(jsonRpc.messageReceived) + socket.on("data", decoder.messageReceived) } } const enum State {LENGTH, CONTENT} -class SocketTransport implements rpc.Transport { +export class SocketTransport implements Transport { private headerBuffer = new Buffer(4) - constructor(private socket:net.Socket) { + opened: () => void + + constructor(private socket: net.Socket = new net.Socket()) { } - send(id:number, domain:string, command:string, params:any[] = null):void { - var encodedParams = JSON.stringify(params) - var header = (id == -1 ? '' : (id + ', ')) + '"' + domain + '", "' + command + '"'; - this.headerBuffer.writeUInt32BE(Buffer.byteLength(encodedParams) + header.length, 0) + connect(port: number = 63342) { + this.socket.connect(port, null, ()=> { + const opened = this.opened + if (opened != null) { + opened() + } + }) + this.socket.on("error", (e: Error) => { + console.error(e) + }) + this.socket.write(new Buffer([67, 72, 105, -107, 126, -21, -81, -72, 64, 54, -87, -88, 0, -46, -48, 34, -7, -67])) + } + + send(id: number, domain: string, command: string, params: any[] = null): void { + const encodedParams = JSON.stringify(params) + const header = (id == -1 ? '' : (id + ', ')) + '"' + domain + '", "' + command + '"'; + this.headerBuffer.writeUInt32BE(header.length + Buffer.byteLength(encodedParams), 0) this.socket.write(this.headerBuffer) - this.socket.write(encodedParams, 'utf-8') + this.socket.write(header) + this.socket.write(encodedParams) } - sendResult(id:number, result:any):void { + sendResult(id: number, result: any): void { this.sendResultOrError(id, result, false) } - sendError(id:number, error:any):void { + sendError(id: number, error: any): void { this.sendResultOrError(id, error, true) } - private sendResultOrError(id:number, result:any, isError:boolean):void { + private sendResultOrError(id: number, result: any, isError: boolean): void { var encodedResult = JSON.stringify(result) - var header = id + ', "' + (isError ? 'e': 'r') + '"'; + var header = id + ', "' + (isError ? 'e' : 'r') + '"'; this.headerBuffer.writeUInt32BE(Buffer.byteLength(encodedResult) + header.length, 0) this.socket.write(this.headerBuffer) - this.socket.write(encodedResult, 'utf-8') + this.socket.write(encodedResult) } } class MessageDecoder { - private state:State = State.LENGTH - private contentLength:number = 0 + private state: State = State.LENGTH + private contentLength: number = 0 - private buffers:Array = [] - private totalBufferLength:number = 0 - private offset:number = 0 + private buffers: Array = [] + private totalBufferLength: number = 0 + private offset: number = 0 - constructor(private messageProcessor:(message:any)=>void) { + constructor(private messageProcessor: (message: any)=>void) { } - private byteConsumed(count:number) { + private byteConsumed(count: number) { this.offset += count this.totalBufferLength -= count } - messageReceived(buffer:Buffer) { + messageReceived(buffer: Buffer) { this.totalBufferLength += buffer.length while (true) { //noinspection FallThroughInSwitchStatementJS switch (this.state) { - case State.LENGTH: { + case State.LENGTH: + { if (this.totalBufferLength < 4) { this.buffers.push(buffer) return } - var totalBuffer:Buffer + var totalBuffer: Buffer if (this.buffers.length === 0) { totalBuffer = buffer } @@ -92,13 +108,14 @@ class MessageDecoder { buffer = totalBuffer } - case State.CONTENT: { + case State.CONTENT: + { if (this.totalBufferLength < this.contentLength) { this.buffers.push(buffer) return } - var totalBuffer:Buffer + var totalBuffer: Buffer if (this.buffers.length === 0) { totalBuffer = buffer } diff --git a/platform/built-in-server/client/node-rpc-client/src/rpc.ts b/platform/built-in-server/client/node-rpc-client/src/rpc.ts index c7a54193f663..7aba41a980da 100644 --- a/platform/built-in-server/client/node-rpc-client/src/rpc.ts +++ b/platform/built-in-server/client/node-rpc-client/src/rpc.ts @@ -1,39 +1,39 @@ -/// -/// -"use strict" - import Promise = require("bluebird") class PromiseCallback { - constructor(public resolve:(value?:any) => void, public reject:(error?:any) => void) { + constructor(public resolve: (value?: any) => void, public reject: (error?: any) => void) { } } export interface Transport { - send(id:number, domain:string, command:string, params:any[]):void + opened?: () => void - sendResult(id:number, result:any):void + connect(port: number): void - sendError(id:number, error:any):void + send(id: number, domain: string, command: string, params: any[]): void + + sendResult(id: number, result: any):void + + sendError(id: number, error: any):void } export class JsonRpc { private messageIdCounter = 0 - private callbacks:Map = new Map() - private domains:Map = new Map() + private callbacks: Map = new Map() + private domains: Map = new Map() - constructor(private transport:Transport) { + constructor(private transport: Transport) { } - public call(domain:string, command:string, ...params: any[]):Promise { - return new Promise((resolve:(value:T) => void, reject:(error?:any) => void) => { + public call(domain: string, command: string, ...params: any[]): Promise { + return new Promise((resolve: (value: T) => void, reject: (error?: any) => void) => { var id = this.messageIdCounter++; this.callbacks.set(id, new PromiseCallback(resolve, reject)) this.transport.send(id, domain, command, params) }) } - messageReceived(message:Array) { + messageReceived(message: Array) { if (message.length === 1 || (message.length === 2 && !(typeof message[1] === 'string'))) { var promiseCallback = this.callbacks.get(message[0]) var singletonArray = safeGet(message, 1) @@ -45,8 +45,8 @@ export class JsonRpc { } } else { - var id:number - var offset:number + var id: number + var offset: number if (typeof message[0] === 'string') { id = -1 offset = 0 @@ -56,11 +56,11 @@ export class JsonRpc { offset = 1 } - var onRejected = id === -1 ? null : (error:any) => this.transport.sendError(id, error) + var onRejected = id === -1 ? null : (error: any) => this.transport.sendError(id, error) try { var object = this.domains.get(message[offset]) var method = object[message[offset + 1]] - var result:any + var result: any var args = safeGet(message, offset + 2) if (args === null) { result = method.call(object) @@ -70,7 +70,7 @@ export class JsonRpc { } if (id !== -1) { - var onFulfilled = (result:any) => this.transport.sendResult(id, result) + var onFulfilled = (result: any) => this.transport.sendResult(id, result) if (result instanceof Promise) { (>result).done(onFulfilled, onRejected) } @@ -89,6 +89,6 @@ export class JsonRpc { } } -function safeGet(a:any[], index:number):Array { +function safeGet(a: any[], index: number): Array { return index < a.length ? a[index] : null } \ No newline at end of file diff --git a/platform/built-in-server/client/node-rpc-client/test/test.js b/platform/built-in-server/client/node-rpc-client/test/test.js new file mode 100644 index 000000000000..5fa4efa3f6cc --- /dev/null +++ b/platform/built-in-server/client/node-rpc-client/test/test.js @@ -0,0 +1,30 @@ +const should = require("should") +const rpcClient = require("../out/rpc-client") +const rpc = require("../out/rpc") + +describe("RPC", function () { + it("connect", function (done) { + const transport = new rpcClient.SocketTransport() + transport.opened = function () { + done() + } + transport.connect() + }) + it("connect", function (done) { + this.timeout(5000000) + + const transport = new rpcClient.SocketTransport() + transport.opened = function () { + } + transport.connect(63343) + + const rpcServer = new rpc.JsonRpc(transport) + rpcServer.call("Ide", "about") + .then(function (r) { + console.log(r) + done() + }, function (e) { + throw e + }) + }) +}) \ No newline at end of file diff --git a/platform/built-in-server/client/node-rpc-client/tsconfig.json b/platform/built-in-server/client/node-rpc-client/tsconfig.json new file mode 100644 index 000000000000..c7a0c1aa243f --- /dev/null +++ b/platform/built-in-server/client/node-rpc-client/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "removeComments": true, + "outDir": "out", + "newLine": "LF", + "noResolve": true, + "noEmitOnError": true, + "inlineSources": true, + "sourceMap": true + }, + "filesGlob": [ + "src/*.ts", + "typings/**/*.d.ts" + ], + "files": [ + "typings/bluebird/bluebird.d.ts", + "typings/node/node.d.ts", + "src/rpc-client.ts", + "src/rpc.ts" + ] +} diff --git a/platform/built-in-server/client/node-rpc-client/tsd.json b/platform/built-in-server/client/node-rpc-client/tsd.json index c5e6b3b94da0..924203dfa87c 100644 --- a/platform/built-in-server/client/node-rpc-client/tsd.json +++ b/platform/built-in-server/client/node-rpc-client/tsd.json @@ -3,13 +3,12 @@ "repo": "borisyankov/DefinitelyTyped", "ref": "master", "path": "typings", - "bundle": "typings/tsd.d.ts", "installed": { "node/node.d.ts": { - "commit": "35fffaa44bff5392741b3022d805fe3563023a3d" + "commit": "dc9dabe74a5be62613b17a3605309783a12ff28a" }, "bluebird/bluebird.d.ts": { - "commit": "cf7c97b2a68a385c98c75fb6edd81083c97c983c" + "commit": "dc9dabe74a5be62613b17a3605309783a12ff28a" } } } diff --git a/platform/built-in-server/client/node-rpc-client/typings/bluebird/bluebird.d.ts b/platform/built-in-server/client/node-rpc-client/typings/bluebird/bluebird.d.ts index 93c81138a8ef..ea8bebe0c2b9 100644 --- a/platform/built-in-server/client/node-rpc-client/typings/bluebird/bluebird.d.ts +++ b/platform/built-in-server/client/node-rpc-client/typings/bluebird/bluebird.d.ts @@ -1,6 +1,6 @@ // Type definitions for bluebird 2.0.0 // Project: https://github.com/petkaantonov/bluebird -// Definitions by: Bart van der Schoor +// Definitions by: Bart van der Schoor , falsandtru // Definitions: https://github.com/borisyankov/DefinitelyTyped // ES6 model with generics overload was sourced and trans-multiplied from es6-promises.d.ts @@ -16,695 +16,766 @@ // TODO verify support to have no return statement in handlers to get a Promise (more overloads?) -declare class Promise implements Promise.Thenable, Promise.Inspection { - /** - * Create a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise. - */ - constructor(callback: (resolve: (thenable: Promise.Thenable) => void, reject: (error: any) => void) => void); - constructor(callback: (resolve: (result: R) => void, reject: (error: any) => void) => void); - - /** - * Promises/A+ `.then()` with progress handler. Returns a new promise chained from this promise. The new promise will be rejected or resolved dedefer on the passed `fulfilledHandler`, `rejectedHandler` and the state of this promise. - */ - then(onFulfill: (value: R) => Promise.Thenable, onReject: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): Promise; - then(onFulfill: (value: R) => Promise.Thenable, onReject?: (error: any) => U, onProgress?: (note: any) => any): Promise; - then(onFulfill: (value: R) => U, onReject: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): Promise; - then(onFulfill?: (value: R) => U, onReject?: (error: any) => U, onProgress?: (note: any) => any): Promise; - - /** - * This is a catch-all exception handler, shortcut for calling `.then(null, handler)` on this promise. Any exception happening in a `.then`-chain will propagate to nearest `.catch` handler. - * - * Alias `.caught();` for compatibility with earlier ECMAScript version. - */ - catch(onReject?: (error: any) => Promise.Thenable): Promise; - caught(onReject?: (error: any) => Promise.Thenable): Promise; - - catch(onReject?: (error: any) => U): Promise; - caught(onReject?: (error: any) => U): Promise; - - /** - * This extends `.catch` to work more like catch-clauses in languages like Java or C#. Instead of manually checking `instanceof` or `.name === "SomeError"`, you may specify a number of error constructors which are eligible for this catch handler. The catch handler that is first met that has eligible constructors specified, is the one that will be called. - * - * This method also supports predicate-based filters. If you pass a predicate function instead of an error constructor, the predicate will receive the error as an argument. The return result of the predicate will be used determine whether the error handler should be called. - * - * Alias `.caught();` for compatibility with earlier ECMAScript version. - */ - catch(predicate: (error: any) => boolean, onReject: (error: any) => Promise.Thenable): Promise; - caught(predicate: (error: any) => boolean, onReject: (error: any) => Promise.Thenable): Promise; - - catch(predicate: (error: any) => boolean, onReject: (error: any) => U): Promise; - caught(predicate: (error: any) => boolean, onReject: (error: any) => U): Promise; - - catch(ErrorClass: Function, onReject: (error: any) => Promise.Thenable): Promise; - caught(ErrorClass: Function, onReject: (error: any) => Promise.Thenable): Promise; - - catch(ErrorClass: Function, onReject: (error: any) => U): Promise; - caught(ErrorClass: Function, onReject: (error: any) => U): Promise; - - /** - * Like `.catch` but instead of catching all types of exceptions, it only catches those that don't originate from thrown errors but rather from explicit rejections. - */ - error(onReject: (reason: any) => Promise.Thenable): Promise; - error(onReject: (reason: any) => U): Promise; - - /** - * Pass a handler that will be called regardless of this promise's fate. Returns a new promise chained from this promise. There are special semantics for `.finally()` in that the final value cannot be modified from the handler. - * - * Alias `.lastly();` for compatibility with earlier ECMAScript version. - */ - finally(handler: () => Promise.Thenable): Promise; - finally(handler: () => U): Promise; - - lastly(handler: () => Promise.Thenable): Promise; - lastly(handler: () => U): Promise; - - /** - * Create a promise that follows this promise, but is bound to the given `thisArg` value. A bound promise will call its handlers with the bound value set to `this`. Additionally promises derived from a bound promise will also be bound promises with the same `thisArg` binding as the original promise. - */ - bind(thisArg: any): Promise; - - /** - * Like `.then()`, but any unhandled rejection that ends up here will be thrown as an error. - */ - done(onFulfilled: (value: R) => Promise.Thenable, onRejected: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): void; - done(onFulfilled: (value: R) => Promise.Thenable, onRejected?: (error: any) => U, onProgress?: (note: any) => any): void; - done(onFulfilled: (value: R) => U, onRejected: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): void; - done(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U, onProgress?: (note: any) => any): void; - - /** - * Like `.finally()`, but not called for rejections. - */ - tap(onFulFill: (value: R) => Promise.Thenable): Promise; - tap(onFulfill: (value: R) => U): Promise; - - /** - * Shorthand for `.then(null, null, handler);`. Attach a progress handler that will be called if this promise is progressed. Returns a new promise chained from this promise. - */ - progressed(handler: (note: any) => any): Promise; - - /** - * Same as calling `Promise.delay(this, ms)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - delay(ms: number): Promise; - - /** - * Returns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. However, if this promise is not fulfilled or rejected within `ms` milliseconds, the returned promise is rejected with a `Promise.TimeoutError` instance. - * - * You may specify a custom error message with the `message` parameter. - */ - timeout(ms: number, message?: string): Promise; - - /** - * Register a node-style callback on this promise. When this promise is is either fulfilled or rejected, the node callback will be called back with the node.js convention where error reason is the first argument and success value is the second argument. The error argument will be `null` in case of success. - * Returns back this promise instead of creating a new one. If the `callback` argument is not a function, this method does not do anything. - */ - nodeify(callback: (err: any, value?: R) => void): Promise; - nodeify(...sink: any[]): void; - - /** - * Marks this promise as cancellable. Promises by default are not cancellable after v0.11 and must be marked as such for `.cancel()` to have any effect. Marking a promise as cancellable is infectious and you don't need to remark any descendant promise. - */ - cancellable(): Promise; - - /** - * Cancel this promise. The cancellation will propagate to farthest cancellable ancestor promise which is still pending. - * - * That ancestor will then be rejected with a `CancellationError` (get a reference from `Promise.CancellationError`) object as the rejection reason. - * - * In a promise rejection handler you may check for a cancellation by seeing if the reason object has `.name === "Cancel"`. - * - * Promises are by default not cancellable. Use `.cancellable()` to mark a promise as cancellable. - */ - // TODO what to do with this? - cancel(): Promise; - - /** - * Like `.then()`, but cancellation of the the returned promise or any of its descendant will not propagate cancellation to this promise or this promise's ancestors. - */ - fork(onFulfilled: (value: R) => Promise.Thenable, onRejected: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): Promise; - fork(onFulfilled: (value: R) => Promise.Thenable, onRejected?: (error: any) => U, onProgress?: (note: any) => any): Promise; - fork(onFulfilled: (value: R) => U, onRejected: (error: any) => Promise.Thenable, onProgress?: (note: any) => any): Promise; - fork(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U, onProgress?: (note: any) => any): Promise; - - /** - * Create an uncancellable promise based on this promise. - */ - uncancellable(): Promise; - - /** - * See if this promise can be cancelled. - */ - isCancellable(): boolean; - - /** - * See if this `promise` has been fulfilled. - */ - isFulfilled(): boolean; - - /** - * See if this `promise` has been rejected. - */ - isRejected(): boolean; - - /** - * See if this `promise` is still defer. - */ - isPending(): boolean; - - /** - * See if this `promise` is resolved -> either fulfilled or rejected. - */ - isResolved(): boolean; - - /** - * Get the fulfillment value of the underlying promise. Throws if the promise isn't fulfilled yet. - * - * throws `TypeError` - */ - value(): R; - - /** - * Get the rejection reason for the underlying promise. Throws if the promise isn't rejected yet. - * - * throws `TypeError` - */ - reason(): any; - - /** - * Synchronously inspect the state of this `promise`. The `PromiseInspection` will represent the state of the promise as snapshotted at the time of calling `.inspect()`. - */ - inspect(): Promise.Inspection; - - /** - * This is a convenience method for doing: - * - * - * promise.then(function(obj){ - * return obj[propertyName].call(obj, arg...); - * }); - * - */ - call(propertyName: string, ...args: any[]): Promise; - - /** - * This is a convenience method for doing: - * - * - * promise.then(function(obj){ - * return obj[propertyName]; - * }); - * - */ - // TODO find way to fix get() - // get(propertyName: string): Promise; - - /** - * Convenience method for: - * - * - * .then(function() { - * return value; - * }); - * - * - * in the case where `value` doesn't change its value. That means `value` is bound at the time of calling `.return()` - * - * Alias `.thenReturn();` for compatibility with earlier ECMAScript version. - */ - return(): Promise; - thenReturn(): Promise; - return(value: U): Promise; - thenReturn(value: U): Promise; - - /** - * Convenience method for: - * - * - * .then(function() { - * throw reason; - * }); - * - * Same limitations apply as with `.return()`. - * - * Alias `.thenThrow();` for compatibility with earlier ECMAScript version. - */ - throw(reason: Error): Promise; - thenThrow(reason: Error): Promise; - - /** - * Convert to String. - */ - toString(): string; - - /** - * This is implicitly called by `JSON.stringify` when serializing the object. Returns a serialized representation of the `Promise`. - */ - toJSON(): Object; - - /** - * Like calling `.then`, but the fulfillment value or rejection reason is assumed to be an array, which is flattened to the formal parameters of the handlers. - */ - // TODO how to model instance.spread()? like Q? - spread(onFulfill: Function, onReject?: (reason: any) => Promise.Thenable): Promise; - spread(onFulfill: Function, onReject?: (reason: any) => U): Promise; - /* - // TODO or something like this? - spread(onFulfill: (...values: W[]) => Promise.Thenable, onReject?: (reason: any) => Promise.Thenable): Promise; - spread(onFulfill: (...values: W[]) => Promise.Thenable, onReject?: (reason: any) => U): Promise; - spread(onFulfill: (...values: W[]) => U, onReject?: (reason: any) => Promise.Thenable): Promise; - spread(onFulfill: (...values: W[]) => U, onReject?: (reason: any) => U): Promise; - */ - /** - * Same as calling `Promise.all(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - all(): Promise; - - /** - * Same as calling `Promise.props(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO how to model instance.props()? - props(): Promise; - - /** - * Same as calling `Promise.settle(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - settle(): Promise[]>; - - /** - * Same as calling `Promise.any(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - any(): Promise; - - /** - * Same as calling `Promise.some(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - some(count: number): Promise; - - /** - * Same as calling `Promise.race(thisPromise, count)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - race(): Promise; - - /** - * Same as calling `Promise.map(thisPromise, mapper)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - map(mapper: (item: Q, index: number, arrayLength: number) => Promise.Thenable): Promise; - map(mapper: (item: Q, index: number, arrayLength: number) => U): Promise; - - /** - * Same as calling `Promise.reduce(thisPromise, Function reducer, initialValue)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => Promise.Thenable, initialValue?: U): Promise; - reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => U, initialValue?: U): Promise; - - /** - * Same as calling ``Promise.filter(thisPromise, filterer)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. - */ - // TODO type inference from array-resolving promise? - filter(filterer: (item: U, index: number, arrayLength: number) => Promise.Thenable): Promise; - filter(filterer: (item: U, index: number, arrayLength: number) => boolean): Promise; - - /** - * Start the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise. - * - * Note about second argument: if it's specifically a true array, its values become respective arguments for the function call. Otherwise it is passed as is as the first argument for the function call. - * - * Alias for `attempt();` for compatibility with earlier ECMAScript version. - */ - static try(fn: () => Promise.Thenable, args?: any[], ctx?: any): Promise; - static try(fn: () => R, args?: any[], ctx?: any): Promise; - - static attempt(fn: () => Promise.Thenable, args?: any[], ctx?: any): Promise; - static attempt(fn: () => R, args?: any[], ctx?: any): Promise; - - /** - * Returns a new function that wraps the given function `fn`. The new function will always return a promise that is fulfilled with the original functions return values or rejected with thrown exceptions from the original function. - * This method is convenient when a function can sometimes return synchronously or throw synchronously. - */ - static method(fn: Function): Function; - - /** - * Create a promise that is resolved with the given `value`. If `value` is a thenable or promise, the returned promise will assume its state. - */ - static resolve(): Promise; - static resolve(value: Promise.Thenable): Promise; - static resolve(value: R): Promise; - - /** - * Create a promise that is rejected with the given `reason`. - */ - static reject(reason: any): Promise; - static reject(reason: any): Promise; - - /** - * Create a promise with undecided fate and return a `PromiseResolver` to control it. See resolution?: Promise(#promise-resolution). - */ - static defer(): Promise.Resolver; - - /** - * Cast the given `value` to a trusted promise. If `value` is already a trusted `Promise`, it is returned as is. If `value` is not a thenable, a fulfilled is: Promise returned with `value` as its fulfillment value. If `value` is a thenable (Promise-like object, like those returned by jQuery's `$.ajax`), returns a trusted that: Promise assimilates the state of the thenable. - */ - static cast(value: Promise.Thenable): Promise; - static cast(value: R): Promise; - - /** - * Sugar for `Promise.resolve(undefined).bind(thisArg);`. See `.bind()`. - */ - static bind(thisArg: any): Promise; - - /** - * See if `value` is a trusted Promise. - */ - static is(value: any): boolean; - - /** - * Call this right after the library is loaded to enabled long stack traces. Long stack traces cannot be disabled after being enabled, and cannot be enabled after promises have alread been created. Long stack traces imply a substantial performance penalty, around 4-5x for throughput and 0.5x for latency. - */ - static longStackTraces(): void; - - /** - * Returns a promise that will be fulfilled with `value` (or `undefined`) after given `ms` milliseconds. If `value` is a promise, the delay will start counting down when it is fulfilled and the returned promise will be fulfilled with the fulfillment value of the `value` promise. - */ - // TODO enable more overloads - static delay(value: Promise.Thenable, ms: number): Promise; - static delay(value: R, ms: number): Promise; - static delay(ms: number): Promise; - - /** - * Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. - * - * If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. - * - * If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. - */ - // TODO how to model promisify? - static promisify(nodeFunction: Function, receiver?: any): Function; - - /** - * Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. - * - * Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. - */ - // TODO how to model promisifyAll? - static promisifyAll(target: Object): Object; - - /** - * Returns a function that can use `yield` to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. - */ - // TODO fix coroutine GeneratorFunction - static coroutine(generatorFunction: Function): Function; - - /** - * Spawn a coroutine which may yield promises to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. - */ - // TODO fix spawn GeneratorFunction - static spawn(generatorFunction: Function): Promise; - - /** - * This is relevant to browser environments with no module loader. - * - * Release control of the `Promise` namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else. - */ - static noConflict(): typeof Promise; - - /** - * Add `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers. - * - * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. - */ - static onPossiblyUnhandledRejection(handler: (reason: any) => any): void; - - /** - * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason. - */ - // TODO enable more overloads - // promise of array with promises of value - static all(values: Promise.Thenable[]>): Promise; - // promise of array with values - static all(values: Promise.Thenable): Promise; - // array with promises of value - static all(values: Promise.Thenable[]): Promise; - // array with values - static all(values: R[]): Promise; - - /** - * Like ``Promise.all`` but for object properties instead of array items. Returns a promise that is fulfilled when all the properties of the object are fulfilled. The promise's fulfillment value is an object with fulfillment values at respective keys to the original object. If any promise in the object rejects, the returned promise is rejected with the rejection reason. - * - * If `object` is a trusted `Promise`, then it will be treated as a promise for object rather than for its properties. All other objects are treated for their properties as is returned by `Object.keys` - the object's own enumerable properties. - * - * *The original object is not modified.* - */ - // TODO verify this is correct - // trusted promise for object - static props(object: Promise): Promise; - // object - static props(object: Object): Promise; - - /** - * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are either fulfilled or rejected. The fulfillment value is an array of ``PromiseInspection`` instances at respective positions in relation to the input array. - * - * *original: The array is not modified. The input array sparsity is retained in the resulting array.* - */ - // promise of array with promises of value - static settle(values: Promise.Thenable[]>): Promise[]>; - // promise of array with values - static settle(values: Promise.Thenable): Promise[]>; - // array with promises of value - static settle(values: Promise.Thenable[]): Promise[]>; - // array with values - static settle(values: R[]): Promise[]>; - - /** - * Like `Promise.some()`, with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly. - */ - // promise of array with promises of value - static any(values: Promise.Thenable[]>): Promise; - // promise of array with values - static any(values: Promise.Thenable): Promise; - // array with promises of value - static any(values: Promise.Thenable[]): Promise; - // array with values - static any(values: R[]): Promise; - - /** - * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value. - * - * **Note** If you pass empty array or a sparse array with no values, or a promise/thenable for such, it will be forever pending. - */ - // promise of array with promises of value - static race(values: Promise.Thenable[]>): Promise; - // promise of array with values - static race(values: Promise.Thenable): Promise; - // array with promises of value - static race(values: Promise.Thenable[]): Promise; - // array with values - static race(values: R[]): Promise; - - /** - * Initiate a competetive race between multiple promises or values (values will become immediately fulfilled promises). When `count` amount of promises have been fulfilled, the returned promise is fulfilled with an array that contains the fulfillment values of the winners in order of resolution. - * - * If too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an array of rejection reasons in the order they were thrown in. - * - * *The original array is not modified.* - */ - // promise of array with promises of value - static some(values: Promise.Thenable[]>, count: number): Promise; - // promise of array with values - static some(values: Promise.Thenable, count: number): Promise; - // array with promises of value - static some(values: Promise.Thenable[], count: number): Promise; - // array with values - static some(values: R[], count: number): Promise; - - /** - * Like `Promise.all()` but instead of having to pass an array, the array is generated from the passed variadic arguments. - */ - // variadic array with promises of value - static join(...values: Promise.Thenable[]): Promise; - // variadic array with values - static join(...values: R[]): Promise; - - /** - * Map an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `mapper` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * If the `mapper` function returns promises or thenables, the returned promise will wait for all the mapped results to be resolved as well. - * - * *The original array is not modified.* - */ - // promise of array with promises of value - static map(values: Promise.Thenable[]>, mapper: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static map(values: Promise.Thenable[]>, mapper: (item: R, index: number, arrayLength: number) => U): Promise; - - // promise of array with values - static map(values: Promise.Thenable, mapper: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static map(values: Promise.Thenable, mapper: (item: R, index: number, arrayLength: number) => U): Promise; - - // array with promises of value - static map(values: Promise.Thenable[], mapper: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static map(values: Promise.Thenable[], mapper: (item: R, index: number, arrayLength: number) => U): Promise; - - // array with values - static map(values: R[], mapper: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static map(values: R[], mapper: (item: R, index: number, arrayLength: number) => U): Promise; - - /** - * Reduce an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `reducer` function with the signature `(total, current, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * If the reducer function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. - * - * *The original array is not modified. If no `intialValue` is given and the array doesn't contain at least 2 items, the callback will not be called and `undefined` is returned. If `initialValue` is given and the array doesn't have at least 1 item, `initialValue` is returned.* - */ - // promise of array with promises of value - static reduce(values: Promise.Thenable[]>, reducer: (total: U, current: R, index: number, arrayLength: number) => Promise.Thenable, initialValue?: U): Promise; - static reduce(values: Promise.Thenable[]>, reducer: (total: U, current: R, index: number, arrayLength: number) => U, initialValue?: U): Promise; - - // promise of array with values - static reduce(values: Promise.Thenable, reducer: (total: U, current: R, index: number, arrayLength: number) => Promise.Thenable, initialValue?: U): Promise; - static reduce(values: Promise.Thenable, reducer: (total: U, current: R, index: number, arrayLength: number) => U, initialValue?: U): Promise; - - // array with promises of value - static reduce(values: Promise.Thenable[], reducer: (total: U, current: R, index: number, arrayLength: number) => Promise.Thenable, initialValue?: U): Promise; - static reduce(values: Promise.Thenable[], reducer: (total: U, current: R, index: number, arrayLength: number) => U, initialValue?: U): Promise; - - // array with values - static reduce(values: R[], reducer: (total: U, current: R, index: number, arrayLength: number) => Promise.Thenable, initialValue?: U): Promise; - static reduce(values: R[], reducer: (total: U, current: R, index: number, arrayLength: number) => U, initialValue?: U): Promise; - - /** - * Filter an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `filterer` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. - * - * The return values from the filtered functions are coerced to booleans, with the exception of promises and thenables which are awaited for their eventual result. - * - * *The original array is not modified. - */ - // promise of array with promises of value - static filter(values: Promise.Thenable[]>, filterer: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static filter(values: Promise.Thenable[]>, filterer: (item: R, index: number, arrayLength: number) => boolean): Promise; - - // promise of array with values - static filter(values: Promise.Thenable, filterer: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static filter(values: Promise.Thenable, filterer: (item: R, index: number, arrayLength: number) => boolean): Promise; - - // array with promises of value - static filter(values: Promise.Thenable[], filterer: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static filter(values: Promise.Thenable[], filterer: (item: R, index: number, arrayLength: number) => boolean): Promise; - - // array with values - static filter(values: R[], filterer: (item: R, index: number, arrayLength: number) => Promise.Thenable): Promise; - static filter(values: R[], filterer: (item: R, index: number, arrayLength: number) => boolean): Promise; +declare var Promise: PromiseConstructor; + +interface PromiseConstructor { + /** + * Create a new promise. The passed in function will receive functions `resolve` and `reject` as its arguments which can be called to seal the fate of the created promise. + */ + new (callback: (resolve: (thenableOrResult?: T | PromiseLike) => void, reject: (error: any) => void) => void): Promise; + + // Ideally, we'd define e.g. "export class RangeError extends Error {}", + // but as Error is defined as an interface (not a class), TypeScript doesn't + // allow extending Error, only implementing it. + // However, if we want to catch() only a specific error type, we need to pass + // a constructor function to it. So, as a workaround, we define them here as such. + RangeError(): RangeError; + CancellationError(): Promise.CancellationError; + TimeoutError(): Promise.TimeoutError; + TypeError(): Promise.TypeError; + RejectionError(): Promise.RejectionError; + OperationalError(): Promise.OperationalError; + + /** + * Changes how bluebird schedules calls a-synchronously. + * + * @param scheduler Should be a function that asynchronously schedules + * the calling of the passed in function + */ + setScheduler(scheduler: (callback: (...args: any[]) => void) => void): void; + + /** + * Start the chain of promises with `Promise.try`. Any synchronous exceptions will be turned into rejections on the returned promise. + * + * Note about second argument: if it's specifically a true array, its values become respective arguments for the function call. Otherwise it is passed as is as the first argument for the function call. + * + * Alias for `attempt();` for compatibility with earlier ECMAScript version. + */ + try(fn: () => PromiseLike, args?: any[], ctx?: any): Promise; + try(fn: () => T, args?: any[], ctx?: any): Promise; + + attempt(fn: () => PromiseLike, args?: any[], ctx?: any): Promise; + attempt(fn: () => T, args?: any[], ctx?: any): Promise; + + /** + * Returns a new function that wraps the given function `fn`. The new function will always return a promise that is fulfilled with the original functions return values or rejected with thrown exceptions from the original function. + * This method is convenient when a function can sometimes return synchronously or throw synchronously. + */ + method(fn: Function): Function; + + /** + * Create a promise that is resolved with the given `value`. If `value` is a thenable or promise, the returned promise will assume its state. + */ + resolve(): Promise; + resolve(value: PromiseLike): Promise; + resolve(value: T): Promise; + + /** + * Create a promise that is rejected with the given `reason`. + */ + reject(reason: any): Promise; + reject(reason: any): Promise; + + /** + * Create a promise with undecided fate and return a `PromiseResolver` to control it. See resolution?: Promise(#promise-resolution). + */ + defer(): Promise.Resolver; + + /** + * Cast the given `value` to a trusted promise. If `value` is already a trusted `Promise`, it is returned as is. If `value` is not a thenable, a fulfilled is: Promise returned with `value` as its fulfillment value. If `value` is a thenable (Promise-like object, like those returned by jQuery's `$.ajax`), returns a trusted that: Promise assimilates the state of the thenable. + */ + cast(value: PromiseLike): Promise; + cast(value: T): Promise; + + /** + * Sugar for `Promise.resolve(undefined).bind(thisArg);`. See `.bind()`. + */ + bind(thisArg: any): Promise; + + /** + * See if `value` is a trusted Promise. + */ + is(value: any): boolean; + + /** + * Call this right after the library is loaded to enabled long stack traces. Long stack traces cannot be disabled after being enabled, and cannot be enabled after promises have alread been created. Long stack traces imply a substantial performance penalty, around 4-5x for throughput and 0.5x for latency. + */ + longStackTraces(): void; + + /** + * Returns a promise that will be fulfilled with `value` (or `undefined`) after given `ms` milliseconds. If `value` is a promise, the delay will start counting down when it is fulfilled and the returned promise will be fulfilled with the fulfillment value of the `value` promise. + */ + // TODO enable more overloads + delay(value: PromiseLike, ms: number): Promise; + delay(value: T, ms: number): Promise; + delay(ms: number): Promise; + + /** + * Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument. + * + * If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them. + * + * If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`. + */ + promisify(func: (callback: (err: any, result: T) => void) => void, receiver?: any): () => Promise; + promisify(func: (arg1: A1, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1) => Promise; + promisify(func: (arg1: A1, arg2: A2, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2) => Promise; + promisify(func: (arg1: A1, arg2: A2, arg3: A3, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3) => Promise; + promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3, arg4: A4) => Promise; + promisify(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => Promise; + promisify(nodeFunction: Function, receiver?: any): Function; + + /** + * Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain. The promisified method name will be the original method name postfixed with `Async`. Returns the input object. + * + * Note that the original methods on the object are not overwritten but new methods are created with the `Async`-postfix. For example, if you `promisifyAll()` the node.js `fs` object use `fs.statAsync()` to call the promisified `stat` method. + */ + // TODO how to model promisifyAll? + promisifyAll(target: Object, options?: Promise.PromisifyAllOptions): any; + + + /** + * Returns a promise that is resolved by a node style callback function. + */ + fromNode(resolver: (callback: (err: any, result?: any) => void) => void): Promise; + + /** + * Returns a function that can use `yield` to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. + */ + // TODO fix coroutine GeneratorFunction + coroutine(generatorFunction: Function): Function; + + /** + * Spawn a coroutine which may yield promises to run asynchronous code synchronously. This feature requires the support of generators which are drafted in the next version of the language. Node version greater than `0.11.2` is required and needs to be executed with the `--harmony-generators` (or `--harmony`) command-line switch. + */ + // TODO fix spawn GeneratorFunction + spawn(generatorFunction: Function): Promise; + + /** + * This is relevant to browser environments with no module loader. + * + * Release control of the `Promise` namespace to whatever it was before this library was loaded. Returns a reference to the library namespace so you can attach it to something else. + */ + noConflict(): typeof Promise; + + /** + * Add `handler` as the handler to call when there is a possibly unhandled rejection. The default handler logs the error stack to stderr or `console.error` in browsers. + * + * Passing no value or a non-function will have the effect of removing any kind of handling for possibly unhandled rejections. + */ + onPossiblyUnhandledRejection(handler: (reason: any) => any): void; + + /** + * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are fulfilled. The promise's fulfillment value is an array with fulfillment values at respective positions to the original array. If any promise in the array rejects, the returned promise is rejected with the rejection reason. + */ + // TODO enable more overloads + // promise of array with promises of value + all(values: PromiseLike[]>): Promise; + // promise of array with values + all(values: PromiseLike): Promise; + // array with promises of value + all(values: PromiseLike[]): Promise; + // array with promises of different types + all(values: [PromiseLike, PromiseLike]): Promise<[T1, T2]>; + all(values: [PromiseLike, PromiseLike, PromiseLike]): Promise<[T1, T2, T3]>; + all(values: [PromiseLike, PromiseLike, PromiseLike, PromiseLike]): Promise<[T1, T2, T3, T4]>; + all(values: [PromiseLike, PromiseLike, PromiseLike, PromiseLike, PromiseLike]): Promise<[T1, T2, T3, T4, T5]>; + // array with values + all(values: T[]): Promise; + + /** + * Like ``Promise.all`` but for object properties instead of array items. Returns a promise that is fulfilled when all the properties of the object are fulfilled. The promise's fulfillment value is an object with fulfillment values at respective keys to the original object. If any promise in the object rejects, the returned promise is rejected with the rejection reason. + * + * If `object` is a trusted `Promise`, then it will be treated as a promise for object rather than for its properties. All other objects are treated for their properties as is returned by `Object.keys` - the object's own enumerable properties. + * + * *The original object is not modified.* + */ + // TODO verify this is correct + // trusted promise for object + props(object: Promise): Promise; + // object + props(object: Object): Promise; + + /** + * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled when all the items in the array are either fulfilled or rejected. The fulfillment value is an array of ``PromiseInspection`` instances at respective positions in relation to the input array. + * + * *original: The array is not modified. The input array sparsity is retained in the resulting array.* + */ + // promise of array with promises of value + settle(values: PromiseLike[]>): Promise[]>; + // promise of array with values + settle(values: PromiseLike): Promise[]>; + // array with promises of value + settle(values: PromiseLike[]): Promise[]>; + // array with values + settle(values: T[]): Promise[]>; + + /** + * Like `Promise.some()`, with 1 as `count`. However, if the promise fulfills, the fulfillment value is not an array of 1 but the value directly. + */ + // promise of array with promises of value + any(values: PromiseLike[]>): Promise; + // promise of array with values + any(values: PromiseLike): Promise; + // array with promises of value + any(values: PromiseLike[]): Promise; + // array with values + any(values: T[]): Promise; + + /** + * Given an array, or a promise of an array, which contains promises (or a mix of promises and values) return a promise that is fulfilled or rejected as soon as a promise in the array is fulfilled or rejected with the respective rejection reason or fulfillment value. + * + * **Note** If you pass empty array or a sparse array with no values, or a promise/thenable for such, it will be forever pending. + */ + // promise of array with promises of value + race(values: PromiseLike[]>): Promise; + // promise of array with values + race(values: PromiseLike): Promise; + // array with promises of value + race(values: PromiseLike[]): Promise; + // array with values + race(values: T[]): Promise; + + /** + * Initiate a competetive race between multiple promises or values (values will become immediately fulfilled promises). When `count` amount of promises have been fulfilled, the returned promise is fulfilled with an array that contains the fulfillment values of the winners in order of resolution. + * + * If too many promises are rejected so that the promise can never become fulfilled, it will be immediately rejected with an array of rejection reasons in the order they were thrown in. + * + * *The original array is not modified.* + */ + // promise of array with promises of value + some(values: PromiseLike[]>, count: number): Promise; + // promise of array with values + some(values: PromiseLike, count: number): Promise; + // array with promises of value + some(values: PromiseLike[], count: number): Promise; + // array with values + some(values: T[], count: number): Promise; + + /** + * Like `Promise.all()` but instead of having to pass an array, the array is generated from the passed variadic arguments. + */ + // variadic array with promises of value + join(...values: PromiseLike[]): Promise; + // variadic array with values + join(...values: T[]): Promise; + + /** + * Map an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `mapper` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * If the `mapper` function returns promises or thenables, the returned promise will wait for all the mapped results to be resolved as well. + * + * *The original array is not modified.* + */ + // promise of array with promises of value + map(values: PromiseLike[]>, mapper: (item: T, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + map(values: PromiseLike[]>, mapper: (item: T, index: number, arrayLength: number) => U, options?: Promise.ConcurrencyOption): Promise; + + // promise of array with values + map(values: PromiseLike, mapper: (item: T, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + map(values: PromiseLike, mapper: (item: T, index: number, arrayLength: number) => U, options?: Promise.ConcurrencyOption): Promise; + + // array with promises of value + map(values: PromiseLike[], mapper: (item: T, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + map(values: PromiseLike[], mapper: (item: T, index: number, arrayLength: number) => U, options?: Promise.ConcurrencyOption): Promise; + + // array with values + map(values: T[], mapper: (item: T, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + map(values: T[], mapper: (item: T, index: number, arrayLength: number) => U, options?: Promise.ConcurrencyOption): Promise; + + /** + * Similar to `map` with concurrency set to 1 but guaranteed to execute in sequential order + * + * If the `mapper` function returns promises or thenables, the returned promise will wait for all the mapped results to be resolved as well. + * + * *The original array is not modified.* + */ + // promise of array with promises of value + mapSeries(values: PromiseLike[]>, mapper: (item: R, index: number, arrayLength: number) => U | PromiseLike): Promise; + + // promise of array with values + mapSeries(values: PromiseLike, mapper: (item: R, index: number, arrayLength: number) => U | PromiseLike): Promise; + + // array with promises of value + mapSeries(values: PromiseLike[], mapper: (item: R, index: number, arrayLength: number) => U | PromiseLike): Promise; + + // array with values + mapSeries(values: R[], mapper: (item: R, index: number, arrayLength: number) => U | PromiseLike): Promise; + + + /** + * Reduce an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `reducer` function with the signature `(total, current, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * If the reducer function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. + * + * *The original array is not modified. If no `intialValue` is given and the array doesn't contain at least 2 items, the callback will not be called and `undefined` is returned. If `initialValue` is given and the array doesn't have at least 1 item, `initialValue` is returned.* + */ + // promise of array with promises of value + reduce(values: PromiseLike[]>, reducer: (total: U, current: T, index: number, arrayLength: number) => PromiseLike, initialValue?: U): Promise; + reduce(values: PromiseLike[]>, reducer: (total: U, current: T, index: number, arrayLength: number) => U, initialValue?: U): Promise; + + // promise of array with values + reduce(values: PromiseLike, reducer: (total: U, current: T, index: number, arrayLength: number) => PromiseLike, initialValue?: U): Promise; + reduce(values: PromiseLike, reducer: (total: U, current: T, index: number, arrayLength: number) => U, initialValue?: U): Promise; + + // array with promises of value + reduce(values: PromiseLike[], reducer: (total: U, current: T, index: number, arrayLength: number) => PromiseLike, initialValue?: U): Promise; + reduce(values: PromiseLike[], reducer: (total: U, current: T, index: number, arrayLength: number) => U, initialValue?: U): Promise; + + // array with values + reduce(values: T[], reducer: (total: U, current: T, index: number, arrayLength: number) => PromiseLike, initialValue?: U): Promise; + reduce(values: T[], reducer: (total: U, current: T, index: number, arrayLength: number) => U, initialValue?: U): Promise; + + /** + * Filter an array, or a promise of an array, which contains a promises (or a mix of promises and values) with the given `filterer` function with the signature `(item, index, arrayLength)` where `item` is the resolved value of a respective promise in the input array. If any promise in the input array is rejected the returned promise is rejected as well. + * + * The return values from the filtered functions are coerced to booleans, with the exception of promises and thenables which are awaited for their eventual result. + * + * *The original array is not modified. + */ + // promise of array with promises of value + filter(values: PromiseLike[]>, filterer: (item: T, index: number, arrayLength: number) => PromiseLike, option?: Promise.ConcurrencyOption): Promise; + filter(values: PromiseLike[]>, filterer: (item: T, index: number, arrayLength: number) => boolean, option?: Promise.ConcurrencyOption): Promise; + + // promise of array with values + filter(values: PromiseLike, filterer: (item: T, index: number, arrayLength: number) => PromiseLike, option?: Promise.ConcurrencyOption): Promise; + filter(values: PromiseLike, filterer: (item: T, index: number, arrayLength: number) => boolean, option?: Promise.ConcurrencyOption): Promise; + + // array with promises of value + filter(values: PromiseLike[], filterer: (item: T, index: number, arrayLength: number) => PromiseLike, option?: Promise.ConcurrencyOption): Promise; + filter(values: PromiseLike[], filterer: (item: T, index: number, arrayLength: number) => boolean, option?: Promise.ConcurrencyOption): Promise; + + // array with values + filter(values: T[], filterer: (item: T, index: number, arrayLength: number) => PromiseLike, option?: Promise.ConcurrencyOption): Promise; + filter(values: T[], filterer: (item: T, index: number, arrayLength: number) => boolean, option?: Promise.ConcurrencyOption): Promise; + + /** + * Iterate over an array, or a promise of an array, which contains promises (or a mix of promises and values) with the given iterator function with the signature (item, index, value) where item is the resolved value of a respective promise in the input array. Iteration happens serially. If any promise in the input array is rejected the returned promise is rejected as well. + * + * Resolves to the original array unmodified, this method is meant to be used for side effects. If the iterator function returns a promise or a thenable, the result for the promise is awaited for before continuing with next iteration. + */ + // promise of array with promises of value + each(values: PromiseLike[]>, iterator: (item: T, index: number, arrayLength: number) => U | PromiseLike): Promise; + // array with promises of value + each(values: PromiseLike[], iterator: (item: T, index: number, arrayLength: number) => U | PromiseLike): Promise; + // array with values OR promise of array with values + each(values: T[] | PromiseLike, iterator: (item: T, index: number, arrayLength: number) => U | PromiseLike): Promise; } -declare module Promise { - export interface RangeError extends Error { - } - export interface CancellationError extends Error { - } - export interface TimeoutError extends Error { - } - export interface TypeError extends Error { - } - export interface RejectionError extends Error { - } - export interface OperationalError extends Error { - } +interface Promise extends PromiseLike, Promise.Inspection { + /** + * Promises/A+ `.then()` with progress handler. Returns a new promise chained from this promise. The new promise will be rejected or resolved dedefer on the passed `fulfilledHandler`, `rejectedHandler` and the state of this promise. + */ + then(onFulfill: (value: T) => U | PromiseLike, onReject?: (error: any) => U | PromiseLike, onProgress?: (note: any) => any): Promise; + then(onFulfill: (value: T) => U | PromiseLike, onReject?: (error: any) => void | PromiseLike, onProgress?: (note: any) => any): Promise; - // Ideally, we'd define e.g. "export class RangeError extends Error {}", - // but as Error is defined as an interface (not a class), TypeScript doesn't - // allow extending Error, only implementing it. - // However, if we want to catch() only a specific error type, we need to pass - // a constructor function to it. So, as a workaround, we define them here as such. - export function RangeError(): RangeError; - export function CancellationError(): CancellationError; - export function TimeoutError(): TimeoutError; - export function TypeError(): TypeError; - export function RejectionError(): RejectionError; - export function OperationalError(): OperationalError; + /** + * This is a catch-all exception handler, shortcut for calling `.then(null, handler)` on this promise. Any exception happening in a `.then`-chain will propagate to nearest `.catch` handler. + * + * Alias `.caught();` for compatibility with earlier ECMAScript version. + */ + catch(onReject?: (error: any) => T | PromiseLike | void | PromiseLike): Promise; + caught(onReject?: (error: any) => T | PromiseLike | void | PromiseLike): Promise; - export interface Thenable { - then(onFulfilled: (value: R) => Thenable, onRejected: (error: any) => Thenable): Thenable; - then(onFulfilled: (value: R) => Thenable, onRejected?: (error: any) => U): Thenable; - then(onFulfilled: (value: R) => U, onRejected: (error: any) => Thenable): Thenable; - then(onFulfilled?: (value: R) => U, onRejected?: (error: any) => U): Thenable; - } + catch(onReject?: (error: any) => U | PromiseLike): Promise; + caught(onReject?: (error: any) => U | PromiseLike): Promise; - export interface Resolver { - /** - * Returns a reference to the controlled promise that can be passed to clients. - */ - promise: Promise; + /** + * This extends `.catch` to work more like catch-clauses in languages like Java or C#. Instead of manually checking `instanceof` or `.name === "SomeError"`, you may specify a number of error constructors which are eligible for this catch handler. The catch handler that is first met that has eligible constructors specified, is the one that will be called. + * + * This method also supports predicate-based filters. If you pass a predicate function instead of an error constructor, the predicate will receive the error as an argument. The return result of the predicate will be used determine whether the error handler should be called. + * + * Alias `.caught();` for compatibility with earlier ECMAScript version. + */ + catch(predicate: (error: any) => boolean, onReject: (error: any) => T | PromiseLike | void | PromiseLike): Promise; + caught(predicate: (error: any) => boolean, onReject: (error: any) => T | PromiseLike | void | PromiseLike): Promise; - /** - * Resolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state. - */ - resolve(value: R): void; - resolve(): void; + catch(predicate: (error: any) => boolean, onReject: (error: any) => U | PromiseLike): Promise; + caught(predicate: (error: any) => boolean, onReject: (error: any) => U | PromiseLike): Promise; - /** - * Reject the underlying promise with `reason` as the rejection reason. - */ - reject(reason: any): void; + catch(ErrorClass: Function, onReject: (error: any) => T | PromiseLike | void | PromiseLike): Promise; + caught(ErrorClass: Function, onReject: (error: any) => T | PromiseLike | void | PromiseLike): Promise; - /** - * Progress the underlying promise with `value` as the progression value. - */ - progress(value: any): void; + catch(ErrorClass: Function, onReject: (error: any) => U | PromiseLike): Promise; + caught(ErrorClass: Function, onReject: (error: any) => U | PromiseLike): Promise; - /** - * Gives you a callback representation of the `PromiseResolver`. Note that this is not a method but a property. The callback accepts error object in first argument and success values on the 2nd parameter and the rest, I.E. node js conventions. - * - * If the the callback is called with multiple success values, the resolver fullfills its promise with an array of the values. - */ - // TODO specify resolver callback - callback: (err: any, value: R, ...values: R[]) => void; - } - export interface Inspection { - /** - * See if the underlying promise was fulfilled at the creation time of this inspection object. - */ - isFulfilled(): boolean; + /** + * Like `.catch` but instead of catching all types of exceptions, it only catches those that don't originate from thrown errors but rather from explicit rejections. + */ + error(onReject: (reason: any) => PromiseLike): Promise; + error(onReject: (reason: any) => U): Promise; - /** - * See if the underlying promise was rejected at the creation time of this inspection object. - */ - isRejected(): boolean; + /** + * Pass a handler that will be called regardless of this promise's fate. Returns a new promise chained from this promise. There are special semantics for `.finally()` in that the final value cannot be modified from the handler. + * + * Alias `.lastly();` for compatibility with earlier ECMAScript version. + */ + finally(handler: () => PromiseLike): Promise; + finally(handler: () => U): Promise; - /** - * See if the underlying promise was defer at the creation time of this inspection object. - */ - isPending(): boolean; + lastly(handler: () => PromiseLike): Promise; + lastly(handler: () => U): Promise; - /** - * Get the fulfillment value of the underlying promise. Throws if the promise wasn't fulfilled at the creation time of this inspection object. - * - * throws `TypeError` - */ - value(): R; + /** + * Create a promise that follows this promise, but is bound to the given `thisArg` value. A bound promise will call its handlers with the bound value set to `this`. Additionally promises derived from a bound promise will also be bound promises with the same `thisArg` binding as the original promise. + */ + bind(thisArg: any): Promise; - /** - * Get the rejection reason for the underlying promise. Throws if the promise wasn't rejected at the creation time of this inspection object. - * - * throws `TypeError` - */ - reason(): any; - } + /** + * Like `.then()`, but any unhandled rejection that ends up here will be thrown as an error. + */ + done(onFulfilled: (value: T) => PromiseLike, onRejected: (error: any) => PromiseLike, onProgress?: (note: any) => any): void; + done(onFulfilled: (value: T) => PromiseLike, onRejected?: (error: any) => U, onProgress?: (note: any) => any): void; + done(onFulfilled: (value: T) => U, onRejected: (error: any) => PromiseLike, onProgress?: (note: any) => any): void; + done(onFulfilled?: (value: T) => U, onRejected?: (error: any) => U, onProgress?: (note: any) => any): void; - /** - * Changes how bluebird schedules calls a-synchronously. - * - * @param scheduler Should be a function that asynchronously schedules - * the calling of the passed in function - */ - export function setScheduler(scheduler: (callback: (...args: any[]) => void) => void): void; + /** + * Like `.finally()`, but not called for rejections. + */ + tap(onFulFill: (value: T) => PromiseLike): Promise; + tap(onFulfill: (value: T) => U): Promise; + + /** + * Shorthand for `.then(null, null, handler);`. Attach a progress handler that will be called if this promise is progressed. Returns a new promise chained from this promise. + */ + progressed(handler: (note: any) => any): Promise; + + /** + * Same as calling `Promise.delay(this, ms)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + delay(ms: number): Promise; + + /** + * Returns a promise that will be fulfilled with this promise's fulfillment value or rejection reason. However, if this promise is not fulfilled or rejected within `ms` milliseconds, the returned promise is rejected with a `Promise.TimeoutError` instance. + * + * You may specify a custom error message with the `message` parameter. + */ + timeout(ms: number, message?: string): Promise; + + /** + * Register a node-style callback on this promise. When this promise is is either fulfilled or rejected, the node callback will be called back with the node.js convention where error reason is the first argument and success value is the second argument. The error argument will be `null` in case of success. + * Returns back this promise instead of creating a new one. If the `callback` argument is not a function, this method does not do anything. + */ + nodeify(callback: (err: any, value?: T) => void, options?: Promise.SpreadOption): Promise; + nodeify(...sink: any[]): Promise; + + /** + * Marks this promise as cancellable. Promises by default are not cancellable after v0.11 and must be marked as such for `.cancel()` to have any effect. Marking a promise as cancellable is infectious and you don't need to remark any descendant promise. + */ + cancellable(): Promise; + + /** + * Cancel this promise. The cancellation will propagate to farthest cancellable ancestor promise which is still pending. + * + * That ancestor will then be rejected with a `CancellationError` (get a reference from `Promise.CancellationError`) object as the rejection reason. + * + * In a promise rejection handler you may check for a cancellation by seeing if the reason object has `.name === "Cancel"`. + * + * Promises are by default not cancellable. Use `.cancellable()` to mark a promise as cancellable. + */ + // TODO what to do with this? + cancel(reason?: any): Promise; + + /** + * Like `.then()`, but cancellation of the the returned promise or any of its descendant will not propagate cancellation to this promise or this promise's ancestors. + */ + fork(onFulfilled: (value: T) => PromiseLike, onRejected: (error: any) => PromiseLike, onProgress?: (note: any) => any): Promise; + fork(onFulfilled: (value: T) => PromiseLike, onRejected?: (error: any) => U, onProgress?: (note: any) => any): Promise; + fork(onFulfilled: (value: T) => U, onRejected: (error: any) => PromiseLike, onProgress?: (note: any) => any): Promise; + fork(onFulfilled?: (value: T) => U, onRejected?: (error: any) => U, onProgress?: (note: any) => any): Promise; + + /** + * Create an uncancellable promise based on this promise. + */ + uncancellable(): Promise; + + /** + * See if this promise can be cancelled. + */ + isCancellable(): boolean; + + /** + * See if this `promise` has been fulfilled. + */ + isFulfilled(): boolean; + + /** + * See if this `promise` has been rejected. + */ + isRejected(): boolean; + + /** + * See if this `promise` is still defer. + */ + isPending(): boolean; + + /** + * See if this `promise` is resolved -> either fulfilled or rejected. + */ + isResolved(): boolean; + + /** + * Get the fulfillment value of the underlying promise. Throws if the promise isn't fulfilled yet. + * + * throws `TypeError` + */ + value(): T; + + /** + * Get the rejection reason for the underlying promise. Throws if the promise isn't rejected yet. + * + * throws `TypeError` + */ + reason(): any; + + /** + * Synchronously inspect the state of this `promise`. The `PromiseInspection` will represent the state of the promise as snapshotted at the time of calling `.inspect()`. + */ + inspect(): Promise.Inspection; + + /** + * This is a convenience method for doing: + * + * + * promise.then(function(obj){ + * return obj[propertyName].call(obj, arg...); + * }); + * + */ + call(propertyName: string, ...args: any[]): Promise; + + /** + * This is a convenience method for doing: + * + * + * promise.then(function(obj){ + * return obj[propertyName]; + * }); + * + */ + // TODO find way to fix get() + // get(propertyName: string): Promise; + + /** + * Convenience method for: + * + * + * .then(function() { + * return value; + * }); + * + * + * in the case where `value` doesn't change its value. That means `value` is bound at the time of calling `.return()` + * + * Alias `.thenReturn();` for compatibility with earlier ECMAScript version. + */ + return(): Promise; + thenReturn(): Promise; + return(value: U): Promise; + thenReturn(value: U): Promise; + + /** + * Convenience method for: + * + * + * .then(function() { + * throw reason; + * }); + * + * Same limitations apply as with `.return()`. + * + * Alias `.thenThrow();` for compatibility with earlier ECMAScript version. + */ + throw(reason: Error): Promise; + thenThrow(reason: Error): Promise; + + /** + * Convert to String. + */ + toString(): string; + + /** + * This is implicitly called by `JSON.stringify` when serializing the object. Returns a serialized representation of the `Promise`. + */ + toJSON(): Object; + + /** + * Like calling `.then`, but the fulfillment value or rejection reason is assumed to be an array, which is flattened to the formal parameters of the handlers. + */ + // TODO how to model instance.spread()? like Q? + spread(onFulfill: Function, onReject?: (reason: any) => PromiseLike): Promise; + spread(onFulfill: Function, onReject?: (reason: any) => U): Promise; + /* + // TODO or something like this? + spread(onFulfill: (...values: W[]) => PromiseLike, onReject?: (reason: any) => PromiseLike): Promise; + spread(onFulfill: (...values: W[]) => PromiseLike, onReject?: (reason: any) => U): Promise; + spread(onFulfill: (...values: W[]) => U, onReject?: (reason: any) => PromiseLike): Promise; + spread(onFulfill: (...values: W[]) => U, onReject?: (reason: any) => U): Promise; + */ + /** + * Same as calling `Promise.all(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + all(): Promise; + + /** + * Same as calling `Promise.props(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO how to model instance.props()? + props(): Promise; + + /** + * Same as calling `Promise.settle(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + settle(): Promise[]>; + + /** + * Same as calling `Promise.any(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + any(): Promise; + + /** + * Same as calling `Promise.some(thisPromise)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + some(count: number): Promise; + + /** + * Same as calling `Promise.race(thisPromise, count)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + race(): Promise; + + /** + * Same as calling `Promise.map(thisPromise, mapper)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + map(mapper: (item: Q, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + map(mapper: (item: Q, index: number, arrayLength: number) => U, options?: Promise.ConcurrencyOption): Promise; + + /** + * Same as `Promise.mapSeries(thisPromise, mapper)`. + */ + // TODO type inference from array-resolving promise? + mapSeries(mapper: (item: Q, index: number, arrayLength: number) => U | PromiseLike): Promise; + + /** + * Same as calling `Promise.reduce(thisPromise, Function reducer, initialValue)`. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => PromiseLike, initialValue?: U): Promise; + reduce(reducer: (memo: U, item: Q, index: number, arrayLength: number) => U, initialValue?: U): Promise; + + /** + * Same as calling ``Promise.filter(thisPromise, filterer)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + // TODO type inference from array-resolving promise? + filter(filterer: (item: U, index: number, arrayLength: number) => PromiseLike, options?: Promise.ConcurrencyOption): Promise; + filter(filterer: (item: U, index: number, arrayLength: number) => boolean, options?: Promise.ConcurrencyOption): Promise; + + /** + * Same as calling ``Promise.each(thisPromise, iterator)``. With the exception that if this promise is bound to a value, the returned promise is bound to that value too. + */ + each(iterator: (item: T, index: number, arrayLength: number) => U | PromiseLike): Promise; +} + +/** + * Don't use variable namespace such as variables, functions, and classes. + * If you use this namespace, it will conflict in es6. + */ +declare namespace Promise { + export interface RangeError extends Error { + } + export interface CancellationError extends Error { + } + export interface TimeoutError extends Error { + } + export interface TypeError extends Error { + } + export interface RejectionError extends Error { + } + export interface OperationalError extends Error { + } + + export interface ConcurrencyOption { + concurrency: number; + } + export interface SpreadOption { + spread: boolean; + } + export interface PromisifyAllOptions { + suffix?: string; + filter?: (name: string, func: Function, target?: any, passesDefaultFilter?: boolean) => boolean; + // The promisifier gets a reference to the original method and should return a function which returns a promise + promisifier?: (originalMethod: Function) => () => PromiseLike; + } + + export interface Resolver { + /** + * Returns a reference to the controlled promise that can be passed to clients. + */ + promise: Promise; + + /** + * Resolve the underlying promise with `value` as the resolution value. If `value` is a thenable or a promise, the underlying promise will assume its state. + */ + resolve(value: T): void; + resolve(): void; + + /** + * Reject the underlying promise with `reason` as the rejection reason. + */ + reject(reason: any): void; + + /** + * Progress the underlying promise with `value` as the progression value. + */ + progress(value: any): void; + + /** + * Gives you a callback representation of the `PromiseResolver`. Note that this is not a method but a property. The callback accepts error object in first argument and success values on the 2nd parameter and the rest, I.E. node js conventions. + * + * If the the callback is called with multiple success values, the resolver fullfills its promise with an array of the values. + */ + // TODO specify resolver callback + callback: (err: any, value: T, ...values: T[]) => void; + } + + export interface Inspection { + /** + * See if the underlying promise was fulfilled at the creation time of this inspection object. + */ + isFulfilled(): boolean; + + /** + * See if the underlying promise was rejected at the creation time of this inspection object. + */ + isRejected(): boolean; + + /** + * See if the underlying promise was defer at the creation time of this inspection object. + */ + isPending(): boolean; + + /** + * Get the fulfillment value of the underlying promise. Throws if the promise wasn't fulfilled at the creation time of this inspection object. + * + * throws `TypeError` + */ + value(): T; + + /** + * Get the rejection reason for the underlying promise. Throws if the promise wasn't rejected at the creation time of this inspection object. + * + * throws `TypeError` + */ + reason(): any; + } } declare module 'bluebird' { - export = Promise; + export = Promise; } diff --git a/platform/built-in-server/client/node-rpc-client/typings/node/node.d.ts b/platform/built-in-server/client/node-rpc-client/typings/node/node.d.ts index 6c09ee04f556..450facb4a535 100644 --- a/platform/built-in-server/client/node-rpc-client/typings/node/node.d.ts +++ b/platform/built-in-server/client/node-rpc-client/typings/node/node.d.ts @@ -1,21 +1,34 @@ -// Type definitions for Node.js v0.12.0 +// Type definitions for Node.js v4.x // Project: http://nodejs.org/ // Definitions by: Microsoft TypeScript , DefinitelyTyped // Definitions: https://github.com/borisyankov/DefinitelyTyped /************************************************ * * -* Node.js v0.12.0 API * +* Node.js v4.x API * * * ************************************************/ +interface Error { + stack?: string; +} + + +// compat for TypeScript 1.5.3 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.5.3. +interface MapConstructor {} +interface WeakMapConstructor {} +interface SetConstructor {} +interface WeakSetConstructor {} + /************************************************ * * * GLOBAL * * * ************************************************/ declare var process: NodeJS.Process; -declare var global: any; +declare var global: NodeJS.Global; declare var __filename: string; declare var __dirname: string; @@ -27,23 +40,30 @@ declare function clearInterval(intervalId: NodeJS.Timer): void; declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; declare function clearImmediate(immediateId: any): void; -declare var require: { +interface NodeRequireFunction { (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { resolve(id:string): string; cache: any; extensions: any; main: any; -}; +} -declare var module: { +declare var require: NodeRequire; + +interface NodeModule { exports: any; - require(id: string): any; + require: NodeRequireFunction; id: string; filename: string; loaded: boolean; parent: any; children: any[]; -}; +} + +declare var module: NodeModule; // Same as module.exports declare var exports: any; @@ -61,15 +81,76 @@ declare var SlowBuffer: { // Buffer class interface Buffer extends NodeBuffer {} + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ new (size: number): Buffer; - new (size: Uint8Array): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ new (array: any[]): Buffer; prototype: Buffer; - isBuffer(obj: any): boolean; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): obj is Buffer; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; }; /************************************************ @@ -79,10 +160,11 @@ declare var Buffer: { ************************************************/ declare module NodeJS { export interface ErrnoException extends Error { - errno?: any; + errno?: number; code?: string; path?: string; syscall?: string; + stack?: string; } export interface EventEmitter { @@ -91,14 +173,16 @@ declare module NodeJS { once(event: string, listener: Function): EventEmitter; removeListener(event: string, listener: Function): EventEmitter; removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; + setMaxListeners(n: number): EventEmitter; + getMaxListeners(): number; listeners(event: string): Function[]; emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; } export interface ReadableStream extends EventEmitter { readable: boolean; - read(size?: number): any; + read(size?: number): string|Buffer; setEncoding(encoding: string): void; pause(): void; resume(): void; @@ -111,8 +195,7 @@ declare module NodeJS { export interface WritableStream extends EventEmitter { writable: boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; + write(buffer: Buffer|string, cb?: Function): boolean; write(str: string, encoding?: string, cb?: Function): boolean; end(): void; end(buffer: Buffer, cb?: Function): void; @@ -175,7 +258,7 @@ declare module NodeJS { visibility: string; }; }; - kill(pid: number, signal?: string): void; + kill(pid:number, signal?: string|number): void; pid: number; title: string; arch: string; @@ -190,6 +273,72 @@ declare module NodeJS { send?(message: any, sendHandle?: any): void; } + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + v8debug?: any; + } + export interface Timer { ref() : void; unref() : void; @@ -205,8 +354,18 @@ interface NodeBuffer { toString(encoding?: string, start?: number, end?: number): string; toJSON(): any; length: number; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer): number; copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; readUInt8(offset: number, noAsset?: boolean): number; readUInt16LE(offset: number, noAssert?: boolean): number; readUInt16BE(offset: number, noAssert?: boolean): number; @@ -221,21 +380,21 @@ interface NodeBuffer { readFloatBE(offset: number, noAssert?: boolean): number; readDoubleLE(offset: number, noAssert?: boolean): number; readDoubleBE(offset: number, noAssert?: boolean): number; - writeUInt8(value: number, offset: number, noAssert?: boolean): void; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeInt8(value: number, offset: number, noAssert?: boolean): void; - writeInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeFloatLE(value: number, offset: number, noAssert?: boolean): void; - writeFloatBE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; - fill(value: any, offset?: number, end?: number): void; + writeUInt8(value: number, offset: number, noAssert?: boolean): number; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeInt8(value: number, offset: number, noAssert?: boolean): number; + writeInt16LE(value: number, offset: number, noAssert?: boolean): number; + writeInt16BE(value: number, offset: number, noAssert?: boolean): number; + writeInt32LE(value: number, offset: number, noAssert?: boolean): number; + writeInt32BE(value: number, offset: number, noAssert?: boolean): number; + writeFloatLE(value: number, offset: number, noAssert?: boolean): number; + writeFloatBE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number; + fill(value: any, offset?: number, end?: number): Buffer; } /************************************************ @@ -248,49 +407,74 @@ declare module "buffer" { } declare module "querystring" { - export function stringify(obj: any, sep?: string, eq?: string): string; - export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; - export function escape(): any; - export function unescape(): any; + export interface StringifyOptions { + encodeURIComponent?: Function; + } + + export interface ParseOptions { + maxKeys?: number; + decodeURIComponent?: Function; + } + + export function stringify(obj: T, sep?: string, eq?: string, options?: StringifyOptions): string; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): any; + export function parse(str: string, sep?: string, eq?: string, options?: ParseOptions): T; + export function escape(str: string): string; + export function unescape(str: string): string; } declare module "events" { export class EventEmitter implements NodeJS.EventEmitter { - static listenerCount(emitter: EventEmitter, event: string): number; + static EventEmitter: EventEmitter; + static listenerCount(emitter: EventEmitter, event: string): number; // deprecated + static defaultMaxListeners: number; addListener(event: string, listener: Function): EventEmitter; on(event: string, listener: Function): EventEmitter; once(event: string, listener: Function): EventEmitter; removeListener(event: string, listener: Function): EventEmitter; removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; + setMaxListeners(n: number): EventEmitter; + getMaxListeners(): number; listeners(event: string): Function[]; emit(event: string, ...args: any[]): boolean; - } + listenerCount(type: string): number; + } } declare module "http" { - import events = require("events"); - import net = require("net"); - import stream = require("stream"); + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface RequestOptions { + protocol?: string; + host?: string; + hostname?: string; + family?: number; + port?: number + localAddress?: string; + socketPath?: string; + method?: string; + path?: string; + headers?: { [key: string]: any }; + auth?: string; + agent?: Agent|boolean; + } export interface Server extends events.EventEmitter { listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; + listen(port: number, hostname?: string, callback?: Function): Server; listen(path: string, callback?: Function): Server; listen(handle: any, listeningListener?: Function): Server; close(cb?: any): Server; address(): { port: number; family: string; address: string; }; maxHeadersCount: number; } - export interface ServerRequest extends events.EventEmitter, stream.Readable { - method: string; - url: string; - headers: any; - trailers: string; - httpVersion: string; - setEncoding(encoding?: string): void; - pause(): void; - resume(): void; + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { connection: net.Socket; } export interface ServerResponse extends events.EventEmitter, stream.Writable { @@ -305,6 +489,8 @@ declare module "http" { writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; writeHead(statusCode: number, headers?: any): void; statusCode: number; + statusMessage: string; + headersSent: boolean; setHeader(name: string, value: string): void; sendDate: boolean; getHeader(name: string): string; @@ -340,31 +526,88 @@ declare module "http" { end(str: string, encoding?: string, cb?: Function): void; end(data?: any, encoding?: string): void; } - export interface ClientResponse extends events.EventEmitter, stream.Readable { - statusCode: number; + export interface IncomingMessage extends events.EventEmitter, stream.Readable { httpVersion: string; headers: any; + rawHeaders: string[]; trailers: any; - setEncoding(encoding?: string): void; - pause(): void; - resume(): void; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; } - export interface Agent { maxSockets: number; sockets: any; requests: any; } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; export var STATUS_CODES: { [errorCode: number]: string; [errorCode: string]: string; }; - export function createServer(requestListener?: (request: ServerRequest, response: ServerResponse) =>void ): Server; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; export function createClient(port?: number, host?: string): any; - export function request(options: any, callback?: Function): ClientRequest; - export function get(options: any, callback?: Function): ClientRequest; + export function request(options: RequestOptions, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; export var globalAgent: Agent; } declare module "cluster" { - import child = require("child_process"); - import events = require("events"); + import * as child from "child_process"; + import * as events from "events"; export interface ClusterSettings { exec?: string; @@ -403,7 +646,7 @@ declare module "cluster" { } declare module "zlib" { - import stream = require("stream"); + import * as stream from "stream"; export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } export interface Gzip extends stream.Transform { } @@ -423,12 +666,19 @@ declare module "zlib" { export function createUnzip(options?: ZlibOptions): Unzip; export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; // Constants export var Z_NO_FLUSH: number; @@ -465,7 +715,29 @@ declare module "zlib" { } declare module "os" { + export interface CpuInfo { + model: string; + speed: number; + times: { + user: number; + nice: number; + sys: number; + idle: number; + irq: number; + } + } + + export interface NetworkInterfaceInfo { + address: string; + netmask: string; + family: string; + mac: string; + internal: boolean; + } + export function tmpdir(): string; + export function homedir(): string; + export function endianness(): string; export function hostname(): string; export function type(): string; export function platform(): string; @@ -475,15 +747,15 @@ declare module "os" { export function loadavg(): number[]; export function totalmem(): number; export function freemem(): number; - export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; - export function networkInterfaces(): any; + export function cpus(): CpuInfo[]; + export function networkInterfaces(): {[index: string]: NetworkInterfaceInfo[]}; export var EOL: string; } declare module "https" { - import tls = require("tls"); - import events = require("events"); - import http = require("http"); + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; export interface ServerOptions { pfx?: any; @@ -500,15 +772,7 @@ declare module "https" { SNICallback?: (servername: string) => any; } - export interface RequestOptions { - host?: string; - hostname?: string; - port?: number; - path?: string; - method?: string; - headers?: any; - auth?: string; - agent?: any; + export interface RequestOptions extends http.RequestOptions{ pfx?: any; key?: any; passphrase?: string; @@ -516,6 +780,7 @@ declare module "https" { ca?: any; ciphers?: string; rejectUnauthorized?: boolean; + secureProtocol?: string; } export interface Agent { @@ -528,8 +793,8 @@ declare module "https" { }; export interface Server extends tls.Server { } export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: http.ClientResponse) =>void ): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: http.ClientResponse) =>void ): http.ClientRequest; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; export var globalAgent: Agent; } @@ -540,15 +805,15 @@ declare module "punycode" { export function toASCII(domain: string): string; export var ucs2: ucs2; interface ucs2 { - decode(string: string): string; + decode(string: string): number[]; encode(codePoints: number[]): string; } export var version: any; } declare module "repl" { - import stream = require("stream"); - import events = require("events"); + import * as stream from "stream"; + import * as events from "events"; export interface ReplOptions { prompt?: string; @@ -565,25 +830,52 @@ declare module "repl" { } declare module "readline" { - import events = require("events"); - import stream = require("stream"); + import * as events from "events"; + import * as stream from "stream"; + + export interface Key { + sequence?: string; + name?: string; + ctrl?: boolean; + meta?: boolean; + shift?: boolean; + } export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string, length: number): void; + setPrompt(prompt: string): void; prompt(preserveCursor?: boolean): void; - question(query: string, callback: Function): void; - pause(): void; - resume(): void; + question(query: string, callback: (answer: string) => void): void; + pause(): ReadLine; + resume(): ReadLine; close(): void; - write(data: any, key?: any): void; + write(data: string|Buffer, key?: Key): void; } + + export interface Completer { + (line: string): CompleterResult; + (line: string, callback: (err: any, result: CompleterResult) => void): any; + } + + export interface CompleterResult { + completions: string[]; + line: string; + } + export interface ReadLineOptions { input: NodeJS.ReadableStream; - output: NodeJS.WritableStream; - completer?: Function; + output?: NodeJS.WritableStream; + completer?: Completer; terminal?: boolean; + historySize?: number; } + + export function createInterface(input: NodeJS.ReadableStream, output?: NodeJS.WritableStream, completer?: Completer, terminal?: boolean): ReadLine; export function createInterface(options: ReadLineOptions): ReadLine; + + export function cursorTo(stream: NodeJS.WritableStream, x: number, y: number): void; + export function moveCursor(stream: NodeJS.WritableStream, dx: number|string, dy: number|string): void; + export function clearLine(stream: NodeJS.WritableStream, dir: number): void; + export function clearScreenDown(stream: NodeJS.WritableStream): void; } declare module "vm" { @@ -600,8 +892,8 @@ declare module "vm" { } declare module "child_process" { - import events = require("events"); - import stream = require("stream"); + import * as events from "events"; + import * as stream from "stream"; export interface ChildProcess extends events.EventEmitter { stdin: stream.Writable; @@ -609,8 +901,9 @@ declare module "child_process" { stderr: stream.Readable; pid: number; kill(signal?: string): void; - send(message: any, sendHandle: any): void; + send(message: any, sendHandle?: any): void; disconnect(): void; + unref(): void; } export function spawn(command: string, args?: string[], options?: { @@ -629,8 +922,8 @@ declare module "child_process" { timeout?: number; maxBuffer?: number; killSignal?: string; - }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function exec(command: string, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; export function execFile(file: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; export function execFile(file: string, args?: string[], @@ -642,33 +935,67 @@ declare module "child_process" { env?: any; encoding?: string; timeout?: number; - maxBuffer?: string; + maxBuffer?: number; killSignal?: string; }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; export function fork(modulePath: string, args?: string[], options?: { cwd?: string; env?: any; - encoding?: string; + execPath?: string; + execArgv?: string[]; + silent?: boolean; + uid?: number; + gid?: number; }): ChildProcess; + export function spawnSync(command: string, args?: string[], options?: { + cwd?: string; + input?: string | Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): { + pid: number; + output: string[]; + stdout: string | Buffer; + stderr: string | Buffer; + status: number; + signal: string; + error: Error; + }; + export function execSync(command: string, options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): string | Buffer; + export function execFileSync(command: string, args?: string[], options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): string | Buffer; } declare module "url" { export interface Url { - href: string; - protocol: string; - auth: string; - hostname: string; - port: string; - host: string; - pathname: string; - search: string; - query: any; // string | Object - slashes: boolean; - hash?: string; - path?: string; - } - - export interface UrlOptions { + href?: string; protocol?: string; auth?: string; hostname?: string; @@ -676,13 +1003,14 @@ declare module "url" { host?: string; pathname?: string; search?: string; - query?: any; + query?: any; // string | Object + slashes?: boolean; hash?: string; path?: string; } export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; - export function format(url: UrlOptions): string; + export function format(url: Url): string; export function resolve(from: string, to: string): string; } @@ -702,7 +1030,7 @@ declare module "dns" { } declare module "net" { - import stream = require("stream"); + import * as stream from "stream"; export interface Socket extends stream.Duplex { // Extended base methods @@ -728,7 +1056,10 @@ declare module "net" { ref(): void; remoteAddress: string; + remoteFamily: string; remotePort: number; + localAddress: string; + localPort: number; bytesRead: number; bytesWritten: number; @@ -755,10 +1086,10 @@ declare module "net" { } export function createServer(connectionListener?: (socket: Socket) =>void ): Server; export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; - export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; export function connect(port: number, host?: string, connectionListener?: Function): Socket; export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(options: { port: number, host?: string, localAddress? : string, localPort? : string, family? : number, allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; export function createConnection(path: string, connectionListener?: Function): Socket; export function isIP(input: string): number; @@ -767,7 +1098,7 @@ declare module "net" { } declare module "dgram" { - import events = require("events"); + import * as events from "events"; interface RemoteInfo { address: string; @@ -797,8 +1128,8 @@ declare module "dgram" { } declare module "fs" { - import stream = require("stream"); - import events = require("events"); + import * as stream from "stream"; + import * as events from "events"; interface Stats { isFile(): boolean; @@ -821,6 +1152,7 @@ declare module "fs" { atime: Date; mtime: Date; ctime: Date; + birthtime: Date; } interface FSWatcher extends events.EventEmitter { @@ -832,9 +1164,21 @@ declare module "fs" { } export interface WriteStream extends stream.Writable { close(): void; + bytesWritten: number; } + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ export function renameSync(oldPath: string, newPath: string): void; export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; @@ -874,15 +1218,71 @@ declare module "fs" { export function readlinkSync(path: string): string; export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; - export function realpathSync(path: string, cache?: {[path: string]: string}): string; + export function realpathSync(path: string, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ export function unlinkSync(path: string): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ export function rmdirSync(path: string): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function mkdirSync(path: string, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ export function mkdirSync(path: string, mode?: string): void; export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; export function readdirSync(path: string): string[]; @@ -904,15 +1304,64 @@ declare module "fs" { export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; export function fsyncSync(fd: number): void; export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; @@ -931,36 +1380,178 @@ declare module "fs" { export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; export function exists(path: string, callback?: (exists: boolean) => void): void; export function existsSync(path: string): boolean; + /** Constant for fs.access(). File is visible to the calling process. */ + export var F_OK: number; + /** Constant for fs.access(). File can be read by the calling process. */ + export var R_OK: number; + /** Constant for fs.access(). File can be written by the calling process. */ + export var W_OK: number; + /** Constant for fs.access(). File can be executed by the calling process. */ + export var X_OK: number; + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string, mode ?: number): void; export function createReadStream(path: string, options?: { flags?: string; encoding?: string; - fd?: string; + fd?: number; mode?: number; - bufferSize?: number; - }): ReadStream; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: string; - mode?: string; - bufferSize?: number; + autoClose?: boolean; }): ReadStream; export function createWriteStream(path: string, options?: { flags?: string; encoding?: string; - string?: string; + fd?: number; + mode?: number; }): WriteStream; } declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } } declare module "string_decoder" { @@ -974,14 +1565,16 @@ declare module "string_decoder" { } declare module "tls" { - import crypto = require("crypto"); - import net = require("net"); - import stream = require("stream"); + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; var CLIENT_RENEG_LIMIT: number; var CLIENT_RENEG_WINDOW: number; export interface TlsOptions { + host?: string; + port?: number; pfx?: any; //string or buffer key?: any; //string or buffer passphrase?: string; @@ -1050,11 +1643,27 @@ declare module "tls" { cleartext: any; } + export interface SecureContextOptions { + pfx?: any; //string | buffer + key?: any; //string | buffer + passphrase?: string; + cert?: any; // string | buffer + ca?: any; // string | buffer + crl?: any; // string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; } declare module "crypto" { @@ -1103,12 +1712,12 @@ declare module "crypto" { setAutoPadding(auto_padding: boolean): void; } export function createSign(algorithm: string): Signer; - interface Signer { + interface Signer extends NodeJS.WritableStream { update(data: any): void; sign(private_key: string, output_format: string): string; } export function createVerify(algorith: string): Verify; - interface Verify { + interface Verify extends NodeJS.WritableStream { update(data: any): void; verify(object: string, signature: string, signature_format?: string): boolean; } @@ -1125,8 +1734,10 @@ declare module "crypto" { setPrivateKey(public_key: string, encoding?: string): void; } export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; - export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; + export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number) : Buffer; + export function pbkdf2Sync(password: string|Buffer, salt: string|Buffer, iterations: number, keylen: number, digest: string) : Buffer; export function randomBytes(size: number): Buffer; export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; export function pseudoRandomBytes(size: number): Buffer; @@ -1134,9 +1745,9 @@ declare module "crypto" { } declare module "stream" { - import events = require("events"); + import * as events from "events"; - export interface Stream extends events.EventEmitter { + export class Stream extends events.EventEmitter { pipe(destination: T, options?: { end?: boolean; }): T; } @@ -1156,8 +1767,7 @@ declare module "stream" { resume(): void; pipe(destination: T, options?: { end?: boolean; }): T; unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; + unshift(chunk: any): void; wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; push(chunk: any, encoding?: string): boolean; } @@ -1165,20 +1775,18 @@ declare module "stream" { export interface WritableOptions { highWaterMark?: number; decodeStrings?: boolean; + objectMode?: boolean; } export class Writable extends events.EventEmitter implements NodeJS.WritableStream { writable: boolean; constructor(opts?: WritableOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; } export interface DuplexOptions extends ReadableOptions, WritableOptions { @@ -1189,15 +1797,12 @@ declare module "stream" { export class Duplex extends Readable implements NodeJS.ReadWriteStream { writable: boolean; constructor(opts?: DuplexOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; } export interface TransformOptions extends ReadableOptions, WritableOptions {} @@ -1207,8 +1812,7 @@ declare module "stream" { readable: boolean; writable: boolean; constructor(opts?: TransformOptions); - _transform(chunk: Buffer, encoding: string, callback: Function): void; - _transform(chunk: string, encoding: string, callback: Function): void; + _transform(chunk: any, encoding: string, callback: Function): void; _flush(callback: Function): void; read(size?: number): any; setEncoding(encoding: string): void; @@ -1216,17 +1820,14 @@ declare module "stream" { resume(): void; pipe(destination: T, options?: { end?: boolean; }): T; unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; + unshift(chunk: any): void; wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; push(chunk: any, encoding?: string): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; } export class PassThrough extends Transform {} @@ -1253,6 +1854,7 @@ declare module "util" { export function isDate(object: any): boolean; export function isError(object: any): boolean; export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key:string): (msg:string,...param: any[])=>void; } declare module "assert" { @@ -1278,6 +1880,8 @@ declare module "assert" { export function notDeepEqual(acutal: any, expected: any, message?: string): void; export function strictEqual(actual: any, expected: any, message?: string): void; export function notStrictEqual(actual: any, expected: any, message?: string): void; + export function deepStrictEqual(actual: any, expected: any, message?: string): void; + export function notDeepStrictEqual(actual: any, expected: any, message?: string): void; export var throws: { (block: Function, message?: string): void; (block: Function, error: Function, message?: string): void; @@ -1299,7 +1903,7 @@ declare module "assert" { } declare module "tty" { - import net = require("net"); + import * as net from "net"; export function isatty(fd: number): boolean; export interface ReadStream extends net.Socket { @@ -1313,7 +1917,7 @@ declare module "tty" { } declare module "domain" { - import events = require("events"); + import * as events from "events"; export class Domain extends events.EventEmitter { run(fn: Function): void; @@ -1332,3 +1936,227 @@ declare module "domain" { export function create(): Domain; } + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; +} diff --git a/platform/built-in-server/client/node-rpc-client/typings/tsd.d.ts b/platform/built-in-server/client/node-rpc-client/typings/tsd.d.ts deleted file mode 100644 index ea098ee01b97..000000000000 --- a/platform/built-in-server/client/node-rpc-client/typings/tsd.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file diff --git a/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java b/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java index f45c6f309ede..264dc890663b 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java +++ b/platform/built-in-server/src/org/jetbrains/ide/AboutHttpService.java @@ -34,6 +34,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.io.OutputStream; /** * @api {get} /about The application info @@ -41,6 +42,7 @@ import java.io.IOException; * @apiGroup Platform * * @apiParam {Boolean} [registeredFileTypes=false] Whether to include the list of registered file types. + * @apiParam {Boolean} [more=false] Whether to include the full info. * * @apiSuccess {String} name The full application name. * @apiSuccess {String} productName The product name. @@ -58,7 +60,7 @@ import java.io.IOException; * @apiUse SuccessExample * @apiUse SuccessExampleWithRegisteredFileTypes */ -class AboutHttpService extends RestService { +public class AboutHttpService extends RestService { @NotNull @Override protected String getServiceName() { @@ -73,10 +75,17 @@ class AboutHttpService extends RestService { @Nullable @Override public String execute(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) throws IOException { - BuildNumber build = ApplicationInfo.getInstance().getBuild(); @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") BufferExposingByteArrayOutputStream byteOut = new BufferExposingByteArrayOutputStream(); - JsonWriter writer = createJsonWriter(byteOut); + getAbout(byteOut, urlDecoder); + send(byteOut, request, context); + return null; + } + + public static void getAbout(@NotNull OutputStream out, @Nullable QueryStringDecoder urlDecoder) throws IOException { + BuildNumber build = ApplicationInfo.getInstance().getBuild(); + + JsonWriter writer = createJsonWriter(out); writer.beginObject(); ApplicationInfoEx appInfo = ApplicationInfoEx.getInstanceEx(); @@ -94,7 +103,7 @@ class AboutHttpService extends RestService { writer.name("buildNumber").value(build.getBuildNumber()); } - if (getBooleanParameter("registeredFileTypes", urlDecoder)) { + if (urlDecoder != null && getBooleanParameter("registeredFileTypes", urlDecoder)) { writer.name("registeredFileTypes").beginArray(); for (FileType fileType : FileTypeRegistry.getInstance().getRegisteredFileTypes()) { writer.beginObject(); @@ -106,8 +115,7 @@ class AboutHttpService extends RestService { writer.endArray(); } - String uri = request.getUri(); - if (uri != null && uri.endsWith("?more")) { + if (urlDecoder != null && getBooleanParameter("more", urlDecoder)) { writer.name("vendor").value(appInfo.getCompanyName()); writer.name("isEAP").value(appInfo.isEAP()); writer.name("productCode").value(appInfo.getBuild().getProductCode()); @@ -122,12 +130,5 @@ class AboutHttpService extends RestService { writer.endObject(); writer.close(); - send(byteOut, request, context); - return null; - } - - @Override - protected boolean activateToolBeforeExecution() { - return false; } } diff --git a/platform/built-in-server/src/org/jetbrains/ide/ActivateApplicationHttpService.java b/platform/built-in-server/src/org/jetbrains/ide/ActivateApplicationHttpService.java index e1cadcfbe3a2..27fc0ee28dda 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/ActivateApplicationHttpService.java +++ b/platform/built-in-server/src/org/jetbrains/ide/ActivateApplicationHttpService.java @@ -38,6 +38,7 @@ public class ActivateApplicationHttpService extends RestService { if (frame instanceof Window) { sendOk(request, context); Runnable runnable = new Runnable() { + @Override public void run() { Window window = (Window)frame; window.toFront(); diff --git a/platform/built-in-server/src/org/jetbrains/ide/JetBrainsProtocolHandlerHttpService.java b/platform/built-in-server/src/org/jetbrains/ide/JetBrainsProtocolHandlerHttpService.java index a095fefb43d2..811f13985acb 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/JetBrainsProtocolHandlerHttpService.java +++ b/platform/built-in-server/src/org/jetbrains/ide/JetBrainsProtocolHandlerHttpService.java @@ -40,6 +40,8 @@ public class JetBrainsProtocolHandlerHttpService extends RestService { final String url = reader.nextString(); reader.endObject(); + activateLastFocusedFrame(); + if (URL_PARAM_NAME.equals(name) && url != null && url.startsWith(JetBrainsProtocolHandler.PROTOCOL)) { JetBrainsProtocolHandler.processJetBrainsLauncherParameters(url); ApplicationManager.getApplication().invokeLater(new Runnable() { diff --git a/platform/built-in-server/src/org/jetbrains/ide/ProjectSetRequestHandler.java b/platform/built-in-server/src/org/jetbrains/ide/ProjectSetRequestHandler.java index 085eaf90d415..351ac3483cd9 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/ProjectSetRequestHandler.java +++ b/platform/built-in-server/src/org/jetbrains/ide/ProjectSetRequestHandler.java @@ -67,6 +67,7 @@ public class ProjectSetRequestHandler extends RestService { @Override public void run() { new ProjectSetReader().readDescriptor(descriptor, null); + activateLastFocusedFrame(); } }); sendOk(request, context); diff --git a/platform/built-in-server/src/org/jetbrains/ide/RestService.java b/platform/built-in-server/src/org/jetbrains/ide/RestService.java index c05b71e3713c..4b4df33cdd26 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/RestService.java +++ b/platform/built-in-server/src/org/jetbrains/ide/RestService.java @@ -44,6 +44,7 @@ import org.jetbrains.io.Responses; import java.awt.*; import java.io.IOException; import java.io.InputStreamReader; +import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.List; @@ -103,10 +104,6 @@ public abstract class RestService extends HttpRequestHandler { return false; } - protected boolean activateToolBeforeExecution() { - return true; - } - @NotNull /** * Use human-readable name or UUID if it is an internal service. @@ -118,13 +115,6 @@ public abstract class RestService extends HttpRequestHandler { @Override public final boolean process(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) throws IOException { try { - if (activateToolBeforeExecution()) { - IdeFrame frame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame(); - if (frame instanceof Window) { - ((Window)frame).toFront(); - } - } - String error = execute(urlDecoder, request, context); if (error != null) { Responses.sendStatus(HttpResponseStatus.BAD_REQUEST, context.channel(), error, request); @@ -147,6 +137,13 @@ public abstract class RestService extends HttpRequestHandler { return true; } + protected final void activateLastFocusedFrame() { + IdeFrame frame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame(); + if (frame instanceof Window) { + ((Window)frame).toFront(); + } + } + @Nullable("error text or null if successful") /** * Return error or send response using {@link #sendOk(FullHttpRequest, ChannelHandlerContext)}, {@link #send(BufferExposingByteArrayOutputStream, FullHttpRequest, ChannelHandlerContext)} @@ -161,7 +158,7 @@ public abstract class RestService extends HttpRequestHandler { } @NotNull - protected static JsonWriter createJsonWriter(@NotNull BufferExposingByteArrayOutputStream out) { + protected static JsonWriter createJsonWriter(@NotNull OutputStream out) { JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, CharsetToolkit.UTF8_CHARSET)); writer.setIndent(" "); return writer; diff --git a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt index 17bf1fa7d732..7d79cdbbf4f3 100644 --- a/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt +++ b/platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt @@ -82,7 +82,7 @@ abstract class FastCgiService(project: Project) : SingleConnectionNetService(pro promise = processHandler.get() } - promise + (promise as Promise) .done { fastCgiRequest.writeToServerChannel(notEmptyContent, processChannel.get()!!) } .rejected { Promise.logError(LOG, it) diff --git a/platform/built-in-server/src/org/jetbrains/io/jsonRpc/JsonRpcServer.java b/platform/built-in-server/src/org/jetbrains/io/jsonRpc/JsonRpcServer.java index 17e265c14ebb..857b711f0ce5 100644 --- a/platform/built-in-server/src/org/jetbrains/io/jsonRpc/JsonRpcServer.java +++ b/platform/built-in-server/src/org/jetbrains/io/jsonRpc/JsonRpcServer.java @@ -96,6 +96,10 @@ public class JsonRpcServer implements MessageServer { if (!isBinary) { reader.beginArray(); } + else { + // to allow top-level member to be not a object or array + reader.setLenient(true); + } int messageId = reader.peek() == JsonToken.NUMBER ? reader.nextInt() : -1; String domainName = reader.nextString(); @@ -155,7 +159,22 @@ public class JsonRpcServer implements MessageServer { method.setAccessible(true); Object result = method.invoke(isStatic ? null : domain, parameters); if (messageId != -1) { - client.send(encodeMessage(client.getByteBufAllocator(), messageId, null, null, null, new Object[]{result})); + if (result instanceof ByteBuf) { + ByteBuf buffer = (ByteBuf)result; + boolean success = false; + try { + client.send(encodeMessage(client.getByteBufAllocator(), messageId, null, null, buffer, null)); + success = true; + } + finally { + if (!success) { + buffer.release(); + } + } + } + else { + client.send(encodeMessage(client.getByteBufAllocator(), messageId, null, null, null, new Object[]{result})); + } } return; } diff --git a/platform/built-in-server/src/org/jetbrains/io/jsonRpc/socket/RpcBinaryRequestHandler.java b/platform/built-in-server/src/org/jetbrains/io/jsonRpc/socket/RpcBinaryRequestHandler.java index 7b5987fc2472..3f59d4c259e6 100644 --- a/platform/built-in-server/src/org/jetbrains/io/jsonRpc/socket/RpcBinaryRequestHandler.java +++ b/platform/built-in-server/src/org/jetbrains/io/jsonRpc/socket/RpcBinaryRequestHandler.java @@ -74,7 +74,6 @@ class RpcBinaryRequestHandler extends BinaryRequestHandler implements ExceptionH private class MyDecoder extends MessageDecoder { private State state = State.LENGTH; - private int contentLength; private final SocketClient client; diff --git a/platform/built-in-server/testSrc/BinaryRequestHandlerTest.kt b/platform/built-in-server/testSrc/BinaryRequestHandlerTest.kt index f8866b383c97..015ff80dd1a9 100644 --- a/platform/built-in-server/testSrc/BinaryRequestHandlerTest.kt +++ b/platform/built-in-server/testSrc/BinaryRequestHandlerTest.kt @@ -56,7 +56,7 @@ internal class BinaryRequestHandlerTest { try { result.rejected(object : Consumer { override fun consume(error: Throwable) { - TestCase.fail(error.getMessage()) + TestCase.fail(error.message) } }) diff --git a/platform/configuration-store-impl/src/ExportSettingsAction.kt b/platform/configuration-store-impl/src/ExportSettingsAction.kt index ad32c14fe37d..249ddfb03858 100644 --- a/platform/configuration-store-impl/src/ExportSettingsAction.kt +++ b/platform/configuration-store-impl/src/ExportSettingsAction.kt @@ -186,12 +186,7 @@ fun getExportableComponentsMap(onlyExisting: Boolean, } if (onlyExisting || onlyPaths != null) { - val it = result.keySet().iterator() - while (it.hasNext()) { - if (isSkipFile(it.next())) { - it.remove() - } - } + result.keys.removeAll(::isSkipFile) } ServiceManagerImpl.processAllImplementationClasses(ApplicationManager.getApplication() as ApplicationImpl, object : PairProcessor, PluginDescriptor> { diff --git a/platform/configuration-store-impl/src/SchemeManagerImpl.kt b/platform/configuration-store-impl/src/SchemeManagerImpl.kt index 4f81db442e4d..7f8df4c186d4 100644 --- a/platform/configuration-store-impl/src/SchemeManagerImpl.kt +++ b/platform/configuration-store-impl/src/SchemeManagerImpl.kt @@ -362,7 +362,7 @@ public class SchemeManagerImpl(private val removeScheme(existingScheme) } else { - if (schemeExtension != extension && schemeToInfo.get(existingScheme)?.fileNameWithoutExtension == fileNameWithoutExtension) { + if (schemeExtension != extension && schemeToInfo.get(existingScheme as Scheme)?.fileNameWithoutExtension == fileNameWithoutExtension) { // 1.oldExt is loading after 1.newExt - we should delete 1.oldExt filesToDelete.add(fileName.toString()) } @@ -678,11 +678,7 @@ public class SchemeManagerImpl(private val schemes.clear() } else { - for (i in schemes.indices.reversed()) { - if (removeCondition.value(schemes.get(i))) { - schemes.remove(i) - } - } + schemes.removeAll { removeCondition.value(it) } } retainExternalInfo(newSchemes) @@ -741,8 +737,8 @@ public class SchemeManagerImpl(private val toReplace = i if (replaceExisting && existing is ExternalizableScheme) { - val oldInfo = schemeToInfo.remove(existing as E) - if (oldInfo != null && scheme is ExternalizableScheme && !schemeToInfo.containsKey(scheme)) { + val oldInfo = schemeToInfo.remove(existing as ExternalizableScheme) + if (oldInfo != null && scheme is ExternalizableScheme && !schemeToInfo.containsKey(scheme as ExternalizableScheme)) { @Suppress("UNCHECKED_CAST") schemeToInfo.put(scheme as E, oldInfo) } @@ -762,7 +758,7 @@ public class SchemeManagerImpl(private val } if (scheme is ExternalizableScheme && filesToDelete.isNotEmpty()) { - val info = schemeToInfo.get(scheme) + val info = schemeToInfo[scheme as ExternalizableScheme] if (info != null) { filesToDelete.remove("${info.fileName}") } @@ -841,9 +837,9 @@ public class SchemeManagerImpl(private val } if (s is ExternalizableScheme) { - schemeToInfo.remove(s as E)?.scheduleDelete() + schemeToInfo.remove(s as ExternalizableScheme)?.scheduleDelete() } - schemes.remove(i) + schemes.removeAt(i) break } } diff --git a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt index 94e6a35b57b6..5254eafe518b 100644 --- a/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/SchemeManagerTest.kt @@ -354,7 +354,7 @@ private fun checkSchemes(baseDir: File, expected: String, ignoreDeleted: Boolean } } - for (file in fileToSchemeMap.keySet()) { + for (file in fileToSchemeMap.keys) { assertThat(File(baseDir, "$file.xml")).isFile() } diff --git a/platform/configuration-store-impl/testSrc/StorageManagerTest.kt b/platform/configuration-store-impl/testSrc/StorageManagerTest.kt index 7f5a9ae3bc92..de91c8966b8c 100644 --- a/platform/configuration-store-impl/testSrc/StorageManagerTest.kt +++ b/platform/configuration-store-impl/testSrc/StorageManagerTest.kt @@ -62,7 +62,7 @@ internal class StorageManagerTest { TestCase.fail("Exception expected") } catch (e: IllegalArgumentException) { - assertThat(e.getMessage()).isEqualTo("Unknown macro: \$UNKNOWN_MACRO$ in storage file spec: \$UNKNOWN_MACRO$/test.xml") + assertThat(e.message).isEqualTo("Unknown macro: \$UNKNOWN_MACRO$ in storage file spec: \$UNKNOWN_MACRO$/test.xml") } } diff --git a/platform/configuration-store-impl/testSrc/configuration-store-tests.iml b/platform/configuration-store-impl/testSrc/configuration-store-tests.iml index d563be49ab2b..cc0f357793cc 100644 --- a/platform/configuration-store-impl/testSrc/configuration-store-tests.iml +++ b/platform/configuration-store-impl/testSrc/configuration-store-tests.iml @@ -18,6 +18,5 @@ - \ No newline at end of file diff --git a/platform/core-api/src/org/jetbrains/concurrency/AsyncPromise.java b/platform/core-api/src/org/jetbrains/concurrency/AsyncPromise.java index d1dc07b7a441..5874cfb9b0c4 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/AsyncPromise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/AsyncPromise.java @@ -30,8 +30,8 @@ public class AsyncPromise extends Promise implements Getter { public static final RuntimeException OBSOLETE_ERROR = Promise.createError("Obsolete"); - private volatile Consumer done; - private volatile Consumer rejected; + private volatile Consumer done; + private volatile Consumer rejected; protected volatile State state = State.PENDING; // result object or error message @@ -45,7 +45,7 @@ public class AsyncPromise extends Promise implements Getter { @NotNull @Override - public Promise done(@NotNull Consumer done) { + public Promise done(@NotNull Consumer done) { if (isObsolete(done)) { return this; } @@ -94,9 +94,9 @@ public class AsyncPromise extends Promise implements Getter { @SuppressWarnings("SynchronizeOnThis") private static final class CompoundConsumer implements Consumer { - private List> consumers = new ArrayList>(); + private List> consumers = new ArrayList>(); - public CompoundConsumer(@NotNull Consumer c1, @NotNull Consumer c2) { + public CompoundConsumer(@NotNull Consumer c1, @NotNull Consumer c2) { synchronized (this) { consumers.add(c1); consumers.add(c2); @@ -105,14 +105,14 @@ public class AsyncPromise extends Promise implements Getter { @Override public void consume(T t) { - List> list; + List> list; synchronized (this) { list = consumers; consumers = null; } if (list != null) { - for (Consumer consumer : list) { + for (Consumer consumer : list) { if (!isObsolete(consumer)) { consumer.consume(t); } @@ -120,7 +120,7 @@ public class AsyncPromise extends Promise implements Getter { } } - public void add(@NotNull Consumer consumer) { + public void add(@NotNull Consumer consumer) { synchronized (this) { if (consumers != null) { consumers.add(consumer); @@ -131,7 +131,7 @@ public class AsyncPromise extends Promise implements Getter { @Override @NotNull - public Promise then(@NotNull final Function fulfilled) { + public Promise then(@NotNull final Function fulfilled) { switch (state) { case PENDING: break; @@ -168,7 +168,7 @@ public class AsyncPromise extends Promise implements Getter { } @Override - public void notify(@NotNull final AsyncPromise child) { + public void notify(@NotNull final AsyncPromise child) { LOG.assertTrue(child != this); switch (state) { @@ -203,7 +203,7 @@ public class AsyncPromise extends Promise implements Getter { @Override @NotNull - public Promise thenAsync(@NotNull final AsyncFunction fulfilled) { + public Promise thenAsync(@NotNull final AsyncFunction fulfilled) { switch (state) { case PENDING: break; @@ -249,7 +249,7 @@ public class AsyncPromise extends Promise implements Getter { @Override @NotNull - public Promise processed(@NotNull final AsyncPromise fulfilled) { + public Promise processed(@NotNull final AsyncPromise fulfilled) { switch (state) { case PENDING: break; @@ -287,7 +287,7 @@ public class AsyncPromise extends Promise implements Getter { } @NotNull - private static Consumer setHandler(@Nullable Consumer oldConsumer, @NotNull Consumer newConsumer) { + private static Consumer setHandler(@Nullable Consumer oldConsumer, @NotNull Consumer newConsumer) { if (oldConsumer == null) { return newConsumer; } @@ -308,7 +308,7 @@ public class AsyncPromise extends Promise implements Getter { this.result = result; state = State.FULFILLED; - Consumer done = this.done; + Consumer done = this.done; clearHandlers(); if (done != null && !isObsolete(done)) { done.consume(result); @@ -331,7 +331,7 @@ public class AsyncPromise extends Promise implements Getter { result = error; state = State.REJECTED; - Consumer rejected = this.rejected; + Consumer rejected = this.rejected; clearHandlers(); if (rejected != null) { if (!isObsolete(rejected)) { @@ -350,7 +350,7 @@ public class AsyncPromise extends Promise implements Getter { } @Override - public Promise processed(@NotNull final Consumer processed) { + public Promise processed(@NotNull final Consumer processed) { done(processed); rejected(new Consumer() { @Override diff --git a/platform/core-api/src/org/jetbrains/concurrency/DonePromise.java b/platform/core-api/src/org/jetbrains/concurrency/DonePromise.java index 08035b3a89cc..1f619862257d 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/DonePromise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/DonePromise.java @@ -29,7 +29,7 @@ class DonePromise extends Promise implements Getter { @NotNull @Override - public Promise done(@NotNull Consumer done) { + public Promise done(@NotNull Consumer done) { if (!AsyncPromise.isObsolete(done)) { done.consume(result); } @@ -38,13 +38,13 @@ class DonePromise extends Promise implements Getter { @NotNull @Override - public Promise processed(@NotNull AsyncPromise fulfilled) { + public Promise processed(@NotNull AsyncPromise fulfilled) { fulfilled.setResult(result); return this; } @Override - public Promise processed(@NotNull Consumer processed) { + public Promise processed(@NotNull Consumer processed) { done(processed); return this; } @@ -57,7 +57,7 @@ class DonePromise extends Promise implements Getter { @NotNull @Override - public Promise then(@NotNull Function done) { + public Promise then(@NotNull Function done) { if (done instanceof Obsolescent && ((Obsolescent)done).isObsolete()) { return Promise.reject("obsolete"); } @@ -68,7 +68,7 @@ class DonePromise extends Promise implements Getter { @NotNull @Override - public Promise thenAsync(@NotNull AsyncFunction done) { + public Promise thenAsync(@NotNull AsyncFunction done) { return done.fun(result); } @@ -84,7 +84,7 @@ class DonePromise extends Promise implements Getter { } @Override - public void notify(@NotNull AsyncPromise child) { + public void notify(@NotNull AsyncPromise child) { child.setResult(result); } } \ No newline at end of file diff --git a/platform/core-api/src/org/jetbrains/concurrency/Promise.java b/platform/core-api/src/org/jetbrains/concurrency/Promise.java index 3075b324432d..15566aa3c80e 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/Promise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/Promise.java @@ -138,21 +138,21 @@ public abstract class Promise { } @NotNull - public abstract Promise done(@NotNull Consumer done); + public abstract Promise done(@NotNull Consumer done); @NotNull - public abstract Promise processed(@NotNull AsyncPromise fulfilled); + public abstract Promise processed(@NotNull AsyncPromise fulfilled); @NotNull public abstract Promise rejected(@NotNull Consumer rejected); - public abstract Promise processed(@NotNull Consumer processed); + public abstract Promise processed(@NotNull Consumer processed); @NotNull - public abstract Promise then(@NotNull Function done); + public abstract Promise then(@NotNull Function done); @NotNull - public abstract Promise thenAsync(@NotNull AsyncFunction done); + public abstract Promise thenAsync(@NotNull AsyncFunction done); @NotNull public abstract State getState(); @@ -195,5 +195,5 @@ public abstract class Promise { } } - public abstract void notify(@NotNull AsyncPromise child); + public abstract void notify(@NotNull AsyncPromise child); } \ No newline at end of file diff --git a/platform/core-api/src/org/jetbrains/concurrency/RejectedPromise.java b/platform/core-api/src/org/jetbrains/concurrency/RejectedPromise.java index f0652a76dd60..d9a8946b1495 100644 --- a/platform/core-api/src/org/jetbrains/concurrency/RejectedPromise.java +++ b/platform/core-api/src/org/jetbrains/concurrency/RejectedPromise.java @@ -28,13 +28,13 @@ class RejectedPromise extends Promise { @NotNull @Override - public Promise done(@NotNull Consumer done) { + public Promise done(@NotNull Consumer done) { return this; } @NotNull @Override - public Promise processed(@NotNull AsyncPromise fulfilled) { + public Promise processed(@NotNull AsyncPromise fulfilled) { fulfilled.setError(error); return this; } @@ -49,21 +49,21 @@ class RejectedPromise extends Promise { } @Override - public RejectedPromise processed(@NotNull Consumer processed) { + public RejectedPromise processed(@NotNull Consumer processed) { processed.consume(null); return this; } @NotNull @Override - public Promise then(@NotNull Function done) { + public Promise then(@NotNull Function done) { //noinspection unchecked return (Promise)this; } @NotNull @Override - public Promise thenAsync(@NotNull AsyncFunction done) { + public Promise thenAsync(@NotNull AsyncFunction done) { //noinspection unchecked return (Promise)this; } @@ -75,7 +75,7 @@ class RejectedPromise extends Promise { } @Override - public void notify(@NotNull AsyncPromise child) { + public void notify(@NotNull AsyncPromise child) { child.setError(error); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/util/UrlImpl.java b/platform/platform-impl/src/com/intellij/util/UrlImpl.java index 6876998e0a03..99b6e629415f 100644 --- a/platform/platform-impl/src/com/intellij/util/UrlImpl.java +++ b/platform/platform-impl/src/com/intellij/util/UrlImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.intellij.util; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.util.io.URLUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -71,7 +70,7 @@ public final class UrlImpl implements Url { @Override public boolean isInLocalFileSystem() { - return StandardFileSystems.FILE_PROTOCOL.equals(scheme); + return URLUtil.FILE_PROTOCOL.equals(scheme); } @Nullable diff --git a/platform/script-debugger/backend/src/EvaluateContextBase.kt b/platform/script-debugger/backend/src/EvaluateContextBase.kt index 16f5cd0f4efe..9477f118f5c7 100644 --- a/platform/script-debugger/backend/src/EvaluateContextBase.kt +++ b/platform/script-debugger/backend/src/EvaluateContextBase.kt @@ -16,10 +16,11 @@ package org.jetbrains.debugger import org.jetbrains.concurrency.Promise +import org.jetbrains.concurrency.then import org.jetbrains.debugger.values.ValueManager abstract class EvaluateContextBase(val valueManager: VALUE_MANAGER) : EvaluateContext { override fun withValueManager(objectGroup: String) = this - override fun refreshOnDone(promise: Promise<*>): Promise<*> = promise.then { valueManager.clearCaches() } + override fun refreshOnDone(promise: Promise<*>): Promise<*> = (promise as Promise).then { valueManager.clearCaches() } } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/SuspendContext.kt b/platform/script-debugger/backend/src/SuspendContext.kt index 4fccd74f80a6..0aa92d760ef7 100755 --- a/platform/script-debugger/backend/src/SuspendContext.kt +++ b/platform/script-debugger/backend/src/SuspendContext.kt @@ -69,7 +69,7 @@ abstract class ContextDependentAsyncResultConsumer(private val context: Suspe } -inline fun Promise.done(context: SuspendContext<*>, crossinline handler: (result: T) -> Unit) = done(object : ContextDependentAsyncResultConsumer(context) { +inline fun Promise.done(context: SuspendContext<*>, crossinline handler: (result: T) -> Unit) = (this as Promise).done(object : ContextDependentAsyncResultConsumer(context) { override fun consume(result: T, vm: Vm) = handler(result) }) diff --git a/platform/script-debugger/backend/src/SuspendContextManager.kt b/platform/script-debugger/backend/src/SuspendContextManager.kt index a583270cf06f..2822370bdf00 100644 --- a/platform/script-debugger/backend/src/SuspendContextManager.kt +++ b/platform/script-debugger/backend/src/SuspendContextManager.kt @@ -27,7 +27,7 @@ interface SuspendContextManager { val contextOrFail: SuspendContext - fun isContextObsolete(context: SuspendContext): Boolean + fun isContextObsolete(context: SuspendContext<*>): Boolean fun setOverlayMessage(message: String?) diff --git a/platform/script-debugger/backend/src/SuspendContextManagerBase.kt b/platform/script-debugger/backend/src/SuspendContextManagerBase.kt index 286980038fd7..a1fb77e3a91d 100644 --- a/platform/script-debugger/backend/src/SuspendContextManagerBase.kt +++ b/platform/script-debugger/backend/src/SuspendContextManagerBase.kt @@ -44,7 +44,7 @@ abstract class SuspendContextManagerBase): Promise<*> { val context = contextOrFail - promise.done { contextDismissed(context) } + (promise as Promise).done { contextDismissed(context) } return promise } @@ -72,7 +72,7 @@ abstract class SuspendContextManagerBase - override fun isContextObsolete(context: SuspendContext) = this.context !== context + override fun isContextObsolete(context: SuspendContext<*>) = this.context !== context override fun setOverlayMessage(message: String?) { } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt index 83ff590c0175..b4fe404d341c 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/DebugProcessImpl.kt @@ -24,10 +24,7 @@ import com.intellij.util.io.socketConnection.ConnectionStatus import com.intellij.xdebugger.DefaultDebugProcessHandler import com.intellij.xdebugger.XDebugProcess import com.intellij.xdebugger.XDebugSession -import com.intellij.xdebugger.breakpoints.XBreakpoint -import com.intellij.xdebugger.breakpoints.XBreakpointHandler -import com.intellij.xdebugger.breakpoints.XLineBreakpoint -import com.intellij.xdebugger.breakpoints.XLineBreakpointType +import com.intellij.xdebugger.breakpoints.* import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider import com.intellij.xdebugger.frame.XSuspendContext import com.intellij.xdebugger.stepping.XSmartStepIntoHandler @@ -200,7 +197,7 @@ abstract class DebugProcessImpl>(session: XDebugSession, } override final fun startPausing() { - connection.vm.suspendContextManager.suspend().rejected(RejectErrorReporter(session, "Cannot pause")) + connection.vm!!.suspendContextManager.suspend().rejected(RejectErrorReporter(session, "Cannot pause")) } override final fun getCurrentStateMessage() = connection.state.message @@ -218,7 +215,8 @@ abstract class DebugProcessImpl>(session: XDebugSession, override fun isLibraryFrameFilterSupported() = true } -class LineBreakpointHandler(breakpointTypeClass: Class>, private val manager: LineBreakpointManager) : XBreakpointHandler>(breakpointTypeClass) { +class LineBreakpointHandler(breakpointTypeClass: Class>, private val manager: LineBreakpointManager) + : XBreakpointHandler>(breakpointTypeClass as Class, out XBreakpointProperties<*>>>) { override fun registerBreakpoint(breakpoint: XLineBreakpoint<*>) { manager.setBreakpoint(breakpoint) } diff --git a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt index 2a94fd62e452..904ae71baabe 100644 --- a/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt +++ b/platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.kt @@ -178,7 +178,7 @@ class VariableView(name: String, private val variable: Variable, private val con } if (hasIndexedProperties == hasNamedProperties || additionalProperties != null) { - Promise.all(promises).processed(object : ObsolescentConsumer(node) { + (Promise.all(promises) as Promise).processed(object : ObsolescentConsumer(node) { override fun consume(aVoid: Any?) = node.addChildren(XValueChildrenList.EMPTY, true) }) } @@ -302,7 +302,7 @@ class VariableView(name: String, private val variable: Variable, private val con } override fun setValue(expression: String, callback: XValueModifier.XModificationCallback) { - variable.valueModifier!!.setValue(variable, expression, evaluateContext) + (variable.valueModifier!!.setValue(variable, expression, evaluateContext) as Promise) .done { value = null callback.valueModified() diff --git a/platform/script-debugger/protocol/protocol-reader/src/InterfaceReader.kt b/platform/script-debugger/protocol/protocol-reader/src/InterfaceReader.kt index 0c11cad8c7e2..0cabc7230f40 100644 --- a/platform/script-debugger/protocol/protocol-reader/src/InterfaceReader.kt +++ b/platform/script-debugger/protocol/protocol-reader/src/InterfaceReader.kt @@ -78,12 +78,13 @@ internal class InterfaceReader(val typeToTypeHandler: LinkedHashMap, Ty hasUnresolved = false // refs can be modified - new items can be added for (i in 0..refs.size - 1) { - val ref = refs.get(i) - ref.type = typeToTypeHandler.get(ref.typeClass) + val ref: TypeRef = refs.get(i) + val typeClass: Class = ref.typeClass + (ref as TypeRef).type = typeToTypeHandler.get(typeClass) as TypeWriter? if (ref.type == null) { - createIfNotExists(ref.typeClass) + createIfNotExists(typeClass) hasUnresolved = true - ref.type = typeToTypeHandler.get(ref.typeClass) ?: throw IllegalStateException() + (ref as TypeRef).type = typeToTypeHandler.get(typeClass) as TypeWriter? ?: throw IllegalStateException() } } } @@ -126,7 +127,7 @@ internal class InterfaceReader(val typeToTypeHandler: LinkedHashMap, Ty for (ref in refs) { if (ref.typeClass == typeClass) { assert(ref.type == null) - ref.type = typeWriter + (ref as TypeRef).type = typeWriter as TypeWriter break } } diff --git a/platform/testFramework/test-framework-java8/FixtureRule.kt b/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt similarity index 99% rename from platform/testFramework/test-framework-java8/FixtureRule.kt rename to platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt index 65ca4821c237..3d3a5e18c45c 100644 --- a/platform/testFramework/test-framework-java8/FixtureRule.kt +++ b/platform/testFramework/src/com/intellij/testFramework/FixtureRule.kt @@ -58,6 +58,7 @@ open class ApplicationRule : ExternalResource() { override public final fun before() { IdeaTestApplication.getInstance() TestRunnerUtil.replaceIdeEventQueueSafely() + (PersistentFS.getInstance() as PersistentFSImpl).cleanPersistedContents() } } diff --git a/platform/testFramework/test-framework-java8/TemporaryDirectory.kt b/platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt similarity index 100% rename from platform/testFramework/test-framework-java8/TemporaryDirectory.kt rename to platform/testFramework/src/com/intellij/testFramework/TemporaryDirectory.kt diff --git a/platform/testFramework/src/com/intellij/testFramework/fsBuilder.kt b/platform/testFramework/src/com/intellij/testFramework/fsBuilder.kt new file mode 100644 index 000000000000..3488972488e8 --- /dev/null +++ b/platform/testFramework/src/com/intellij/testFramework/fsBuilder.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.testFramework + +import java.nio.file.FileSystem + +fun FileSystem.file(path: String, data: ByteArray): FileSystem { + getPath(path).write(data) + return this +} + +fun FileSystem.file(path: String, data: String) = file(path, data.toByteArray()) \ No newline at end of file diff --git a/platform/testFramework/test-framework-java8/path.kt b/platform/testFramework/src/com/intellij/testFramework/path.kt similarity index 83% rename from platform/testFramework/test-framework-java8/path.kt rename to platform/testFramework/src/com/intellij/testFramework/path.kt index 0e354d5d822a..d2c5f95e763a 100644 --- a/platform/testFramework/test-framework-java8/path.kt +++ b/platform/testFramework/src/com/intellij/testFramework/path.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.testFramework import com.intellij.openapi.util.io.FileUtil diff --git a/platform/testFramework/test-framework-java8.iml b/platform/testFramework/test-framework-java8.iml deleted file mode 100644 index 05d5f2939193..000000000000 --- a/platform/testFramework/test-framework-java8.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/platform/testFramework/test-framework-java8/fsBuilder.kt b/platform/testFramework/test-framework-java8/fsBuilder.kt deleted file mode 100644 index ea32d71474af..000000000000 --- a/platform/testFramework/test-framework-java8/fsBuilder.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.intellij.testFramework - -import java.nio.file.FileSystem - -fun FileSystem.file(path: String, data: ByteArray): FileSystem { - getPath(path).write(data) - return this -} - -fun FileSystem.file(path: String, data: String) = file(path, data.toByteArray()) \ No newline at end of file diff --git a/platform/testFramework/testFramework.iml b/platform/testFramework/testFramework.iml index 3c86f81a1070..b7ca16f78b78 100644 --- a/platform/testFramework/testFramework.iml +++ b/platform/testFramework/testFramework.iml @@ -1,6 +1,6 @@ - + @@ -25,5 +25,6 @@ + \ No newline at end of file diff --git a/platform/testFramework/test-framework-java8/assertJ.kt b/platform/testFramework/testSrc/assertJ.kt similarity index 97% rename from platform/testFramework/test-framework-java8/assertJ.kt rename to platform/testFramework/testSrc/assertJ.kt index d1a396a1b70b..3a64435f6300 100644 --- a/platform/testFramework/test-framework-java8/assertJ.kt +++ b/platform/testFramework/testSrc/assertJ.kt @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt index 97110743e3cd..faeb0b4e9882 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.kt @@ -619,7 +619,7 @@ internal class XmlSerializerTest { TestCase.assertEquals("bye", bean.STRING_V) TestCase.assertNotNull(bean.actions) - TestCase.assertEquals(2, bean.actions!!.size()) + TestCase.assertEquals(2, bean.actions!!.size) TestCase.assertEquals(2, bean.actions!![0].getChildren().size) TestCase.assertEquals(1, bean.actions!![1].getChildren().size) @@ -676,7 +676,7 @@ internal class XmlSerializerTest { val bb = doSerializerTest("\n \n", bean) - for (collection in bb.myMap.keySet()) { + for (collection in bb.myMap.keys) { assertThat(collection).isInstanceOf(Set::class.java) } } diff --git a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt index 31c13234755b..e844da1f80de 100644 --- a/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt +++ b/platform/vcs-log/impl/test/com/intellij/vcs/log/data/VisiblePackBuilderTest.kt @@ -109,7 +109,7 @@ class VisiblePackBuilderTest { } } - graph.providers.entrySet().iterator().next().getValue().setFilteredCommitsProvider(func) + graph.providers.entries.iterator().next().value.setFilteredCommitsProvider(func) val visiblePack = graph.build(filters(VcsLogBranchFilterImpl.fromTextPresentation(setOf("-master"), setOf("master")), userFilter(DEFAULT_USER))) val visibleGraph = visiblePack.getVisibleGraph() assertEquals(3, visibleGraph.getVisibleCommitCount()) @@ -138,7 +138,7 @@ class VisiblePackBuilderTest { }) val dataPack = DataPack.build(commits, mapOf(root to refs), providers, hashMap, true) - val detailsCache = data.entrySet().map { + val detailsCache = data.entries.map { val hash = hashMap.getHash(it.key.getId()) val metadata = if (it.value.user == null) null @@ -226,7 +226,7 @@ class VisiblePackBuilderTest { } class ConstantVcsLogHashMap(val map: Map) : VcsLogHashMap { - val reverseMap = map.entrySet().map { Pair(it.value, it.key) }.toMap() + val reverseMap = map.entries.map { Pair(it.value, it.key) }.toMap() override fun getCommitIndex(hash: Hash, root: VirtualFile) = map.get(hash)!! diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java index adbc7b206b54..9def9119a71d 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XLineBreakpointTypeBase.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.xdebugger.breakpoints; import com.intellij.openapi.project.Project; @@ -8,7 +23,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public abstract class XLineBreakpointTypeBase extends XLineBreakpointType { +public abstract class XLineBreakpointTypeBase extends XLineBreakpointType { private final XDebuggerEditorsProvider myEditorsProvider; protected XLineBreakpointTypeBase(@NonNls @NotNull final String id, @Nls @NotNull final String title, @Nullable XDebuggerEditorsProvider editorsProvider) { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 12bb98488a5f..97450393ccb4 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -303,10 +303,10 @@ bundle="com.siyeh.InspectionGadgetsBundle" key="non.short.circuit.boolean.expression.display.name" groupBundle="messages.InspectionsBundle" groupKey="group.names.probable.bugs" enabledByDefault="false" level="WARNING" implementationClass="com.siyeh.ig.bugs.NonShortCircuitBooleanInspection"/> - + @@ -319,7 +319,8 @@ - diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties index bbd02d90902a..c65a8128fb0f 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties @@ -128,10 +128,10 @@ misspelled.tostring.problem.descriptor=#ref() method should probabl non.short.circuit.boolean.expression.display.name=Non-short-circuit boolean expression non.short.circuit.boolean.expression.problem.descriptor=Non-short-circuit boolean expression #ref #loc non.short.circuit.boolean.expression.replace.quickfix=Replace with short circuit expression -null.argument.to.var.arg.method.display.name=Confusing 'null' argument to var-arg method -null.argument.to.var.arg.method.problem.descriptor=Confusing #ref argument to var-arg method #loc -primitive.array.argument.to.var.arg.method.display.name=Confusing primitive array argument to var-arg method -primitive.array.argument.to.var.arg.method.problem.descriptor=Confusing primitive array argument to var-arg method #loc +null.argument.to.var.arg.method.display.name=Confusing argument to varargs method +null.argument.to.var.arg.method.problem.descriptor=Confusing argument #ref, unclear if a varargs or non-varargs call is desired #loc +primitive.array.argument.to.var.arg.method.display.name=Confusing primitive array argument to varargs method +primitive.array.argument.to.var.arg.method.problem.descriptor=Confusing primitive array argument to varargs method #loc object.comparison.display.name=Object comparison using '==', instead of 'equals()' object.comparison.enumerated.ignore.option=Ignore '==' between enumerated types object.comparison.klass.ignore.option=Ignore '==' on 'java.lang.Class' objects @@ -1874,8 +1874,8 @@ array.hash.code.display.name='hashCode()' called on array array.hash.code.problem.descriptor=#ref() called on array should probably be 'Arrays.hashCode()' #loc arrays.deep.hash.code.quickfix=Replace with 'Arrays.deepHashCode()' arrays.hash.code.quickfix=Replace with 'Arrays.hashCode()' -method.can.be.variable.arity.method.display.name=Method can be variable arity method -method.can.be.variable.arity.method.problem.descriptor=#ref() can be converted to variable arity method #loc +method.can.be.variable.arity.method.display.name=Method can be varargs method +method.can.be.variable.arity.method.problem.descriptor=#ref() can be converted to varargs method #loc method.can.be.variable.arity.method.ignore.byte.short.option=Ignore methods with a last parameter of type byte[] or short[] method.can.be.variable.arity.method.ignore.multiple.arrays.option=Ignore methods with multiple array parameters convert.to.variable.arity.method.quickfix=Convert to varargs method diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java index 6466d73eb4b6..22b7f87f6673 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/NullArgumentToVariableArgMethodInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,29 +15,53 @@ */ package com.siyeh.ig.bugs; +import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeCastFix; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.DelegatingFix; +import com.siyeh.ig.InspectionGadgetsFix; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class NullArgumentToVariableArgMethodInspection - extends BaseInspection { +public class NullArgumentToVariableArgMethodInspection extends BaseInspection { + + @NotNull + @Override + public String getID() { + return "ConfusingArgumentToVarargsMethod"; + } + + @Nullable + @Override + public String getAlternativeID() { + return "NullArgumentToVariableArgMethod"; // old suppressions should keep working + } @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "null.argument.to.var.arg.method.display.name"); + return InspectionGadgetsBundle.message("null.argument.to.var.arg.method.display.name"); } @Override @NotNull public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "null.argument.to.var.arg.method.problem.descriptor"); + return InspectionGadgetsBundle.message("null.argument.to.var.arg.method.problem.descriptor"); + } + + @NotNull + @Override + protected InspectionGadgetsFix[] buildFixes(Object... infos) { + final PsiExpression argument = (PsiExpression)infos[0]; + final PsiType type1 = (PsiType)infos[1]; + final PsiType type2 = (PsiType)infos[2]; + return new InspectionGadgetsFix[] { + new DelegatingFix(new AddTypeCastFix(type1, argument)), + new DelegatingFix(new AddTypeCastFix(type2, argument)) + }; } @Override @@ -55,21 +79,26 @@ public class NullArgumentToVariableArgMethodInspection return new NullArgumentToVariableArgVisitor(); } - private static class NullArgumentToVariableArgVisitor - extends BaseInspectionVisitor { + private static class NullArgumentToVariableArgVisitor extends BaseInspectionVisitor { @Override - public void visitMethodCallExpression( - @NotNull PsiMethodCallExpression call) { + public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { super.visitMethodCallExpression(call); - final PsiExpressionList argumentList = call.getArgumentList(); - final PsiExpression[] args = argumentList.getExpressions(); - if (args.length == 0) { + final PsiExpression[] arguments = argumentList.getExpressions(); + if (arguments.length == 0) { return; } - final PsiExpression lastArg = args[args.length - 1]; - if (!ExpressionUtils.isNullLiteral(lastArg)) { + final PsiExpression lastArgument = arguments[arguments.length - 1]; + final PsiType type = lastArgument.getType(); + final boolean checkArray; + if (PsiType.NULL.equals(type)) { + checkArray = false; + } + else if (type instanceof PsiArrayType) { + checkArray = true; + } + else { return; } final PsiMethod method = call.resolveMethod(); @@ -77,16 +106,26 @@ public class NullArgumentToVariableArgMethodInspection return; } final PsiParameterList parameterList = method.getParameterList(); - if (parameterList.getParametersCount() != args.length) { + if (parameterList.getParametersCount() != arguments.length) { return; } final PsiParameter[] parameters = parameterList.getParameters(); - final PsiParameter lastParameter = - parameters[parameters.length - 1]; + final PsiParameter lastParameter = parameters[parameters.length - 1]; if (!lastParameter.isVarArgs()) { return; } - registerError(lastArg); + final PsiType type1 = lastParameter.getType(); + if (!(type1 instanceof PsiEllipsisType)) { + return; + } + final PsiEllipsisType ellipsisType = (PsiEllipsisType)type1; + final PsiType arrayType = ellipsisType.toArrayType(); + if (checkArray) { + if (arrayType.equals(type) || !arrayType.isAssignableFrom(type)) { + return; + } + } + registerError(lastArgument, lastArgument, ellipsisType.getComponentType(), arrayType); } } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/PrimitiveArrayArgumentToVariableArgMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/PrimitiveArrayArgumentToVariableArgMethodInspection.java index 9f4a952b51fc..4dc241c12896 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/PrimitiveArrayArgumentToVariableArgMethodInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/PrimitiveArrayArgumentToVariableArgMethodInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,18 +16,34 @@ package com.siyeh.ig.bugs; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeCastFix; import com.intellij.psi.*; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; +import com.siyeh.ig.DelegatingFix; +import com.siyeh.ig.InspectionGadgetsFix; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Arrays; public class PrimitiveArrayArgumentToVariableArgMethodInspection extends BaseInspection { + @NotNull + @Override + public String getID() { + return "PrimitiveArrayArgumentToVarargsMethod"; + } + + @Nullable + @Override + public String getAlternativeID() { + return "PrimitiveArrayArgumentToVariableArgMethod"; // keep old suppression working + } + @Override @NotNull public String getDisplayName() { @@ -50,6 +66,14 @@ public class PrimitiveArrayArgumentToVariableArgMethodInspection extends BaseIns return PsiUtil.isLanguageLevel5OrHigher(file); } + @Nullable + @Override + protected InspectionGadgetsFix buildFix(Object... infos) { + final PsiExpression argument = (PsiExpression)infos[0]; + final PsiType type = (PsiType)infos[1]; + return new DelegatingFix(new AddTypeCastFix(type, argument)); + } + @Override public BaseInspectionVisitor buildVisitor() { return new PrimitiveArrayArgumentToVariableArgVisitor(); @@ -84,11 +108,11 @@ public class PrimitiveArrayArgumentToVariableArgMethodInspection extends BaseIns if (!lastParameter.isVarArgs()) { return; } - final PsiType parameterType = lastParameter.getType(); + final PsiEllipsisType parameterType = (PsiEllipsisType)lastParameter.getType(); if (isDeepPrimitiveArrayType(parameterType, result.getSubstitutor())) { return; } - registerError(lastArgument); + registerError(lastArgument, lastArgument, parameterType.getComponentType()); } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/EmptyClassInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/EmptyClassInspectionBase.java index fd694002129f..f191618ba300 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/EmptyClassInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/classlayout/EmptyClassInspectionBase.java @@ -39,7 +39,7 @@ public class EmptyClassInspectionBase extends BaseInspection { @SuppressWarnings("PublicField") public boolean ignoreThrowables = true; @SuppressWarnings("PublicField") - public boolean commentsAreContent = false; + public boolean commentsAreContent = true; @Override public void writeSettings(@NotNull Element node) throws WriteExternalException { diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java index c7502a5af5e3..f124e4f6cb12 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,12 +20,12 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ClassUtils; +import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -98,8 +98,7 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection } @Override - public void doFix(Project project, ProblemDescriptor descriptor) - throws IncorrectOperationException { + public void doFix(Project project, ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (constructor) { makeConstructorPackageLocal(project, element); @@ -127,8 +126,7 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection modifiers.setModifierProperty(PsiModifier.PRIVATE, false); } - private static void makeConstructorPackageLocal(Project project, - PsiElement element) { + private static void makeConstructorPackageLocal(Project project, PsiElement element) { final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class); @@ -175,8 +173,7 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection return new PrivateMemberAccessFromInnerClassVisitor(); } - private static class PrivateMemberAccessFromInnerClassVisitor - extends BaseInspectionVisitor { + private static class PrivateMemberAccessFromInnerClassVisitor extends BaseInspectionVisitor { @Override public void visitNewExpression(PsiNewExpression expression) { @@ -219,11 +216,9 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection } @Override - public void visitReferenceExpression( - @NotNull PsiReferenceExpression expression) { + public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiElement referenceNameElement = - expression.getReferenceNameElement(); + final PsiElement referenceNameElement = expression.getReferenceNameElement(); if (referenceNameElement == null) { return; } @@ -235,6 +230,10 @@ public class PrivateMemberAccessBetweenOuterAndInnerClassInspection if (!member.hasModifierProperty(PsiModifier.PRIVATE)) { return; } + final Object value = ExpressionUtils.computeConstantExpression(expression); + if (value != null) { + return; // no synthetic accessor created, compile time constant will be inlined by javac + } final PsiElement containingClass = getContainingContextClass(expression); if (containingClass == null) { return; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspection.java index fa07adabb4dd..705b5c816689 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspection.java @@ -21,6 +21,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExpressionUtils; +import com.siyeh.ig.psiutils.ParenthesesUtils; import com.siyeh.ig.psiutils.TypeUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -40,8 +41,7 @@ public class AtomicFieldUpdaterIssuesInspection extends BaseInspection { @NotNull @Override protected String buildErrorString(Object... infos) { - final String message = (String)infos[0]; - return message; + return (String)infos[0]; } @Override @@ -70,7 +70,7 @@ public class AtomicFieldUpdaterIssuesInspection extends BaseInspection { return; } final String fieldName = (String)value; - final PsiExpression firstArgument = arguments[0]; + final PsiExpression firstArgument = ParenthesesUtils.stripParentheses(arguments[0]); if (!(firstArgument instanceof PsiClassObjectAccessExpression)) { return; } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AtomicFieldUpdaterIssues.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AtomicFieldUpdaterIssues.html index cb8e1ba516fd..7e493daaf478 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AtomicFieldUpdaterIssues.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/AtomicFieldUpdaterIssues.html @@ -1,7 +1,5 @@ - - Reports issues on fields of type java.util.concurrent.atomic.AtomicLongFieldUpdater, java.util.concurrent.atomic.AtomicIntegerFieldUpdater or java.util.concurrent.atomic.AtomicReferenceFieldUpdater. The issues reported are identical to the runtime problems that can happen with atomic field updaters: @@ -11,6 +9,4 @@ specified field not found, specified field not accessible, specified field of th

New in 16 - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html index 26e0474ebaed..774c41767144 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/MethodCanBeVariableArityMethod.html @@ -1,19 +1,19 @@ Reports methods with which can be converted to be a variable -arity/varargs method, available in Java 5 and newer. +arity method, available in Java 5 and newer.

This inspection only reports if the project or module is configured to use a language level of 5.0 or higher.

-Use the first checkbox below to not offer to convert byte[] or short[] parameters to vararg. +Use the first checkbox below to not offer to convert byte[] or short[] parameters to varargs.

Use the second checkbox below to ignore methods overriding or implementing a method from a superclass.

Use the third checkbox below to only report when the method is public

-Use the fourth checkbox below ot ignore method with more than one array parameter. +Use the fourth checkbox below to ignore methods with two or more array parameters.

\ No newline at end of file diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html index 5c3508f7d142..dce77b590429 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/NullArgumentToVariableArgMethod.html @@ -1,9 +1,9 @@ -Reports any calls to a variable-argument method which has a null -in the variable-argument position (e.g System.out.printf("%s", null) ). -Such a null argument may be confusing, as it is not -wrapped as a single-element array, as may be expected. +Reports any calls to a variable arity method where the call has a single argument +in the variable arity parameter position, which is either a null or an array of a subtype of the variable arity parameter. +Such an argument may be confusing as it is unclear if a varargs or non-varargs call is desired. +For example System.out.printf("%s", null).

diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html index 4016a7494423..7cc58b83f598 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PrimitiveArrayArgumentToVariableArgMethod.html @@ -1,7 +1,7 @@ -Reports any calls to a variable-argument method which has a primitive array in -in the variable-argument position (e.g System.out.printf("%s", new int[]{1, 2, 3}) ). +Reports any calls to a variable arity method where the call has a primitive array in +in the variable arity parameter position (e.g System.out.printf("%s", new int[]{1, 2, 3}) ). Such a primitive-array argument may be confusing, as it will wrapped as a single-element array, rather than each individual element being boxed, as might be expected. diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html b/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html index 815bfa6930fe..d306240b079e 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/PrivateMemberAccessBetweenOuterAndInnerClass.html @@ -3,6 +3,9 @@ This inspection is intended for J2ME and other highly resource constrained environments. Applying the results of this inspection without consideration might have negative effects on code clarity and design.

+Reports references to non-constant private members of an outer class from inside an inner class or +to members of an inner class from a containing class. +

An inner class and its containing class are compiled to separate class files. The virtual machine normally prohibits access from a class to private fields and methods of another class. To enable access from an inner class to private members of a diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html index abf21de69210..b68eeb731b7f 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/ProblematicVarargsMethodOverride.html @@ -1,6 +1,7 @@ -Reports methods overriding a variable arity (varargs) method with an array parameter. While this is legal Java, it can be confusing. +Reports methods overriding a variable arity method and replacing the variable arity parameter with an array parameter. +While this is legal Java, it can be confusing.

diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java index 44d88f74b9dc..43e63a73704c 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/null_argument_to_variable_arg_method/NullArgumentToVariableArgMethod.java @@ -1,9 +1,10 @@ package com.siyeh.igtest.bugs.null_argument_to_variable_arg_method; public class NullArgumentToVariableArgMethod { - public void foo() + public void foo(String[] ss) { - String.format("%s", null); + String.format("%s", null); String.format("%d", 1); + String.format("%s", ss); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/var_arg/PrimitiveArrayArgumentToVariableArgMethod.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/var_arg/PrimitiveArrayArgumentToVariableArgMethod.java index 3c4ab826ef53..e56390324c55 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/var_arg/PrimitiveArrayArgumentToVariableArgMethod.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/var_arg/PrimitiveArrayArgumentToVariableArgMethod.java @@ -6,7 +6,7 @@ public class PrimitiveArrayArgumentToVariableArgMethod { public static void main(String[] arg) throws Throwable { - methodVarArgObject(new byte[3]); + methodVarArgObject(new byte[3]); methodVarArgByteArray(new byte[3]); MethodHandle meh = null; meh.invokeExact(new int[] { }); @@ -31,7 +31,7 @@ public class PrimitiveArrayArgumentToVariableArgMethod } void m() { - String.format("%s", new int[]{1, 2, 3}); + String.format("%s", new int[]{1, 2, 3}); } static void bar1(java.lang.Object... objects) { @@ -48,7 +48,7 @@ public class PrimitiveArrayArgumentToVariableArgMethod public static void invoke() { int[] ints = {1, 2, 3}; - bar1(ints); // warn here + bar1(ints); // warn here bar2(ints); // no warning needed here } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/private_member_access_between_outer_and_inner_class/PrivateMemberAccessBetweenOuterAndInnerClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/private_member_access_between_outer_and_inner_class/PrivateMemberAccessBetweenOuterAndInnerClass.java index a0ebd068824b..3d86bf5f9144 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/private_member_access_between_outer_and_inner_class/PrivateMemberAccessBetweenOuterAndInnerClass.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/j2me/private_member_access_between_outer_and_inner_class/PrivateMemberAccessBetweenOuterAndInnerClass.java @@ -2,12 +2,14 @@ package com.siyeh.igtest.j2me.private_member_access_between_outer_and_inner_clas public class PrivateMemberAccessBetweenOuterAndInnerClass { private String caption = "Button"; + private final int N = 100; private void initialize() { System.out.println(caption); Object btn = new Object() { public void foo() { System.out.println(caption); + System.out.println(N); } }; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/method_can_be_variable_arity_method/MethodCanBeVariableArity.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/method_can_be_variable_arity_method/MethodCanBeVariableArity.java index 3b15deab1620..8eb2aae4014b 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/method_can_be_variable_arity_method/MethodCanBeVariableArity.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/method_can_be_variable_arity_method/MethodCanBeVariableArity.java @@ -7,7 +7,7 @@ public class MethodCanBeVariableArity { public void method(String... s) {} - public void convertMe(String[] ss) {} + public void convertMe(String[] ss) {} public void convertMeNot(byte[] bs) {} } @@ -31,7 +31,7 @@ class Annotated { void m(String[] ss) {} } interface X { - void m(String[] ss); + void m(String[] ss); } class Yes { void m(int[] is, int[] js) {} diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspectionTest.java index 88b74be2444f..230a10cfa147 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/threading/AtomicFieldUpdaterIssuesInspectionTest.java @@ -38,7 +38,7 @@ public class AtomicFieldUpdaterIssuesInspectionTest extends LightInspectionTestC "class A {" + " private static volatile int value = 0;" + " private static final AtomicIntegerFieldUpdater updater = " + - " AtomicIntegerFieldUpdater.newUpdater(A.class, /*Field 'value' has 'static' modifier*/\"value\"/**/);" + + " AtomicIntegerFieldUpdater.newUpdater((A.class), /*Field 'value' has 'static' modifier*/(\"value\")/**/);" + "}"); } @@ -100,6 +100,20 @@ public class AtomicFieldUpdaterIssuesInspectionTest extends LightInspectionTestC "}"); } + /** + * private fields are not accessible at runtime even from inner classes. + */ + public void testNotAccessible2() { + doTest("import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;" + + "class Z {" + + " private volatile int value = 0;" + + " static class A {\n" + + " private static final AtomicIntegerFieldUpdater updater = \n" + + " AtomicIntegerFieldUpdater.newUpdater(Z.class, /*'private' field 'value' is not accessible from here*/\"value\"/**/);\n" + + " }" + + "}"); + } + @Nullable @Override protected InspectionProfileEntry getInspection() { diff --git a/plugins/java-decompiler/plugin/src/org/jetbrains/java/decompiler/IdeaDecompiler.kt b/plugins/java-decompiler/plugin/src/org/jetbrains/java/decompiler/IdeaDecompiler.kt index 88fb3c19ebcd..18e84513277e 100644 --- a/plugins/java-decompiler/plugin/src/org/jetbrains/java/decompiler/IdeaDecompiler.kt +++ b/plugins/java-decompiler/plugin/src/org/jetbrains/java/decompiler/IdeaDecompiler.kt @@ -53,7 +53,7 @@ import java.util.jar.Manifest class IdeaDecompiler : ClassFileDecompilers.Light() { companion object { - val BANNER = "//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\n" + const val BANNER = "//\n// Source code recreated from a .class file by IntelliJ IDEA\n// (powered by Fernflower decompiler)\n//\n\n" private val LEGAL_NOTICE_KEY = "decompiler.legal.notice.accepted" diff --git a/plugins/settings-repository/settings-repository-tests.iml b/plugins/settings-repository/settings-repository-tests.iml index d443e18e45cf..a403eda57634 100644 --- a/plugins/settings-repository/settings-repository-tests.iml +++ b/plugins/settings-repository/settings-repository-tests.iml @@ -34,6 +34,5 @@ - \ No newline at end of file diff --git a/plugins/settings-repository/src/actions/SyncAction.kt b/plugins/settings-repository/src/actions/SyncAction.kt index ebe6571b82cc..46b2bd2cef66 100644 --- a/plugins/settings-repository/src/actions/SyncAction.kt +++ b/plugins/settings-repository/src/actions/SyncAction.kt @@ -44,7 +44,7 @@ fun syncAndNotify(syncType: SyncType, project: Project?, notifyIfUpToDate: Boole } catch (e: Exception) { LOG.warn(e) - NOTIFICATION_GROUP.createNotification(icsMessage("sync.rejected.title"), e.getMessage() ?: "Internal error", NotificationType.ERROR, null).notify(project) + NOTIFICATION_GROUP.createNotification(icsMessage("sync.rejected.title"), e.message ?: "Internal error", NotificationType.ERROR, null).notify(project) } } diff --git a/plugins/settings-repository/src/git/GitEx.kt b/plugins/settings-repository/src/git/GitEx.kt index 97c5f01e600b..6c24a22141ef 100644 --- a/plugins/settings-repository/src/git/GitEx.kt +++ b/plugins/settings-repository/src/git/GitEx.kt @@ -48,7 +48,7 @@ fun wrapIfNeedAndReThrow(e: TransportException) { throw org.jetbrains.settingsRepository.NoRemoteRepositoryException(e) } - val message = e.getMessage()!! + val message = e.message!! if (e.status == TransportException.Status.NOT_AUTHORIZED || e.status == TransportException.Status.NOT_PERMITTED || message.contains(JGitText.get().notAuthorized) || message.contains("Auth cancel") || message.contains("Auth fail") || message.contains(": reject HostKey:") /* JSch */) { throw AuthenticationException(e) @@ -73,7 +73,7 @@ fun Repository.fetch(remoteConfig: RemoteConfig, credentialsProvider: Credential } } catch (e: TransportException) { - val message = e.getMessage()!! + val message = e.message!! if (message.startsWith("Remote does not have ")) { LOG.info(message) // "Remote does not have refs/heads/master available for fetch." - remote repository is not initialized diff --git a/plugins/settings-repository/src/git/pull.kt b/plugins/settings-repository/src/git/pull.kt index f380892e6046..e03a434283ae 100644 --- a/plugins/settings-repository/src/git/pull.kt +++ b/plugins/settings-repository/src/git/pull.kt @@ -310,7 +310,7 @@ private fun resolveConflicts(mergeProvider: JGitMergeProvider, unresolv break } else { - unresolvedFiles.removeAll(mergedFiles) + unresolvedFiles.removeAll { it.path in mergedFiles } } } diff --git a/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt b/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt index 2f7ebf16c661..ab8fc9fb96f5 100644 --- a/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt +++ b/plugins/settings-repository/src/keychain/OSXKeychainLibrary.kt @@ -96,7 +96,7 @@ public interface OSXKeychainLibrary : com.sun.jna.Library { } else { val buf = CharArray(LIBRARY.CFStringGetLength(translated).toInt()) - for (i in 0..buf.size() - 1) { + for (i in 0..buf.size - 1) { buf[i] = LIBRARY.CFStringGetCharacterAtIndex(translated, i.toLong()) } LIBRARY.CFRelease(translated) diff --git a/plugins/settings-repository/src/settings/upstreamEditor.kt b/plugins/settings-repository/src/settings/upstreamEditor.kt index 2cddd13f3117..719c7ea55f67 100644 --- a/plugins/settings-repository/src/settings/upstreamEditor.kt +++ b/plugins/settings-repository/src/settings/upstreamEditor.kt @@ -97,10 +97,10 @@ fun createMergeActions(project: Project?, urlTextField: TextFieldWithBrowseButto LOG.warn(e) if (!upstreamSet || e is NoRemoteRepositoryException) { - Messages.showErrorDialog(dialogParent, icsMessage("set.upstream.failed.message", e.getMessage()), icsMessage("set.upstream.failed.title")) + Messages.showErrorDialog(dialogParent, icsMessage("set.upstream.failed.message", e.message), icsMessage("set.upstream.failed.title")) } else { - Messages.showErrorDialog(dialogParent, StringUtil.notNullize(e.getMessage(), "Internal error"), icsMessage(if (e is AuthenticationException) "sync.not.authorized.title" else "sync.rejected.title")) + Messages.showErrorDialog(dialogParent, StringUtil.notNullize(e.message, "Internal error"), icsMessage(if (e is AuthenticationException) "sync.not.authorized.title" else "sync.rejected.title")) } return } diff --git a/resources-en/src/messages/QuickFixBundle.properties b/resources-en/src/messages/QuickFixBundle.properties index b3775aa3095a..506d63d4b51f 100644 --- a/resources-en/src/messages/QuickFixBundle.properties +++ b/resources-en/src/messages/QuickFixBundle.properties @@ -1,5 +1,6 @@ add.import=Add Import class.to.import.chooser.title=Class to Import +method.to.import.chooser.title=Method to Import access.static.via.class.reference.family=Access static via class reference access.static.via.class.reference.text=Access static ''{1}.{0}'' via class ''{2}'' reference add.default.constructor.family=Add Default Constructor