2016-06-26 10 views
-1

편집 : 설명을 위해 JavaScript 또는 TypeScript 리팩토링 변환기를 찾고 있습니다. 에서 이름 바꾸기를 수행하려면 런타임시가 아니라 시간을 빌드하십시오.자바 스크립트 용 리팩터링 또는 JavaScript 용 리팩터링 트랜스 퍼터가 있습니까?

특정 라이브러리를 사용하고 싶습니다. API가 내 코드베이스의 이름 지정 스타일 (소리 친숙합니까?)에 맞지 않으므로 동일한 코딩 호출을 사용하여 API 호출을 재정의하려고합니다. 자신의 코드.

그러나 이것은 프로토 타입에 도입 된 100 가지가 넘는 메서드를 사용하여 개체의 서명을 변경함으로써 많은 런타임 오버 헤드를 초래합니다. 내가 API 호출에 리팩토링 규칙을 실행되는 컴파일 단계를 소개 할 수 있다면

Object.defineProperty(Room.prototype, 'getController', {get: function() {return this.controller}}); 

대신, 내 코드는 우리가 내 선호하는 API하지만 결과 코드는 공개 API를 사용할 수 있습니다. 나는 반복 리팩토링 요청을 실행하기위한 DSL이있는 자바 스크립트 리팩토링 도구를 찾을 수 없어, 뭔가 같은 :

rename(Room.prototype.controller, 'getController') 

'자동 리팩토링'에 대한 검색을위한 떡 프로젝트의 수십납니다 사람이 입력하지 않아도 코드를 개선 할 수 있습니다. 그건 내가 원하는 것이 아닙니다. 필자는 수동으로 입력 된 스크립팅 된 리팩토링을 내 빌드 파이프 라인에 도입하여 외부 API의 다양한 명명 규칙에서 작업 코드를 보호하고자합니다.

+1

모든 코드를 IIFE에 넣고 전역 네임 스페이스에서 분리 하시겠습니까 ?? ??충돌이 발생하는 곳을 완전히 명확히하지 않음 – charlietfl

+0

이것은 정확하게 지금하고있는 일이지만 추가 기능 호출은 피하고 싶지 않은 오버 헤드이므로 이름 바꾸기 작업을 수행 할 수있는 방법에 대한 요청입니다. –

답변

0

js 접근시 예상 결과가 반환되지만 이름을 조정할 수 있으면 Function.prototype.bind()을 사용하여 별도의 개체를 만들어 함수의 컨텍스트를 설정해야합니다. 정확한 요구 사항을 충족시키기 위해 구현을 개선 할 수 있습니다.

다른 방법

function Mirror() { 
 
    var ctx = Object.create(null); 
 
    this.rename = function(obj, name, context, args) { 
 
    ctx[name] = obj.bind(context || ctx, args || null); 
 
    return ctx 
 
    } 
 
} 
 

 
// `Room` 
 
function Room() { 
 

 
} 
 

 
Room.prototype.controller = function() { 
 
    console.log(this) 
 
} 
 

 
var mirror = new Mirror(); 
 
let _room = mirror.rename(
 
       Room.prototype.controller 
 
       , "getController" 
 
       , new Room()); 
 
_room.getController()

는 텍스트 편집기에서 한 번에 기능을 하나의 이름을 조정할 수 있습니다.

+0

아마 내가 오해하고 있습니다. 그러나 이것은 런타임에 Object.defineProperty() 이름을 바꾸는 DSL 인 것으로 보입니다. 내 목표는 배포 된 코드에서 게시 된 API를 직접 사용하도록하는 것이지만 내부 코드는 이름 바꾸기 단계에서 개인 API를 사용합니다. –

+0

@MyrddinEmrys _ "배포 된 코드에서 게시 된 API를 직접 사용하는 것이지만 내부 코드는 이름 바꾸기 단계와 함께 개인 API를 사용합니다."_ 대안 접근 방식을 참조하십시오. 이러한 프로세스를 생성하기위한 노력은 기존 API 전체를 다시 쓰는 데 사용될 수 있습니다. – guest271314

+0

기존 API를 다시 쓸 수있는 권한이 없습니다. 또는 나는 할 것이다. 이 자바 스크립트 알고 있지만이 경우 수정을 위해 API를 사용할 수 없습니다. –

1

은 당신이 원하는 것은 program transformation system (PTS).

이러한 도구는 당신에게 표면 구문 패턴과 다른하는 AST로 그하는 AST를 변환 할 수있는 기능을 제공하는 AST에 소스 코드를 분석하고, 소스 - 소스 A가 소스를 뱉어입니다 수정 된 AST에 대한 코드 한 언어로 된 AST에서 다른 언어로 AST로 변환한다면, 당신이 말하는 트랜스퍼를 얻게됩니다. (내가 좋아하는 용어가 아닌, PTS는 괜찮 았을 것입니다.) 소스 변환 구문

소스는 다르지만 본질적으로는 (실제) 언어 소스 및 대상 언어의 구문 표면을 사용하여이 같은 것을 쓰기 :

if you see *this*, replace it by *that* if some_condition(*this*) 

요소 언어 구문으로 표현 된 패턴입니다. 선택적인 조건 적 ("의미 적 제한")은 도구가 문맥 정보 (예 : 기호 속성 등)를 고려하도록 허용합니다. 복잡한 변환을 수행하기 위해 종종 여러 규칙을 필요로합니다. 규칙은 일반적으로 관심의 복합 효과를 달성하기 위해 시퀀싱 될 수 있습니다. 규칙의 표현과 순서는 OP에 관심있는 "스크립팅"부분입니다.

