Changed behavior of "organize imports" command for relative imports. They're now placed in their own group after local imports.

This commit is contained in:
Eric Traut 2019-09-05 15:47:22 +00:00
parent f1c823ae5c
commit 7e35e4ef1f
3 changed files with 44 additions and 16 deletions

View File

@ -58,7 +58,9 @@ export class ImportResolver {
if (moduleDescriptor.leadingDots > 0) {
const relativeImport = this._resolveRelativeImport(sourceFilePath,
moduleDescriptor, importName, importFailureInfo);
if (relativeImport) {
relativeImport.isRelative = true;
return relativeImport;
}
} else {
@ -168,6 +170,7 @@ export class ImportResolver {
const notFoundResult: ImportResult = {
importName,
isRelative: false,
isImportFound: false,
importFailureInfo,
resolvedPaths: [],
@ -641,6 +644,7 @@ export class ImportResolver {
return {
importName,
isRelative: false,
isImportFound: importFound,
importFailureInfo,
importType: ImportType.Local,

View File

@ -8,11 +8,9 @@
*/
export enum ImportType {
// The ordering here is important because this is the order
// in which PEP8 specifies that imports should be ordered.
BuiltIn = 0,
ThirdParty = 1,
Local = 2
BuiltIn,
ThirdParty,
Local
}
export interface ImplicitImport {
@ -25,6 +23,10 @@ export interface ImportResult {
// The formatted import name. Useful for error messages.
importName: string;
// Indicates whether the import name was relative (starts
// with one or more dots).
isRelative: boolean;
// True if import was resolved to a module or file.
isImportFound: boolean;

View File

@ -18,6 +18,15 @@ import { ParseResults } from '../parser/parser';
const _maxLineLength = 80;
export enum ImportGroup {
// The ordering here is important because this is the order
// in which PEP8 specifies that imports should be ordered.
BuiltIn = 0,
ThirdParty = 1,
Local = 2,
LocalRelative = 3
}
export class ImportSorter {
constructor(private _parseResults: ParseResults) {}
@ -51,21 +60,34 @@ export class ImportSorter {
}
private _compareImportStatements(a: ImportStatement, b: ImportStatement) {
const aImportType = this._getImportType(a);
const bImportType = this._getImportType(b);
const aImportGroup = this._getImportGroup(a);
const bImportGroup = this._getImportGroup(b);
if (aImportType < bImportType) {
if (aImportGroup < bImportGroup) {
return -1;
} else if (aImportType > bImportType) {
} else if (aImportGroup > bImportGroup) {
return 1;
}
return (a.moduleName < b.moduleName) ? -1 : 1;
}
private _getImportType(statement: ImportStatement): ImportType {
return statement.importResult ?
statement.importResult.importType : ImportType.Local;
private _getImportGroup(statement: ImportStatement): ImportGroup {
if (statement.importResult) {
if (statement.importResult.importType === ImportType.BuiltIn) {
return ImportGroup.BuiltIn;
} else if (statement.importResult.importType === ImportType.ThirdParty) {
return ImportGroup.ThirdParty;
}
if (statement.importResult.isRelative) {
return ImportGroup.LocalRelative;
}
return ImportGroup.Local;
} else {
return ImportGroup.Local;
}
}
// Determines the text range for the existing primary block of import statements.
@ -121,14 +143,14 @@ export class ImportSorter {
private _generateSortedImportText(sortedStatements: ImportStatement[]): string {
let importText = '';
let prevImportType = this._getImportType(sortedStatements[0]);
let prevImportGroup = this._getImportGroup(sortedStatements[0]);
for (const statement of sortedStatements) {
// Insert a blank space between import type groups.
const curImportType = this._getImportType(statement);
if (prevImportType !== curImportType) {
const curImportType = this._getImportGroup(statement);
if (prevImportGroup !== curImportType) {
importText += this._parseResults.predominantLineEndSequence;
prevImportType = curImportType;
prevImportGroup = curImportType;
}
let importLine: string;