/* * Copyright (c) 2014, the Dart project authors. * * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html * * 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.google.dart.java2dart.engine; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.io.Files; import com.google.dart.engine.AnalysisEngine; import com.google.dart.engine.ast.AsExpression; import com.google.dart.engine.ast.AstNode; import com.google.dart.engine.ast.ClassDeclaration; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.ast.CompilationUnitMember; import com.google.dart.engine.ast.Expression; import com.google.dart.engine.ast.ParenthesizedExpression; import com.google.dart.engine.ast.visitor.NodeLocator; import com.google.dart.engine.context.AnalysisContext; import com.google.dart.engine.context.AnalysisErrorInfo; import com.google.dart.engine.context.AnalysisResult; import com.google.dart.engine.context.ChangeSet; import com.google.dart.engine.error.AnalysisError; import com.google.dart.engine.error.HintCode; import com.google.dart.engine.sdk.DirectoryBasedDartSdk; import com.google.dart.engine.source.DartUriResolver; import com.google.dart.engine.source.FileBasedSource; import com.google.dart.engine.source.FileUriResolver; import com.google.dart.engine.source.PackageUriResolver; import com.google.dart.engine.source.Source; import com.google.dart.engine.source.SourceFactory; import com.google.dart.engine.utilities.io.PrintStringWriter; import com.google.dart.java2dart.Context; import com.google.dart.java2dart.processor.BeautifySemanticProcessor; import com.google.dart.java2dart.processor.CollectionSemanticProcessor; import com.google.dart.java2dart.processor.GuavaSemanticProcessor; import com.google.dart.java2dart.processor.IOSemanticProcessor; import com.google.dart.java2dart.processor.JUnitSemanticProcessor; import com.google.dart.java2dart.processor.ObjectSemanticProcessor; import com.google.dart.java2dart.processor.PropertySemanticProcessor; import com.google.dart.java2dart.processor.RenameConstructorsSemanticProcessor; import com.google.dart.java2dart.processor.SemanticProcessor; import com.google.dart.java2dart.processor.TypeSemanticProcessor; import com.google.dart.java2dart.processor.UniqueMemberNamesSemanticProcessor; import com.google.dart.java2dart.util.ToFormattedSourceVisitor; import static com.google.dart.java2dart.util.AstFactory.importDirective; import static com.google.dart.java2dart.util.AstFactory.importHideCombinator; import static com.google.dart.java2dart.util.AstFactory.importShowCombinator; import static com.google.dart.java2dart.util.AstFactory.libraryDirective; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; /** * Translates some parts of "com.google.dart.engine" project. */ public class MainAnalysisServer { static class Edit { public final int offset; public final int length; public final String replacement; public Edit(int offset, int length, String replacement) { this.offset = offset; this.length = length; this.replacement = replacement; } @Override public String toString() { return (offset < 0 ? "(" : "X(") + "offset: " + offset + ", length " + length + ", replacement :>" + replacement + "<:)"; } } private static final Context context = new Context(); private static File engineFolder; private static File serverFolder; private static File serviceFolder; private static CompilationUnit dartUnit; private static final String HEADER = "// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file\n" + "// for details. All rights reserved. Use of this source code is governed by a\n" + "// BSD-style license that can be found in the LICENSE file.\n" + "\n" + "// This code was auto-generated, is not intended to be edited, and is subject to\n" + "// significant change. Please see the README file for more information.\n\n"; public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println("Usage: java2dart <services-target-src-folder> <server-target-src-folder>"); System.exit(0); } String targetFolderServices = args[0]; String targetFolderServer = args[1]; System.out.println("Generating files into\n\t" + targetFolderServices + "\n\t" + targetFolderServer); new File(targetFolderServer).mkdirs(); // engineFolder = new File("../../../tools/plugins/com.google.dart.engine/src"); serviceFolder = new File("../../../tools/plugins/com.google.dart.engine.services/src"); serverFolder = new File("../../../tools/plugins/com.google.dart.server/src"); engineFolder = engineFolder.getCanonicalFile(); // configure Context context.addClasspathFile(new File("../../../../third_party/guava/r13/guava-13.0.1.jar")); context.addClasspathFile(new File( "../../../../third_party/commons-lang/3.2.1/commons-lang3-3.2.1.jar")); context.addClasspathFile(new File("../../../../third_party/junit/v4_8_2/junit.jar")); context.addSourceFolder(engineFolder); context.addSourceFolder(serviceFolder); context.addSourceFolder(serverFolder); context.addSourceFiles(new File(engineFolder, "com/google/dart/engine/")); context.addSourceFiles(new File(serverFolder, "com/google/dart/server/")); context.removeSourceFiles(new File(serverFolder, "com/google/dart/server/internal/remote/")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/assist")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/change")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/completion")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/correction")); context.addSourceFiles(new File( serviceFolder, "com/google/dart/engine/services/internal/completion")); context.addSourceFiles(new File( serviceFolder, "com/google/dart/engine/services/internal/correction")); context.addSourceFiles(new File( serviceFolder, "com/google/dart/engine/services/internal/refactoring")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/internal/util")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/refactoring")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/status")); context.addSourceFiles(new File(serviceFolder, "com/google/dart/engine/services/util")); // translate into single CompilationUnit dartUnit = context.translate(); // run processors { List<SemanticProcessor> PROCESSORS = ImmutableList.of( new TypeSemanticProcessor(context), new ObjectSemanticProcessor(context), new CollectionSemanticProcessor(context), new IOSemanticProcessor(context), new PropertySemanticProcessor(context), new GuavaSemanticProcessor(context), new JUnitSemanticProcessor(context), new EngineAnnotationProcessor(context), new UniqueMemberNamesSemanticProcessor(context), new RenameConstructorsSemanticProcessor(context), new EngineSemanticProcessor(context), new EngineInstanceOfProcessor(context), new BeautifySemanticProcessor(context)); for (SemanticProcessor processor : PROCESSORS) { processor.process(dartUnit); } } // run this again, because we may introduce conflicts when convert methods to getters/setters context.ensureUniqueClassMemberNames(); context.applyLocalVariableSemanticChanges(dartUnit); { CompilationUnit library = buildServiceInterfacesLibrary(); Files.write(getFormattedSource(library), new File(targetFolderServer + "/service_interfaces.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServiceComputersLibrary(); Files.write(getFormattedSource(library), new File(targetFolderServer + "/service_computers.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServicesLibrary_change(); Files.write( getFormattedSource(library), new File(targetFolderServices + "/change.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServicesLibrary_completion(); String source = getFormattedSource(library); // TODO(scheglov) improve java2dart to make this translated correctly source = replaceSourceFragment( source, "new CompletionEngine_CommentReferenceCompleter(this, _completionNode)", "new CompletionEngine_CommentReferenceCompleter(CompletionEngine_this, _completionNode)"); source = replaceSourceFragment( source, "new CompletionEngine_TypeNameCompleter(this, _completionNode, node)", "new CompletionEngine_TypeNameCompleter(CompletionEngine_this, _completionNode, node)"); // source = replaceSourceFragment( // source, // "new CompletionEngine_NameCollector(this)", // "new CompletionEngine_NameCollector(CompletionEngine_this)"); source = replaceSourceFragment( source, "new CompletionEngine_IdentifierCompleter(this, node)", "new CompletionEngine_IdentifierCompleter(CompletionEngine_this, node)"); source = replaceSourceFragment( source, "new CompletionEngine_StringCompleter(this, node)", "new CompletionEngine_StringCompleter(CompletionEngine_this, node)"); Files.write(source, new File(targetFolderServices + "/completion.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServicesLibrary_status(); Files.write( getFormattedSource(library), new File(targetFolderServices + "/status.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServicesLibrary_proposal(); Files.write( getFormattedSource(library), new File(targetFolderServices + "/proposal.dart"), Charsets.UTF_8); } { CompilationUnit library = buildServicesLibrary_util(); Files.write( getFormattedSource(library), new File(targetFolderServices + "/util.dart"), Charsets.UTF_8); } // TODO(scheglov) restore to translate more // { // CompilationUnit library = buildServicesLibrary_assist(); // Files.write(getFormattedSource(library), new File(targetFolder2 // + "/service_correction.dart"), Charsets.UTF_8); // } { CompilationUnit library = buildServicesLibrary_refactoring(); Files.write( getFormattedSource(library), new File(targetFolderServices + "/refactoring.dart"), Charsets.UTF_8); } { String projectFolder = new File(targetFolderServices).getParentFile().getParentFile().getParent(); fixUnnecessaryCastHints(projectFolder); } { String projectFolder = new File(targetFolderServer).getParentFile().getParentFile().getParent(); fixUnnecessaryCastHints(projectFolder); } System.out.println("Translation complete"); } private static void addNotRemovedCompiationUnitEntries(CompilationUnit targetUnit, List<CompilationUnitMember> members) { for (CompilationUnitMember member : members) { // may be removed CompilationUnit memberUnit = (CompilationUnit) member.getParent(); if (memberUnit == null || !memberUnit.getDeclarations().contains(member)) { continue; } // OK, add this member targetUnit.getDeclarations().add(member); } } private static void applyEdits(File file, List<Edit> edits) throws IOException { // sort in descending order Collections.sort(edits, new Comparator<Edit>() { @Override public int compare(Edit o1, Edit o2) { return o2.offset - o1.offset; } }); // apply to file String content = Files.toString(file, Charsets.UTF_8); for (Edit edit : edits) { content = content.substring(0, edit.offset) + edit.replacement + content.substring(edit.offset + edit.length); } Files.write(content, file, Charsets.UTF_8); } private static CompilationUnit buildServiceComputersLibrary() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("service", "computers")); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_core.dart", null, importShowCombinator("JavaStringBuilder", "StringUtils"))); unit.getDirectives().add( importDirective("package:analyzer/src/generated/java_engine.dart", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/source.dart", null, importShowCombinator("Source"))); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/scanner.dart", null, importShowCombinator("Token"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", "pae")); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/element.dart", null, importShowCombinator("DartType"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source.dart", null)); unit.getDirectives().add(importDirective("service_interfaces.dart", "psi")); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServerPath(file, "internal/local/computer/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } EngineSemanticProcessor.useImportPrefix( context, unit, "psi", new String[] {"com.google.dart.server."}, true); EngineSemanticProcessor.useImportPrefix( context, unit, "pae", new String[] {"com.google.dart.engine.element."}, false); return unit; } private static CompilationUnit buildServiceInterfacesLibrary() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("service", "interfaces")); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_core.dart", null, importShowCombinator("Enum", "StringUtils"))); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/source.dart", null, importShowCombinator("Source"))); unit.getDirectives().add( importDirective( "package:analysis_services/src/generated/change.dart", null, importShowCombinator("SourceChange"))); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServerPath(file, "AssistsConsumer.java") || isServerPath(file, "CompletionSuggestion.java") || isServerPath(file, "CompletionSuggestionKind.java") || isServerPath(file, "Consumer.java") || isServerPath(file, "Element.java") || isServerPath(file, "ElementKind.java") || isServerPath(file, "HighlightRegion.java") || isServerPath(file, "HighlightType.java") || isServerPath(file, "ListSourceSet.java") || isServerPath(file, "NavigationRegion.java") || isServerPath(file, "NotificationKind.java") || isServerPath(file, "Outline.java") || isServerPath(file, "OutlineKind.java") || isServerPath(file, "SearchResult.java") || isServerPath(file, "SearchResultKind.java") || isServerPath(file, "SearchResultsConsumer.java") || isServerPath(file, "SourceRegion.java") || isServerPath(file, "SourceSet.java") || isServerPath(file, "SourceSetKind.java") || isServerPath(file, "TypeHierarchyItem.java") || isServerPath(file, "internal/local/ImplicitSourceSet.java")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_assist() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("service", "correction")); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/engine.dart", null, importShowCombinator("AnalysisContext"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/error.dart", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_core.dart", null, importHideCombinator("StringUtils"))); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_io.dart", null, importShowCombinator("JavaFile"))); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/parser.dart", null, importShowCombinator("ParserErrorCode"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/scanner.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/sdk.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source_io.dart", null)); unit.getDirectives().add( importDirective("package:analyzer/src/generated/utilities_dart.dart", null)); unit.getDirectives().add(importDirective("change.dart", null)); unit.getDirectives().add(importDirective("proposal.dart", null)); unit.getDirectives().add(importDirective("stubs.dart", null)); unit.getDirectives().add(importDirective("util.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isCorrectionProposalFile(file)) { continue; } if (isCorrectionUtilFile(file)) { continue; } if (isServicePath(file, "assist/") || isServicePath(file, "correction/") || isServicePath(file, "internal/correction/") || isServicePath(file, "internal/util/TokenUtils.java") || isServicePath(file, "util/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_change() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("services", "change")); unit.getDirectives().add(importDirective("dart:collection", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_io.dart", null, importShowCombinator("JavaFile"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServicePath(file, "change/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_completion() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("services", "completion")); unit.getDirectives().add(importDirective("dart:collection", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_core.dart", null, importHideCombinator("StringUtils"))); unit.getDirectives().add( importDirective("package:analyzer/src/generated/java_engine.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/java_io.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/engine.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/error.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/resolver.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/scanner.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/sdk.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source_io.dart", null)); unit.getDirectives().add( importDirective("package:analyzer/src/generated/utilities_dart.dart", null)); unit.getDirectives().add(importDirective("stubs.dart", null)); unit.getDirectives().add(importDirective("util.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServicePath(file, "completion/") || isServicePath(file, "internal/completion/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_proposal() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("services", "proposal")); unit.getDirectives().add(importDirective("package:analyzer/src/generated/java_core.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/java_io.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source.dart", null)); unit.getDirectives().add(importDirective("change.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isCorrectionProposalFile(file)) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_refactoring() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("service", "refactoring")); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", null)); // unit.getDirectives().add( // importDirective( // "package:analyzer/src/generated/engine.dart", // null, // importShowCombinator("AnalysisContext"))); // unit.getDirectives().add(importDirective("package:analyzer/src/generated/error.dart", null)); // unit.getDirectives().add( // importDirective( // "package:analyzer/src/generated/java_core.dart", // null, // importHideCombinator("StringUtils"))); // unit.getDirectives().add( // importDirective( // "package:analyzer/src/generated/java_io.dart", // null, // importShowCombinator("JavaFile"))); // unit.getDirectives().add( // importDirective( // "package:analyzer/src/generated/parser.dart", // null, // importShowCombinator("ParserErrorCode"))); // unit.getDirectives().add(importDirective("package:analyzer/src/generated/scanner.dart", null)); // unit.getDirectives().add(importDirective("package:analyzer/src/generated/sdk.dart", null)); // unit.getDirectives().add(importDirective("package:analyzer/src/generated/source_io.dart", null)); // unit.getDirectives().add( // importDirective("package:analyzer/src/generated/utilities_dart.dart", null)); // unit.getDirectives().add(importDirective("change.dart", null)); // unit.getDirectives().add(importDirective("proposal.dart", null)); // unit.getDirectives().add(importDirective("stubs.dart", null)); // unit.getDirectives().add(importDirective("util.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServicePath(file, "refactoring/") || isServicePath(file, "internal/refactoring/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_status() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("services", "status")); unit.getDirectives().add(importDirective("package:analyzer/src/generated/java_core.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/engine.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source.dart", null)); unit.getDirectives().add(importDirective("stubs.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isServicePath(file, "status/")) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static CompilationUnit buildServicesLibrary_util() throws Exception { CompilationUnit unit = new CompilationUnit(null, null, null, null, null); unit.getDirectives().add(libraryDirective("services", "util")); unit.getDirectives().add(importDirective("dart:collection", null)); unit.getDirectives().add( importDirective( "package:analyzer/src/generated/java_core.dart", null, importHideCombinator("StringUtils"))); unit.getDirectives().add(importDirective("package:analyzer/src/generated/ast.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/element.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/engine.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/error.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/resolver.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/source.dart", null)); unit.getDirectives().add(importDirective("package:analyzer/src/generated/scanner.dart", null)); unit.getDirectives().add(importDirective("change.dart", null)); unit.getDirectives().add(importDirective("proposal.dart", null)); unit.getDirectives().add(importDirective("status.dart", null)); unit.getDirectives().add(importDirective("stubs.dart", null)); for (Entry<File, List<CompilationUnitMember>> entry : context.getFileToMembers().entrySet()) { File file = entry.getKey(); if (isCorrectionUtilFile(file)) { addNotRemovedCompiationUnitEntries(unit, entry.getValue()); } } return unit; } private static void fixUnnecessaryCastHints(String projectPath) throws Exception { System.out.println(); System.out.println("Removing unnecessary casts."); AnalysisContext context = AnalysisEngine.getInstance().createAnalysisContext(); DirectoryBasedDartSdk sdk = DirectoryBasedDartSdk.getDefaultSdk(); SourceFactory sourceFactory = new SourceFactory( new DartUriResolver(sdk), new FileUriResolver(), new PackageUriResolver(new File(projectPath + "/packages"))); context.setSourceFactory(sourceFactory); // prepare sources List<Source> sources = Lists.newArrayList(); Map<Source, File> sourceToFile = Maps.newHashMap(); for (File file : FileUtils.listFiles( new File(projectPath + "/lib/src/generated"), new String[] {"dart"}, true)) { if (file.getAbsolutePath().contains("/packages/")) { continue; } FileBasedSource source = new FileBasedSource(file); sources.add(source); sourceToFile.put(source, file); } // add sources to AnalysisContext { ChangeSet changeSet = new ChangeSet(); for (Source source : sources) { changeSet.addedSource(source); } context.applyChanges(changeSet); } System.out.println(sources.size() + " sources to analyze."); // perform analysis while (true) { AnalysisResult analysisResult = context.performAnalysisTask(); if (analysisResult.getChangeNotices() == null) { break; } } System.out.println("Analysis done."); // process errors for (Source source : sources) { CompilationUnit unit = context.parseCompilationUnit(source); List<Edit> edits = Lists.newArrayList(); AnalysisErrorInfo errorInfo = context.getErrors(source); AnalysisError[] errors = errorInfo.getErrors(); for (AnalysisError error : errors) { if (error.getErrorCode() == HintCode.UNNECESSARY_CAST) { AstNode node = new NodeLocator(error.getOffset()).searchWithin(unit); AsExpression asExpression = node.getAncestor(AsExpression.class); if (asExpression != null) { // remove "as" and its enclosing () AstNode enclosing = asExpression; if (enclosing.getParent() instanceof ParenthesizedExpression) { enclosing = enclosing.getParent(); } // add Edit Expression expr = asExpression.getExpression(); int enOffset = enclosing.getOffset(); int exEnd = expr.getEnd(); edits.add(new Edit(enOffset, expr.getOffset() - enOffset, "")); edits.add(new Edit(exEnd, enclosing.getEnd() - exEnd, "")); } } } // apply edits to file File file = sourceToFile.get(source); applyEdits(file, edits); } System.out.println("Edits applied."); System.out.println(); } /** * @return the formatted Dart source dump of the given {@link AstNode}. */ private static String getFormattedSource(CompilationUnit unit) { PrintStringWriter writer = new PrintStringWriter(); writer.append(HEADER); sortUnitMembersByName(unit); unit.accept(new ToFormattedSourceVisitor(writer)); String source = writer.toString(); source = removeTrailingWhitespaces(source); return source; } private static boolean isCorrectionProposalFile(File file) throws Exception { return isServicePath(file, "correction/AddDependencyCorrectionProposal.java") || isServicePath(file, "correction/ChangeCorrectionProposal.java") || isServicePath(file, "correction/CorrectionImage.java") || isServicePath(file, "correction/CorrectionKind.java") || isServicePath(file, "correction/CorrectionProposal.java") || isServicePath(file, "correction/CreateFileCorrectionProposal.java") || isServicePath(file, "correction/LinkedPositionProposal.java") || isServicePath(file, "correction/SourceCorrectionProposal.java"); } private static boolean isCorrectionUtilFile(File file) throws Exception { return isServicePath(file, "assist/AssistContext.java") || isServicePath(file, "util/HierarchyUtils.java") || isServicePath(file, "util/NameOccurrencesFinder.java") || isServicePath(file, "util/SelectionAnalyzer.java") || isServicePath(file, "internal/correction/CorrectionUtils.java") || isServicePath(file, "internal/correction/SourceBuilder.java") || isServicePath(file, "internal/correction/StatementAnalyzer.java") || isServicePath(file, "internal/correction/URIUtils.java") || isServicePath(file, "internal/util/TokenUtils.java"); } /** * @param serverPackage the sub-package in <code>com/google/dart/server</code>. * @return <code>true</code> if given {@link File} is located in sub-package of Engine project. */ private static boolean isServerPath(File file, String serverPackage) throws Exception { String filePath = file.getCanonicalPath(); String prefix = serverFolder.getCanonicalPath() + "/com/google/dart/server/" + serverPackage; return filePath.startsWith(prefix); } /** * @param servicePackage the sub-package in <code>com/google/dart/engine/services</code>. * @return <code>true</code> if given {@link File} is located in sub-package of Engine project. */ private static boolean isServicePath(File file, String servicePackage) throws Exception { String filePath = file.getCanonicalPath(); String prefix = serviceFolder.getCanonicalPath() + "/com/google/dart/engine/services/" + servicePackage; return filePath.startsWith(prefix); } /** * Removes trailing spaces from the given Dart source. */ private static String removeTrailingWhitespaces(String source) { String[] lines = StringUtils.splitPreserveAllTokens(source, '\n'); for (int i = 0; i < lines.length; i++) { lines[i] = StringUtils.stripEnd(lines[i], null); } return StringUtils.join(lines, "\n"); } /** * Replaces the fragment of the source specified by the RE pattern with the given source. * * @param source the source to replace fragment in * @param pattern the fragment to replace * @param replacement the source to replace fragment with * @return the source with the replacement fragment */ private static String replaceSourceFragment(String source, String pattern, String replacement) { int index = source.indexOf(pattern); if (index == -1) { throw new IllegalArgumentException("Not found: " + pattern); } return StringUtils.replace(source, pattern, replacement); } private static void sortUnitMembersByName(CompilationUnit unit) { Collections.sort(unit.getDeclarations(), new Comparator<CompilationUnitMember>() { @Override public int compare(CompilationUnitMember o1, CompilationUnitMember o2) { String name1 = ((ClassDeclaration) o1).getName().getName(); String name2 = ((ClassDeclaration) o2).getName().getName(); return name1.compareTo(name2); } }); } }