새로운 언어 정의를 받아 들일 JavaScript를 정의하거나 이미 사용 가능한 JavaScript 구문 분석기를 가지고 있어야합니다.

이들 중 하나 인 PTS는 DMS Software Reengineering Toolkit입니다. 사용할 수있는 Javascript front end이 있습니다. 다음과 같이

OP의 이름을 바꾸는 문제는 a DMS Rewrite Rule로 지정 될 수 있습니다 :

rule rename_controller(): IDENTIFIER 
    "controller" -> "getController"; 

인용 부호 패턴 언어의 구문을 구분하는 데 사용 메타 인용하고, 소스/대상되는 언어의 구문에서 이것은 메타 따옴표 안에 적혀 있습니다.

모든 API 호출의 이름을 바꾸려면 OP에는 각 고유 API 항목에 대한 규칙이 필요합니다.

쓰기 쉽지만 이것은 다소 힘든 일입니다. 에 의해 처리되는 파일의 해당 이름을 가진 식별자가 그렇게 바뀝니다. OP가 의도하지 않은 범위에서 "컨트롤러"의 이름을 바꿀 수 있습니다. 동일한 이름의 선언이 여러 번 나타날 위험이 없다면 DMS의 "모든 규칙 적용"명령 줄 스크립트 가능 작업으로 기본 제공 전술을 사용하여 실행하는 것이 안전합니다.

(OP 식별자에서 사용 된 식별자의 이름을 API 식별자로 변경하는 것이 더 쉬울 수도 있지만, 작성한 코드의 이름 충돌은 소스 파일에서 작성하지 않은 API와 이름 충돌보다 쉽습니다.

이렇게하려면 OP가 아무 래도 을 수락해야합니다. "컨트롤러"라는 이름이 바뀌 었는지 선언해야합니다. 즉 그는 같은 "오른쪽"하나, 뭔가 이름을 변경한다 확인하는 사용자 정의 제약 조건을 정의해야 할 것 :

rule rename_controller(i:IDENTIFIER): IDENTIFIER 
    "\i" -> "getController" 
      if (match(i,"controller") & declaration_at_line(i,1219); 
여기

우리는 우리가 AST 노드에 대한 액세스를 획득의 의도와 어떤 ID와 일치를하는 것이 이 발견되었습니다 (\ i 내부 표면 구문 텍스트, i 해당 텍스트 외부에 있음). 일치하는 술어는 이미 DMS에 내장되어 있습니다. 그것은 우리가 올바른 이름을 찾았다 고 주장하는 데 사용됩니다. declaration_at_line 술어는 일치하는 AST 노드가 파일의 특정 위치에 선언 된 동일한 이름을 가진 노드와 일치하는지 확인하는 데 사용됩니다. ECMAScript 규칙을 따르는 범위가 지정된 이름 조회에 필요한 금액이 필요하므로 일부 사용자 지정 작업이 필요합니다. (현재이 DMS 프런트 엔드는이를 제공하지 않으며 다른 언어의 다른 DMS 프런트 엔드는 때때로이 기능을 제공합니다.) 어떤 선언을 목표로하는 지에 대한 선택은 다소 임의적입니다. 영업 이익은 자신의 예에서 힌트로 하나는에 도착 얻기 위해 글로벌 네임 스페이스의 루트에서 경로에 의해 정의 할 수 있습니다 :

 ... declaration_in(i,"Room.prototype") ... 

하나는 여전히 경로를 처리하는 범위 조회 규칙이 필요합니다.

OP에서 어떤 PTS를 선택했는지에 관계없이 정확한 이름을 변경하려면 범위 지정 조회가 필요합니다. 다른 많은 PTS (TXL, Stratego, ...)는 이것을 구현하기 위해 어떠한 지원도 제공하지 않습니다.

+0

저는 AST라는 용어에 익숙했으며 도구의 AST 출력에서이 작업을 직접 수행하는 방법을 모색하고있었습니다. PTS라는 용어에 대해 들어 보지 못했습니다. Google에 대한 또 다른 도구입니다. 기능에 대한 빠른 질문 (문서가 공개 된만큼 공개되지 않기 때문에) : 선언을 선이 아닌 파일로 제한 할 수 있습니까? –

+0

"그냥"AST로는이 작업을 수행 할 수 없습니다. AST에서 유효한 * 소스 코드를 재생성 할 수 있어야합니다. 보이는 것보다 더 어렵습니다. (http://stackoverflow.com/a/5834775/120163 참조) 이것은 순수 파서가 실제로 충분하지 않은 많은 이유 중 하나입니다 ("파싱 후의 수명"http : //www.semdesigns .com/Products/DMS/LifeAfterParsing.html 자세한 내용은 –

+0

제약 조건 : DMS는 사용자 정의 가능한 PTS입니다 .; 사람들이 소스 코드로하고 싶어하는 광범위하고 다양한 것들을 충족시키는 방법이어야합니다. 관심있는 소스 파일을 많이 또는 적게 읽을 수 있도록 구성 할 수 있습니다. 분명히 읽지 않는 파일은 수정되지 않을 것입니다 : -} 파일 제한과 같은 제한을 쉽게 구현할 수 있습니다 (각 AST 노드는 원본 파일에 대해 스탬프 처리됩니다). semanitc 술어는 AST 노드에서 파일 표시를 검사하고 해당 파일이 관심 대상의 "하나"인지 확인해야합니다. –