Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/tools/eslint-plugin-azure-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Some rules (see table below) are fixable using the `--fix` ESLint option (added
| [**ts-apisurface-supportcancellation**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-apisurface-supportcancellation.md) | :triangular_flag_on_post: | :x: | `1.2.0` |
| [**ts-config-include**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-config-include.md) | :triangular_flag_on_post: | :heavy_check_mark: | `1.0.0` |
| [**ts-doc-internal**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-doc-internal.md) | :triangular_flag_on_post: | :x: | `1.1.0` |
| [**ts-doc-internal-private-member**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-doc-internal.md) | :triangular_flag_on_post: | :x: | `3.1.0` |
| [**ts-error-handling**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-error-handling.md) | :heavy_multiplication_x: | :x: | `1.1.0` |
| [**ts-modules-only-named**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-modules-only-named.md) | :triangular_flag_on_post: | :x: | `1.1.0` |
| [**ts-naming-drop-noun**](https://github.com/Azure/azure-sdk-for-js/blob/main/common/tools/eslint-plugin-azure-sdk/docs/rules/ts-naming-drop-noun.md) | :triangular_flag_on_post: | :x: | `1.2.0` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export = {
"@azure/azure-sdk/ts-apisurface-supportcancellation": "error",
"@azure/azure-sdk/ts-config-include": "error",
"@azure/azure-sdk/ts-doc-internal": "error",
"@azure/azure-sdk/ts-doc-internal-private-member": "error",
"@azure/azure-sdk/ts-error-handling": "off",
"@azure/azure-sdk/ts-modules-only-named": "error",
"@azure/azure-sdk/ts-naming-drop-noun": "error",
Expand Down
2 changes: 2 additions & 0 deletions common/tools/eslint-plugin-azure-sdk/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import tsApisurfaceStandardizedVerbs from "./ts-apisurface-standardized-verbs";
import tsApisurfaceSupportcancellation from "./ts-apisurface-supportcancellation";
import tsConfigInclude from "./ts-config-include";
import tsDocInternal from "./ts-doc-internal";
import tsDocInternalPrivateMember from "./ts-doc-internal-private-member";
import tsErrorHandling from "./ts-error-handling";
import tsModulesOnlyNamed from "./ts-modules-only-named";
import tsNamingDropNoun from "./ts-naming-drop-noun";
Expand Down Expand Up @@ -49,6 +50,7 @@ export = {
"ts-apisurface-supportcancellation": tsApisurfaceSupportcancellation,
"ts-config-include": tsConfigInclude,
"ts-doc-internal": tsDocInternal,
"ts-doc-internal-private-member": tsDocInternalPrivateMember,
"ts-error-handling": tsErrorHandling,
"ts-modules-only-named": tsModulesOnlyNamed,
"ts-naming-drop-noun": tsNamingDropNoun,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* @file Rule to check if a private class member is tagged with @internal
* @author Hamsa Shankar
*/

import { ParserServices, TSESTree } from "@typescript-eslint/experimental-utils";
import { ParserWeakMapESTreeToTSNode } from "@typescript-eslint/typescript-estree/dist/parser-options";
import { Rule } from "eslint";
import { Node } from "estree";
import { readFileSync } from "fs";
import { sync as globSync } from "glob";
import { relative } from "path";
import { Modifier, SyntaxKind } from "typescript";
import { getRuleMetaData } from "../utils";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

/**
* Helper method for reporting on a node
* @param node the Node being operated on
* @param context the ESLint runtime context
* @param converter a converter from TSESTree Nodes to TSNodes
* @param typeChecker the TypeScript TypeChecker
* @throws if the Node passes throught the initial checks and has an internal tag
*/
const reportInternal = (
node: Node,
context: Rule.RuleContext,
converter: ParserWeakMapESTreeToTSNode,
): void => {
const tsNode = converter.get(node as TSESTree.Node) as any;

const modifiers = converter.get(node as TSESTree.Node).modifiers;
// if type is internal and has a TSDoc and is a private member
if (tsNode.jsDoc !== undefined
&& modifiers !== undefined && modifiers.some(
(modifier: Modifier): boolean => modifier.kind === SyntaxKind.PrivateKeyword)
) {
// fetch all tags
let TSDocTags: string[] = [];
tsNode.jsDoc.forEach((TSDocComment: any): void => {
TSDocTags = TSDocTags.concat(
TSDocComment.tags !== undefined
? TSDocComment.tags.map((TSDocTag: any): string => TSDocTag.tagName.escapedText)
: []
);
});

// see if any tags match internal
if (TSDocTags.some((TSDocTag: string): boolean => /(internal)/.test(TSDocTag))) {
context.report({
node: node,
message: "private class members should not include an @internal tag"
});
}
}
};

/**
* Determine whether this rule should examine a given file
* @param fileName the filename of the file in question
* @param exclude the list of files excluded by TypeDoc (other than those in node_modues)
* @returns false if not in src or is excluded by TypeDoc
*/
const shouldExamineFile = (fileName: string, exclude: string[]): boolean => {
if (!/src/.test(fileName)) {
return false;
}
const relativePath = relative("", fileName).replace(/\\/g, "/");
return !exclude.includes(relativePath);
};

let exclude: string[] = [];
try {
const typeDocText = readFileSync("typedoc.json", "utf8");
const typeDoc = JSON.parse(typeDocText);

// if typeDoc.exclude exists, add all files matching the glob patterns to exclude
if (typeDoc.exclude !== undefined) {
typeDoc.exclude.forEach((excludedGlob: string): void => {
exclude = exclude.concat(
globSync(excludedGlob).filter(
(excludeFile: string): boolean => !/node_modules/.test(excludeFile)
)
);
});
}
} catch (err) {
exclude = [];
}

export = {
meta: getRuleMetaData(
"ts-doc-internal-private-member",
"requires TSDoc comments to not include an '@internal' tag if the object is private"
),
create: (context: Rule.RuleContext): Rule.RuleListener => {
const fileName = context.getFilename();

const parserServices = context.parserServices as ParserServices;
if (
parserServices.program === undefined ||
parserServices.esTreeNodeToTSNodeMap === undefined
) {
return {};
}

const converter = parserServices.esTreeNodeToTSNodeMap;

return shouldExamineFile(fileName, exclude)
? {
// callback functions

// container declarations
":matches(TSInterfaceDeclaration, ClassDeclaration, TSModuleDeclaration)": (
node: Node
): void => reportInternal(node, context, converter),

// functions
":function": (node: Node): void => {
reportInternal(node, context, converter);
}
}
: {};
}
};
1 change: 1 addition & 0 deletions common/tools/eslint-plugin-azure-sdk/tests/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const ruleList = [
"ts-apisurface-supportcancellation",
"ts-config-include",
"ts-doc-internal",
"ts-doc-internal-private-member",
"ts-error-handling",
"ts-modules-only-named",
"ts-naming-drop-noun",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

/**
* @file Testing the ts-doc-internal-private-member rule.
* @author Hamsa Shankar
*/

import rule from "../../src/rules/ts-doc-internal-private-member";
import { RuleTester } from "eslint";

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
parser: require.resolve("@typescript-eslint/parser"),
parserOptions: {
createDefaultProgram: true,
project: "./tsconfig.json"
},
settings: {
exported: []
}
});

ruleTester.run("ts-doc-internal-private-member", rule, {
valid: [
// class
{
code: `
/**
* Other documentation
* @internal
*/
class ExampleClass {}`,
filename: "src/test.ts"
},
{
code: `
/**
* Other documentation
*/
private class ExampleClass {}`,
filename: "src/test.ts"
},
// interface
{
code: `
/**
* Other documentation
* @internal
* @hidden
*/
interface ExampleInterface {}`,
filename: "src/test.ts"
},
{
code: `
/**
* Other documentation
*/
private interface ExampleInterface {}`,
filename: "src/test.ts"
},
// function
{
code: `
/**
* Other documentation
* @internal
*/
function ExampleFunction() {}`,
filename: "src/test.ts"
},
{
code: `
/**
* Other documentation
*/
private function ExampleFunction() {}`,
filename: "src/test.ts"
}
],
invalid: [
// class
{
code: `
/**
* Other documentation
* @internal
*/
private class ExampleClass {
}`,
filename: "src/test.ts",
errors: [
{
message: "private class members should not include an @internal tag"
}
]
},
// interface
{
code: `
/**
* Other documentation
* @internal
*/
private interface ExampleInterface {}`,
filename: "src/test.ts",
errors: [
{
message: "private class members should not include an @internal tag"
}
]
},
// function
{
code: `
/**
* Other documentation
* @internal
* @param {object} len - length
*/
private function ExampleFunction(len) {}`,
filename: "src/test.ts",
errors: [
{
message: "private class members should not include an @internal tag"
}
]
}
]
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"preinstall": "node common/scripts/rush-welcome.js"
},
"devDependencies": {
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
"@octokit/rest": "^16.26.0",
"@ts-common/azure-js-dev-tools": "^0.7.0",
"@types/glob": "^7.1.1",
Expand Down
4 changes: 0 additions & 4 deletions sdk/core/core-lro/src/poller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,6 @@ export abstract class Poller<TState extends PollOperationState<TResult>, TResult
protected abstract delay(): Promise<void>;

/**
* @internal
* Starts a loop that will break only if the poller is done
* or if the poller is stopped.
*/
Expand All @@ -301,7 +300,6 @@ export abstract class Poller<TState extends PollOperationState<TResult>, TResult
}

/**
* @internal
* pollOnce does one polling, by calling to the update method of the underlying
* poll operation to make any relevant change effective.
*
Expand Down Expand Up @@ -335,7 +333,6 @@ export abstract class Poller<TState extends PollOperationState<TResult>, TResult
}

/**
* @internal
* fireProgress calls the functions passed in via onProgress the method of the poller.
*
* It loops over all of the callbacks received from onProgress, and executes them, sending them
Expand All @@ -350,7 +347,6 @@ export abstract class Poller<TState extends PollOperationState<TResult>, TResult
}

/**
* @internal
* Invokes the underlying operation's cancel method, and rejects the
* pollUntilDone promise.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,6 @@ export class DocumentAnalysisClient {
*
* This is the meat of all analysis polling operations.
*
* @internal
* @param input - either a string for URL inputs or a FormRecognizerRequestBody to upload a file directly to the Form
* Recognizer API
* @param definition - operation definition (initial model ID, operation transforms, request options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ export class DocumentModelAdministrationClient {
*
* This is the meat of all training polling operations.
*
* @internal
* @param definition - operation definition (start operation method, request options)
* @returns a training poller that produces a ModelInfo
*/
Expand Down
4 changes: 0 additions & 4 deletions sdk/keyvault/keyvault-admin/src/accessControlClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ export class KeyVaultAccessControlClient {
}

/**
* @internal
* Deals with the pagination of {@link listRoleAssignments}.
* @param roleScope - The scope of the role assignments.
* @param continuationState - An object that indicates the position of the paginated request.
Expand Down Expand Up @@ -246,7 +245,6 @@ export class KeyVaultAccessControlClient {
}

/**
* @internal
* Deals with the iteration of all the available results of {@link listRoleAssignments}.
* @param roleScope - The scope of the role assignments.
* @param options - Common options for the iterative endpoints.
Expand Down Expand Up @@ -293,7 +291,6 @@ export class KeyVaultAccessControlClient {
}

/**
* @internal
* Deals with the pagination of {@link listRoleDefinitions}.
* @param roleScope - The scope of the role definition.
* @param continuationState - An object that indicates the position of the paginated request.
Expand Down Expand Up @@ -336,7 +333,6 @@ export class KeyVaultAccessControlClient {
}

/**
* @internal
* Deals with the iteration of all the available results of {@link listRoleDefinitions}.
* @param roleScope - The scope of the role definition.
* @param options - Common options for the iterative endpoints.
Expand Down
Loading